jail.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* Copyright (C) 2004,2005 David Antliff <dave.antliff@paradise.net.nz>
  2. *
  3. * This program is free software; you can redistribute it and/or
  4. * modify it under the terms of version 2 of the GNU General Public
  5. * License as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. * General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public
  13. * License along with this program; if not, write to the
  14. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. * Boston, MA 02111-1307, USA.
  16. *
  17. *
  18. *
  19. * This program allows you to block the mouse a specified area or
  20. * a twinView screen of your desktop.
  21. * Usage: ./Jail X1 Y1 X2 Y2
  22. * or ./Jail ScreenIdx
  23. *
  24. * Compile with:
  25. * gcc -g Jail.c -o Jail -L /usr/X11R6/lib -lX11 -lXtst -lXext -lXrandr
  26. *
  27. * This program was heavily based on switchscreen, by David Antliff.
  28. * Created by Sebastien Marion <seb.marion@gmail.com>
  29. *
  30. * Original program bz David Antliff modified to take in coordinates
  31. * instead of whole X Screen
  32. * (for those twinView guys out there)
  33. *
  34. * Enhanced by Tom Li <biergaizi@member.fsf.org> for Xrandr Screen.
  35. */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <unistd.h>
  39. #include <X11/X.h>
  40. #include <X11/Xutil.h>
  41. #include <X11/extensions/XTest.h>
  42. #include <X11/extensions/Xrandr.h>
  43. /******************************************************************************
  44. FUNCTION : main
  45. DESCRIPTION :
  46. ******************************************************************************/
  47. int main(int argc, char **argv)
  48. {
  49. Display *display;
  50. int majorOpcode, firstEvent, firstError;
  51. char *displayName;
  52. int thisScreen;
  53. int otherScreen = -1;
  54. int CX1 = -1, CY1 = -1, CX2 = -1, CY2 = -1;
  55. int screen_idx = -1;
  56. if (argc == 5) {
  57. CX1 = atoi(argv[1]);
  58. CY1 = atoi(argv[2]);
  59. CX2 = atoi(argv[3]);
  60. CY2 = atoi(argv[4]);
  61. } else if (argc == 2) {
  62. screen_idx = atoi(argv[1]);
  63. } else {
  64. fprintf(stderr, "Usage: %s X1 Y1 X2 Y2\n", argv[0]);
  65. fprintf(stderr, "Or %s ScreenIdx\n", argv[0]);
  66. return 0;
  67. }
  68. displayName = getenv("DISPLAY");
  69. if (displayName == NULL) {
  70. fprintf(stderr, "DISPLAY is not set\n");
  71. exit(1);
  72. }
  73. fprintf(stderr, "Opening display %s\n", displayName);
  74. display = XOpenDisplay(displayName);
  75. if (!XQueryExtension(display,
  76. XTestExtensionName,
  77. &majorOpcode, &firstEvent, &firstError)) {
  78. fprintf(stderr, "XTEST extension not available\n");
  79. return (1);
  80. }
  81. if (!XRRQueryExtension(display, &firstEvent, &firstError)) {
  82. fprintf(stderr, "XRandr extension not available\n");
  83. return (1);
  84. }
  85. thisScreen = DefaultScreen(display);
  86. if (otherScreen == -1) {
  87. otherScreen = 1 - DefaultScreen(display);
  88. }
  89. if (screen_idx != -1) {
  90. XRRScreenResources *screen =
  91. XRRGetScreenResources(display, DefaultRootWindow(display));
  92. if (screen_idx > screen->ncrtc) {
  93. fprintf(stderr, "Screen %d is not exist.\n", screen_idx);
  94. return 1;
  95. }
  96. XRRCrtcInfo *crtc_info =
  97. XRRGetCrtcInfo(display, screen, screen->crtcs[screen_idx]);
  98. CX1 = crtc_info->x;
  99. CY1 = crtc_info->y;
  100. CX2 = crtc_info->x + crtc_info->width;
  101. CY2 = crtc_info->y + crtc_info->height;
  102. }
  103. else if (CX1 >= 0 && CY1 >= 0 && CX2 >= 0 && CY2 >= 0) {
  104. // okay
  105. }
  106. else {
  107. fprintf(stderr, "neither coordinate or screen was specificed\n");
  108. return 1;
  109. }
  110. fprintf(stderr, "thisScreen: %d -- otherScreen: %d", thisScreen,
  111. otherScreen);
  112. if (otherScreen != thisScreen) {
  113. int root_x, root_y;
  114. int win_x, win_y;
  115. unsigned int mask;
  116. Window root, child;
  117. int modif = 0;
  118. while (1) {
  119. // get current mouse coordinates
  120. XQueryPointer(display,
  121. RootWindow(display, thisScreen),
  122. &root,
  123. &child, &root_x, &root_y, &win_x, &win_y, &mask);
  124. //only modify 1 coordinate when possible..
  125. // lets the mouse move more 'freely'
  126. // at the edge
  127. if (root_x < CX1) {
  128. root_x = CX1;
  129. modif = 1;
  130. } else if (root_x > CX2) {
  131. root_x = CX2;
  132. modif = 1;
  133. } else if (root_y < CY1) {
  134. root_y = CY1;
  135. modif = 1;
  136. } else if (root_y > CY2) {
  137. root_y = CY2;
  138. modif = 1;
  139. };
  140. if (modif == 1) {
  141. XTestFakeMotionEvent(display, thisScreen, root_x, root_y,
  142. CurrentTime);
  143. }
  144. usleep(1000);
  145. modif = 0;
  146. }
  147. }
  148. XCloseDisplay(display);
  149. return (0);
  150. }