Advertisement
metalx1000

C Programming draw Rectangle with mouse coordinates

May 4th, 2024
1,285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.80 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<X11/Xlib.h>
  4. #include<X11/cursorfont.h>
  5. #include<unistd.h> // added for sleep/usleep
  6.  
  7. // original from [https://bbs.archlinux.org/viewtopic.php?id=85378 Select a screen area with mouse and return the geometry of this area? / Programming & Scripting / Arch Linux Forums]
  8. // build with (Ubuntu 14.04):
  9. // gcc -Wall xrectsel.c -o xrectsel -lX11
  10.  
  11. int main(void)
  12. {
  13.   int rx = 0, ry = 0, rw = 0, rh = 0;
  14.   int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0;
  15.   int btn_pressed = 0, done = 0;
  16.  
  17.   XEvent ev;
  18.   Display *disp = XOpenDisplay(NULL);
  19.  
  20.   if(!disp)
  21.     return EXIT_FAILURE;
  22.  
  23.   Screen *scr = NULL;
  24.   scr = ScreenOfDisplay(disp, DefaultScreen(disp));
  25.  
  26.   Window root = 0;
  27.   root = RootWindow(disp, XScreenNumberOfScreen(scr));
  28.  
  29.   Cursor cursor, cursor2;
  30.   cursor = XCreateFontCursor(disp, XC_left_ptr);
  31.   cursor2 = XCreateFontCursor(disp, XC_lr_angle);
  32.  
  33.   XGCValues gcval;
  34.   gcval.foreground = XWhitePixel(disp, 0);
  35.   gcval.function = GXxor;
  36.   gcval.background = XBlackPixel(disp, 0);
  37.   gcval.plane_mask = gcval.background ^ gcval.foreground;
  38.   gcval.subwindow_mode = IncludeInferiors;
  39.  
  40.   GC gc;
  41.   gc = XCreateGC(disp, root,
  42.                  GCFunction | GCForeground | GCBackground | GCSubwindowMode,
  43.                  &gcval);
  44.  
  45.   /* this XGrab* stuff makes XPending true ? */
  46.   if ((XGrabPointer
  47.     (disp, root, False,
  48.      ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
  49.      GrabModeAsync, root, cursor, CurrentTime) != GrabSuccess))
  50.     printf("couldn't grab pointer:");
  51.  
  52.   if ((XGrabKeyboard
  53.     (disp, root, False, GrabModeAsync, GrabModeAsync,
  54.      CurrentTime) != GrabSuccess))
  55.     printf("couldn't grab keyboard:");
  56.  
  57.   // see also: http://stackoverflow.com/questions/19659486/xpending-cycle-is-making-cpu-100
  58.   while (!done) {
  59.     //~ while (!done && XPending(disp)) {
  60.     //~ XNextEvent(disp, &ev);
  61.     if (!XPending(disp)) { usleep(1000); continue; } // fixes the 100% CPU hog issue in original code
  62.     if ( (XNextEvent(disp, &ev) >= 0) ) {
  63.       switch (ev.type) {
  64.         case MotionNotify:
  65.           /* this case is purely for drawing rect on screen */
  66.           if (btn_pressed) {
  67.             if (rect_w) {
  68.               /* re-draw the last rect to clear it */
  69.               XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  70.             } else {
  71.               /* Change the cursor to show we're selecting a region */
  72.               XChangeActivePointerGrab(disp,
  73.                                        ButtonMotionMask | ButtonReleaseMask,
  74.                                        cursor2, CurrentTime);
  75.             }
  76.             rect_x = rx;
  77.             rect_y = ry;
  78.             rect_w = ev.xmotion.x - rect_x;
  79.             rect_h = ev.xmotion.y - rect_y;
  80.  
  81.             if (rect_w < 0) {
  82.               rect_x += rect_w;
  83.               rect_w = 0 - rect_w;
  84.             }
  85.             if (rect_h < 0) {
  86.               rect_y += rect_h;
  87.               rect_h = 0 - rect_h;
  88.             }
  89.             /* draw rectangle */
  90.             XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  91.             XFlush(disp);
  92.           }
  93.           break;
  94.         case ButtonPress:
  95.           btn_pressed = 1;
  96.           rx = ev.xbutton.x;
  97.           ry = ev.xbutton.y;
  98.           break;
  99.         case ButtonRelease:
  100.           done = 1;
  101.           break;
  102.       }
  103.     }
  104.   }
  105.   /* clear the drawn rectangle */
  106.   if (rect_w) {
  107.     XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
  108.     XFlush(disp);
  109.   }
  110.   rw = ev.xbutton.x - rx;
  111.   rh = ev.xbutton.y - ry;
  112.   /* cursor moves backwards */
  113.   if (rw < 0) {
  114.     rx += rw;
  115.     rw = 0 - rw;
  116.   }
  117.   if (rh < 0) {
  118.     ry += rh;
  119.     rh = 0 - rh;
  120.   }
  121.  
  122.   XCloseDisplay(disp);
  123.  
  124.   printf("%dx%d+%d+%d\n",rw,rh,rx,ry);
  125.  
  126.   return EXIT_SUCCESS;
  127. }
  128.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement