- Add new server type "struct security_descriptor".
[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             if (owner->queue->input == input)
1111             {
1112                 msg->win = new_win;
1113                 set_queue_bits( owner->queue, get_hardware_msg_bit( msg ));
1114                 remove = 0;
1115             }
1116             release_object( owner );
1117         }
1118     }
1119     if (remove)
1120     {
1121         update_input_key_state( input, msg );
1122         list_remove( &msg->entry );
1123         free_message( msg );
1124     }
1125 }
1126
1127 /* find the window that should receive a given hardware message */
1128 static user_handle_t find_hardware_message_window( struct thread_input *input, struct message *msg,
1129                                                    unsigned int *msg_code )
1130 {
1131     user_handle_t win = 0;
1132
1133     *msg_code = msg->msg;
1134     if (is_keyboard_msg( msg ))
1135     {
1136         if (input && !(win = input->focus))
1137         {
1138             win = input->active;
1139             if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
1140         }
1141     }
1142     else  /* mouse message */
1143     {
1144         if (!input || !(win = input->capture))
1145         {
1146             if (!(win = msg->win) || !is_window_visible( win ))
1147                 win = window_from_point( msg->x, msg->y );
1148         }
1149     }
1150     return win;
1151 }
1152
1153 /* queue a hardware message into a given thread input */
1154 static void queue_hardware_message( struct msg_queue *queue, struct message *msg )
1155 {
1156     user_handle_t win;
1157     struct thread *thread;
1158     struct thread_input *input;
1159     unsigned int msg_code;
1160
1161     last_input_time = get_tick_count();
1162
1163     win = find_hardware_message_window( queue ? queue->input : foreground_input, msg, &msg_code );
1164     if (!win || !(thread = get_window_thread(win)))
1165     {
1166         free( msg );
1167         return;
1168     }
1169     input = thread->queue->input;
1170
1171     if (msg->msg == WM_MOUSEMOVE && merge_message( input, msg )) free( msg );
1172     else
1173     {
1174         msg->unique_id = 0;  /* will be set once we return it to the app */
1175         list_add_tail( &input->msg_list, &msg->entry );
1176         set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
1177     }
1178     release_object( thread );
1179 }
1180
1181 /* check message filter for a hardware message */
1182 static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
1183                                     user_handle_t filter_win, unsigned int first, unsigned int last )
1184 {
1185     if (msg_code >= WM_KEYFIRST && msg_code <= WM_KEYLAST)
1186     {
1187         /* we can only test the window for a keyboard message since the
1188          * dest window for a mouse message depends on hittest */
1189         if (filter_win && win != filter_win && !is_child_window( filter_win, win ))
1190             return 0;
1191         /* the message code is final for a keyboard message, we can simply check it */
1192         return check_msg_filter( msg_code, first, last );
1193     }
1194     else  /* mouse message */
1195     {
1196         /* we need to check all possible values that the message can have in the end */
1197
1198         if (check_msg_filter( msg_code, first, last )) return 1;
1199         if (msg_code == WM_MOUSEWHEEL) return 0;  /* no other possible value for this one */
1200
1201         /* all other messages can become non-client messages */
1202         if (check_msg_filter( msg_code + (WM_NCMOUSEFIRST - WM_MOUSEFIRST), first, last )) return 1;
1203
1204         /* clicks can become double-clicks or non-client double-clicks */
1205         if (msg_code == WM_LBUTTONDOWN || msg_code == WM_MBUTTONDOWN ||
1206             msg_code == WM_RBUTTONDOWN || msg_code == WM_XBUTTONDOWN)
1207         {
1208             if (check_msg_filter( msg_code + (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN), first, last )) return 1;
1209             if (check_msg_filter( msg_code + (WM_NCLBUTTONDBLCLK - WM_LBUTTONDOWN), first, last )) return 1;
1210         }
1211         return 0;
1212     }
1213 }
1214
1215
1216 /* find a hardware message for the given queue */
1217 static int get_hardware_message( struct thread *thread, int hw_id, user_handle_t filter_win,
1218                                  unsigned int first, unsigned int last, struct get_message_reply *reply )
1219 {
1220     struct thread_input *input = thread->queue->input;
1221     struct thread *win_thread;
1222     struct list *ptr;
1223     user_handle_t win;
1224     int clear_bits, got_one = 0;
1225     unsigned int msg_code;
1226
1227     ptr = list_head( &input->msg_list );
1228     if (hw_id)
1229     {
1230         while (ptr)
1231         {
1232             struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1233             if (msg->unique_id == hw_id) break;
1234             ptr = list_next( &input->msg_list, ptr );
1235         }
1236         if (!ptr) ptr = list_head( &input->msg_list );
1237         else ptr = list_next( &input->msg_list, ptr );  /* start from the next one */
1238     }
1239
1240     if (ptr == list_head( &input->msg_list ))
1241         clear_bits = QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON;
1242     else
1243         clear_bits = 0;  /* don't clear bits if we don't go through the whole list */
1244
1245     while (ptr)
1246     {
1247         struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1248         ptr = list_next( &input->msg_list, ptr );
1249         win = find_hardware_message_window( input, msg, &msg_code );
1250         if (!win || !(win_thread = get_window_thread( win )))
1251         {
1252             /* no window at all, remove it */
1253             update_input_key_state( input, msg );
1254             list_remove( &msg->entry );
1255             free_message( msg );
1256             continue;
1257         }
1258         if (win_thread != thread)
1259         {
1260             if (win_thread->queue->input == input)
1261             {
1262                 /* wake the other thread */
1263                 set_queue_bits( win_thread->queue, get_hardware_msg_bit(msg) );
1264                 got_one = 1;
1265             }
1266             else
1267             {
1268                 /* for another thread input, drop it */
1269                 update_input_key_state( input, msg );
1270                 list_remove( &msg->entry );
1271                 free_message( msg );
1272             }
1273             release_object( win_thread );
1274             continue;
1275         }
1276         release_object( win_thread );
1277
1278         /* if we already got a message for another thread, or if it doesn't
1279          * match the filter we skip it */
1280         if (got_one || !check_hw_message_filter( win, msg_code, filter_win, first, last ))
1281         {
1282             clear_bits &= ~get_hardware_msg_bit( msg );
1283             continue;
1284         }
1285         /* now we can return it */
1286         if (!msg->unique_id) msg->unique_id = get_unique_id();
1287         reply->type   = MSG_HARDWARE;
1288         reply->win    = win;
1289         reply->msg    = msg_code;
1290         reply->wparam = msg->wparam;
1291         reply->lparam = msg->lparam;
1292         reply->x      = msg->x;
1293         reply->y      = msg->y;
1294         reply->time   = msg->time;
1295         reply->info   = msg->info;
1296         reply->hw_id  = msg->unique_id;
1297         return 1;
1298     }
1299     /* nothing found, clear the hardware queue bits */
1300     clear_queue_bits( thread->queue, clear_bits );
1301     return 0;
1302 }
1303
1304 /* increment (or decrement if 'incr' is negative) the queue paint count */
1305 void inc_queue_paint_count( struct thread *thread, int incr )
1306 {
1307     struct msg_queue *queue = thread->queue;
1308
1309     assert( queue );
1310
1311     if ((queue->paint_count += incr) < 0) queue->paint_count = 0;
1312
1313     if (queue->paint_count)
1314         set_queue_bits( queue, QS_PAINT );
1315     else
1316         clear_queue_bits( queue, QS_PAINT );
1317 }
1318
1319
1320 /* remove all messages and timers belonging to a certain window */
1321 void queue_cleanup_window( struct thread *thread, user_handle_t win )
1322 {
1323     struct msg_queue *queue = thread->queue;
1324     struct list *ptr;
1325     int i;
1326
1327     if (!queue) return;
1328
1329     /* remove timers */
1330
1331     ptr = list_head( &queue->pending_timers );
1332     while (ptr)
1333     {
1334         struct list *next = list_next( &queue->pending_timers, ptr );
1335         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1336         if (timer->win == win) free_timer( queue, timer );
1337         ptr = next;
1338     }
1339     ptr = list_head( &queue->expired_timers );
1340     while (ptr)
1341     {
1342         struct list *next = list_next( &queue->expired_timers, ptr );
1343         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1344         if (timer->win == win) free_timer( queue, timer );
1345         ptr = next;
1346     }
1347
1348     /* remove messages */
1349     for (i = 0; i < NB_MSG_KINDS; i++)
1350     {
1351         struct list *ptr, *next;
1352
1353         LIST_FOR_EACH_SAFE( ptr, next, &queue->msg_list[i] )
1354         {
1355             struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1356             if (msg->win == win) remove_queue_message( queue, msg, i );
1357         }
1358     }
1359
1360     thread_input_cleanup_window( queue, win );
1361 }
1362
1363 /* post a message to a window; used by socket handling */
1364 void post_message( user_handle_t win, unsigned int message,
1365                    unsigned int wparam, unsigned int lparam )
1366 {
1367     struct message *msg;
1368     struct thread *thread = get_window_thread( win );
1369
1370     if (!thread) return;
1371
1372     if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
1373     {
1374         msg->type      = MSG_POSTED;
1375         msg->win       = get_user_full_handle( win );
1376         msg->msg       = message;
1377         msg->wparam    = wparam;
1378         msg->lparam    = lparam;
1379         msg->time      = get_tick_count();
1380         msg->x         = 0;
1381         msg->y         = 0;
1382         msg->info      = 0;
1383         msg->hook      = 0;
1384         msg->hook_proc = NULL;
1385         msg->result    = NULL;
1386         msg->data      = NULL;
1387         msg->data_size = 0;
1388
1389         list_add_tail( &thread->queue->msg_list[POST_MESSAGE], &msg->entry );
1390         set_queue_bits( thread->queue, QS_POSTMESSAGE );
1391     }
1392     release_object( thread );
1393 }
1394
1395 /* post a win event */
1396 void post_win_event( struct thread *thread, unsigned int event,
1397                      user_handle_t win, unsigned int object_id,
1398                      unsigned int child_id, void *hook_proc,
1399                      const WCHAR *module, size_t module_size,
1400                      user_handle_t hook)
1401 {
1402     struct message *msg;
1403
1404     if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
1405     {
1406         msg->type      = MSG_WINEVENT;
1407         msg->win       = get_user_full_handle( win );
1408         msg->msg       = event;
1409         msg->wparam    = object_id;
1410         msg->lparam    = child_id;
1411         msg->time      = get_tick_count();
1412         msg->x         = 0;
1413         msg->y         = 0;
1414         msg->info      = get_thread_id( current );
1415         msg->result    = NULL;
1416         msg->hook      = hook;
1417         msg->hook_proc = hook_proc;
1418
1419         if ((msg->data = malloc( module_size )))
1420         {
1421             msg->data_size = module_size;
1422             memcpy( msg->data, module, module_size );
1423
1424             if (debug_level > 1)
1425                 fprintf( stderr, "post_win_event: tid %04x event %04x win %p object_id %d child_id %d\n",
1426                          get_thread_id(thread), event, win, object_id, child_id );
1427             list_add_tail( &thread->queue->msg_list[SEND_MESSAGE], &msg->entry );
1428             set_queue_bits( thread->queue, QS_SENDMESSAGE );
1429         }
1430         else
1431             free( msg );
1432     }
1433 }
1434
1435 /* get the message queue of the current thread */
1436 DECL_HANDLER(get_msg_queue)
1437 {
1438     struct msg_queue *queue = get_current_queue();
1439
1440     reply->handle = 0;
1441     if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
1442 }
1443
1444
1445 /* set the current message queue wakeup mask */
1446 DECL_HANDLER(set_queue_mask)
1447 {
1448     struct msg_queue *queue = get_current_queue();
1449
1450     if (queue)
1451     {
1452         queue->wake_mask    = req->wake_mask;
1453         queue->changed_mask = req->changed_mask;
1454         reply->wake_bits    = queue->wake_bits;
1455         reply->changed_bits = queue->changed_bits;
1456         if (is_signaled( queue ))
1457         {
1458             /* if skip wait is set, do what would have been done in the subsequent wait */
1459             if (req->skip_wait) msg_queue_satisfied( &queue->obj, current );
1460             else wake_up( &queue->obj, 0 );
1461         }
1462     }
1463 }
1464
1465
1466 /* get the current message queue status */
1467 DECL_HANDLER(get_queue_status)
1468 {
1469     struct msg_queue *queue = current->queue;
1470     if (queue)
1471     {
1472         reply->wake_bits    = queue->wake_bits;
1473         reply->changed_bits = queue->changed_bits;
1474         if (req->clear) queue->changed_bits = 0;
1475     }
1476     else reply->wake_bits = reply->changed_bits = 0;
1477 }
1478
1479
1480 /* send a message to a thread queue */
1481 DECL_HANDLER(send_message)
1482 {
1483     struct message *msg;
1484     struct msg_queue *send_queue = get_current_queue();
1485     struct msg_queue *recv_queue = NULL;
1486     struct thread *thread = NULL;
1487
1488     if (req->id)
1489     {
1490         if (!(thread = get_thread_from_id( req->id ))) return;
1491     }
1492     else if (req->type != MSG_HARDWARE)
1493     {
1494         /* only hardware messages are allowed without destination thread */
1495         set_error( STATUS_INVALID_PARAMETER );
1496         return;
1497     }
1498
1499     if (thread && !(recv_queue = thread->queue))
1500     {
1501         set_error( STATUS_INVALID_PARAMETER );
1502         release_object( thread );
1503         return;
1504     }
1505     if (recv_queue && (req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
1506     {
1507         set_error( STATUS_TIMEOUT );
1508         release_object( thread );
1509         return;
1510     }
1511
1512     if ((msg = mem_alloc( sizeof(*msg) )))
1513     {
1514         msg->type      = req->type;
1515         msg->win       = get_user_full_handle( req->win );
1516         msg->msg       = req->msg;
1517         msg->wparam    = req->wparam;
1518         msg->lparam    = req->lparam;
1519         msg->time      = req->time;
1520         msg->x         = req->x;
1521         msg->y         = req->y;
1522         msg->info      = req->info;
1523         msg->hook      = 0;
1524         msg->hook_proc = NULL;
1525         msg->result    = NULL;
1526         msg->data      = NULL;
1527         msg->data_size = 0;
1528
1529         switch(msg->type)
1530         {
1531         case MSG_OTHER_PROCESS:
1532             msg->data_size = get_req_data_size();
1533             if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
1534             {
1535                 free( msg );
1536                 break;
1537             }
1538             /* fall through */
1539         case MSG_ASCII:
1540         case MSG_UNICODE:
1541         case MSG_CALLBACK:
1542             if (!(msg->result = alloc_message_result( send_queue, recv_queue, msg,
1543                                                       req->timeout, req->callback, req->info )))
1544             {
1545                 free_message( msg );
1546                 break;
1547             }
1548             /* fall through */
1549         case MSG_NOTIFY:
1550             list_add_tail( &recv_queue->msg_list[SEND_MESSAGE], &msg->entry );
1551             set_queue_bits( recv_queue, QS_SENDMESSAGE );
1552             break;
1553         case MSG_POSTED:
1554             /* needed for posted DDE messages */
1555             msg->data_size = get_req_data_size();
1556             if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
1557             {
1558                 free( msg );
1559                 break;
1560             }
1561             list_add_tail( &recv_queue->msg_list[POST_MESSAGE], &msg->entry );
1562             set_queue_bits( recv_queue, QS_POSTMESSAGE );
1563             break;
1564         case MSG_HARDWARE:
1565             queue_hardware_message( recv_queue, msg );
1566             break;
1567         case MSG_CALLBACK_RESULT:  /* cannot send this one */
1568         default:
1569             set_error( STATUS_INVALID_PARAMETER );
1570             free( msg );
1571             break;
1572         }
1573     }
1574     if (thread) release_object( thread );
1575 }
1576
1577
1578 /* get a message from the current queue */
1579 DECL_HANDLER(get_message)
1580 {
1581     struct timer *timer;
1582     struct list *ptr;
1583     struct msg_queue *queue = get_current_queue();
1584     user_handle_t get_win = get_user_full_handle( req->get_win );
1585
1586     reply->active_hooks = get_active_hooks();
1587
1588     if (!queue) return;
1589     gettimeofday( &queue->last_get_msg, NULL );
1590
1591     /* first check for sent messages */
1592     if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))
1593     {
1594         struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1595         receive_message( queue, msg, reply );
1596         return;
1597     }
1598     if (req->flags & GET_MSG_SENT_ONLY) goto done;  /* nothing else to check */
1599
1600     /* clear changed bits so we can wait on them if we don't find a message */
1601     queue->changed_bits = 0;
1602
1603     /* then check for posted messages */
1604     if (get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
1605         return;
1606
1607     /* then check for any raw hardware message */
1608     if (filter_contains_hw_range( req->get_first, req->get_last ) &&
1609         get_hardware_message( current, req->hw_id, get_win, req->get_first, req->get_last, reply ))
1610         return;
1611
1612     /* now check for WM_PAINT */
1613     if (queue->paint_count &&
1614         check_msg_filter( WM_PAINT, req->get_first, req->get_last ) &&
1615         (reply->win = find_window_to_repaint( get_win, current )))
1616     {
1617         reply->type   = MSG_POSTED;
1618         reply->msg    = WM_PAINT;
1619         reply->wparam = 0;
1620         reply->lparam = 0;
1621         reply->x      = 0;
1622         reply->y      = 0;
1623         reply->time   = get_tick_count();
1624         reply->info   = 0;
1625         return;
1626     }
1627
1628     /* now check for timer */
1629     if ((timer = find_expired_timer( queue, get_win, req->get_first,
1630                                      req->get_last, (req->flags & GET_MSG_REMOVE) )))
1631     {
1632         reply->type   = MSG_POSTED;
1633         reply->win    = timer->win;
1634         reply->msg    = timer->msg;
1635         reply->wparam = timer->id;
1636         reply->lparam = timer->lparam;
1637         reply->x      = 0;
1638         reply->y      = 0;
1639         reply->time   = get_tick_count();
1640         reply->info   = 0;
1641         return;
1642     }
1643
1644  done:
1645     set_error( STATUS_PENDING );  /* FIXME */
1646 }
1647
1648
1649 /* reply to a sent message */
1650 DECL_HANDLER(reply_message)
1651 {
1652     if (!current->queue) set_error( STATUS_ACCESS_DENIED );
1653     else if (current->queue->recv_result)
1654         reply_message( current->queue, req->result, 0, req->remove,
1655                        get_req_data(), get_req_data_size() );
1656 }
1657
1658
1659 /* accept the current hardware message */
1660 DECL_HANDLER(accept_hardware_message)
1661 {
1662     if (current->queue)
1663         release_hardware_message( current->queue, req->hw_id, req->remove, req->new_win );
1664     else
1665         set_error( STATUS_ACCESS_DENIED );
1666 }
1667
1668
1669 /* retrieve the reply for the last message sent */
1670 DECL_HANDLER(get_message_reply)
1671 {
1672     struct message_result *result;
1673     struct list *entry;
1674     struct msg_queue *queue = current->queue;
1675
1676     if (queue)
1677     {
1678         set_error( STATUS_PENDING );
1679         reply->result = 0;
1680
1681         if (!(entry = list_head( &queue->send_result ))) return;  /* no reply ready */
1682
1683         result = LIST_ENTRY( entry, struct message_result, sender_entry );
1684         if (result->replied || req->cancel)
1685         {
1686             if (result->replied)
1687             {
1688                 reply->result = result->result;
1689                 set_error( result->error );
1690                 if (result->data)
1691                 {
1692                     size_t data_len = min( result->data_size, get_reply_max_size() );
1693                     set_reply_data_ptr( result->data, data_len );
1694                     result->data = NULL;
1695                     result->data_size = 0;
1696                 }
1697             }
1698             remove_result_from_sender( result );
1699
1700             entry = list_head( &queue->send_result );
1701             if (!entry) clear_queue_bits( queue, QS_SMRESULT );
1702             else
1703             {
1704                 result = LIST_ENTRY( entry, struct message_result, sender_entry );
1705                 if (!result->replied) clear_queue_bits( queue, QS_SMRESULT );
1706             }
1707         }
1708     }
1709     else set_error( STATUS_ACCESS_DENIED );
1710 }
1711
1712
1713 /* set a window timer */
1714 DECL_HANDLER(set_win_timer)
1715 {
1716     struct timer *timer;
1717     struct msg_queue *queue;
1718     struct thread *thread = NULL;
1719     user_handle_t win = 0;
1720     unsigned int id = req->id;
1721
1722     if (req->win)
1723     {
1724         if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
1725         {
1726             set_error( STATUS_INVALID_HANDLE );
1727             return;
1728         }
1729         if (thread->process != current->process)
1730         {
1731             release_object( thread );
1732             set_error( STATUS_ACCESS_DENIED );
1733             return;
1734         }
1735         queue = thread->queue;
1736         /* remove it if it existed already */
1737         if ((timer = find_timer( queue, win, req->msg, id ))) free_timer( queue, timer );
1738     }
1739     else
1740     {
1741         queue = get_current_queue();
1742         /* find a free id for it */
1743         do
1744         {
1745             id = queue->next_timer_id;
1746             if (++queue->next_timer_id >= 0x10000) queue->next_timer_id = 1;
1747         }
1748         while (find_timer( queue, 0, req->msg, id ));
1749     }
1750
1751     if ((timer = set_timer( queue, req->rate )))
1752     {
1753         timer->win    = win;
1754         timer->msg    = req->msg;
1755         timer->id     = id;
1756         timer->lparam = req->lparam;
1757         reply->id     = id;
1758     }
1759     if (thread) release_object( thread );
1760 }
1761
1762 /* kill a window timer */
1763 DECL_HANDLER(kill_win_timer)
1764 {
1765     struct timer *timer;
1766     struct thread *thread;
1767     user_handle_t win = 0;
1768
1769     if (req->win)
1770     {
1771         if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
1772         {
1773             set_error( STATUS_INVALID_HANDLE );
1774             return;
1775         }
1776         if (thread->process != current->process)
1777         {
1778             release_object( thread );
1779             set_error( STATUS_ACCESS_DENIED );
1780             return;
1781         }
1782     }
1783     else thread = (struct thread *)grab_object( current );
1784
1785     if (thread->queue && (timer = find_timer( thread->queue, win, req->msg, req->id )))
1786         free_timer( thread->queue, timer );
1787     else
1788         set_error( STATUS_INVALID_PARAMETER );
1789
1790     release_object( thread );
1791 }
1792
1793
1794 /* attach (or detach) thread inputs */
1795 DECL_HANDLER(attach_thread_input)
1796 {
1797     struct thread *thread_from = get_thread_from_id( req->tid_from );
1798     struct thread *thread_to = get_thread_from_id( req->tid_to );
1799
1800     if (!thread_from || !thread_to)
1801     {
1802         if (thread_from) release_object( thread_from );
1803         if (thread_to) release_object( thread_to );
1804         return;
1805     }
1806     if (thread_from != thread_to)
1807     {
1808         if (req->attach) attach_thread_input( thread_from, thread_to );
1809         else detach_thread_input( thread_from, thread_to );
1810     }
1811     else set_error( STATUS_ACCESS_DENIED );
1812     release_object( thread_from );
1813     release_object( thread_to );
1814 }
1815
1816
1817 /* get thread input data */
1818 DECL_HANDLER(get_thread_input)
1819 {
1820     struct thread *thread = NULL;
1821     struct thread_input *input;
1822
1823     if (req->tid)
1824     {
1825         if (!(thread = get_thread_from_id( req->tid ))) return;
1826         input = thread->queue ? thread->queue->input : NULL;
1827     }
1828     else input = foreground_input;  /* get the foreground thread info */
1829
1830     if (input)
1831     {
1832         reply->focus      = input->focus;
1833         reply->capture    = input->capture;
1834         reply->active     = input->active;
1835         reply->menu_owner = input->menu_owner;
1836         reply->move_size  = input->move_size;
1837         reply->caret      = input->caret;
1838         reply->rect       = input->caret_rect;
1839     }
1840     else
1841     {
1842         reply->focus      = 0;
1843         reply->capture    = 0;
1844         reply->active     = 0;
1845         reply->menu_owner = 0;
1846         reply->move_size  = 0;
1847         reply->caret      = 0;
1848         reply->rect.left = reply->rect.top = reply->rect.right = reply->rect.bottom = 0;
1849     }
1850     /* foreground window is active window of foreground thread */
1851     reply->foreground = foreground_input ? foreground_input->active : 0;
1852     if (thread) release_object( thread );
1853 }
1854
1855
1856 /* retrieve queue keyboard state for a given thread */
1857 DECL_HANDLER(get_key_state)
1858 {
1859     struct thread *thread;
1860     struct thread_input *input;
1861
1862     if (!(thread = get_thread_from_id( req->tid ))) return;
1863     input = thread->queue ? thread->queue->input : NULL;
1864     if (input)
1865     {
1866         if (req->key >= 0) reply->state = input->keystate[req->key & 0xff];
1867         set_reply_data( input->keystate, min( get_reply_max_size(), sizeof(input->keystate) ));
1868     }
1869     release_object( thread );
1870 }
1871
1872
1873 /* set queue keyboard state for a given thread */
1874 DECL_HANDLER(set_key_state)
1875 {
1876     struct thread *thread = NULL;
1877     struct thread_input *input;
1878
1879     if (!(thread = get_thread_from_id( req->tid ))) return;
1880     input = thread->queue ? thread->queue->input : NULL;
1881     if (input)
1882     {
1883         size_t size = min( sizeof(input->keystate), get_req_data_size() );
1884         if (size) memcpy( input->keystate, get_req_data(), size );
1885     }
1886     release_object( thread );
1887 }
1888
1889
1890 /* set the system foreground window */
1891 DECL_HANDLER(set_foreground_window)
1892 {
1893     struct msg_queue *queue = get_current_queue();
1894
1895     reply->previous = foreground_input ? foreground_input->active : 0;
1896     reply->send_msg_old = (reply->previous && foreground_input != queue->input);
1897     reply->send_msg_new = FALSE;
1898
1899     if (req->handle)
1900     {
1901         struct thread *thread;
1902
1903         if (is_top_level_window( req->handle ) &&
1904             ((thread = get_window_thread( req->handle ))))
1905         {
1906             foreground_input = thread->queue->input;
1907             reply->send_msg_new = (foreground_input != queue->input);
1908             release_object( thread );
1909         }
1910         else set_error( STATUS_INVALID_HANDLE );
1911     }
1912     else foreground_input = NULL;
1913 }
1914
1915
1916 /* set the current thread focus window */
1917 DECL_HANDLER(set_focus_window)
1918 {
1919     struct msg_queue *queue = get_current_queue();
1920
1921     reply->previous = 0;
1922     if (queue && check_queue_input_window( queue, req->handle ))
1923     {
1924         reply->previous = queue->input->focus;
1925         queue->input->focus = get_user_full_handle( req->handle );
1926     }
1927 }
1928
1929
1930 /* set the current thread active window */
1931 DECL_HANDLER(set_active_window)
1932 {
1933     struct msg_queue *queue = get_current_queue();
1934
1935     reply->previous = 0;
1936     if (queue && check_queue_input_window( queue, req->handle ))
1937     {
1938         if (!req->handle || make_window_active( req->handle ))
1939         {
1940             reply->previous = queue->input->active;
1941             queue->input->active = get_user_full_handle( req->handle );
1942         }
1943         else set_error( STATUS_INVALID_HANDLE );
1944     }
1945 }
1946
1947
1948 /* set the current thread capture window */
1949 DECL_HANDLER(set_capture_window)
1950 {
1951     struct msg_queue *queue = get_current_queue();
1952
1953     reply->previous = reply->full_handle = 0;
1954     if (queue && check_queue_input_window( queue, req->handle ))
1955     {
1956         struct thread_input *input = queue->input;
1957
1958         reply->previous = input->capture;
1959         input->capture = get_user_full_handle( req->handle );
1960         input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
1961         input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
1962         reply->full_handle = input->capture;
1963     }
1964 }
1965
1966
1967 /* Set the current thread caret window */
1968 DECL_HANDLER(set_caret_window)
1969 {
1970     struct msg_queue *queue = get_current_queue();
1971
1972     reply->previous = 0;
1973     if (queue && check_queue_input_window( queue, req->handle ))
1974     {
1975         struct thread_input *input = queue->input;
1976
1977         reply->previous  = input->caret;
1978         reply->old_rect  = input->caret_rect;
1979         reply->old_hide  = input->caret_hide;
1980         reply->old_state = input->caret_state;
1981
1982         set_caret_window( input, get_user_full_handle(req->handle) );
1983         input->caret_rect.right  = input->caret_rect.left + req->width;
1984         input->caret_rect.bottom = input->caret_rect.top + req->height;
1985     }
1986 }
1987
1988
1989 /* Set the current thread caret information */
1990 DECL_HANDLER(set_caret_info)
1991 {
1992     struct msg_queue *queue = get_current_queue();
1993     struct thread_input *input;
1994
1995     if (!queue) return;
1996     input = queue->input;
1997     reply->full_handle = input->caret;
1998     reply->old_rect    = input->caret_rect;
1999     reply->old_hide    = input->caret_hide;
2000     reply->old_state   = input->caret_state;
2001
2002     if (req->handle && get_user_full_handle(req->handle) != input->caret)
2003     {
2004         set_error( STATUS_ACCESS_DENIED );
2005         return;
2006     }
2007     if (req->flags & SET_CARET_POS)
2008     {
2009         input->caret_rect.right  += req->x - input->caret_rect.left;
2010         input->caret_rect.bottom += req->y - input->caret_rect.top;
2011         input->caret_rect.left = req->x;
2012         input->caret_rect.top  = req->y;
2013     }
2014     if (req->flags & SET_CARET_HIDE)
2015     {
2016         input->caret_hide += req->hide;
2017         if (input->caret_hide < 0) input->caret_hide = 0;
2018     }
2019     if (req->flags & SET_CARET_STATE)
2020     {
2021         if (req->state == -1) input->caret_state = !input->caret_state;
2022         else input->caret_state = !!req->state;
2023     }
2024 }
2025
2026
2027 /* get the time of the last input event */
2028 DECL_HANDLER(get_last_input_time)
2029 {
2030     reply->time = last_input_time;
2031 }