home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / win / tkWinPointer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  10.2 KB  |  454 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkWinPointer.c --
  3.  *
  4.  *    Windows specific mouse tracking code.
  5.  *
  6.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * SCCS: @(#) tkWinPointer.c 1.27 97/08/11 10:46:46
  12.  */
  13.  
  14. #include "tkWinInt.h"
  15.  
  16. /*
  17.  * Check for enter/leave events every MOUSE_TIMER_INTERVAL milliseconds.
  18.  */
  19.  
  20. #define MOUSE_TIMER_INTERVAL 250
  21.  
  22. /*
  23.  * Declarations of static variables used in this file.
  24.  */
  25.  
  26. static int captured = 0;        /* 1 if mouse is currently captured. */
  27. static TkWindow *keyboardWinPtr = NULL; /* Current keyboard grab window. */
  28. static Tcl_TimerToken mouseTimer;    /* Handle to the latest mouse timer. */
  29. static int mouseTimerSet = 0;        /* 1 if the mouse timer is active. */
  30.  
  31. /*
  32.  * Forward declarations of procedures used in this file.
  33.  */
  34.  
  35. static void        MouseTimerProc _ANSI_ARGS_((ClientData clientData));
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * TkWinGetModifierState --
  41.  *
  42.  *    Return the modifier state as of the last message.
  43.  *
  44.  * Results:
  45.  *    Returns the X modifier mask.
  46.  *
  47.  * Side effects:
  48.  *    None.
  49.  *
  50.  *----------------------------------------------------------------------
  51.  */
  52.  
  53. int
  54. TkWinGetModifierState()
  55. {
  56.     int state = 0;
  57.  
  58.     if (GetKeyState(VK_SHIFT) & 0x8000) {
  59.     state |= ShiftMask;
  60.     }
  61.     if (GetKeyState(VK_CONTROL) & 0x8000) {
  62.     state |= ControlMask;
  63.     }
  64.     if (GetKeyState(VK_MENU) & 0x8000) {
  65.     state |= Mod2Mask;
  66.     }
  67.     if (GetKeyState(VK_CAPITAL) & 0x0001) {
  68.     state |= LockMask;
  69.     }
  70.     if (GetKeyState(VK_NUMLOCK) & 0x0001) {
  71.     state |= Mod1Mask;
  72.     }
  73.     if (GetKeyState(VK_SCROLL) & 0x0001) {
  74.     state |= Mod3Mask;
  75.     }
  76.     if (GetKeyState(VK_LBUTTON) & 0x8000) {
  77.     state |= Button1Mask;
  78.     }
  79.     if (GetKeyState(VK_MBUTTON) & 0x8000) {
  80.     state |= Button2Mask;
  81.     }
  82.     if (GetKeyState(VK_RBUTTON) & 0x8000) {
  83.     state |= Button3Mask;
  84.     }
  85.     return state;
  86. }
  87.  
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * Tk_PointerEvent --
  92.  *
  93.  *    This procedure is called for each pointer-related event.
  94.  *    It converts the position to root coords and updates the
  95.  *    global pointer state machine.  It also ensures that the
  96.  *    mouse timer is scheduled.
  97.  *
  98.  * Results:
  99.  *    None.
  100.  *
  101.  * Side effects:
  102.  *    May queue events and change the grab state.
  103.  *
  104.  *----------------------------------------------------------------------
  105.  */
  106.  
  107. void
  108. Tk_PointerEvent(hwnd, x, y)
  109.     HWND hwnd;                /* Window for coords, or NULL for
  110.                      * the root window. */
  111.     int x, y;                /* Coords relative to hwnd, or screen
  112.                      * if hwnd is NULL. */
  113. {
  114.     POINT pos;
  115.     int state;
  116.     Tk_Window tkwin;
  117.  
  118.     pos.x = x;
  119.     pos.y = y;
  120.  
  121.     /*
  122.      * Convert client coords to root coords if we were given a window.
  123.      */
  124.  
  125.     if (hwnd) {
  126.     ClientToScreen(hwnd, &pos);
  127.     }
  128.  
  129.     /*
  130.      * If the mouse is captured, Windows will report all pointer
  131.      * events to the capture window.  So, we need to determine which
  132.      * window the mouse is really over and change the event.  Note
  133.      * that the computed hwnd may point to a window not owned by Tk,
  134.      * or a toplevel decorative frame, so tkwin can be NULL.
  135.      */
  136.  
  137.     if (captured || hwnd == NULL) {
  138.     hwnd = WindowFromPoint(pos);
  139.     }
  140.     tkwin = Tk_HWNDToWindow(hwnd);
  141.  
  142.     state = TkWinGetModifierState();
  143.  
  144.     Tk_UpdatePointer(tkwin, pos.x, pos.y, state);
  145.  
  146.     if ((captured || tkwin) && !mouseTimerSet) {
  147.     mouseTimerSet = 1;
  148.     mouseTimer = Tcl_CreateTimerHandler(MOUSE_TIMER_INTERVAL,
  149.         MouseTimerProc, NULL);
  150.     }
  151. }
  152.  
  153. /*
  154.  *----------------------------------------------------------------------
  155.  *
  156.  * XGrabKeyboard --
  157.  *
  158.  *    Simulates a keyboard grab by setting the focus.
  159.  *
  160.  * Results:
  161.  *    Always returns GrabSuccess.
  162.  *
  163.  * Side effects:
  164.  *    Sets the keyboard focus to the specified window.
  165.  *
  166.  *----------------------------------------------------------------------
  167.  */
  168.  
  169. int
  170. XGrabKeyboard(display, grab_window, owner_events, pointer_mode,
  171.     keyboard_mode, time)
  172.     Display* display;
  173.     Window grab_window;
  174.     Bool owner_events;
  175.     int pointer_mode;
  176.     int keyboard_mode;
  177.     Time time;
  178. {
  179.     keyboardWinPtr = TkWinGetWinPtr(grab_window);
  180.     return GrabSuccess;
  181. }
  182.  
  183. /*
  184.  *----------------------------------------------------------------------
  185.  *
  186.  * XUngrabKeyboard --
  187.  *
  188.  *    Releases the simulated keyboard grab.
  189.  *
  190.  * Results:
  191.  *    None.
  192.  *
  193.  * Side effects:
  194.  *    Sets the keyboard focus back to the value before the grab.
  195.  *
  196.  *----------------------------------------------------------------------
  197.  */
  198.  
  199. void
  200. XUngrabKeyboard(display, time)
  201.     Display* display;
  202.     Time time;
  203. {
  204.     keyboardWinPtr = NULL;
  205. }
  206.  
  207. /*
  208.  *----------------------------------------------------------------------
  209.  *
  210.  * MouseTimerProc --
  211.  *
  212.  *    Check the current mouse position and look for enter/leave 
  213.  *    events.
  214.  *
  215.  * Results:
  216.  *    None.
  217.  *
  218.  * Side effects:
  219.  *    May schedule a new timer and/or generate enter/leave events.
  220.  *
  221.  *----------------------------------------------------------------------
  222.  */
  223.  
  224. void
  225. MouseTimerProc(clientData)
  226.     ClientData clientData;
  227. {
  228.     POINT pos;
  229.  
  230.     mouseTimerSet = 0;
  231.  
  232.     /*
  233.      * Get the current mouse position and window.  Don't do anything
  234.      * if the mouse hasn't moved since the last time we looked.
  235.      */
  236.  
  237.     GetCursorPos(&pos);
  238.     Tk_PointerEvent(NULL, pos.x, pos.y);
  239. }
  240.  
  241. /*
  242.  *----------------------------------------------------------------------
  243.  *
  244.  * TkGetPointerCoords --
  245.  *
  246.  *    Fetch the position of the mouse pointer.
  247.  *
  248.  * Results:
  249.  *    *xPtr and *yPtr are filled in with the root coordinates
  250.  *    of the mouse pointer for the display.
  251.  *
  252.  * Side effects:
  253.  *    None.
  254.  *
  255.  *----------------------------------------------------------------------
  256.  */
  257.  
  258. void
  259. TkGetPointerCoords(tkwin, xPtr, yPtr)
  260.     Tk_Window tkwin;        /* Window that identifies screen on which
  261.                  * lookup is to be done. */
  262.     int *xPtr, *yPtr;        /* Store pointer coordinates here. */
  263. {
  264.     POINT point;
  265.  
  266.     GetCursorPos(&point);
  267.     *xPtr = point.x;
  268.     *yPtr = point.y;
  269. }
  270.  
  271. /*
  272.  *----------------------------------------------------------------------
  273.  *
  274.  * XQueryPointer --
  275.  *
  276.  *    Check the current state of the mouse.  This is not a complete
  277.  *    implementation of this function.  It only computes the root
  278.  *    coordinates and the current mask.
  279.  *
  280.  * Results:
  281.  *    Sets root_x_return, root_y_return, and mask_return.  Returns
  282.  *    true on success.
  283.  *
  284.  * Side effects:
  285.  *    None.
  286.  *
  287.  *----------------------------------------------------------------------
  288.  */
  289.  
  290. Bool
  291. XQueryPointer(display, w, root_return, child_return, root_x_return,
  292.     root_y_return, win_x_return, win_y_return, mask_return)
  293.     Display* display;
  294.     Window w;
  295.     Window* root_return;
  296.     Window* child_return;
  297.     int* root_x_return;
  298.     int* root_y_return;
  299.     int* win_x_return;
  300.     int* win_y_return;
  301.     unsigned int* mask_return;
  302. {
  303.     display->request++;
  304.     TkGetPointerCoords(NULL, root_x_return, root_y_return);
  305.     *mask_return = TkWinGetModifierState();
  306.     return True;
  307. }
  308.  
  309. /*
  310.  *----------------------------------------------------------------------
  311.  *
  312.  * XGetInputFocus --
  313.  *
  314.  *    Retrieves the current keyboard focus window.
  315.  *
  316.  * Results:
  317.  *    Returns the current focus window.
  318.  *
  319.  * Side effects:
  320.  *    None.
  321.  *
  322.  *----------------------------------------------------------------------
  323.  */
  324.  
  325. void
  326. XGetInputFocus(display, focus_return, revert_to_return)
  327.     Display *display;
  328.     Window *focus_return;
  329.     int *revert_to_return;
  330. {
  331.     Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());
  332.     *focus_return = tkwin ? Tk_WindowId(tkwin) : None;
  333.     *revert_to_return = RevertToParent;
  334.     display->request++;
  335. }
  336.  
  337. /*
  338.  *----------------------------------------------------------------------
  339.  *
  340.  * XSetInputFocus --
  341.  *
  342.  *    Set the current focus window.
  343.  *
  344.  * Results:
  345.  *    None.
  346.  *
  347.  * Side effects:
  348.  *    Changes the keyboard focus and causes the selected window to
  349.  *    be activated.
  350.  *
  351.  *----------------------------------------------------------------------
  352.  */
  353.  
  354. void
  355. XSetInputFocus(display, focus, revert_to, time)
  356.     Display* display;
  357.     Window focus;
  358.     int revert_to;
  359.     Time time;
  360. {
  361.     display->request++;
  362.     if (focus != None) {
  363.     SetFocus(Tk_GetHWND(focus));
  364.     }
  365. }
  366.  
  367. /*
  368.  *----------------------------------------------------------------------
  369.  *
  370.  * TkpChangeFocus --
  371.  *
  372.  *    This procedure is invoked to move the system focus from
  373.  *    one window to another.
  374.  *
  375.  * Results:
  376.  *    None.
  377.  *
  378.  * Side effects:
  379.  *    The official X focus window changes;  the application's focus
  380.  *    window isn't changed by this procedure.
  381.  *
  382.  *----------------------------------------------------------------------
  383.  */
  384.  
  385. void
  386. TkpChangeFocus(winPtr, force)
  387.     TkWindow *winPtr;        /* Window that is to receive the X focus. */
  388.     int force;            /* Non-zero means claim the focus even
  389.                  * if it didn't originally belong to
  390.                  * topLevelPtr's application. */
  391. {
  392.     TkDisplay *dispPtr = winPtr->dispPtr;
  393.     Window focusWindow;
  394.     int dummy;
  395.     TkWindow *winPtr2;
  396.  
  397.     if (!force) {
  398.     XGetInputFocus(dispPtr->display, &focusWindow, &dummy);
  399.     winPtr2 = (TkWindow *) Tk_IdToWindow(dispPtr->display, focusWindow);
  400.     if ((winPtr2 == NULL) || (winPtr2->mainPtr != winPtr->mainPtr)) {
  401.         return;
  402.     }
  403.     }
  404.  
  405.     if (winPtr->window == None) {
  406.     panic("ChangeXFocus got null X window");
  407.     }
  408.     XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent,
  409.         CurrentTime);
  410.  
  411.     /*
  412.      * Remember the current serial number for the X server and issue
  413.      * a dummy server request.  This marks the position at which we
  414.      * changed the focus, so we can distinguish FocusIn and FocusOut
  415.      * events on either side of the mark.
  416.      */
  417.  
  418.     winPtr->mainPtr->focusSerial = NextRequest(winPtr->display);
  419.     XNoOp(winPtr->display);
  420.     return;
  421. }
  422.  
  423. /*
  424.  *----------------------------------------------------------------------
  425.  *
  426.  * TkpSetCapture --
  427.  *
  428.  *    This function captures the mouse so that all future events
  429.  *    will be reported to this window, even if the mouse is outside
  430.  *    the window.  If the specified window is NULL, then the mouse
  431.  *    is released. 
  432.  *
  433.  * Results:
  434.  *    None.
  435.  *
  436.  * Side effects:
  437.  *    Sets the capture flag and captures the mouse.
  438.  *
  439.  *----------------------------------------------------------------------
  440.  */
  441.  
  442. void
  443. TkpSetCapture(winPtr)
  444.     TkWindow *winPtr;            /* Capture window, or NULL. */
  445. {
  446.     if (winPtr) {
  447.     SetCapture(Tk_GetHWND(Tk_WindowId(winPtr)));
  448.     captured = 1;
  449.     } else {
  450.     captured = 0;
  451.     ReleaseCapture();
  452.     }
  453. }
  454.