event.c 24 KB

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