tkWinPointer.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
源码类别:

通讯编程

开发平台:

Visual C++

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