| /* |
| * 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 */ |
| #define DBLCLICK_TIME 300 /* Max. time for a double click (milliseconds) */ |
| |
| |
| /* Event handlers */ |
| static void EVENT_expose(); |
| static void EVENT_key(); |
| static void EVENT_mouse_motion(); |
| static void EVENT_mouse_button(); |
| static void EVENT_structure(); |
| |
| /* State variables */ |
| static HWND captureWnd = 0; |
| |
| /*********************************************************************** |
| * EVENT_AddHandlers |
| * |
| * Add the event handlers to the given window |
| */ |
| 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 ); |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_RemoveHandlers |
| * |
| * Remove the event handlers of the given window |
| */ |
| void EVENT_RemoveHandlers( Widget w, int hwnd ) |
| { |
| 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 ); |
| } |
| |
| |
| /*********************************************************************** |
| * 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; |
| rect.left = event->x; |
| rect.top = event->y; |
| rect.right = event->x + event->width; |
| rect.bottom = event->y + event->height; |
| |
| 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; |
| |
| msg.hwnd = hwnd; |
| msg.message = (event->type == KeyRelease) ? WM_KEYUP : WM_KEYDOWN; |
| msg.wParam = 0; |
| msg.lParam = (event->x & 0xffff) | (event->y << 16); |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| |
| MSG_AddMsg( &msg ); |
| } |
| |
| |
| /*********************************************************************** |
| * EVENT_mouse_motion |
| * |
| * Handle a X mouse motion event |
| */ |
| static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, |
| Boolean *cont_dispatch ) |
| { |
| MSG msg; |
| |
| msg.hwnd = hwnd; |
| msg.message = WM_MOUSEMOVE; |
| msg.wParam = EVENT_XStateToKeyState( event->state ); |
| msg.lParam = (event->x & 0xffff) | (event->y << 16); |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| |
| MSG_AddMsg( &msg ); |
| } |
| |
| |
| /*********************************************************************** |
| * 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 }; |
| |
| MSG msg; |
| int buttonNum, prevTime, type; |
| |
| 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; |
| } |
| |
| msg.hwnd = hwnd; |
| msg.message = messages[type][buttonNum]; |
| msg.wParam = EVENT_XStateToKeyState( event->state ); |
| msg.lParam = (event->x & 0xffff) | (event->y << 16); |
| msg.time = event->time; |
| msg.pt.x = event->x & 0xffff; |
| msg.pt.y = event->y & 0xffff; |
| |
| MSG_AddMsg( &msg ); |
| } |
| |
| |
| /*********************************************************************** |
| * 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: |
| { |
| XConfigureEvent * evt = (XConfigureEvent *)event; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| wndPtr->rectClient.right = wndPtr->rectClient.left + evt->width; |
| wndPtr->rectClient.bottom = wndPtr->rectClient.top + evt->height; |
| PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, |
| (evt->width & 0xffff) | (evt->height << 16) ); |
| } |
| 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; |
| |
| rv = XtGrabPointer(wnd_p->winWidget, False, |
| ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, |
| GrabModeAsync, GrabModeSync, None, None, CurrentTime); |
| |
| 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; |
| |
| XtUngrabPointer(wnd_p->winWidget, CurrentTime); |
| |
| captureWnd = 0; |
| } |