home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1999 March / PCShareware-3-99.iso / IMPLE / DJGPP.RAR / DJGPP2 / XLIB-SR0.ZIP / SRC / XLIBEMU / POINTER.C < prev    next >
C/C++ Source or Header  |  1994-01-26  |  9KB  |  327 lines

  1. /* $Id: pointer.c 1.3 1994/01/26 19:27:22 ulrich Exp $ */
  2. /*
  3.  * pointer.c
  4.  *
  5.  * X library functions for pointer grabbing and querying.
  6.  */
  7. #include "Xlibemu.h"
  8.  
  9.  
  10. int XGrabPointer
  11. (    Display *    dpy,
  12.     Window        grab_window,
  13.     Bool        owner_events,
  14.     unsigned int    event_mask,
  15.     int        pointer_mode,
  16.     int        keyboard_mode,
  17.     Window        confine_to,
  18.     Cursor        cursor,
  19.     Time        time)
  20. {
  21.   XEvent xe;
  22.   _WQueueEvent ev;
  23.   Window pointer_window;
  24.  
  25.   _WCheckWindow (dpy, grab_window, X_GrabPointer);
  26.  
  27.   if (_PointerGrab.active != 0 && _PointerGrab.display != dpy)
  28.     return AlreadyGrabbed;
  29.  
  30.   if ((! grab_window->viewable) ||
  31.       (confine_to && ! confine_to->viewable))
  32.     return GrabNotViewable;
  33.  
  34.   _PointerGrab.display = dpy;
  35.   _PointerGrab.grab_window = grab_window;
  36.   _PointerGrab.owner_events = owner_events;
  37.   _PointerGrab.event_mask = event_mask;
  38.   _PointerGrab.pointer_mode = pointer_mode;
  39.   _PointerGrab.keyboard_mode = keyboard_mode;
  40.   _PointerGrab.confine_to = confine_to;
  41.   _PointerGrab.cursor = cursor;
  42.   _PointerGrab.time = (time == CurrentTime) ? _WCurrentTime() : time;
  43.   _PointerGrab.pointer_x = -1;
  44.   _PointerGrab.pointer_y = -1;
  45.  
  46.   _WQueueQuery (&ev);
  47.   pointer_window = _WPointToWindow (dpy, ev.x, ev.y);
  48.  
  49.   if (confine_to != None && confine_to != pointer_window &&
  50.       ! _WIsInferior (confine_to, pointer_window)) {
  51.     _PointerGrab.pointer_x = ev.x;
  52.     _PointerGrab.pointer_y = ev.y;
  53.     XWarpPointer (dpy, None, confine_to, 0, 0, 0, 0, 0, 0);
  54.   }
  55.   
  56.   xe.xcrossing.send_event = 0;
  57.   xe.xcrossing.display = dpy;
  58.   xe.xcrossing.root = DefaultRootWindow (dpy);
  59.   xe.xcrossing.subwindow = None;
  60.   xe.xcrossing.time = (time == CurrentTime) ? _WCurrentTime() : time;
  61.   xe.xcrossing.x = ev.x - pointer_window->window_port.x1;
  62.   xe.xcrossing.y = ev.y - pointer_window->window_port.y1;
  63.   xe.xcrossing.x_root = ev.x;
  64.   xe.xcrossing.y_root = ev.y;
  65.   xe.xcrossing.mode = NotifyGrab;
  66.   xe.xcrossing.detail = 0;
  67.   xe.xcrossing.same_screen = True;
  68.   xe.xcrossing.focus = 0;
  69.   xe.xcrossing.state = 0;
  70.  
  71.   if (pointer_window->event_mask & LeaveWindowMask) {
  72.     xe.xcrossing.type = LeaveNotify;
  73.     xe.xcrossing.window = pointer_window;
  74.     xe.xcrossing.focus = _WIsFocus (xe.xcrossing.root, xe.xcrossing.window);
  75.     _XEnq (dpy, &xe);
  76.   }
  77.   if (grab_window->event_mask & EnterWindowMask) {
  78.     xe.xcrossing.type = EnterNotify;
  79.     xe.xcrossing.window = grab_window;
  80.     xe.xcrossing.focus = _WIsFocus (xe.xcrossing.root, xe.xcrossing.window);
  81.     _XEnq (dpy, &xe);
  82.   }
  83.  
  84.   if (cursor) _WDefineCursor (cursor);
  85.  
  86.   _PointerGrab.active = 1;
  87.  
  88.   return GrabSuccess;
  89. }
  90.  
  91. int XUngrabPointer (Display *dpy, Time time)
  92. {
  93.   XEvent xe;
  94.   _WQueueEvent ev;
  95.   Window pointer_window;
  96.  
  97.   if (_PointerGrab.active == 0 || _PointerGrab.display != dpy)
  98.     return 0;
  99.  
  100.   if (time != CurrentTime && 
  101.       (time < _PointerGrab.time || time > _WCurrentTime ()))
  102.     return 0;
  103.   
  104.   _PointerGrab.active = 0;
  105.   _PointerGrab.display = NULL;
  106.  
  107.   _WQueueQuery (&ev);
  108.   pointer_window = _WPointToWindow (dpy, ev.x, ev.y);
  109.  
  110.   xe.xcrossing.send_event = 0;
  111.   xe.xcrossing.display = dpy;
  112.   xe.xcrossing.root = DefaultRootWindow (dpy);
  113.   xe.xcrossing.subwindow = None;
  114.   xe.xcrossing.time = (time == CurrentTime) ? _WCurrentTime() : time;
  115.   xe.xcrossing.x = ev.x - pointer_window->window_port.x1;
  116.   xe.xcrossing.y = ev.y - pointer_window->window_port.y1;
  117.   xe.xcrossing.x_root = ev.x;
  118.   xe.xcrossing.y_root = ev.y;
  119.   xe.xcrossing.mode = NotifyUngrab;
  120.   xe.xcrossing.detail = 0;
  121.   xe.xcrossing.same_screen = True;
  122.   xe.xcrossing.focus = 0;
  123.   xe.xcrossing.state = 0;
  124.  
  125.   if (_PointerGrab.grab_window->event_mask & LeaveWindowMask) {
  126.     xe.xcrossing.window = _PointerGrab.grab_window;
  127.     xe.xcrossing.type = LeaveNotify;
  128.     _XEnq (dpy, &xe);
  129.   }
  130.   if (pointer_window->event_mask & EnterWindowMask) {
  131.     xe.xcrossing.window = pointer_window;
  132.     xe.xcrossing.type = EnterNotify;
  133.     _XEnq (dpy, &xe);
  134.   }
  135.  
  136.   if (_PointerGrab.confine_to != None
  137.       && _PointerGrab.pointer_x > 0
  138.       && _PointerGrab.pointer_y > 0) {
  139.     XWarpPointer (dpy,
  140.           _PointerGrab.confine_to, _PointerGrab.grab_window,
  141.           0, 0, 0, 0,
  142.           _PointerGrab.pointer_x - _PointerGrab.grab_window->window_port.x1,
  143.           _PointerGrab.pointer_y - _PointerGrab.grab_window->window_port.y1);
  144.   }
  145.   if (_PointerGrab.cursor) {
  146.     _WDefineCursor (_WGetWindowCursor (_PointerGrab.grab_window));
  147.   }
  148.   return 0;
  149. }
  150.  
  151. int XChangeActivePointerGrab
  152. (    Display *    dpy,
  153.     unsigned int    event_mask,
  154.     Cursor        cursor,
  155.     Time        time)
  156. {
  157.   if (_PointerGrab.active == 0 || _PointerGrab.display != dpy)
  158.     return 0;
  159.  
  160.   if (time != CurrentTime &&
  161.       (time < _PointerGrab.time || time > _WCurrentTime()))
  162.     return 0;
  163.  
  164.   _PointerGrab.event_mask = event_mask;
  165.   _PointerGrab.cursor = cursor;
  166.   _PointerGrab.time = (time == CurrentTime) ? _WCurrentTime() : time;
  167.  
  168.   _WDefineCursor (cursor);    /* request cursor change */
  169.   return 1;
  170. }
  171.  
  172. int XWarpPointer
  173. (    Display *    dpy,
  174.     Window        src_w,
  175.     Window        dest_w,
  176.     int        src_x,
  177.     int        src_y,
  178.     unsigned int    src_width,
  179.     unsigned int    src_height,
  180.     int        dest_x,
  181.     int        dest_y)
  182. {
  183.   Window enter_window, leave_window;
  184.   XEvent xe;
  185.   _WQueueEvent ev;
  186.   
  187.   /* first determine window containing the pointer */
  188.  
  189.   _WQueueQuery (&ev);
  190.  
  191.   /* test condition if any */
  192.   
  193.   if (src_w != None &&
  194.       src_w == _WPointToWindow (dpy, ev.x, ev.y)) {
  195.     BoxRec port;
  196.  
  197.     port = src_w->window_port;
  198.     port.x1 += src_x;
  199.     port.y1 += src_y;
  200.     if (port.x1 >= port.x2 || port.y1 >= port.y2)
  201.       return 0;
  202.     if (port.x1 + src_width < port.x2)
  203.       port.x2 = port.x1 + src_width;
  204.     if (port.y1 + src_height < port.y2)
  205.       port.y2 = port.y1 + src_height;
  206.     if (! INBOX(port, ev.x, ev.y))
  207.       return 0;
  208.   }
  209.   /* move relative or window absolute */
  210.   
  211.   if (dest_w != None) {
  212.     dest_x += dest_w->window_port.x1;
  213.     dest_y += dest_w->window_port.y1;
  214.   }
  215.   else {
  216.     dest_x = ev.x;
  217.     dest_y = ev.y;
  218.   }
  219.   _WMouseWarp (dest_x, dest_y);
  220.  
  221.   leave_window = _WPointToWindow (dpy, ev.x, ev.y);
  222.   enter_window = _WPointToWindow (dpy, dest_x, dest_y);
  223.  
  224.   xe.xany.send_event = 0;
  225.   xe.xany.display = dpy;
  226.  
  227.   if (leave_window == enter_window) {
  228.     xe.xmotion.type = MotionNotify;
  229.     xe.xmotion.window = enter_window;
  230.     xe.xmotion.root = DefaultRootWindow (dpy);
  231.     xe.xmotion.subwindow = None;
  232.     xe.xmotion.x = dest_x - enter_window->window_port.x1;
  233.     xe.xmotion.y = dest_y - enter_window->window_port.y1;
  234.     xe.xmotion.x_root = dest_x;
  235.     xe.xmotion.y_root = dest_y;
  236.     xe.xmotion.state = _WButtonAndModifierState (&ev);
  237.     xe.xmotion.is_hint = NotifyHint;
  238.     xe.xmotion.same_screen = True;
  239.     _WDispatchEvent (&xe);
  240.  
  241.     return 0;
  242.   }
  243.   if (leave_window->event_mask & LeaveWindowMask) {
  244.     xe.xcrossing.type = LeaveNotify;
  245.     xe.xcrossing.window = leave_window;
  246.     xe.xcrossing.root = DefaultRootWindow (dpy);
  247.     xe.xcrossing.subwindow = (enter_window->parent == leave_window) ? enter_window : None;
  248.     xe.xcrossing.time = _WCurrentTime ();
  249.     xe.xcrossing.x = ev.x - leave_window->window_port.x1;
  250.     xe.xcrossing.y = ev.y - leave_window->window_port.y1;
  251.     xe.xcrossing.x_root = ev.x;
  252.     xe.xcrossing.y_root = ev.y;
  253.     xe.xcrossing.mode = NotifyNormal;
  254.     if (_WIsInferior (leave_window, enter_window))
  255.       xe.xcrossing.detail = NotifyAncestor;
  256.     else if (_WIsInferior (enter_window, leave_window))
  257.       xe.xcrossing.detail = NotifyInferior;
  258.     else
  259.       xe.xcrossing.detail = NotifyNonlinear;
  260.     xe.xcrossing.same_screen = True;
  261.     xe.xcrossing.focus = 0;
  262.     xe.xcrossing.state = _WButtonAndModifierState (&ev);
  263.     _WDispatchEvent (&xe);
  264.   }
  265.   if (enter_window->event_mask & EnterWindowMask) {
  266.     xe.xcrossing.type = EnterNotify;
  267.     xe.xcrossing.window = enter_window;
  268.     xe.xcrossing.root = DefaultRootWindow (dpy);
  269.     xe.xcrossing.subwindow = None;
  270.     xe.xcrossing.time = _WCurrentTime ();
  271.     xe.xcrossing.x = dest_x - enter_window->window_port.x1;
  272.     xe.xcrossing.y = dest_y - enter_window->window_port.y1;
  273.     xe.xcrossing.x_root = dest_x;
  274.     xe.xcrossing.y_root = dest_y;
  275.     xe.xcrossing.mode = NotifyNormal;
  276.     if (_WIsInferior (enter_window, leave_window))
  277.       xe.xcrossing.detail = NotifyAncestor;
  278.     else if (_WIsInferior (leave_window, enter_window))
  279.       xe.xcrossing.detail = NotifyInferior;
  280.     else
  281.       xe.xcrossing.detail = NotifyNonlinear;
  282.     xe.xcrossing.same_screen = True;
  283.     xe.xcrossing.focus = 0;
  284.     xe.xcrossing.state = _WButtonAndModifierState (&ev);
  285.     _WDispatchEvent (&xe);
  286.   }
  287.   return 0;
  288. }
  289.  
  290. Bool XQueryPointer
  291. (    Display*    dpy,
  292.     Window        w,
  293.     Window*        root_return,
  294.     Window*        child_return,
  295.     int*        root_x_return,
  296.     int*        root_y_return,
  297.     int*        win_x_return,
  298.     int*        win_y_return,
  299.     unsigned int*    mask_return)
  300. {
  301.   int x, y;
  302.   _WQueueEvent ev;
  303.   Window child;
  304.  
  305.   _WQueueQuery (&ev);
  306.  
  307.   x = y = 0;
  308.   if (w != None) {
  309.     x = w->window_port.x1;
  310.     y = w->window_port.y1;
  311.   }
  312.   child = _WPointToWindow (dpy, ev.x, ev.y);
  313.   while (child != None && child->parent != w) {
  314.     child = child->parent;
  315.   }
  316.  
  317.   *root_return = DefaultRootWindow (dpy);
  318.   *child_return = child;
  319.   *root_x_return = ev.x;
  320.   *root_y_return = ev.y;
  321.   *win_x_return = ev.x - x;
  322.   *win_y_return = ev.y - y;
  323.   *mask_return = _WButtonAndModifierState (&ev);
  324.  
  325.   return True;
  326. }
  327.