ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/W11/w32/event.c
Revision: 1.1
Committed: Mon Nov 24 17:28:08 2003 UTC (20 years, 7 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-7_0, post_menubar_removal, rel-6_2, rel-6_3, rel-6_0, rel-6_1, rel-2_1_0, rel-5_5, rel-5_4, rel-5_7, rel-5_1, rel-5_0, rel-5_3, rel-5_2, rel-4_4, rel-4_6, rel-4_7, rel-5_9, rel-5_8, rel-4_2, rel-4_3, rel-3_7, rel-3_8, rel-3_5, rel-3_4, rel-3_3, rel-3_2, rel-2_8, rel-3_0, rel-4_0, rel-2_4, rel-2_5, rel-2_2, rel-2_3, rel-2_0, rel-4_1, rel-1-9, rel-1-3, rel-1-2, rxvt-2-0, rel-1_9, rel-3_6, rel-2_7, rel-4_8, rel-4_9
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1
2     #include <X11/Xlib.h>
3     #include <X11/Xatom.h>
4     #include <X11/keysymdef.h>
5     #include "ntdef.h"
6    
7     /* a crude method to avoid losing the selection when
8     calling EmptyClipboard, which is necessary to do
9     every time the selection content changes, otherwise
10     windows apps use a cached copy of the selection */
11     static volatile int destroyClipboardCatcher = 0;
12     static NT_window *NT_CWIN = NULL;
13     void
14     catchNextDestroyClipboard()
15     {
16     destroyClipboardCatcher=1;
17     }
18    
19     typedef struct WinEvent_
20     {
21     NT_window *window;
22     UINT message;
23     UINT wParam;
24     LONG lParam;
25     } WinEvent;
26    
27     #define W11_QSIZE 100
28     typedef struct WinEventQ_
29     {
30     int num;
31     int avail;
32     int next;
33     int count;
34     int dispatch;
35     proto_W11EventHandler *handler;
36     WinEvent list[W11_QSIZE];
37     } WinEventQ;
38    
39     static WinEventQ *wineventq = NULL;
40    
41     void
42     initQ() {
43     int i;
44     WinEventQ *q = (WinEventQ *)allocateMemory(sizeof(WinEventQ));
45     q->num=W11_QSIZE-1;
46     q->avail=0;
47     q->next=0;
48     q->count=0;
49     q->dispatch=0;
50     q->handler=NULL;
51     for (i=0; i<W11_QSIZE; i++) {
52     q->list[i].message=0;
53     q->list[i].window = NULL;
54     }
55     wineventq = q;
56     }
57    
58     static int
59     getQdEvent(WinEventQ *q, XEvent *ev)
60     {
61     WinEvent we;
62     if (q->count<=0) {
63     cjh_printf("Queue is empty\n");
64     return 0;
65     }
66     we = q->list[q->next];
67     WinEventToXEvent(&we,ev);
68     q->next++;
69     q->count--;
70     if (q->next>q->num) q->next=0;
71     return 1;
72     }
73    
74     static void
75     QSendEvent(WinEventQ *q)
76     {
77     XEvent e;
78     if (q->handler != NULL) {
79     if (getQdEvent(q,&e)) (q->handler)(&e);
80     }
81     }
82    
83     static int
84     QEvent(WinEventQ *q, NT_window *window,UINT message,UINT wParam,LONG lParam)
85     {
86     q->list[q->avail].window=window;
87     q->list[q->avail].message=message;
88     q->list[q->avail].wParam=wParam;
89     q->list[q->avail].lParam=lParam;
90     q->avail++; q->count++;
91     if (q->avail>q->num) q->avail=0;
92     if (q->dispatch) QSendEvent(q);
93     return 1;
94     }
95    
96    
97     /* Allow application to install an event handler call back.
98     This will make some actions such as moving the window work
99     better.
100    
101     The event handler should look like:
102     void process_xevent(XEvent *ev) { }
103    
104     To install it:
105     W11AddEventHandler(display,process_xevent);
106    
107     The specific problem is that calling DefWindowProc()
108     in response to a WM_SYSCOMMAND will cause windows to run its
109     own event loop waiting for the mouse up event. The application
110     therefore cannot rely on it's main event loop to get run for
111     each event. Without running multiple threads, or setjmp, there
112     is little recourse for alerting the application in the
113     traditional X manner to Expose events while the window is
114     being moved.
115     */
116    
117     void W11AddEventHandler(Display *d, proto_W11EventHandler *ev)
118     {
119     wineventq->handler = ev;
120     }
121    
122    
123     static void
124     doTranslateMessage(MSG *m)
125     {
126     if ((m->message == WM_KEYDOWN) &&
127     ((m->wParam == VK_BACK) ||
128     (((m->wParam == VK_ADD) || (m->wParam == VK_SUBTRACT)) &&
129     (GetKeyState(VK_SHIFT) & 0x8000)))) return;
130     if ((m->message == WM_SYSKEYDOWN) && (m->wParam == VK_F10))
131     {
132     m->message = WM_KEYDOWN;
133     return;
134     }
135     TranslateMessage(m);
136     }
137    
138     static LONG
139     NT_default(HWND hWnd,UINT message,UINT wParam,LONG lParam)
140     {
141     return DefWindowProc(hWnd, message, wParam, lParam);
142     }
143    
144     static void
145     NT_wakeup(HWND hWnd)
146     {
147     PostMessage(hWnd,USR_WakeUp,0,0L);
148     }
149    
150     /*****************************************************************\
151    
152     Function: MainWndProc
153     Inputs: Window handle, message, message parameters.
154    
155     Comments: This is called when messages are sent to the application
156     but not to the application's message queue. If an
157     event can be processed, it is done here. The equivalent
158     XEvent is filled out in l_event, which is picked up
159     in the X event routines. Some events are not received
160     from Windows, eg Enter/LeaveNotify, so these are made
161     up as required.
162    
163     Caution: The application does not see HWND, but Window.
164    
165     \*****************************************************************/
166    
167     /* queued messages
168     WM_KEYDOWN
169     WM_KEYUP
170     WM_CHAR
171     WM_MOUSEMOVE
172     WM_BUTTONxx
173     WM_TIMER
174     WM_PAINT
175     WM_QUIT
176     */
177    
178     LONG NT_handleMsg(
179     HWND hWnd, /* window handle */
180     UINT message, /* type of message */
181     UINT wParam, /* additional information */
182     LONG lParam) /* additional information */
183     {
184     RECT rect;
185     WINDOWPOS *posStruct;
186     unsigned long int st=0L;
187     NT_window *window;
188     long mask;
189     PAINTSTRUCT paintStruct;
190    
191     /* if (message == WM_CLOSE) exit(0); */
192    
193     window = NT_find_window_from_id(hWnd);
194     if (window == NULL) return (NT_default(hWnd, message, wParam, lParam));
195    
196     mask = window->mask;
197    
198     switch (message) {
199     /* we'll handle these, later */
200     case WM_KILLFOCUS:
201     QEvent(wineventq,window,message,wParam,lParam);
202     NT_wakeup(hWnd);
203     break;
204     case WM_SETFOCUS:
205     case WM_QUIT:
206     case WM_CLOSE:
207     case WM_DESTROY:
208     case WM_SYSCHAR: /* alt-keys go here */
209     case WM_CHAR:
210     case WM_LBUTTONDBLCLK:
211     case WM_MBUTTONDBLCLK:
212     case WM_RBUTTONDBLCLK:
213     case USR_MapNotify:
214     case USR_EnterNotify:
215     case WM_MOVE:
216     #if defined(WIN9X)
217     case WM_SIZING:
218     #endif
219     case WM_SIZE:
220     QEvent(wineventq,window,message,wParam,lParam);
221     break;
222     case WM_DESTROYCLIPBOARD:
223     if (destroyClipboardCatcher)
224     destroyClipboardCatcher=0;
225     else {
226     QEvent(wineventq,window,message,wParam,lParam);
227     NT_wakeup(hWnd);
228     }
229     break;
230     case WM_PAINT:
231     BeginPaint(hWnd,&paintStruct);
232     FillRect(paintStruct.hdc, &paintStruct.rcPaint,window->bg);
233     QEvent(wineventq,window,message,
234     (((paintStruct.rcPaint.right-paintStruct.rcPaint.left)&0xffff) |
235     (((paintStruct.rcPaint.bottom-paintStruct.rcPaint.top)&0xffff)<<16)),
236     (((paintStruct.rcPaint.left)&0xffff) | (((paintStruct.rcPaint.top)&0xffff)<<16)));
237    
238     EndPaint(hWnd,&paintStruct);
239     break;
240     /* capture the mouse on button down to emulate x */
241     case WM_LBUTTONDOWN:
242     case WM_MBUTTONDOWN:
243     case WM_RBUTTONDOWN:
244     SetCapture(hWnd);
245     QEvent(wineventq,window,message,wParam,lParam);
246     break;
247     case WM_MBUTTONUP:
248     case WM_LBUTTONUP:
249     case WM_RBUTTONUP:
250     ReleaseCapture();
251     QEvent(wineventq,window,message,wParam,lParam);
252     break;
253     case WM_MOUSEMOVE:
254     if ((mask&PointerMotionMask) ||
255     ((mask&Button1MotionMask)&& (wParam&MK_LBUTTON)) ||
256     ((mask&Button2MotionMask)&& (wParam&MK_MBUTTON)) ||
257     ((mask&Button3MotionMask)&& (wParam&MK_RBUTTON)) ||
258     ((mask&ButtonMotionMask)&&((wParam&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))))
259     )
260     QEvent(wineventq,window,message,wParam,lParam);
261     else
262     return (NT_default(hWnd, message, wParam, lParam));
263     break;
264     case WM_MOUSEWHEEL:
265     /* this event only seems to go to the top most window.
266     see if child windows accept it. */
267     window = NT_find_child(window,ButtonPressMask|Button2MotionMask|Button3MotionMask,
268     ButtonPressMask|Button3MotionMask );
269     if (window && ((window->mask)&ButtonPressMask))
270     QEvent(wineventq,window,message,wParam,lParam);
271     else
272     return (NT_default(hWnd, message, wParam, lParam));
273     break;
274     case WM_ERASEBKGND:
275     /* don't erase the background */
276     return 1;
277     break;
278     case WM_SYSCOMMAND:
279     wineventq->dispatch++;
280     NT_default(hWnd, message, wParam, lParam);
281     wineventq->dispatch--;
282     break;
283     case WM_KEYDOWN:
284     switch (wParam)
285     {
286     case VK_CANCEL:
287     case VK_CLEAR:
288     case VK_PAUSE:
289     case VK_PRIOR:
290     case VK_NEXT:
291     case VK_END:
292     case VK_HOME:
293     case VK_LEFT:
294     case VK_UP:
295     case VK_RIGHT:
296     case VK_DOWN:
297     case VK_SELECT:
298     case VK_PRINT:
299     case VK_EXECUTE:
300     case VK_INSERT:
301     case VK_DELETE:
302     case VK_HELP:
303     case VK_NUMLOCK:
304     case VK_SCROLL:
305     case VK_BACK:
306     case VK_F1:
307     case VK_F2:
308     case VK_F3:
309     case VK_F4:
310     case VK_F5:
311     case VK_F6:
312     case VK_F7:
313     case VK_F8:
314     case VK_F9:
315     case VK_F10:
316     case VK_F11:
317     case VK_F12:
318     case VK_ADD:
319     case VK_SUBTRACT:
320     QEvent(wineventq,window,message,wParam,lParam);
321     break;
322     default:
323     return (NT_default(hWnd, message, wParam, lParam));
324     break;
325    
326     }
327     break;
328     default: /* Passes it on if unproccessed */
329     return (NT_default(hWnd, message, wParam, lParam));
330     }
331     return 0L;
332     }
333    
334     /*****************************************************************\
335    
336     Function: NT_get_state
337     Inputs:
338    
339     Comments: Get the keyboard state
340    
341     \*****************************************************************/
342    
343     static unsigned int
344     NT_get_state()
345     {
346     unsigned int state = 0;
347     if (GetKeyState(VK_SHIFT) & 0x8000) state |= ShiftMask;
348     if (GetKeyState(VK_CONTROL) & 0x8000)
349     {
350     if (!(GetKeyState(VK_MENU) & 0x8000))
351     state |= ControlMask;
352     }
353     else if (GetKeyState(VK_MENU) & 0x8000)
354     state |= Mod1Mask;
355     if (GetKeyState(VK_CAPITAL) & 0x0001) state |= LockMask;
356     if (GetKeyState(VK_NUMLOCK) & 0x0001) state |= Mod5Mask;
357     if (GetKeyState(VK_SCROLL) & 0x0001) state |= Mod3Mask;
358     if (GetKeyState(VK_LBUTTON) & 0x8000) state |= Button1Mask;
359     if (GetKeyState(VK_MBUTTON) & 0x8000) state |= Button2Mask;
360     if (GetKeyState(VK_RBUTTON) & 0x8000) state |= Button3Mask;
361     return state;
362     }
363    
364     int
365     WinEventToXEvent(
366     WinEvent *we,
367     XEvent *event)
368     {
369     POINT pt;
370     RECT rect;
371     unsigned long int st=0L;
372     UINT key;
373     HWND hWnd;
374     UINT wParam;
375     LONG lParam;
376     NT_window *window;
377    
378     do {
379     if (event==NULL) break;
380     if (we == NULL) break;
381    
382     window = we->window;
383     wParam = we->wParam;
384     lParam = we->lParam;
385    
386     event->type=-1;
387     event->xbutton.subwindow = None;
388     hWnd = window->w;
389    
390     switch (we->message) {
391     case WM_SETFOCUS:
392     event->type=FocusIn;
393     event->xfocus.window=(Window)window;
394     break;
395     case WM_KILLFOCUS:
396     event->type=FocusOut;
397     event->xfocus.window=(Window)window;
398     break;
399     /* case WM_ERASEBKGND: */
400     case WM_PAINT:
401     event->type=Expose;
402     event->xexpose.x=LOWORD(lParam); /* right */
403     event->xexpose.y=HIWORD(lParam); /* top */
404     event->xexpose.width=LOWORD(wParam);
405     event->xexpose.height=HIWORD(wParam);
406     event->xexpose.count=0;
407     event->xexpose.window=(Window)window;
408     break;
409     case WM_LBUTTONDOWN:
410     case WM_LBUTTONDBLCLK:
411     event->type = ButtonPress;
412     event->xbutton.x = LOWORD (lParam);
413     event->xbutton.y = HIWORD (lParam);
414     if ( wParam & MK_SHIFT )
415     event->xbutton.button=Button2;
416     else
417     event->xbutton.button=Button1;
418     event->xbutton.window = (Window)window;
419     event->xbutton.time=GetTickCount();
420     break;
421     case WM_LBUTTONUP:
422     event->type=ButtonRelease;
423     event->xbutton.x=LOWORD(lParam);
424     event->xbutton.y=HIWORD (lParam);
425     if ( wParam & MK_SHIFT )
426     event->xbutton.button=Button2;
427     else
428     event->xbutton.button=Button1;
429     event->xbutton.window=(Window)window;
430     event->xbutton.time=GetTickCount();
431     break;
432     case WM_MBUTTONDOWN:
433     case WM_MBUTTONDBLCLK:
434     event->type=ButtonPress;
435     event->xbutton.x=LOWORD(lParam);
436     event->xbutton.y=HIWORD (lParam);
437     event->xbutton.button=Button2;
438     event->xbutton.window=(Window)window;
439     event->xbutton.time=GetTickCount();
440     break;
441     case WM_MBUTTONUP:
442     event->type=ButtonRelease;
443     event->xbutton.x=LOWORD(lParam);
444     event->xbutton.y=HIWORD (lParam);
445     event->xbutton.button=Button2;
446     event->xbutton.window=(Window)window;
447     event->xbutton.time=GetTickCount();
448     break;
449     case WM_RBUTTONDOWN:
450     case WM_RBUTTONDBLCLK:
451     event->type=ButtonPress;
452     event->xbutton.x=LOWORD(lParam);
453     event->xbutton.y=HIWORD (lParam);
454     event->xbutton.button=Button3;
455     event->xbutton.window=(Window)window;
456     event->xbutton.time=GetTickCount();
457     break;
458     case WM_RBUTTONUP:
459     event->type=ButtonRelease;
460     event->xbutton.x=LOWORD(lParam);
461     event->xbutton.y=HIWORD (lParam);
462     event->xbutton.button=Button3;
463     event->xbutton.window=(Window)window;
464     event->xbutton.time=GetTickCount();
465     break;
466     case WM_MOUSEMOVE:
467     if (hWnd!=(HWND)NT_CWIN) /* Mouse in different window? */
468     {
469     if (NT_CWIN==NULL) /* No previous window */
470     {
471     event->type = EnterNotify;
472     event->xcrossing.x = LOWORD(lParam);
473     event->xcrossing.y = HIWORD(lParam);
474     event->xcrossing.window = (Window)window;
475     }
476     else
477     {
478     event->type=LeaveNotify;
479     event->xcrossing.x=LOWORD(lParam);
480     event->xcrossing.y=HIWORD(lParam);
481     event->xcrossing.window = (Window)NT_find_window_from_id(NT_CWIN);
482     }
483     }
484     else
485     {
486     event->type=MotionNotify; /* Fill out mouse event */
487     event->xmotion.window=(Window)window;
488     event->xmotion.x=pt.x=LOWORD(lParam);
489     event->xmotion.y=pt.y=HIWORD(lParam);
490     event->xmotion.time=GetTickCount();
491     ClientToScreen(hWnd,&pt); /* Translate coordinates */
492     event->xmotion.x_root=pt.x;
493     event->xmotion.y_root=pt.y;
494     if (wParam&MK_CONTROL)
495     st|=ControlMask;
496     if (wParam&MK_SHIFT)
497     st|=ShiftMask;
498     if (wParam&MK_LBUTTON)
499     st|=Button1Mask;
500     if (wParam&MK_MBUTTON)
501     st|=Button2Mask;
502     if (wParam&MK_RBUTTON)
503     st|=Button3Mask;
504     event->xmotion.state=st;
505     }
506     NT_CWIN=(NT_window *)hWnd;
507     break;
508     case WM_MOUSEWHEEL:
509     event->type=ButtonRelease;
510     event->xbutton.x=LOWORD(lParam);
511     event->xbutton.y=HIWORD (lParam);
512     event->xbutton.button=HIWORD(wParam)>32768?Button5:Button4;
513     event->xbutton.window=(Window)window;
514     event->xbutton.time=GetTickCount();
515     if (wParam&MK_CONTROL)
516     st|=ControlMask;
517     if (wParam&MK_SHIFT)
518     st|=ShiftMask;
519     if (wParam&MK_LBUTTON)
520     st|=Button1Mask;
521     if (wParam&MK_MBUTTON)
522     st|=Button2Mask;
523     if (wParam&MK_RBUTTON)
524     st|=Button3Mask;
525     event->xbutton.state=st;
526     break;
527     case WM_SYSCHAR:
528     case WM_CHAR:
529     event->type=KeyPress;
530     event->xkey.state=NT_get_state();
531     event->xkey.x=event->xkey.y=0; /* Inside the window */
532     event->xkey.keycode=LOWORD(wParam);
533     if (GetKeyState(VK_CONTROL) & 0x8000) {
534     if (event->xkey.keycode == 32) { event->xkey.keycode=0; }
535     if (event->xkey.keycode >255 ) { event->xkey.keycode=0; }
536     }
537     event->xkey.window=(Window)window;
538     break;
539     case WM_KEYDOWN:
540     event->type=KeyPress;
541     switch (wParam)
542     {
543     case VK_CANCEL: key=XK_Cancel; break;
544     case VK_CLEAR: key=XK_Clear; break;
545     /* causes AltGr to create a keypress */
546     /* case VK_MENU: key=XK_Alt_L; break;*/
547     case VK_PAUSE: key=XK_Pause; break;
548     case VK_PRIOR: key=XK_Prior; break;
549     case VK_NEXT: key=XK_Next; break;
550     case VK_END: key=XK_End; break;
551     case VK_HOME: key=XK_Home; break;
552     case VK_LEFT: key=XK_Left; break;
553     case VK_UP: key=XK_Up; break;
554     case VK_RIGHT: key=XK_Right; break;
555     case VK_DOWN: key=XK_Down; break;
556     case VK_SELECT: key=XK_Select; break;
557     case VK_PRINT: key=XK_Print; break;
558     case VK_EXECUTE: key=XK_Execute; break;
559     case VK_INSERT: key=XK_Insert; break;
560     case VK_DELETE: key=XK_Delete; break;
561     case VK_HELP: key=XK_Help; break;
562     case VK_NUMLOCK: key=XK_Num_Lock; break;
563     case VK_SCROLL: key=XK_Scroll_Lock; break;
564     case VK_BACK: key=XK_BackSpace; break;
565     case VK_F1: key=XK_F1; break;
566     case VK_F2: key=XK_F2; break;
567     case VK_F3: key=XK_F3; break;
568     case VK_F4: key=XK_F4; break;
569     case VK_F5: key=XK_F5; break;
570     case VK_F6: key=XK_F6; break;
571     case VK_F7: key=XK_F7; break;
572     case VK_F8: key=XK_F8; break;
573     case VK_F9: key=XK_F9; break;
574     case VK_F10: key=XK_F10; break;
575     case VK_F11: key=XK_F11; break;
576     case VK_F12: key=XK_F12; break;
577     case VK_ADD: key=XK_KP_Add; break;
578     case VK_SUBTRACT:key=XK_KP_Subtract; break;
579     default: key=0; break;
580     }
581     if (key == 0) {
582     event->type = -1;
583     }
584     else
585     {
586     event->xkey.keycode=key;
587     event->xkey.window=(Window)window;
588     event->xkey.state=NT_get_state();
589     event->xkey.x=event->xkey.y=0; /* Inside the window */
590     }
591     break;
592     case WM_DESTROY:
593     case WM_QUIT:
594     case WM_CLOSE:
595     event->type = ClientMessage;
596     event->xclient.format = 32;
597     event->xclient.data.l[0] = XInternAtom(NULL,"WM_DELETE_WINDOW", FALSE);
598     break;
599     case USR_EnterNotify:
600     event->type = EnterNotify;
601     event->xcrossing.x = LOWORD(lParam);
602     event->xcrossing.y = HIWORD(lParam);
603     event->xcrossing.window = (Window)window;
604     break;
605     case WM_MOVE:
606     if (window->min==0)
607     {
608     window->x = LOWORD(lParam);
609     window->y = HIWORD(lParam);
610     NT_configureNotify(window,window->x,window->y);
611     event->type = ConfigureNotify;
612     event->xconfigure.window = (Window)window;
613     event->xconfigure.x = 0; /* client area is always @ 0 */
614     event->xconfigure.y = 0;
615     event->xconfigure.width = window->wdth;
616     event->xconfigure.height = window->hght;
617     event->xconfigure.above = Above;
618     }
619     break;
620     case WM_SIZING:
621     event->type = ConfigureNotify;
622     window->wdth = LOWORD(lParam);
623     if (window->wdth<window->minx)
624     window->wdth = window->minx;
625     window->hght = HIWORD(lParam);
626     if (window->hght<window->minx)
627     window->hght = window->miny;
628     NT_configureNotify(window,window->x,window->y);
629     event->xconfigure.window = (Window)window;
630     event->xconfigure.x = 0;
631     event->xconfigure.y = 0;
632     event->xconfigure.width = window->wdth;
633     event->xconfigure.height = window->hght;
634     event->xconfigure.above = Above;
635     break;
636     case WM_SIZE:
637     switch(wParam)
638     {
639     case SIZE_MINIMIZED:
640     event->type=UnmapNotify;
641     window->min=1;
642     break;
643     default:
644     event->type = ConfigureNotify;
645     window->wdth = LOWORD(lParam);
646     if (window->wdth<window->minx)
647     window->wdth = window->minx;
648     window->hght = HIWORD(lParam);
649     if (window->hght<window->minx)
650     window->hght = window->miny;
651     event->xconfigure.window = (Window)window;
652     event->xconfigure.x = 0;
653     event->xconfigure.y = 0;
654     event->xconfigure.width = window->wdth;
655     event->xconfigure.height = window->hght;
656     event->xconfigure.above = Above;
657     #if !defined(WIN9X)
658     if (window->min) event->type=MapNotify;
659     #endif
660     window->min=0;
661     break;
662     }
663     break;
664     case WM_DESTROYCLIPBOARD:
665     event->type = SelectionClear;
666     event->xselectionclear.time = GetTickCount();
667     break;
668     case USR_MapNotify:
669     event->type=MapNotify;
670     break;
671     case USR_ConvertSelection:
672     event->type=SelectionNotify;
673     event->xselection.requestor = (Window)window;
674     event->xselection.property = XA_CUT_BUFFER0;
675     break;
676     default:
677     break;
678     }
679     } while(0);
680     return (event==NULL?0: (event->type==-1?0:1));
681     }
682     /*****************************************************************\
683    
684    
685     Function: XCheckWindowEvent
686     Inputs: display, window, event mask.
687     Returned: pointer to filled in event structure, status.
688    
689     Comments: This is fudged at the moment to work with the toolkit.
690     The event system needs rewriting to account properly for
691     event masks.
692    
693     \*****************************************************************/
694    
695     BoolDef
696     XCheckTypedEvent(display,ev,rep)
697     Display *display;
698     int ev;
699     XEvent *rep;
700     {
701     xtrace("XCheckTypedEvent\n");
702     return (False);
703     }
704    
705     BoolDef
706     XCheckWindowEvent(display,w,emask,ev)
707     Display *display;
708     Window w;
709     long emask;
710     XEvent *ev;
711     {
712     NT_window *ntw=(NT_window *)w;
713     MSG msg;
714     BoolDef status = 0;
715    
716     xtrace("XCheckWindowEvent\n");
717     if (emask&0)
718     if (PeekMessage(&msg,ntw->w,USR_MapNotify,
719     USR_MapNotify,PM_REMOVE)||
720     PeekMessage(&msg,ntw->w,WM_PAINT,WM_PAINT,PM_REMOVE))
721     {
722     cjh_printf("removed message\n");
723     ev->type=ConfigureNotify;
724     status = 1;
725     }
726     return(status);
727     }
728    
729     /*
730     XPending checks for x events pending.
731     We don't know if we have x events until we process
732     the win events.
733     */
734     int
735     XPending (display)
736     Display *display;
737     {
738     MSG msg;
739     /* xtrace("XPending\n"); */
740     while(wineventq->count<=0 && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
741     {
742     doTranslateMessage(&msg);
743     DispatchMessage(&msg);
744     }
745     return wineventq->count;
746     }
747    
748     int
749     XPutBackEvent(display,event)
750     Display *display;
751     XEvent *event;
752     {
753     xtrace("XPutBackEvent\n");
754     return 0;
755     }
756    
757    
758     StatusDef
759     XSendEvent(display,w,prop,emask,event)
760     Display *display;
761     Window w;
762     BoolDef prop;
763     long emask;
764     XEvent *event;
765     {
766     xtrace("XSendEvent\n");
767     return 0;
768     }
769    
770     /* I'm tempted to flush the windows queue
771     ** before checking, but I think that would
772     ** break the assumtion that most of the WM_PAINT
773     ** messges are only going to be dispatched when
774     ** the app is directly calling us.
775     */
776    
777     BoolDef
778     XCheckTypedWindowEvent(
779     Display* display,
780     Window w,
781     int event_type,
782     XEvent* event_return)
783     {
784     int i,j;
785     xtrace("XCheckTypedWindowEvent\n");
786     if (w==0) return 0;
787     /*
788     i = wineventq->next;
789     while(i != wineventq->avail)
790     {
791     if (wineventq->list[i].window==(NT_window*)w)
792     {
793     WinEventToXEvent(&wineventq->list[i],event_return);
794     if (event_return->type == event_type)
795     {
796     break;
797     }
798     }
799     i++;
800     if (i>wineventq->num) i=0;
801     }
802     if (i != wineventq->avail)
803     {
804     while(i != wineventq->next)
805     {
806     j =i-1;
807     if (j<0) j= wineventq->num;
808     copyWinEvent(&wineventq->list[i],&wineventq->list[j]);
809     i = j;
810     }
811     wineventq->next++;
812     wineventq->count--;
813     cjh_printf("removed an event\n");
814     return 1;
815     }
816     */
817     return 0;
818     }
819    
820     /*****************************************************************\
821    
822    
823     Function: XWindowEvent
824     Inputs: display, window, event mask.
825     Returned: pointer to filled in event structure.
826    
827     Comments: This is fudged at the moment to work with the toolkit.
828     The event system needs rewriting to account properly for
829     event masks.
830    
831     \*****************************************************************/
832    
833     int
834     XWindowEvent(display,w,emask,rep)
835     Display *display;
836     Window w;
837     long emask;
838     XEvent *rep;
839     {
840     NT_window *ntw=(NT_window *)w;
841     MSG msg;
842    
843     xtrace("XWindowEvent\n");
844     if (emask&ExposureMask)
845     {
846     GetMessage(&msg,ntw->w,USR_MapNotify,USR_MapNotify);
847     rep->type=ConfigureNotify;
848     }
849     return 0;
850     }
851    
852    
853    
854     /*****************************************************************\
855    
856     Function: XNextEvent
857     Inputs: display, event structure pointer.
858    
859     Comments: Windows routines receive messages (events) in two ways:
860     firstly by GetMessage, which takes messages from the
861     calling thread's message queue, and secondly by the
862     window function being called with events as arguments.
863     To simulate the X system, we get messages from the queue
864     and pass them to the window function anyway, which
865     processes them and fills out the local XEvent structure.
866     DispatchMessage calls the window procedure and waits until
867     it returns. Translate message turns WM_KEYUP/DOWN messages
868     into WM_CHAR.
869    
870     \*****************************************************************/
871    
872     int
873     XNextEvent(Display *display,XEvent *event)
874     {
875     MSG msg;
876    
877     xtrace("XNextEvent\n");
878    
879     /* if there isn't already an event in the pipe, this will block */
880     while(wineventq->count <= 0 && GetMessage(&msg, NULL, 0, 0)>0)
881     {
882     doTranslateMessage(&msg);
883     DispatchMessage(&msg);
884     }
885     if (wineventq->count>0)
886     {
887     getQdEvent(wineventq,event);
888     }
889     else
890     {
891     /* hmm, GetMessage failed, maybe we're supposed to quit */
892     event->type=ClientMessage;
893     event->xclient.format = 32;
894     event->xclient.data.l[0] = XInternAtom(NULL,"WM_DELETE_WINDOW", FALSE);
895     return 1;
896     }
897     return 1;
898     }
899    
900     BoolDef
901     XFilterEvent(XEvent* event,Window window)
902     {
903     xtrace("XFilterEvent\n");
904     return 0;
905     }
906    
907     BoolDef
908     XQueryPointer(
909     Display* display,
910     Window w,
911     Window* root_return,
912     Window* child_return,
913     int* root_x_return,
914     int* root_y_return,
915     int* win_x_return,
916     int* win_y_return,
917     unsigned int* mask_return)
918     {
919     POINT point;
920     RECT rect;
921     xtrace("XQueryPointer\n");
922     GetCursorPos(&point);
923     *root_x_return = point.x;
924     *root_y_return = point.y;
925     GetWindowRect(((NT_window*)w)->w,&rect);
926     *win_x_return= point.x - rect.left;
927     *win_y_return= point.y - rect.top;
928     *mask_return = NT_get_state();
929     return True;
930     }
931    
932     int
933     XConvertSelection(
934     Display *display,
935     Atom sel, Atom target, Atom prop,
936     Window req,
937     Time time)
938     {
939     xtrace("XConvertSelection\n");
940     QEvent(wineventq,(NT_window*)req,USR_ConvertSelection,0,0L);
941     NT_wakeup(((NT_window*)req)->w);
942     return 0;
943     }
944