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

# Content
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