queue.c 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936
  1. /*
  2. * Server-side message queues
  3. *
  4. * Copyright (C) 2000 Alexandre Julliard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #include <assert.h>
  23. #include <stdarg.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include "windef.h"
  27. #include "winbase.h"
  28. #include "wingdi.h"
  29. #include "winuser.h"
  30. #include "handle.h"
  31. #include "file.h"
  32. #include "thread.h"
  33. #include "process.h"
  34. #include "request.h"
  35. #include "user.h"
  36. enum message_kind { SEND_MESSAGE, POST_MESSAGE };
  37. #define NB_MSG_KINDS (POST_MESSAGE+1)
  38. struct message_result
  39. {
  40. struct list sender_entry; /* entry in sender list */
  41. struct message_result *recv_next; /* next in receiver list */
  42. struct msg_queue *sender; /* sender queue */
  43. struct msg_queue *receiver; /* receiver queue */
  44. int replied; /* has it been replied to? */
  45. unsigned int result; /* reply result */
  46. unsigned int error; /* error code to pass back to sender */
  47. struct message *callback_msg; /* message to queue for callback */
  48. void *data; /* message reply data */
  49. unsigned int data_size; /* size of message reply data */
  50. struct timeout_user *timeout; /* result timeout */
  51. };
  52. struct message
  53. {
  54. struct message *next; /* next message in list */
  55. struct message *prev; /* prev message in list */
  56. enum message_type type; /* message type */
  57. user_handle_t win; /* window handle */
  58. unsigned int msg; /* message code */
  59. unsigned int wparam; /* parameters */
  60. unsigned int lparam; /* parameters */
  61. int x; /* x position */
  62. int y; /* y position */
  63. unsigned int time; /* message time */
  64. unsigned int info; /* extra info */
  65. user_handle_t hook; /* winevent hook handle */
  66. void *hook_proc; /* winevent hook proc address */
  67. void *data; /* message data for sent messages */
  68. unsigned int data_size; /* size of message data */
  69. struct message_result *result; /* result in sender queue */
  70. };
  71. struct message_list
  72. {
  73. struct message *first; /* head of list */
  74. struct message *last; /* tail of list */
  75. };
  76. struct timer
  77. {
  78. struct list entry; /* entry in timer list */
  79. struct timeval when; /* next expiration */
  80. unsigned int rate; /* timer rate in ms */
  81. user_handle_t win; /* window handle */
  82. unsigned int msg; /* message to post */
  83. unsigned int id; /* timer id */
  84. unsigned int lparam; /* lparam for message */
  85. };
  86. struct thread_input
  87. {
  88. struct object obj; /* object header */
  89. user_handle_t focus; /* focus window */
  90. user_handle_t capture; /* capture window */
  91. user_handle_t active; /* active window */
  92. user_handle_t menu_owner; /* current menu owner window */
  93. user_handle_t move_size; /* current moving/resizing window */
  94. user_handle_t caret; /* caret window */
  95. rectangle_t caret_rect; /* caret rectangle */
  96. int caret_hide; /* caret hide count */
  97. int caret_state; /* caret on/off state */
  98. struct message *msg; /* message currently processed */
  99. struct thread *msg_thread; /* thread processing the message */
  100. struct message_list msg_list; /* list of hardware messages */
  101. unsigned char keystate[256]; /* state of each key */
  102. };
  103. struct msg_queue
  104. {
  105. struct object obj; /* object header */
  106. unsigned int wake_bits; /* wakeup bits */
  107. unsigned int wake_mask; /* wakeup mask */
  108. unsigned int changed_bits; /* changed wakeup bits */
  109. unsigned int changed_mask; /* changed wakeup mask */
  110. int paint_count; /* pending paint messages count */
  111. struct message_list msg_list[NB_MSG_KINDS]; /* lists of messages */
  112. struct list send_result; /* stack of sent messages waiting for result */
  113. struct list callback_result; /* list of callback messages waiting for result */
  114. struct message_result *recv_result; /* stack of received messages waiting for result */
  115. struct list pending_timers; /* list of pending timers */
  116. struct list expired_timers; /* list of expired timers */
  117. unsigned int next_timer_id; /* id for the next timer with a 0 window */
  118. struct timeout_user *timeout; /* timeout for next timer to expire */
  119. struct thread_input *input; /* thread input descriptor */
  120. struct hook_table *hooks; /* hook table */
  121. struct timeval last_get_msg; /* time of last get message call */
  122. };
  123. static void msg_queue_dump( struct object *obj, int verbose );
  124. static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
  125. static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
  126. static int msg_queue_signaled( struct object *obj, struct thread *thread );
  127. static int msg_queue_satisfied( struct object *obj, struct thread *thread );
  128. static void msg_queue_destroy( struct object *obj );
  129. static void thread_input_dump( struct object *obj, int verbose );
  130. static void thread_input_destroy( struct object *obj );
  131. static void timer_callback( void *private );
  132. static const struct object_ops msg_queue_ops =
  133. {
  134. sizeof(struct msg_queue), /* size */
  135. msg_queue_dump, /* dump */
  136. msg_queue_add_queue, /* add_queue */
  137. msg_queue_remove_queue, /* remove_queue */
  138. msg_queue_signaled, /* signaled */
  139. msg_queue_satisfied, /* satisfied */
  140. no_get_fd, /* get_fd */
  141. msg_queue_destroy /* destroy */
  142. };
  143. static const struct object_ops thread_input_ops =
  144. {
  145. sizeof(struct thread_input), /* size */
  146. thread_input_dump, /* dump */
  147. no_add_queue, /* add_queue */
  148. NULL, /* remove_queue */
  149. NULL, /* signaled */
  150. NULL, /* satisfied */
  151. no_get_fd, /* get_fd */
  152. thread_input_destroy /* destroy */
  153. };
  154. /* pointer to input structure of foreground thread */
  155. static struct thread_input *foreground_input;
  156. /* set the caret window in a given thread input */
  157. static void set_caret_window( struct thread_input *input, user_handle_t win )
  158. {
  159. input->caret = win;
  160. input->caret_rect.left = 0;
  161. input->caret_rect.top = 0;
  162. input->caret_rect.right = 0;
  163. input->caret_rect.bottom = 0;
  164. input->caret_hide = 1;
  165. input->caret_state = 0;
  166. }
  167. /* create a thread input object */
  168. static struct thread_input *create_thread_input(void)
  169. {
  170. struct thread_input *input;
  171. if ((input = alloc_object( &thread_input_ops )))
  172. {
  173. input->focus = 0;
  174. input->capture = 0;
  175. input->active = 0;
  176. input->menu_owner = 0;
  177. input->move_size = 0;
  178. input->msg = NULL;
  179. input->msg_thread = NULL;
  180. input->msg_list.first = input->msg_list.last = NULL;
  181. set_caret_window( input, 0 );
  182. memset( input->keystate, 0, sizeof(input->keystate) );
  183. }
  184. return input;
  185. }
  186. /* release the thread input data of a given thread */
  187. static void release_thread_input( struct thread *thread )
  188. {
  189. struct thread_input *input = thread->queue->input;
  190. if (!input) return;
  191. if (input->msg_thread == thread)
  192. {
  193. release_object( input->msg_thread );
  194. input->msg_thread = NULL;
  195. input->msg = NULL;
  196. }
  197. release_object( input );
  198. thread->queue->input = NULL;
  199. }
  200. /* create a message queue object */
  201. static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input )
  202. {
  203. struct msg_queue *queue;
  204. int i;
  205. if (!input && !(input = create_thread_input())) return NULL;
  206. if ((queue = alloc_object( &msg_queue_ops )))
  207. {
  208. queue->wake_bits = 0;
  209. queue->wake_mask = 0;
  210. queue->changed_bits = 0;
  211. queue->changed_mask = 0;
  212. queue->paint_count = 0;
  213. queue->recv_result = NULL;
  214. queue->next_timer_id = 1;
  215. queue->timeout = NULL;
  216. queue->input = (struct thread_input *)grab_object( input );
  217. queue->hooks = NULL;
  218. gettimeofday( &queue->last_get_msg, NULL );
  219. list_init( &queue->send_result );
  220. list_init( &queue->callback_result );
  221. list_init( &queue->pending_timers );
  222. list_init( &queue->expired_timers );
  223. for (i = 0; i < NB_MSG_KINDS; i++)
  224. queue->msg_list[i].first = queue->msg_list[i].last = NULL;
  225. thread->queue = queue;
  226. if (!thread->process->queue)
  227. thread->process->queue = (struct msg_queue *)grab_object( queue );
  228. }
  229. release_object( input );
  230. return queue;
  231. }
  232. /* free the message queue of a thread at thread exit */
  233. void free_msg_queue( struct thread *thread )
  234. {
  235. struct process *process = thread->process;
  236. remove_thread_hooks( thread );
  237. if (!thread->queue) return;
  238. if (process->queue == thread->queue) /* is it the process main queue? */
  239. {
  240. release_object( process->queue );
  241. process->queue = NULL;
  242. if (process->idle_event)
  243. {
  244. set_event( process->idle_event );
  245. release_object( process->idle_event );
  246. process->idle_event = NULL;
  247. }
  248. }
  249. release_thread_input( thread );
  250. release_object( thread->queue );
  251. thread->queue = NULL;
  252. }
  253. /* get the hook table for a given thread */
  254. struct hook_table *get_queue_hooks( struct thread *thread )
  255. {
  256. if (!thread->queue) return NULL;
  257. return thread->queue->hooks;
  258. }
  259. /* set the hook table for a given thread, allocating the queue if needed */
  260. void set_queue_hooks( struct thread *thread, struct hook_table *hooks )
  261. {
  262. struct msg_queue *queue = thread->queue;
  263. if (!queue) queue = create_msg_queue( thread, NULL );
  264. if (queue->hooks) release_object( queue->hooks );
  265. queue->hooks = hooks;
  266. }
  267. /* check the queue status */
  268. inline static int is_signaled( struct msg_queue *queue )
  269. {
  270. return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask));
  271. }
  272. /* set some queue bits */
  273. inline static void set_queue_bits( struct msg_queue *queue, unsigned int bits )
  274. {
  275. queue->wake_bits |= bits;
  276. queue->changed_bits |= bits;
  277. if (is_signaled( queue )) wake_up( &queue->obj, 0 );
  278. }
  279. /* clear some queue bits */
  280. inline static void clear_queue_bits( struct msg_queue *queue, unsigned int bits )
  281. {
  282. queue->wake_bits &= ~bits;
  283. queue->changed_bits &= ~bits;
  284. }
  285. /* check whether msg is a keyboard message */
  286. inline static int is_keyboard_msg( struct message *msg )
  287. {
  288. return (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST);
  289. }
  290. /* get the QS_* bit corresponding to a given hardware message */
  291. inline static int get_hardware_msg_bit( struct message *msg )
  292. {
  293. if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
  294. if (is_keyboard_msg( msg )) return QS_KEY;
  295. return QS_MOUSEBUTTON;
  296. }
  297. /* get the current thread queue, creating it if needed */
  298. inline static struct msg_queue *get_current_queue(void)
  299. {
  300. struct msg_queue *queue = current->queue;
  301. if (!queue) queue = create_msg_queue( current, NULL );
  302. return queue;
  303. }
  304. /* append a message to the end of a list */
  305. inline static void append_message( struct message_list *list, struct message *msg )
  306. {
  307. msg->next = NULL;
  308. if ((msg->prev = list->last)) msg->prev->next = msg;
  309. else list->first = msg;
  310. list->last = msg;
  311. }
  312. /* unlink a message from a list it */
  313. inline static void unlink_message( struct message_list *list, struct message *msg )
  314. {
  315. if (msg->next) msg->next->prev = msg->prev;
  316. else list->last = msg->prev;
  317. if (msg->prev) msg->prev->next = msg->next;
  318. else list->first = msg->next;
  319. }
  320. /* try to merge a message with the last in the list; return 1 if successful */
  321. static int merge_message( struct thread_input *input, const struct message *msg )
  322. {
  323. struct message *prev = input->msg_list.last;
  324. if (!prev) return 0;
  325. if (input->msg == prev) return 0;
  326. if (prev->result) return 0;
  327. if (prev->win != msg->win) return 0;
  328. if (prev->msg != msg->msg) return 0;
  329. if (prev->type != msg->type) return 0;
  330. /* now we can merge it */
  331. prev->wparam = msg->wparam;
  332. prev->lparam = msg->lparam;
  333. prev->x = msg->x;
  334. prev->y = msg->y;
  335. prev->time = msg->time;
  336. prev->info = msg->info;
  337. return 1;
  338. }
  339. /* free a result structure */
  340. static void free_result( struct message_result *result )
  341. {
  342. if (result->timeout) remove_timeout_user( result->timeout );
  343. if (result->data) free( result->data );
  344. if (result->callback_msg) free( result->callback_msg );
  345. free( result );
  346. }
  347. /* remove the result from the sender list it is on */
  348. static inline void remove_result_from_sender( struct message_result *result )
  349. {
  350. assert( result->sender );
  351. list_remove( &result->sender_entry );
  352. result->sender = NULL;
  353. if (!result->receiver) free_result( result );
  354. }
  355. /* store the message result in the appropriate structure */
  356. static void store_message_result( struct message_result *res, unsigned int result,
  357. unsigned int error )
  358. {
  359. res->result = result;
  360. res->error = error;
  361. res->replied = 1;
  362. if (res->timeout)
  363. {
  364. remove_timeout_user( res->timeout );
  365. res->timeout = NULL;
  366. }
  367. if (res->sender)
  368. {
  369. if (res->callback_msg)
  370. {
  371. /* queue the callback message in the sender queue */
  372. res->callback_msg->lparam = result;
  373. append_message( &res->sender->msg_list[SEND_MESSAGE], res->callback_msg );
  374. set_queue_bits( res->sender, QS_SENDMESSAGE );
  375. res->callback_msg = NULL;
  376. remove_result_from_sender( res );
  377. }
  378. else
  379. {
  380. /* wake sender queue if waiting on this result */
  381. if (list_head(&res->sender->send_result) == &res->sender_entry)
  382. set_queue_bits( res->sender, QS_SMRESULT );
  383. }
  384. }
  385. }
  386. /* free a message when deleting a queue or window */
  387. static void free_message( struct message *msg )
  388. {
  389. struct message_result *result = msg->result;
  390. if (result)
  391. {
  392. if (result->sender)
  393. {
  394. result->receiver = NULL;
  395. store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
  396. }
  397. else free_result( result );
  398. }
  399. if (msg->data) free( msg->data );
  400. free( msg );
  401. }
  402. /* remove (and free) a message from a message list */
  403. static void remove_queue_message( struct msg_queue *queue, struct message *msg,
  404. enum message_kind kind )
  405. {
  406. unlink_message( &queue->msg_list[kind], msg );
  407. switch(kind)
  408. {
  409. case SEND_MESSAGE:
  410. if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_SENDMESSAGE );
  411. break;
  412. case POST_MESSAGE:
  413. if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_POSTMESSAGE );
  414. break;
  415. }
  416. free_message( msg );
  417. }
  418. /* message timed out without getting a reply */
  419. static void result_timeout( void *private )
  420. {
  421. struct message_result *result = private;
  422. assert( !result->replied );
  423. result->timeout = NULL;
  424. store_message_result( result, 0, STATUS_TIMEOUT );
  425. }
  426. /* allocate and fill a message result structure */
  427. static struct message_result *alloc_message_result( struct msg_queue *send_queue,
  428. struct msg_queue *recv_queue,
  429. struct message *msg, unsigned int timeout,
  430. void *callback, unsigned int callback_data )
  431. {
  432. struct message_result *result = mem_alloc( sizeof(*result) );
  433. if (result)
  434. {
  435. result->sender = send_queue;
  436. result->receiver = recv_queue;
  437. result->replied = 0;
  438. result->data = NULL;
  439. result->data_size = 0;
  440. result->timeout = NULL;
  441. if (msg->type == MSG_CALLBACK)
  442. {
  443. struct message *callback_msg = mem_alloc( sizeof(*callback_msg) );
  444. if (!callback_msg)
  445. {
  446. free( result );
  447. return NULL;
  448. }
  449. callback_msg->type = MSG_CALLBACK_RESULT;
  450. callback_msg->win = msg->win;
  451. callback_msg->msg = msg->msg;
  452. callback_msg->wparam = (unsigned int)callback;
  453. callback_msg->lparam = 0;
  454. callback_msg->time = get_tick_count();
  455. callback_msg->x = 0;
  456. callback_msg->y = 0;
  457. callback_msg->info = callback_data;
  458. callback_msg->result = NULL;
  459. callback_msg->data = NULL;
  460. callback_msg->data_size = 0;
  461. result->callback_msg = callback_msg;
  462. list_add_head( &send_queue->callback_result, &result->sender_entry );
  463. }
  464. else
  465. {
  466. result->callback_msg = NULL;
  467. list_add_head( &send_queue->send_result, &result->sender_entry );
  468. }
  469. if (timeout != -1)
  470. {
  471. struct timeval when;
  472. gettimeofday( &when, 0 );
  473. add_timeout( &when, timeout );
  474. result->timeout = add_timeout_user( &when, result_timeout, result );
  475. }
  476. }
  477. return result;
  478. }
  479. /* receive a message, removing it from the sent queue */
  480. static void receive_message( struct msg_queue *queue, struct message *msg,
  481. struct get_message_reply *reply )
  482. {
  483. struct message_result *result = msg->result;
  484. reply->total = msg->data_size;
  485. if (msg->data_size > get_reply_max_size())
  486. {
  487. set_error( STATUS_BUFFER_OVERFLOW );
  488. return;
  489. }
  490. reply->type = msg->type;
  491. reply->win = msg->win;
  492. reply->msg = msg->msg;
  493. reply->wparam = msg->wparam;
  494. reply->lparam = msg->lparam;
  495. reply->x = msg->x;
  496. reply->y = msg->y;
  497. reply->time = msg->time;
  498. reply->info = msg->info;
  499. reply->hook = msg->hook;
  500. reply->hook_proc = msg->hook_proc;
  501. if (msg->data) set_reply_data_ptr( msg->data, msg->data_size );
  502. unlink_message( &queue->msg_list[SEND_MESSAGE], msg );
  503. /* put the result on the receiver result stack */
  504. if (result)
  505. {
  506. result->recv_next = queue->recv_result;
  507. queue->recv_result = result;
  508. }
  509. free( msg );
  510. if (!queue->msg_list[SEND_MESSAGE].first) clear_queue_bits( queue, QS_SENDMESSAGE );
  511. }
  512. /* set the result of the current received message */
  513. static void reply_message( struct msg_queue *queue, unsigned int result,
  514. unsigned int error, int remove, const void *data, size_t len )
  515. {
  516. struct message_result *res = queue->recv_result;
  517. if (remove)
  518. {
  519. queue->recv_result = res->recv_next;
  520. res->receiver = NULL;
  521. if (!res->sender) /* no one waiting for it */
  522. {
  523. free_result( res );
  524. return;
  525. }
  526. }
  527. if (!res->replied)
  528. {
  529. if (len && (res->data = memdup( data, len ))) res->data_size = len;
  530. store_message_result( res, result, error );
  531. }
  532. }
  533. /* retrieve a posted message */
  534. static int get_posted_message( struct msg_queue *queue, user_handle_t win,
  535. unsigned int first, unsigned int last, unsigned int flags,
  536. struct get_message_reply *reply )
  537. {
  538. struct message *msg;
  539. struct message_list *list = &queue->msg_list[POST_MESSAGE];
  540. /* check against the filters */
  541. for (msg = list->first; msg; msg = msg->next)
  542. {
  543. if (msg->msg == WM_QUIT) break; /* WM_QUIT is never filtered */
  544. if (win && msg->win && msg->win != win && !is_child_window( win, msg->win )) continue;
  545. if (msg->msg < first) continue;
  546. if (msg->msg > last) continue;
  547. break; /* found one */
  548. }
  549. if (!msg) return 0;
  550. /* return it to the app */
  551. reply->total = msg->data_size;
  552. if (msg->data_size > get_reply_max_size())
  553. {
  554. set_error( STATUS_BUFFER_OVERFLOW );
  555. return 1;
  556. }
  557. reply->type = msg->type;
  558. reply->win = msg->win;
  559. reply->msg = msg->msg;
  560. reply->wparam = msg->wparam;
  561. reply->lparam = msg->lparam;
  562. reply->x = msg->x;
  563. reply->y = msg->y;
  564. reply->time = msg->time;
  565. reply->info = msg->info;
  566. if (flags & GET_MSG_REMOVE)
  567. {
  568. if (msg->data)
  569. {
  570. set_reply_data_ptr( msg->data, msg->data_size );
  571. msg->data = NULL;
  572. msg->data_size = 0;
  573. }
  574. remove_queue_message( queue, msg, POST_MESSAGE );
  575. }
  576. else if (msg->data) set_reply_data( msg->data, msg->data_size );
  577. return 1;
  578. }
  579. /* empty a message list and free all the messages */
  580. static void empty_msg_list( struct message_list *list )
  581. {
  582. struct message *msg = list->first;
  583. while (msg)
  584. {
  585. struct message *next = msg->next;
  586. free_message( msg );
  587. msg = next;
  588. }
  589. }
  590. /* cleanup all pending results when deleting a queue */
  591. static void cleanup_results( struct msg_queue *queue )
  592. {
  593. struct list *entry;
  594. while ((entry = list_head( &queue->send_result )) != NULL)
  595. {
  596. remove_result_from_sender( LIST_ENTRY( entry, struct message_result, sender_entry ) );
  597. }
  598. while ((entry = list_head( &queue->callback_result )) != NULL)
  599. {
  600. remove_result_from_sender( LIST_ENTRY( entry, struct message_result, sender_entry ) );
  601. }
  602. while (queue->recv_result)
  603. reply_message( queue, 0, STATUS_ACCESS_DENIED /*FIXME*/, 1, NULL, 0 );
  604. }
  605. /* check if the thread owning the queue is hung (not checking for messages) */
  606. static int is_queue_hung( struct msg_queue *queue )
  607. {
  608. struct timeval now;
  609. struct wait_queue_entry *entry;
  610. gettimeofday( &now, NULL );
  611. if (now.tv_sec - queue->last_get_msg.tv_sec <= 5)
  612. return 0; /* less than 5 seconds since last get message -> not hung */
  613. for (entry = queue->obj.head; entry; entry = entry->next)
  614. {
  615. if (entry->thread->queue == queue)
  616. return 0; /* thread is waiting on queue -> not hung */
  617. }
  618. return 1;
  619. }
  620. static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
  621. {
  622. struct msg_queue *queue = (struct msg_queue *)obj;
  623. struct process *process = entry->thread->process;
  624. /* a thread can only wait on its own queue */
  625. if (entry->thread->queue != queue)
  626. {
  627. set_error( STATUS_ACCESS_DENIED );
  628. return 0;
  629. }
  630. /* if waiting on the main process queue, set the idle event */
  631. if (process->queue == queue)
  632. {
  633. if (process->idle_event) set_event( process->idle_event );
  634. }
  635. add_queue( obj, entry );
  636. return 1;
  637. }
  638. static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
  639. {
  640. struct msg_queue *queue = (struct msg_queue *)obj;
  641. struct process *process = entry->thread->process;
  642. remove_queue( obj, entry );
  643. assert( entry->thread->queue == queue );
  644. /* if waiting on the main process queue, reset the idle event */
  645. if (process->queue == queue)
  646. {
  647. if (process->idle_event) reset_event( process->idle_event );
  648. }
  649. }
  650. static void msg_queue_dump( struct object *obj, int verbose )
  651. {
  652. struct msg_queue *queue = (struct msg_queue *)obj;
  653. fprintf( stderr, "Msg queue bits=%x mask=%x\n",
  654. queue->wake_bits, queue->wake_mask );
  655. }
  656. static int msg_queue_signaled( struct object *obj, struct thread *thread )
  657. {
  658. struct msg_queue *queue = (struct msg_queue *)obj;
  659. return is_signaled( queue );
  660. }
  661. static int msg_queue_satisfied( struct object *obj, struct thread *thread )
  662. {
  663. struct msg_queue *queue = (struct msg_queue *)obj;
  664. queue->wake_mask = 0;
  665. queue->changed_mask = 0;
  666. return 0; /* Not abandoned */
  667. }
  668. static void msg_queue_destroy( struct object *obj )
  669. {
  670. struct msg_queue *queue = (struct msg_queue *)obj;
  671. struct list *ptr;
  672. int i;
  673. cleanup_results( queue );
  674. for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] );
  675. while ((ptr = list_head( &queue->pending_timers )))
  676. {
  677. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  678. list_remove( &timer->entry );
  679. free( timer );
  680. }
  681. while ((ptr = list_head( &queue->expired_timers )))
  682. {
  683. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  684. list_remove( &timer->entry );
  685. free( timer );
  686. }
  687. if (queue->timeout) remove_timeout_user( queue->timeout );
  688. if (queue->input) release_object( queue->input );
  689. if (queue->hooks) release_object( queue->hooks );
  690. }
  691. static void thread_input_dump( struct object *obj, int verbose )
  692. {
  693. struct thread_input *input = (struct thread_input *)obj;
  694. fprintf( stderr, "Thread input focus=%p capture=%p active=%p\n",
  695. input->focus, input->capture, input->active );
  696. }
  697. static void thread_input_destroy( struct object *obj )
  698. {
  699. struct thread_input *input = (struct thread_input *)obj;
  700. if (foreground_input == input) foreground_input = NULL;
  701. if (input->msg_thread) release_object( input->msg_thread );
  702. empty_msg_list( &input->msg_list );
  703. }
  704. /* fix the thread input data when a window is destroyed */
  705. inline static void thread_input_cleanup_window( struct msg_queue *queue, user_handle_t window )
  706. {
  707. struct thread_input *input = queue->input;
  708. if (window == input->focus) input->focus = 0;
  709. if (window == input->capture) input->capture = 0;
  710. if (window == input->active) input->active = 0;
  711. if (window == input->menu_owner) input->menu_owner = 0;
  712. if (window == input->move_size) input->move_size = 0;
  713. if (window == input->caret) set_caret_window( input, 0 );
  714. }
  715. /* check if the specified window can be set in the input data of a given queue */
  716. static int check_queue_input_window( struct msg_queue *queue, user_handle_t window )
  717. {
  718. struct thread *thread;
  719. int ret = 0;
  720. if (!window) return 1; /* we can always clear the data */
  721. if ((thread = get_window_thread( window )))
  722. {
  723. ret = (queue->input == thread->queue->input);
  724. if (!ret) set_error( STATUS_ACCESS_DENIED );
  725. release_object( thread );
  726. }
  727. else set_error( STATUS_INVALID_HANDLE );
  728. return ret;
  729. }
  730. /* attach two thread input data structures */
  731. int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
  732. {
  733. struct thread_input *input;
  734. if (!thread_to->queue && !(thread_to->queue = create_msg_queue( thread_to, NULL ))) return 0;
  735. input = (struct thread_input *)grab_object( thread_to->queue->input );
  736. if (thread_from->queue)
  737. {
  738. release_thread_input( thread_from );
  739. thread_from->queue->input = input;
  740. }
  741. else
  742. {
  743. if (!(thread_from->queue = create_msg_queue( thread_from, input ))) return 0;
  744. }
  745. memset( input->keystate, 0, sizeof(input->keystate) );
  746. return 1;
  747. }
  748. /* detach two thread input data structures */
  749. static void detach_thread_input( struct thread *thread_from, struct thread *thread_to )
  750. {
  751. struct thread_input *input;
  752. if (!thread_from->queue || !thread_to->queue ||
  753. thread_from->queue->input != thread_to->queue->input)
  754. {
  755. set_error( STATUS_ACCESS_DENIED );
  756. return;
  757. }
  758. if ((input = create_thread_input()))
  759. {
  760. release_thread_input( thread_from );
  761. thread_from->queue->input = input;
  762. }
  763. }
  764. /* set the next timer to expire */
  765. static void set_next_timer( struct msg_queue *queue )
  766. {
  767. struct list *ptr;
  768. if (queue->timeout)
  769. {
  770. remove_timeout_user( queue->timeout );
  771. queue->timeout = NULL;
  772. }
  773. if ((ptr = list_head( &queue->pending_timers )))
  774. {
  775. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  776. queue->timeout = add_timeout_user( &timer->when, timer_callback, queue );
  777. }
  778. /* set/clear QS_TIMER bit */
  779. if (list_empty( &queue->expired_timers ))
  780. clear_queue_bits( queue, QS_TIMER );
  781. else
  782. set_queue_bits( queue, QS_TIMER );
  783. }
  784. /* find a timer from its window and id */
  785. static struct timer *find_timer( struct msg_queue *queue, user_handle_t win,
  786. unsigned int msg, unsigned int id )
  787. {
  788. struct list *ptr;
  789. /* we need to search both lists */
  790. LIST_FOR_EACH( ptr, &queue->pending_timers )
  791. {
  792. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  793. if (timer->win == win && timer->msg == msg && timer->id == id) return timer;
  794. }
  795. LIST_FOR_EACH( ptr, &queue->expired_timers )
  796. {
  797. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  798. if (timer->win == win && timer->msg == msg && timer->id == id) return timer;
  799. }
  800. return NULL;
  801. }
  802. /* callback for the next timer expiration */
  803. static void timer_callback( void *private )
  804. {
  805. struct msg_queue *queue = private;
  806. struct list *ptr;
  807. queue->timeout = NULL;
  808. /* move on to the next timer */
  809. ptr = list_head( &queue->pending_timers );
  810. list_remove( ptr );
  811. list_add_tail( &queue->expired_timers, ptr );
  812. set_next_timer( queue );
  813. }
  814. /* link a timer at its rightful place in the queue list */
  815. static void link_timer( struct msg_queue *queue, struct timer *timer )
  816. {
  817. struct list *ptr;
  818. for (ptr = queue->pending_timers.next; ptr != &queue->pending_timers; ptr = ptr->next)
  819. {
  820. struct timer *t = LIST_ENTRY( ptr, struct timer, entry );
  821. if (!time_before( &t->when, &timer->when )) break;
  822. }
  823. list_add_before( ptr, &timer->entry );
  824. }
  825. /* remove a timer from the queue timer list and free it */
  826. static void free_timer( struct msg_queue *queue, struct timer *timer )
  827. {
  828. list_remove( &timer->entry );
  829. free( timer );
  830. set_next_timer( queue );
  831. }
  832. /* restart an expired timer */
  833. static void restart_timer( struct msg_queue *queue, struct timer *timer )
  834. {
  835. struct timeval now;
  836. list_remove( &timer->entry );
  837. gettimeofday( &now, 0 );
  838. while (!time_before( &now, &timer->when )) add_timeout( &timer->when, timer->rate );
  839. link_timer( queue, timer );
  840. set_next_timer( queue );
  841. }
  842. /* find an expired timer matching the filtering parameters */
  843. static struct timer *find_expired_timer( struct msg_queue *queue, user_handle_t win,
  844. unsigned int get_first, unsigned int get_last,
  845. int remove )
  846. {
  847. struct list *ptr;
  848. LIST_FOR_EACH( ptr, &queue->expired_timers )
  849. {
  850. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  851. if (win && timer->win != win) continue;
  852. if (timer->msg >= get_first && timer->msg <= get_last)
  853. {
  854. if (remove) restart_timer( queue, timer );
  855. return timer;
  856. }
  857. }
  858. return NULL;
  859. }
  860. /* add a timer */
  861. static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
  862. {
  863. struct timer *timer = mem_alloc( sizeof(*timer) );
  864. if (timer)
  865. {
  866. timer->rate = max( rate, 1 );
  867. gettimeofday( &timer->when, 0 );
  868. add_timeout( &timer->when, rate );
  869. link_timer( queue, timer );
  870. /* check if we replaced the next timer */
  871. if (list_head( &queue->pending_timers ) == &timer->entry) set_next_timer( queue );
  872. }
  873. return timer;
  874. }
  875. /* change the input key state for a given key */
  876. static void set_input_key_state( struct thread_input *input, unsigned char key, int down )
  877. {
  878. if (down)
  879. {
  880. if (!(input->keystate[key] & 0x80)) input->keystate[key] ^= 0x01;
  881. input->keystate[key] |= 0x80;
  882. }
  883. else input->keystate[key] &= ~0x80;
  884. }
  885. /* update the input key state for a keyboard message */
  886. static void update_input_key_state( struct thread_input *input, const struct message *msg )
  887. {
  888. unsigned char key;
  889. int down = 0, extended;
  890. switch (msg->msg)
  891. {
  892. case WM_LBUTTONDOWN:
  893. down = 1;
  894. /* fall through */
  895. case WM_LBUTTONUP:
  896. set_input_key_state( input, VK_LBUTTON, down );
  897. break;
  898. case WM_MBUTTONDOWN:
  899. down = 1;
  900. /* fall through */
  901. case WM_MBUTTONUP:
  902. set_input_key_state( input, VK_MBUTTON, down );
  903. break;
  904. case WM_RBUTTONDOWN:
  905. down = 1;
  906. /* fall through */
  907. case WM_RBUTTONUP:
  908. set_input_key_state( input, VK_RBUTTON, down );
  909. break;
  910. case WM_KEYDOWN:
  911. case WM_SYSKEYDOWN:
  912. down = 1;
  913. /* fall through */
  914. case WM_KEYUP:
  915. case WM_SYSKEYUP:
  916. key = (unsigned char)msg->wparam;
  917. extended = ((msg->lparam >> 16) & KF_EXTENDED) != 0;
  918. set_input_key_state( input, key, down );
  919. switch(key)
  920. {
  921. case VK_SHIFT:
  922. set_input_key_state( input, extended ? VK_RSHIFT : VK_LSHIFT, down );
  923. break;
  924. case VK_CONTROL:
  925. set_input_key_state( input, extended ? VK_RCONTROL : VK_LCONTROL, down );
  926. break;
  927. case VK_MENU:
  928. set_input_key_state( input, extended ? VK_RMENU : VK_LMENU, down );
  929. break;
  930. }
  931. break;
  932. }
  933. }
  934. /* release the hardware message currently being processed by the given thread */
  935. static void release_hardware_message( struct thread *thread, int remove )
  936. {
  937. struct thread_input *input = thread->queue->input;
  938. if (input->msg_thread != thread) return;
  939. if (remove)
  940. {
  941. struct message *other;
  942. int clr_bit;
  943. update_input_key_state( input, input->msg );
  944. unlink_message( &input->msg_list, input->msg );
  945. clr_bit = get_hardware_msg_bit( input->msg );
  946. for (other = input->msg_list.first; other; other = other->next)
  947. if (get_hardware_msg_bit( other ) == clr_bit) break;
  948. if (!other) clear_queue_bits( thread->queue, clr_bit );
  949. free_message( input->msg );
  950. }
  951. release_object( input->msg_thread );
  952. input->msg = NULL;
  953. input->msg_thread = NULL;
  954. }
  955. /* find the window that should receive a given hardware message */
  956. static user_handle_t find_hardware_message_window( struct thread_input *input, struct message *msg,
  957. unsigned int *msg_code )
  958. {
  959. user_handle_t win = 0;
  960. *msg_code = msg->msg;
  961. if (is_keyboard_msg( msg ))
  962. {
  963. if (input && !(win = input->focus))
  964. {
  965. win = input->active;
  966. if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
  967. }
  968. }
  969. else /* mouse message */
  970. {
  971. if (!input || !(win = input->capture))
  972. {
  973. if (!(win = msg->win) || !is_window_visible( win ))
  974. win = window_from_point( msg->x, msg->y );
  975. }
  976. }
  977. return win;
  978. }
  979. /* queue a hardware message into a given thread input */
  980. static void queue_hardware_message( struct msg_queue *queue, struct message *msg )
  981. {
  982. user_handle_t win;
  983. struct thread *thread;
  984. struct thread_input *input;
  985. unsigned int msg_code;
  986. win = find_hardware_message_window( queue ? queue->input : foreground_input, msg, &msg_code );
  987. if (!win || !(thread = get_window_thread(win)))
  988. {
  989. free( msg );
  990. return;
  991. }
  992. input = thread->queue->input;
  993. if (msg->msg == WM_MOUSEMOVE && merge_message( input, msg )) free( msg );
  994. else
  995. {
  996. append_message( &input->msg_list, msg );
  997. set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
  998. }
  999. release_object( thread );
  1000. }
  1001. /* find a hardware message for the given queue */
  1002. static int get_hardware_message( struct thread *thread, struct message *first,
  1003. user_handle_t filter_win, struct get_message_reply *reply )
  1004. {
  1005. struct thread_input *input = thread->queue->input;
  1006. struct thread *win_thread;
  1007. struct message *msg;
  1008. user_handle_t win;
  1009. int clear_bits, got_one = 0;
  1010. unsigned int msg_code;
  1011. if (input->msg_thread && input->msg_thread != thread)
  1012. return 0; /* locked by another thread */
  1013. if (!first)
  1014. {
  1015. msg = input->msg_list.first;
  1016. clear_bits = QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON;
  1017. }
  1018. else
  1019. {
  1020. msg = first->next;
  1021. clear_bits = 0; /* don't clear bits if we don't go through the whole list */
  1022. }
  1023. while (msg)
  1024. {
  1025. win = find_hardware_message_window( input, msg, &msg_code );
  1026. if (!win || !(win_thread = get_window_thread( win )))
  1027. {
  1028. /* no window at all, remove it */
  1029. struct message *next = msg->next;
  1030. update_input_key_state( input, msg );
  1031. unlink_message( &input->msg_list, msg );
  1032. free_message( msg );
  1033. msg = next;
  1034. continue;
  1035. }
  1036. if (win_thread != thread)
  1037. {
  1038. /* wake the other thread */
  1039. set_queue_bits( win_thread->queue, get_hardware_msg_bit(msg) );
  1040. release_object( win_thread );
  1041. got_one = 1;
  1042. msg = msg->next;
  1043. continue;
  1044. }
  1045. /* if we already got a message for another thread, or if it doesn't
  1046. * match the filter we skip it (filter is only checked for keyboard
  1047. * messages since the dest window for a mouse message depends on hittest)
  1048. */
  1049. if (got_one ||
  1050. (filter_win && is_keyboard_msg(msg) &&
  1051. win != filter_win && !is_child_window( filter_win, win )))
  1052. {
  1053. clear_bits &= ~get_hardware_msg_bit( msg );
  1054. release_object( win_thread );
  1055. msg = msg->next;
  1056. continue;
  1057. }
  1058. /* now we can return it */
  1059. if (!input->msg_thread) input->msg_thread = win_thread;
  1060. else release_object( win_thread );
  1061. input->msg = msg;
  1062. reply->type = MSG_HARDWARE;
  1063. reply->win = win;
  1064. reply->msg = msg_code;
  1065. reply->wparam = msg->wparam;
  1066. reply->lparam = msg->lparam;
  1067. reply->x = msg->x;
  1068. reply->y = msg->y;
  1069. reply->time = msg->time;
  1070. reply->info = msg->info;
  1071. return 1;
  1072. }
  1073. /* nothing found, clear the hardware queue bits */
  1074. clear_queue_bits( thread->queue, clear_bits );
  1075. if (input->msg_thread) release_object( input->msg_thread );
  1076. input->msg = NULL;
  1077. input->msg_thread = NULL;
  1078. return 0;
  1079. }
  1080. /* increment (or decrement if 'incr' is negative) the queue paint count */
  1081. void inc_queue_paint_count( struct thread *thread, int incr )
  1082. {
  1083. struct msg_queue *queue = thread->queue;
  1084. assert( queue );
  1085. if ((queue->paint_count += incr) < 0) queue->paint_count = 0;
  1086. if (queue->paint_count)
  1087. set_queue_bits( queue, QS_PAINT );
  1088. else
  1089. clear_queue_bits( queue, QS_PAINT );
  1090. }
  1091. /* remove all messages and timers belonging to a certain window */
  1092. void queue_cleanup_window( struct thread *thread, user_handle_t win )
  1093. {
  1094. struct msg_queue *queue = thread->queue;
  1095. struct list *ptr;
  1096. struct message *msg;
  1097. int i;
  1098. if (!queue) return;
  1099. /* remove timers */
  1100. ptr = list_head( &queue->pending_timers );
  1101. while (ptr)
  1102. {
  1103. struct list *next = list_next( &queue->pending_timers, ptr );
  1104. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  1105. if (timer->win == win) free_timer( queue, timer );
  1106. ptr = next;
  1107. }
  1108. ptr = list_head( &queue->expired_timers );
  1109. while (ptr)
  1110. {
  1111. struct list *next = list_next( &queue->expired_timers, ptr );
  1112. struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
  1113. if (timer->win == win) free_timer( queue, timer );
  1114. ptr = next;
  1115. }
  1116. /* remove messages */
  1117. for (i = 0; i < NB_MSG_KINDS; i++)
  1118. {
  1119. msg = queue->msg_list[i].first;
  1120. while (msg)
  1121. {
  1122. struct message *next = msg->next;
  1123. if (msg->win == win) remove_queue_message( queue, msg, i );
  1124. msg = next;
  1125. }
  1126. }
  1127. thread_input_cleanup_window( queue, win );
  1128. }
  1129. /* post a message to a window; used by socket handling */
  1130. void post_message( user_handle_t win, unsigned int message,
  1131. unsigned int wparam, unsigned int lparam )
  1132. {
  1133. struct message *msg;
  1134. struct thread *thread = get_window_thread( win );
  1135. if (!thread) return;
  1136. if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
  1137. {
  1138. msg->type = MSG_POSTED;
  1139. msg->win = get_user_full_handle( win );
  1140. msg->msg = message;
  1141. msg->wparam = wparam;
  1142. msg->lparam = lparam;
  1143. msg->time = get_tick_count();
  1144. msg->x = 0;
  1145. msg->y = 0;
  1146. msg->info = 0;
  1147. msg->result = NULL;
  1148. msg->data = NULL;
  1149. msg->data_size = 0;
  1150. append_message( &thread->queue->msg_list[POST_MESSAGE], msg );
  1151. set_queue_bits( thread->queue, QS_POSTMESSAGE );
  1152. }
  1153. release_object( thread );
  1154. }
  1155. /* post a win event */
  1156. void post_win_event( struct thread *thread, unsigned int event,
  1157. user_handle_t win, unsigned int object_id,
  1158. unsigned int child_id, void *hook_proc,
  1159. const WCHAR *module, size_t module_size,
  1160. user_handle_t hook)
  1161. {
  1162. struct message *msg;
  1163. if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
  1164. {
  1165. msg->type = MSG_WINEVENT;
  1166. msg->win = get_user_full_handle( win );
  1167. msg->msg = event;
  1168. msg->wparam = object_id;
  1169. msg->lparam = child_id;
  1170. msg->time = get_tick_count();
  1171. msg->x = 0;
  1172. msg->y = 0;
  1173. msg->info = get_thread_id( current );
  1174. msg->result = NULL;
  1175. msg->hook = hook;
  1176. msg->hook_proc = hook_proc;
  1177. if ((msg->data = malloc( module_size )))
  1178. {
  1179. msg->data_size = module_size;
  1180. memcpy( msg->data, module, module_size );
  1181. if (debug_level > 1)
  1182. fprintf( stderr, "post_win_event: tid %04x event %04x win %p object_id %d child_id %d\n",
  1183. get_thread_id(thread), event, win, object_id, child_id );
  1184. append_message( &thread->queue->msg_list[SEND_MESSAGE], msg );
  1185. set_queue_bits( thread->queue, QS_SENDMESSAGE );
  1186. }
  1187. else
  1188. free( msg );
  1189. }
  1190. }
  1191. /* get the message queue of the current thread */
  1192. DECL_HANDLER(get_msg_queue)
  1193. {
  1194. struct msg_queue *queue = get_current_queue();
  1195. reply->handle = 0;
  1196. if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
  1197. }
  1198. /* set the current message queue wakeup mask */
  1199. DECL_HANDLER(set_queue_mask)
  1200. {
  1201. struct msg_queue *queue = get_current_queue();
  1202. if (queue)
  1203. {
  1204. queue->wake_mask = req->wake_mask;
  1205. queue->changed_mask = req->changed_mask;
  1206. reply->wake_bits = queue->wake_bits;
  1207. reply->changed_bits = queue->changed_bits;
  1208. if (is_signaled( queue ))
  1209. {
  1210. /* if skip wait is set, do what would have been done in the subsequent wait */
  1211. if (req->skip_wait) msg_queue_satisfied( &queue->obj, current );
  1212. else wake_up( &queue->obj, 0 );
  1213. }
  1214. }
  1215. }
  1216. /* get the current message queue status */
  1217. DECL_HANDLER(get_queue_status)
  1218. {
  1219. struct msg_queue *queue = current->queue;
  1220. if (queue)
  1221. {
  1222. reply->wake_bits = queue->wake_bits;
  1223. reply->changed_bits = queue->changed_bits;
  1224. if (req->clear) queue->changed_bits = 0;
  1225. }
  1226. else reply->wake_bits = reply->changed_bits = 0;
  1227. }
  1228. /* send a message to a thread queue */
  1229. DECL_HANDLER(send_message)
  1230. {
  1231. struct message *msg;
  1232. struct msg_queue *send_queue = get_current_queue();
  1233. struct msg_queue *recv_queue = NULL;
  1234. struct thread *thread = NULL;
  1235. if (req->id)
  1236. {
  1237. if (!(thread = get_thread_from_id( req->id ))) return;
  1238. }
  1239. else if (req->type != MSG_HARDWARE)
  1240. {
  1241. /* only hardware messages are allowed without destination thread */
  1242. set_error( STATUS_INVALID_PARAMETER );
  1243. return;
  1244. }
  1245. if (thread && !(recv_queue = thread->queue))
  1246. {
  1247. set_error( STATUS_INVALID_PARAMETER );
  1248. release_object( thread );
  1249. return;
  1250. }
  1251. if (recv_queue && (req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
  1252. {
  1253. set_error( STATUS_TIMEOUT );
  1254. release_object( thread );
  1255. return;
  1256. }
  1257. if ((msg = mem_alloc( sizeof(*msg) )))
  1258. {
  1259. msg->type = req->type;
  1260. msg->win = get_user_full_handle( req->win );
  1261. msg->msg = req->msg;
  1262. msg->wparam = req->wparam;
  1263. msg->lparam = req->lparam;
  1264. msg->time = req->time;
  1265. msg->x = req->x;
  1266. msg->y = req->y;
  1267. msg->info = req->info;
  1268. msg->result = NULL;
  1269. msg->data = NULL;
  1270. msg->data_size = 0;
  1271. switch(msg->type)
  1272. {
  1273. case MSG_OTHER_PROCESS:
  1274. msg->data_size = get_req_data_size();
  1275. if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
  1276. {
  1277. free( msg );
  1278. break;
  1279. }
  1280. /* fall through */
  1281. case MSG_ASCII:
  1282. case MSG_UNICODE:
  1283. case MSG_CALLBACK:
  1284. if (!(msg->result = alloc_message_result( send_queue, recv_queue, msg,
  1285. req->timeout, req->callback, req->info )))
  1286. {
  1287. free_message( msg );
  1288. break;
  1289. }
  1290. /* fall through */
  1291. case MSG_NOTIFY:
  1292. append_message( &recv_queue->msg_list[SEND_MESSAGE], msg );
  1293. set_queue_bits( recv_queue, QS_SENDMESSAGE );
  1294. break;
  1295. case MSG_POSTED:
  1296. /* needed for posted DDE messages */
  1297. msg->data_size = get_req_data_size();
  1298. if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
  1299. {
  1300. free( msg );
  1301. break;
  1302. }
  1303. append_message( &recv_queue->msg_list[POST_MESSAGE], msg );
  1304. set_queue_bits( recv_queue, QS_POSTMESSAGE );
  1305. break;
  1306. case MSG_HARDWARE:
  1307. queue_hardware_message( recv_queue, msg );
  1308. break;
  1309. case MSG_CALLBACK_RESULT: /* cannot send this one */
  1310. default:
  1311. set_error( STATUS_INVALID_PARAMETER );
  1312. free( msg );
  1313. break;
  1314. }
  1315. }
  1316. if (thread) release_object( thread );
  1317. }
  1318. /* get a message from the current queue */
  1319. DECL_HANDLER(get_message)
  1320. {
  1321. struct timer *timer;
  1322. struct message *msg;
  1323. struct message *first_hw_msg = NULL;
  1324. struct msg_queue *queue = get_current_queue();
  1325. user_handle_t get_win = get_user_full_handle( req->get_win );
  1326. if (!queue) return;
  1327. gettimeofday( &queue->last_get_msg, NULL );
  1328. /* first of all release the hardware input lock if we own it */
  1329. /* we'll grab it again if we find a hardware message */
  1330. if (queue->input->msg_thread == current)
  1331. {
  1332. first_hw_msg = queue->input->msg;
  1333. release_hardware_message( current, 0 );
  1334. }
  1335. /* first check for sent messages */
  1336. if ((msg = queue->msg_list[SEND_MESSAGE].first))
  1337. {
  1338. receive_message( queue, msg, reply );
  1339. return;
  1340. }
  1341. if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */
  1342. /* clear changed bits so we can wait on them if we don't find a message */
  1343. queue->changed_bits = 0;
  1344. /* then check for posted messages */
  1345. if (get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
  1346. return;
  1347. /* then check for any raw hardware message */
  1348. if (get_hardware_message( current, first_hw_msg, get_win, reply ))
  1349. return;
  1350. /* now check for WM_PAINT */
  1351. if (queue->paint_count &&
  1352. (WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last) &&
  1353. (reply->win = find_window_to_repaint( get_win, current )))
  1354. {
  1355. reply->type = MSG_POSTED;
  1356. reply->msg = WM_PAINT;
  1357. reply->wparam = 0;
  1358. reply->lparam = 0;
  1359. reply->x = 0;
  1360. reply->y = 0;
  1361. reply->time = get_tick_count();
  1362. reply->info = 0;
  1363. return;
  1364. }
  1365. /* now check for timer */
  1366. if ((timer = find_expired_timer( queue, get_win, req->get_first,
  1367. req->get_last, (req->flags & GET_MSG_REMOVE) )))
  1368. {
  1369. reply->type = MSG_POSTED;
  1370. reply->win = timer->win;
  1371. reply->msg = timer->msg;
  1372. reply->wparam = timer->id;
  1373. reply->lparam = timer->lparam;
  1374. reply->x = 0;
  1375. reply->y = 0;
  1376. reply->time = get_tick_count();
  1377. reply->info = 0;
  1378. return;
  1379. }
  1380. done:
  1381. set_error( STATUS_PENDING ); /* FIXME */
  1382. }
  1383. /* reply to a sent message */
  1384. DECL_HANDLER(reply_message)
  1385. {
  1386. if (!current->queue)
  1387. {
  1388. set_error( STATUS_ACCESS_DENIED );
  1389. return;
  1390. }
  1391. if (req->type == MSG_HARDWARE)
  1392. {
  1393. struct thread_input *input = current->queue->input;
  1394. if (input->msg_thread == current) release_hardware_message( current, req->remove );
  1395. else set_error( STATUS_ACCESS_DENIED );
  1396. }
  1397. else if (current->queue->recv_result)
  1398. reply_message( current->queue, req->result, 0, req->remove,
  1399. get_req_data(), get_req_data_size() );
  1400. }
  1401. /* retrieve the reply for the last message sent */
  1402. DECL_HANDLER(get_message_reply)
  1403. {
  1404. struct message_result *result;
  1405. struct list *entry;
  1406. struct msg_queue *queue = current->queue;
  1407. if (queue)
  1408. {
  1409. set_error( STATUS_PENDING );
  1410. reply->result = 0;
  1411. if (!(entry = list_head( &queue->send_result ))) return; /* no reply ready */
  1412. result = LIST_ENTRY( entry, struct message_result, sender_entry );
  1413. if (result->replied || req->cancel)
  1414. {
  1415. if (result->replied)
  1416. {
  1417. reply->result = result->result;
  1418. set_error( result->error );
  1419. if (result->data)
  1420. {
  1421. size_t data_len = min( result->data_size, get_reply_max_size() );
  1422. set_reply_data_ptr( result->data, data_len );
  1423. result->data = NULL;
  1424. result->data_size = 0;
  1425. }
  1426. }
  1427. remove_result_from_sender( result );
  1428. entry = list_head( &queue->send_result );
  1429. if (!entry) clear_queue_bits( queue, QS_SMRESULT );
  1430. else
  1431. {
  1432. result = LIST_ENTRY( entry, struct message_result, sender_entry );
  1433. if (!result->replied) clear_queue_bits( queue, QS_SMRESULT );
  1434. }
  1435. }
  1436. }
  1437. else set_error( STATUS_ACCESS_DENIED );
  1438. }
  1439. /* set a window timer */
  1440. DECL_HANDLER(set_win_timer)
  1441. {
  1442. struct timer *timer;
  1443. struct msg_queue *queue;
  1444. struct thread *thread = NULL;
  1445. user_handle_t win = 0;
  1446. unsigned int id = req->id;
  1447. if (req->win)
  1448. {
  1449. if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
  1450. {
  1451. set_error( STATUS_INVALID_HANDLE );
  1452. return;
  1453. }
  1454. if (thread->process != current->process)
  1455. {
  1456. release_object( thread );
  1457. set_error( STATUS_ACCESS_DENIED );
  1458. return;
  1459. }
  1460. queue = thread->queue;
  1461. /* remove it if it existed already */
  1462. if ((timer = find_timer( queue, win, req->msg, id ))) free_timer( queue, timer );
  1463. }
  1464. else
  1465. {
  1466. queue = get_current_queue();
  1467. /* find a free id for it */
  1468. do
  1469. {
  1470. id = queue->next_timer_id;
  1471. if (++queue->next_timer_id >= 0x10000) queue->next_timer_id = 1;
  1472. }
  1473. while (find_timer( queue, 0, req->msg, id ));
  1474. }
  1475. if ((timer = set_timer( queue, req->rate )))
  1476. {
  1477. timer->win = win;
  1478. timer->msg = req->msg;
  1479. timer->id = id;
  1480. timer->lparam = req->lparam;
  1481. reply->id = id;
  1482. }
  1483. if (thread) release_object( thread );
  1484. }
  1485. /* kill a window timer */
  1486. DECL_HANDLER(kill_win_timer)
  1487. {
  1488. struct timer *timer;
  1489. struct thread *thread;
  1490. user_handle_t win = 0;
  1491. if (req->win)
  1492. {
  1493. if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
  1494. {
  1495. set_error( STATUS_INVALID_HANDLE );
  1496. return;
  1497. }
  1498. if (thread->process != current->process)
  1499. {
  1500. release_object( thread );
  1501. set_error( STATUS_ACCESS_DENIED );
  1502. return;
  1503. }
  1504. }
  1505. else thread = (struct thread *)grab_object( current );
  1506. if (thread->queue && (timer = find_timer( thread->queue, win, req->msg, req->id )))
  1507. free_timer( thread->queue, timer );
  1508. else
  1509. set_error( STATUS_INVALID_PARAMETER );
  1510. release_object( thread );
  1511. }
  1512. /* attach (or detach) thread inputs */
  1513. DECL_HANDLER(attach_thread_input)
  1514. {
  1515. struct thread *thread_from = get_thread_from_id( req->tid_from );
  1516. struct thread *thread_to = get_thread_from_id( req->tid_to );
  1517. if (!thread_from || !thread_to)
  1518. {
  1519. if (thread_from) release_object( thread_from );
  1520. if (thread_to) release_object( thread_to );
  1521. return;
  1522. }
  1523. if (thread_from != thread_to)
  1524. {
  1525. if (req->attach) attach_thread_input( thread_from, thread_to );
  1526. else detach_thread_input( thread_from, thread_to );
  1527. }
  1528. else set_error( STATUS_ACCESS_DENIED );
  1529. release_object( thread_from );
  1530. release_object( thread_to );
  1531. }
  1532. /* get thread input data */
  1533. DECL_HANDLER(get_thread_input)
  1534. {
  1535. struct thread *thread = NULL;
  1536. struct thread_input *input;
  1537. if (req->tid)
  1538. {
  1539. if (!(thread = get_thread_from_id( req->tid ))) return;
  1540. input = thread->queue ? thread->queue->input : NULL;
  1541. }
  1542. else input = foreground_input; /* get the foreground thread info */
  1543. if (input)
  1544. {
  1545. reply->focus = input->focus;
  1546. reply->capture = input->capture;
  1547. reply->active = input->active;
  1548. reply->menu_owner = input->menu_owner;
  1549. reply->move_size = input->move_size;
  1550. reply->caret = input->caret;
  1551. reply->rect = input->caret_rect;
  1552. }
  1553. else
  1554. {
  1555. reply->focus = 0;
  1556. reply->capture = 0;
  1557. reply->active = 0;
  1558. reply->menu_owner = 0;
  1559. reply->move_size = 0;
  1560. reply->caret = 0;
  1561. reply->rect.left = reply->rect.top = reply->rect.right = reply->rect.bottom = 0;
  1562. }
  1563. /* foreground window is active window of foreground thread */
  1564. reply->foreground = foreground_input ? foreground_input->active : 0;
  1565. if (thread) release_object( thread );
  1566. }
  1567. /* retrieve queue keyboard state for a given thread */
  1568. DECL_HANDLER(get_key_state)
  1569. {
  1570. struct thread *thread;
  1571. struct thread_input *input;
  1572. if (!(thread = get_thread_from_id( req->tid ))) return;
  1573. input = thread->queue ? thread->queue->input : NULL;
  1574. if (input)
  1575. {
  1576. if (req->key >= 0) reply->state = input->keystate[req->key & 0xff];
  1577. set_reply_data( input->keystate, min( get_reply_max_size(), sizeof(input->keystate) ));
  1578. }
  1579. release_object( thread );
  1580. }
  1581. /* set queue keyboard state for a given thread */
  1582. DECL_HANDLER(set_key_state)
  1583. {
  1584. struct thread *thread = NULL;
  1585. struct thread_input *input;
  1586. if (!(thread = get_thread_from_id( req->tid ))) return;
  1587. input = thread->queue ? thread->queue->input : NULL;
  1588. if (input)
  1589. {
  1590. size_t size = min( sizeof(input->keystate), get_req_data_size() );
  1591. if (size) memcpy( input->keystate, get_req_data(), size );
  1592. }
  1593. release_object( thread );
  1594. }
  1595. /* set the system foreground window */
  1596. DECL_HANDLER(set_foreground_window)
  1597. {
  1598. struct msg_queue *queue = get_current_queue();
  1599. reply->previous = foreground_input ? foreground_input->active : 0;
  1600. reply->send_msg_old = (reply->previous && foreground_input != queue->input);
  1601. reply->send_msg_new = FALSE;
  1602. if (req->handle)
  1603. {
  1604. struct thread *thread;
  1605. if (is_top_level_window( req->handle ) &&
  1606. ((thread = get_window_thread( req->handle ))))
  1607. {
  1608. foreground_input = thread->queue->input;
  1609. reply->send_msg_new = (foreground_input != queue->input);
  1610. release_object( thread );
  1611. }
  1612. else set_error( STATUS_INVALID_HANDLE );
  1613. }
  1614. else foreground_input = NULL;
  1615. }
  1616. /* set the current thread focus window */
  1617. DECL_HANDLER(set_focus_window)
  1618. {
  1619. struct msg_queue *queue = get_current_queue();
  1620. reply->previous = 0;
  1621. if (queue && check_queue_input_window( queue, req->handle ))
  1622. {
  1623. reply->previous = queue->input->focus;
  1624. queue->input->focus = get_user_full_handle( req->handle );
  1625. }
  1626. }
  1627. /* set the current thread active window */
  1628. DECL_HANDLER(set_active_window)
  1629. {
  1630. struct msg_queue *queue = get_current_queue();
  1631. reply->previous = 0;
  1632. if (queue && check_queue_input_window( queue, req->handle ))
  1633. {
  1634. if (!req->handle || make_window_active( req->handle ))
  1635. {
  1636. reply->previous = queue->input->active;
  1637. queue->input->active = get_user_full_handle( req->handle );
  1638. }
  1639. else set_error( STATUS_INVALID_HANDLE );
  1640. }
  1641. }
  1642. /* set the current thread capture window */
  1643. DECL_HANDLER(set_capture_window)
  1644. {
  1645. struct msg_queue *queue = get_current_queue();
  1646. reply->previous = reply->full_handle = 0;
  1647. if (queue && check_queue_input_window( queue, req->handle ))
  1648. {
  1649. struct thread_input *input = queue->input;
  1650. reply->previous = input->capture;
  1651. input->capture = get_user_full_handle( req->handle );
  1652. input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
  1653. input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
  1654. reply->full_handle = input->capture;
  1655. }
  1656. }
  1657. /* Set the current thread caret window */
  1658. DECL_HANDLER(set_caret_window)
  1659. {
  1660. struct msg_queue *queue = get_current_queue();
  1661. reply->previous = 0;
  1662. if (queue && check_queue_input_window( queue, req->handle ))
  1663. {
  1664. struct thread_input *input = queue->input;
  1665. reply->previous = input->caret;
  1666. reply->old_rect = input->caret_rect;
  1667. reply->old_hide = input->caret_hide;
  1668. reply->old_state = input->caret_state;
  1669. set_caret_window( input, get_user_full_handle(req->handle) );
  1670. input->caret_rect.right = req->width;
  1671. input->caret_rect.bottom = req->height;
  1672. }
  1673. }
  1674. /* Set the current thread caret information */
  1675. DECL_HANDLER(set_caret_info)
  1676. {
  1677. struct msg_queue *queue = get_current_queue();
  1678. struct thread_input *input;
  1679. if (!queue) return;
  1680. input = queue->input;
  1681. reply->full_handle = input->caret;
  1682. reply->old_rect = input->caret_rect;
  1683. reply->old_hide = input->caret_hide;
  1684. reply->old_state = input->caret_state;
  1685. if (req->handle && get_user_full_handle(req->handle) != input->caret)
  1686. {
  1687. set_error( STATUS_ACCESS_DENIED );
  1688. return;
  1689. }
  1690. if (req->flags & SET_CARET_POS)
  1691. {
  1692. input->caret_rect.right += req->x - input->caret_rect.left;
  1693. input->caret_rect.bottom += req->y - input->caret_rect.top;
  1694. input->caret_rect.left = req->x;
  1695. input->caret_rect.top = req->y;
  1696. }
  1697. if (req->flags & SET_CARET_HIDE)
  1698. {
  1699. input->caret_hide += req->hide;
  1700. if (input->caret_hide < 0) input->caret_hide = 0;
  1701. }
  1702. if (req->flags & SET_CARET_STATE)
  1703. {
  1704. if (req->state == -1) input->caret_state = !input->caret_state;
  1705. else input->caret_state = !!req->state;
  1706. }
  1707. }