Sun Jan 2 12:38:53 1994 David Metcalfe <david@prism.demon.co.uk> * [windows/class.c] Implemented GetClassName and GetClassInfo. * [windows/caret.c] Various improvements to text caret code. Fri Dec 31 15:22:22 1993 John Brezak <brezak@apollo.hp.com> * [misc/comm.c] Patches to work with NetBSD. Thu Dec 30 12:11:55 1993 John Richardson <jrichard@cs.uml.edu> * [objects/bitblt.c] Added StretchBlt(). Tue Jan 4 05:22:07 1994 julliard@di.epfl.ch (Alexandre Julliard) * [misc/user.c] Added creation of system message queue. * [objects/bitmap.c] [objects/dcvalues.c] [windows/dc.c] Added DC size fields into DC structure. * [objects/clipping.c] Bug fix in CLIPPING_IntersectRect(). * [windows/class.c] Allocate a DCE instead of a DC for CS_CLASSDC classes. * [windows/clipping.c] Fixed GetUpdateRect() and GetUpdateRgn() to clip to the client area. * [windows/dce.c] Implemented GetDCEx() and GetWindowDC(). * [windows/defwnd.c] Implemented WM_WINDOWPOSCHANGED handling. * [windows/event.c] Preliminary support for Xlib event handling instead of Xt callbacks. Changed MSG_AddMsg() calls to hardware_event() or PostMessage(). * [windows/message.c] Preliminary support for multiple message queues. Implemented hardware_event() to store messages into the system queue. Implemented Get/SetTaskQueue(). Better WM_PAINT and WM_TIMER handling. Changes to use Xlib instead of Xt for events. * [windows/painting.c] Use GetDCEx() to retrieve the DC, to get a correct visible region. * [windows/timer.c] Moved the timer procedure callback into DispatchMessage(). Changed implementation to get rid of Xt timeouts. Timer checking is now done inside GetMessage(). * [windows/win.c] Allocate a DCE instead of a DC for CS_OWNDC windows. Replaced Xt calls with Xlib calls. Moved window positioning functions into windows/winpos.c * [windows/winpos.c] (New file) Rewritten most of the window positioning functions. Implemented SetWindowPos() and MapWindowPoints(). Jan 3, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [if1632/user.spec] Bad arguments description for function SetDlgItemText. * [objects/text.c] Function DrawText now handle DT_CALCRECT request. * [misc/message.c] Message boxes now use DrawText with DT_CALCRECT. * [windows/graphics.c] Bug fix in function FrameRect, (it was using PEN instead of BRUSH). * [windows/win.c] Bug fix for flags in function ShowWindow. More accurate WM_SIZE generated by function ShowWindow. * [controls/listbox.c] More code for LBS_MULTIPLESEL. More code for LBS_MULTICOLUMN. * [include/windows.h] Bad define for MF_SEPARATOR. * [controls/menu.c] New functions: PopMenuWndProc() with 'glues', CreatePopupMenu(), AppendMenu(), InsertMenu(), RemoveMenu(), DeleteMenu(), ModifyMenu(), TrackPopupMenu(). Code in stubs: CreateMenu(), DestroyMenu(). Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh) * loader/wine.c: Added support for relocation types 5 and 6. Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl) * [misc/comm.c] new functions: BuildCommDCB(), OpenComm(), CloseComm(), SetCommBreak(), ClearCommBreak(), EscapeCommFunction(), FlushComm(), GetCommError(), SetCommEventMask(), GetCommEventMask(), SetCommState(), GetCommState(), TransmitCommChar(), ReadComm(), WriteComm(). Wed Dec 22 13:00:15 1993 David Metcalfe <david@prism.demon.co.uk> * [windows/caret.c] Implemented text caret functions. Tue Dec 21 06:13:58 1993 julliard@di.epfl.ch (Alexandre Julliard) * [loader/wine.c] Bug fix in LoadImage(). * [objects/bitblt.c] [objects/clipping.c] [objects/text.c] [windows/dc.c] [windows/dce.c] [windows/graphics.c] Modified graphics calls to take into account the DC origin. * [windows/defwnd.c] Added preliminary WM_NCCALCSIZE handling. * [windows/event.c] Send WM_NCCALCSIZE message on resize event. * [windows/win.c] Send WM_NCCALCSIZE message in CreateWindow(). Realize widgets at creation time (should prevent problems with unrealized widgets). Dec 19, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/static.c] Send mouse & keyboard message received to its parent. * [controls/scroll.c] Send keyboard message received to its parent. * [controls/listbox.c] Add Navigation keys . ListBox now use VSCROLL & HSCROLL instead of children. Alpha version of LBS_MULTIPLESEL. Alpha version of LBS_MULTICOLUMN. * [controls/combo.c] Add Navigation keys on closed ComboBox. Remove useless 'COMBOBOX_CreateComboBox' function. Mon Dec 19 20:39:34 1993 Erik Bos (erik@trashcan.hacktic.nl) * [loader/wine. LoadImage() modified to use FindFile(). * [misc/file.c] SetErrorMode added * [misc/dos_fs.c] bug fixes. Dec 13, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [memory/global.c] bug fix in GlobalGetFreeSegment : good ptr in 'g_prev'. * [sysres.dll] preliminary version of a 'glass of wine' bitmap * [windows/event.c] New function 'GetCapture'. * [controls/scroll.c] Remove useless 'SCROLLBAR_CreateScrollBar' function. * [controls/listbox.c] Remove useless 'LISTBOX_CreateListBox' function. Mon Dec 13 13:51:00 1993 David Metcalfe <david@prism.demon.co.uk> * [objects/font.c] Corrected bugs in GetCharWidth(). * [windows/event.c] Modified EVENT_key to send Windows virtual key codes for WM_KEYDOWN and WM_KEYUP messages, and a WM_CHAR message for printable characters. Wed Dec 08 19:20:00 1993 Karl Guenter Wuensch (hn324wu@unidui.uni-duisburg.de) * [windows/graphics.c] Added Polyline and Polygon Mon Dec 13 14:51:54 1993 Erik Bos (erik@trashcan.hacktic.nl) * [controls/listbox.c] ListBoxDirectory() modified to use dos_fs.c's functions to access files&|drives. Sat Dec 04 17:04:23 1993 Erik Bos (erik@trashcan.hacktic.nl) * [misc/dos_fs.c] Added FindFile() to search a file in a dos/unix style path. * [misc/file.c] New Win31 functions: OpenFile, _lcreate, _llseek, GetTempDrive, GetTempFileName, GetWindowsDirectory, GetSystemDirectory, GetDriveType. * [misc/int21.c] Modified. Wed Dec 1 16:20:45 1993 Miguel de Icaza (miguel@roxanne.nuclecu.unam.mx) * [misc/profile.c] The Profile functions now return the correct values. They now implement all the features described in the SDK. Tue Nov 30 13:55:27 1993 Bob Amstadt (bob at amscons) * [loader/selector.c] Rewrote selector aliasing routines to use System V IPC routine to alias memory segments. Nov 28, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/listbox.c] More consistency in functions using wIndexes * [controls/scroll.c] New function : ShowScrollBar(). * [loader/cursor.c] ... New file Move cursor functions from [loader/resource.c]. New function : ClipCursor(). New function : GetClipCursor(). New function : CreateCursor(). SetCursor() now working using gloabal variable 'winHasCursor'. *[object/palette.c] New stub only : SelectPalette(). New stub only : RealizePalette(). *[win/event.c] New function : EVENT_enter_notify(), update 'winHasCursor' and send WM_SETCURSOR. *[win/defwnd.c] Add processing of WM_SETCURSOR message. *[win/win.c] New members in WND structure : hCursor, hWndVScroll & hWndHScroll. CreateWindowEx() now create children for WM_HSCROLL & WM_VSCROLL. New function ClientToScreen(). New function ScreenToClient(). Mon Nov 25 18:25:40 1993 Erik Bos (erik@trashcan.hacktic.nl) * [files.h / regfunc.h / misc/dos.c] Removed. * [misc/dos_fs.c] Added support for loading dosdrive cfg from wine.ini. * [misc/int21.c] Modified. Wed Nov 24 11:37:33 1993 julliard@disuns2.epfl.ch (Alexandre Julliard) * [include/atom.h] [memory/atom.c] Implemented atoms. * [windows/class.c] Modified RegisterClass() to use atoms. Implemented CS_GLOBALCLASS style. * [windows/message.c] Implemented RegisterWindowMessage(). * [loader/resource.c] Bug fix in LoadResource(). * [windows/dialog.c] Modified CreateDialogParam() to use Find/LoadResource().
676 lines
19 KiB
C
676 lines
19 KiB
C
/*
|
|
* 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);
|
|
}
|
|
|
|
|