| /* |
| * X events handling functions |
| * |
| * Copyright 1993 Alexandre Julliard |
| */ |
| |
| static char Copyright[] = "Copyright Alexandre Julliard, 1993"; |
| |
| #include <X11/Intrinsic.h> |
| #include <X11/StringDefs.h> |
| #include <X11/Core.h> |
| |
| #include "windows.h" |
| #include "win.h" |
| #include "class.h" |
| |
| |
| #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ |
| static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */ |
| |
| extern Display * XT_display; |
| |
| /* Event handlers */ |
| static void EVENT_expose(); |
| static void EVENT_key(); |
| static void EVENT_mouse_motion(); |
| static void EVENT_mouse_button(); |
| static void EVENT_structure(); |
| static void EVENT_focus_change(); |
| static void EVENT_enter_notify(); |
| |
| /* X context to associate a hwnd to an X window */ |
| static XContext winContext = 0; |
| |
| /* State variables */ |
| static HWND captureWnd = 0; |
| Window winHasCursor = 0; |
| extern HWND hWndFocus; |
| |
| /* Keyboard translation tables */ |
| static int special_key[] = |
| { |
| VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */ |
| 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */ |
| 0, 0, 0, VK_ESCAPE /* FF18 */ |
| }; |
| |
| static cursor_key[] = |
| { |
| VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, |
| VK_NEXT, VK_END /* FF50 */ |
| }; |
| |
| static misc_key[] = |
| { |
| VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */ |
| VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */ |
| }; |
| |
| static keypad_key[] = |
| { |
| VK_MENU, VK_NUMLOCK, /* FF7E */ |
| 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ |
| 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */ |
| 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */ |
| 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */ |
| 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ |
| 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, |
| VK_DECIMAL, VK_DIVIDE, /* FFA8 */ |
| VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, |
| VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */ |
| VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */ |
| }; |
| |
| static function_key[] = |
| { |
| VK_F1, VK_F2, /* FFBE */ |
| VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ |
| VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */ |
| }; |
| |
| static modifier_key[] = |
| { |
| VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, |
| 0, 0, /* FFE1 */ |
| 0, VK_MENU, VK_MENU /* FFE8 */ |
| }; |
| |
| typedef union |
| { |
| struct |
| { |
| unsigned long count : 16; |
| unsigned long code : 8; |
| unsigned long extended : 1; |
| unsigned long : 4; |
| unsigned long context : 1; |
| unsigned long previous : 1; |
| unsigned long transition : 1; |
| } lp1; |
| unsigned long lp2; |
| } KEYLP; |
| |
| static BOOL KeyDown = FALSE; |
| |
| |
| #ifdef DEBUG_EVENT |
| static char *event_names[] = |
| { |
| "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", |
| "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", |
| "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify", |
| "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest", |
| "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", |
| "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", |
| "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify", |
| "ClientMessage", "MappingNotify" |
| }; |
| #endif |
| |
| |
| /*********************************************************************** |
| * EVENT_ProcessEvent |
| * |
| * Process an X event. |
| */ |
| void EVENT_ProcessEvent( XEvent *event ) |
| { |
| HWND hwnd; |
| XPointer ptr; |
| Boolean cont_dispatch = TRUE; |
| |
| XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr ); |
| hwnd = (HWND)ptr & 0xffff; |
| |
| #ifdef DEBUG_EVENT |
| printf( "Got event %s for hwnd %d\n", |
| event_names[event->type], hwnd ); |
| #endif |
| |
| switch(event->type) |
| { |
| case Expose: |
| EVENT_expose( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case KeyPress: |
| case KeyRelease: |
| EVENT_key( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case MotionNotify: |
| EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case ButtonPress: |
| case ButtonRelease: |
| EVENT_mouse_button( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case CirculateNotify: |
| case ConfigureNotify: |
| case MapNotify: |
| case UnmapNotify: |
| EVENT_structure( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case FocusIn: |
| case FocusOut: |
| EVENT_focus_change( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| case EnterNotify: |
| EVENT_enter_notify( 0, hwnd, event, &cont_dispatch ); |
| break; |
| |
| #ifdef DEBUG_EVENT |
| default: |
| printf( "Unprocessed event %s for hwnd %d\n", |
| event_names[event->type], hwnd ); |
| break; |
| #endif |
| } |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_AddHandlers |
| * |
| * Add the event handlers to the given window |
| */ |
| #ifdef USE_XLIB |
| void EVENT_AddHandlers( Window w, int hwnd ) |
| { |
| if (!winContext) winContext = XUniqueContext(); |
| XSaveContext( XT_display, w, winContext, (XPointer)hwnd ); |
| } |
| #else |
| void EVENT_AddHandlers( Widget w, int hwnd ) |
| { |
| XtAddEventHandler(w, ExposureMask, FALSE, |
| EVENT_expose, (XtPointer)hwnd ); |
| XtAddEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, |
| EVENT_key, (XtPointer)hwnd ); |
| XtAddEventHandler(w, PointerMotionMask, FALSE, |
| EVENT_mouse_motion, (XtPointer)hwnd ); |
| XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE, |
| EVENT_mouse_button, (XtPointer)hwnd ); |
| XtAddEventHandler(w, StructureNotifyMask, FALSE, |
| EVENT_structure, (XtPointer)hwnd ); |
| XtAddEventHandler(w, FocusChangeMask, FALSE, |
| EVENT_focus_change, (XtPointer)hwnd ); |
| XtAddEventHandler(w, EnterWindowMask, FALSE, |
| EVENT_enter_notify, (XtPointer)hwnd ); |
| } |
| #endif |
| |
| |
| /*********************************************************************** |
| * EVENT_RemoveHandlers |
| * |
| * Remove the event handlers of the given window |
| */ |
| void EVENT_RemoveHandlers( Widget w, int hwnd ) |
| { |
| #ifndef USE_XLIB |
| XtRemoveEventHandler(w, ExposureMask, FALSE, |
| EVENT_expose, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, |
| EVENT_key, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, PointerMotionMask, FALSE, |
| EVENT_mouse_motion, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE, |
| EVENT_mouse_button, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, StructureNotifyMask, FALSE, |
| EVENT_structure, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, FocusChangeMask, FALSE, |
| EVENT_focus_change, (XtPointer)hwnd ); |
| XtRemoveEventHandler(w, EnterWindowMask, FALSE, |
| EVENT_enter_notify, (XtPointer)hwnd ); |
| #endif |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_XStateToKeyState |
| * |
| * Translate a X event state (Button1Mask, ShiftMask, etc...) to |
| * a Windows key state (MK_SHIFT, MK_CONTROL, etc...) |
| */ |
| static WORD EVENT_XStateToKeyState( int state ) |
| { |
| int kstate = 0; |
| |
| if (state & Button1Mask) kstate |= MK_LBUTTON; |
| if (state & Button2Mask) kstate |= MK_MBUTTON; |
| if (state & Button3Mask) kstate |= MK_RBUTTON; |
| if (state & ShiftMask) kstate |= MK_SHIFT; |
| if (state & ControlMask) kstate |= MK_CONTROL; |
| return kstate; |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_expose |
| * |
| * Handle a X expose event |
| */ |
| static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| RECT rect; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| /* Make position relative to client area instead of window */ |
| rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); |
| rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); |
| rect.right = rect.left + event->width; |
| rect.bottom = rect.top + event->height; |
| winHasCursor = event->window; |
| |
| InvalidateRect( hwnd, &rect, TRUE ); |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_key |
| * |
| * Handle a X key event |
| */ |
| static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| MSG msg; |
| char Str[24]; |
| XComposeStatus cs; |
| KeySym keysym; |
| WORD xkey, vkey, key_type, key; |
| KEYLP keylp; |
| BOOL extended = FALSE; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| int count = XLookupString(event, Str, 1, &keysym, &cs); |
| Str[count] = '\0'; |
| #ifdef DEBUG_KEY |
| printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", |
| keysym, count, Str[0], Str); |
| #endif |
| |
| xkey = LOWORD(keysym); |
| key_type = HIBYTE(xkey); |
| key = LOBYTE(xkey); |
| #ifdef DEBUG_KEY |
| printf(" key_type=%X, key=%X\n", key_type, key); |
| #endif |
| |
| /* Position must be relative to client area */ |
| event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; |
| event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; |
| |
| if (key_type == 0xFF) /* non-character key */ |
| { |
| if (key >= 0x08 && key <= 0x1B) /* special key */ |
| vkey = special_key[key - 0x08]; |
| else if (key >= 0x50 && key <= 0x57) /* cursor key */ |
| vkey = cursor_key[key - 0x50]; |
| else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */ |
| vkey = misc_key[key - 0x60]; |
| else if (key >= 0x7E && key <= 0xB9) /* keypad key */ |
| { |
| vkey = keypad_key[key - 0x7E]; |
| extended = TRUE; |
| } |
| else if (key >= 0xBE && key <= 0xCD) /* function key */ |
| { |
| vkey = function_key[key - 0xBE]; |
| extended = TRUE; |
| } |
| else if (key >= 0xE1 && key <= 0xEA) /* modifier key */ |
| vkey = modifier_key[key - 0xE1]; |
| else if (key == 0xFF) /* DEL key */ |
| vkey = VK_DELETE; |
| } |
| else if (key_type == 0) /* character key */ |
| { |
| if (key >= 0x61 && key <= 0x7A) |
| vkey = key - 0x20; /* convert lower to uppercase */ |
| else |
| vkey = key; |
| } |
| |
| if (event->type == KeyPress) |
| { |
| msg.hwnd = hwnd; |
| msg.message = WM_KEYDOWN; |
| msg.wParam = vkey; |
| keylp.lp1.count = 1; |
| keylp.lp1.code = LOBYTE(event->keycode); |
| keylp.lp1.extended = (extended ? 1 : 0); |
| keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); |
| keylp.lp1.previous = (KeyDown ? 0 : 1); |
| keylp.lp1.transition = 0; |
| msg.lParam = keylp.lp2; |
| #ifdef DEBUG_KEY |
| printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); |
| #endif |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| |
| hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2, |
| event->x & 0xffff, event->y & 0xffff, event->time, 0 ); |
| KeyDown = TRUE; |
| |
| /* The key translation ought to take place in TranslateMessage(). |
| * However, there is no way of passing the required information |
| * in a Windows message, so TranslateMessage does not currently |
| * do anything and the translation is done here. |
| */ |
| if (count == 1) /* key has an ASCII representation */ |
| { |
| msg.hwnd = hwnd; |
| msg.message = WM_CHAR; |
| msg.wParam = (WORD)Str[0]; |
| msg.lParam = keylp.lp2; |
| #ifdef DEBUG_KEY |
| printf("WM_CHAR : wParam=%X\n", msg.wParam); |
| #endif |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 ); |
| } |
| } |
| else |
| { |
| msg.hwnd = hwnd; |
| msg.message = WM_KEYUP; |
| msg.wParam = vkey; |
| keylp.lp1.count = 1; |
| keylp.lp1.code = LOBYTE(event->keycode); |
| keylp.lp1.extended = (extended ? 1 : 0); |
| keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); |
| keylp.lp1.previous = 1; |
| keylp.lp1.transition = 1; |
| msg.lParam = keylp.lp2; |
| #ifdef DEBUG_KEY |
| printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); |
| #endif |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| |
| hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2, |
| event->x & 0xffff, event->y & 0xffff, event->time, 0 ); |
| KeyDown = FALSE; |
| } |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_mouse_motion |
| * |
| * Handle a X mouse motion event |
| */ |
| static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| |
| /* Position must be relative to client area */ |
| event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; |
| event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; |
| |
| hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), |
| (event->x & 0xffff) | (event->y << 16), |
| event->x & 0xffff, event->y & 0xffff, |
| event->time, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_mouse_button |
| * |
| * Handle a X mouse button event |
| */ |
| static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| static WORD messages[3][NB_BUTTONS] = |
| { |
| { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN }, |
| { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP }, |
| { WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK } |
| }; |
| static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 }; |
| |
| int buttonNum, prevTime, type; |
| |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| |
| /* Position must be relative to client area */ |
| event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; |
| event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; |
| |
| buttonNum = event->button-1; |
| if (buttonNum >= NB_BUTTONS) return; |
| if (event->type == ButtonRelease) type = 1; |
| else |
| { /* Check if double-click */ |
| prevTime = lastClickTime[buttonNum]; |
| lastClickTime[buttonNum] = event->time; |
| if (event->time - prevTime < dblclick_time) |
| { |
| WND * wndPtr; |
| CLASS * classPtr; |
| if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return; |
| if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return; |
| type = (classPtr->wc.style & CS_DBLCLKS) ? 2 : 0; |
| } |
| else type = 0; |
| } |
| |
| winHasCursor = event->window; |
| |
| hardware_event( hwnd, messages[type][buttonNum], |
| EVENT_XStateToKeyState( event->state ), |
| (event->x & 0xffff) | (event->y << 16), |
| event->x & 0xffff, event->y & 0xffff, |
| event->time, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_structure |
| * |
| * Handle a X StructureNotify event |
| */ |
| static void EVENT_structure( Widget w, int hwnd, XEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| MSG msg; |
| |
| msg.hwnd = hwnd; |
| msg.time = GetTickCount(); |
| msg.pt.x = 0; |
| msg.pt.y = 0; |
| |
| switch(event->type) |
| { |
| case ConfigureNotify: |
| { |
| HANDLE handle; |
| NCCALCSIZE_PARAMS *params; |
| XConfigureEvent * evt = (XConfigureEvent *)event; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| wndPtr->rectWindow.left = evt->x; |
| wndPtr->rectWindow.top = evt->y; |
| wndPtr->rectWindow.right = evt->x + evt->width; |
| wndPtr->rectWindow.bottom = evt->y + evt->height; |
| |
| /* Send WM_NCCALCSIZE message */ |
| handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); |
| params = (NCCALCSIZE_PARAMS *)GlobalLock( handle ); |
| params->rgrc[0] = wndPtr->rectWindow; |
| params->lppos = NULL; /* Should be WINDOWPOS struct */ |
| SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params ); |
| wndPtr->rectClient = params->rgrc[0]; |
| PostMessage( hwnd, WM_MOVE, 0, |
| MAKELONG( wndPtr->rectClient.left, |
| wndPtr->rectClient.top )); |
| PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, |
| MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, |
| wndPtr->rectClient.bottom-wndPtr->rectClient.top)); |
| GlobalUnlock( handle ); |
| GlobalFree( handle ); |
| } |
| break; |
| |
| } |
| } |
| |
| |
| /********************************************************************** |
| * EVENT_focus_change |
| * |
| * Handle an X FocusChange event |
| */ |
| static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| switch(event->type) |
| { |
| case FocusIn: |
| { |
| PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); |
| hWndFocus = hwnd; |
| } |
| break; |
| |
| case FocusOut: |
| { |
| if (hWndFocus) |
| { |
| PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); |
| hWndFocus = 0; |
| } |
| } |
| } |
| } |
| |
| |
| /********************************************************************** |
| * EVENT_enter_notify |
| * |
| * Handle an X EnterNotify event |
| */ |
| static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| if (captureWnd != 0) return; |
| |
| winHasCursor = event->window; |
| |
| switch(event->type) |
| { |
| case EnterNotify: |
| PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 ); |
| break; |
| } |
| } |
| |
| |
| /********************************************************************** |
| * SetCapture (USER.18) |
| */ |
| HWND SetCapture(HWND wnd) |
| { |
| int rv; |
| HWND old_capture_wnd = captureWnd; |
| WND *wnd_p = WIN_FindWndPtr(wnd); |
| if (wnd_p == NULL) |
| return 0; |
| |
| #ifdef USE_XLIB |
| rv = XGrabPointer(XT_display, wnd_p->window, False, |
| ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, |
| GrabModeAsync, GrabModeSync, None, None, CurrentTime); |
| #else |
| rv = XtGrabPointer(wnd_p->winWidget, False, |
| ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, |
| GrabModeAsync, GrabModeSync, None, None, CurrentTime); |
| #endif |
| |
| if (rv == GrabSuccess) |
| { |
| captureWnd = wnd; |
| return old_capture_wnd; |
| } |
| else |
| return 0; |
| } |
| |
| /********************************************************************** |
| * ReleaseCapture (USER.19) |
| */ |
| void ReleaseCapture() |
| { |
| WND *wnd_p; |
| |
| if (captureWnd == 0) |
| return; |
| |
| wnd_p = WIN_FindWndPtr(captureWnd); |
| if (wnd_p == NULL) |
| return; |
| |
| #ifdef USE_XLIB |
| XUngrabPointer( XT_display, CurrentTime ); |
| #else |
| XtUngrabPointer(wnd_p->winWidget, CurrentTime); |
| #endif |
| |
| captureWnd = 0; |
| } |
| |
| /********************************************************************** |
| * GetCapture (USER.236) |
| */ |
| HWND GetCapture() |
| { |
| return captureWnd; |
| } |
| |
| /********************************************************************** |
| * SetDoubleClickTime (USER.20) |
| */ |
| void SetDoubleClickTime (WORD interval) |
| { |
| if (interval == 0) |
| dblclick_time = 500; |
| else |
| dblclick_time = interval; |
| } |
| |
| /********************************************************************** |
| * GetDoubleClickTime (USER.21) |
| */ |
| WORD GetDoubleClickTime () |
| { |
| return ((WORD)dblclick_time); |
| } |
| |
| |