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