shell32: Arrays are never NULL (Coverity).
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "ntstatus.h"
30 #define WIN32_NO_STATUS
31 #include "windef.h"
32 #include "winbase.h"
33 #include "wingdi.h"
34 #include "winuser.h"
35 #include "winternl.h"
36
37 #include "handle.h"
38 #include "file.h"
39 #include "thread.h"
40 #include "process.h"
41 #include "request.h"
42 #include "user.h"
43
44 #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
45 #define WM_NCMOUSELAST  (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
46
47 enum message_kind { SEND_MESSAGE, POST_MESSAGE };
48 #define NB_MSG_KINDS (POST_MESSAGE+1)
49
50
51 struct message_result
52 {
53     struct list            sender_entry;  /* entry in sender list */
54     struct message        *msg;           /* message the result is for */
55     struct message_result *recv_next;     /* next in receiver list */
56     struct msg_queue      *sender;        /* sender queue */
57     struct msg_queue      *receiver;      /* receiver queue */
58     int                    replied;       /* has it been replied to? */
59     unsigned int           error;         /* error code to pass back to sender */
60     lparam_t               result;        /* reply result */
61     struct message        *hardware_msg;  /* hardware message if low-level hook result */
62     struct desktop        *desktop;       /* desktop for hardware message */
63     struct message        *callback_msg;  /* message to queue for callback */
64     void                  *data;          /* message reply data */
65     unsigned int           data_size;     /* size of message reply data */
66     struct timeout_user   *timeout;       /* result timeout */
67 };
68
69 struct message
70 {
71     struct list            entry;     /* entry in message list */
72     enum message_type      type;      /* message type */
73     user_handle_t          win;       /* window handle */
74     unsigned int           msg;       /* message code */
75     lparam_t               wparam;    /* parameters */
76     lparam_t               lparam;    /* parameters */
77     unsigned int           time;      /* message time */
78     void                  *data;      /* message data for sent messages */
79     unsigned int           data_size; /* size of message data */
80     unsigned int           unique_id; /* unique id for nested hw message waits */
81     struct message_result *result;    /* result in sender queue */
82 };
83
84 struct timer
85 {
86     struct list     entry;     /* entry in timer list */
87     timeout_t       when;      /* next expiration */
88     unsigned int    rate;      /* timer rate in ms */
89     user_handle_t   win;       /* window handle */
90     unsigned int    msg;       /* message to post */
91     lparam_t        id;        /* timer id */
92     lparam_t        lparam;    /* lparam for message */
93 };
94
95 struct thread_input
96 {
97     struct object          obj;           /* object header */
98     struct desktop        *desktop;       /* desktop that this thread input belongs to */
99     user_handle_t          focus;         /* focus window */
100     user_handle_t          capture;       /* capture window */
101     user_handle_t          active;        /* active window */
102     user_handle_t          menu_owner;    /* current menu owner window */
103     user_handle_t          move_size;     /* current moving/resizing window */
104     user_handle_t          caret;         /* caret window */
105     rectangle_t            caret_rect;    /* caret rectangle */
106     int                    caret_hide;    /* caret hide count */
107     int                    caret_state;   /* caret on/off state */
108     user_handle_t          cursor;        /* current cursor */
109     int                    cursor_count;  /* cursor show count */
110     struct list            msg_list;      /* list of hardware messages */
111     unsigned char          keystate[256]; /* state of each key */
112 };
113
114 struct msg_queue
115 {
116     struct object          obj;             /* object header */
117     struct fd             *fd;              /* optional file descriptor to poll */
118     unsigned int           wake_bits;       /* wakeup bits */
119     unsigned int           wake_mask;       /* wakeup mask */
120     unsigned int           changed_bits;    /* changed wakeup bits */
121     unsigned int           changed_mask;    /* changed wakeup mask */
122     int                    paint_count;     /* pending paint messages count */
123     int                    quit_message;    /* is there a pending quit message? */
124     int                    exit_code;       /* exit code of pending quit message */
125     int                    cursor_count;    /* per-queue cursor show count */
126     struct list            msg_list[NB_MSG_KINDS];  /* lists of messages */
127     struct list            send_result;     /* stack of sent messages waiting for result */
128     struct list            callback_result; /* list of callback messages waiting for result */
129     struct message_result *recv_result;     /* stack of received messages waiting for result */
130     struct list            pending_timers;  /* list of pending timers */
131     struct list            expired_timers;  /* list of expired timers */
132     lparam_t               next_timer_id;   /* id for the next timer with a 0 window */
133     struct timeout_user   *timeout;         /* timeout for next timer to expire */
134     struct thread_input   *input;           /* thread input descriptor */
135     struct hook_table     *hooks;           /* hook table */
136     timeout_t              last_get_msg;    /* time of last get message call */
137 };
138
139 static void msg_queue_dump( struct object *obj, int verbose );
140 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
141 static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
142 static int msg_queue_signaled( struct object *obj, struct thread *thread );
143 static int msg_queue_satisfied( struct object *obj, struct thread *thread );
144 static void msg_queue_destroy( struct object *obj );
145 static void msg_queue_poll_event( struct fd *fd, int event );
146 static void thread_input_dump( struct object *obj, int verbose );
147 static void thread_input_destroy( struct object *obj );
148 static void timer_callback( void *private );
149
150 static const struct object_ops msg_queue_ops =
151 {
152     sizeof(struct msg_queue),  /* size */
153     msg_queue_dump,            /* dump */
154     no_get_type,               /* get_type */
155     msg_queue_add_queue,       /* add_queue */
156     msg_queue_remove_queue,    /* remove_queue */
157     msg_queue_signaled,        /* signaled */
158     msg_queue_satisfied,       /* satisfied */
159     no_signal,                 /* signal */
160     no_get_fd,                 /* get_fd */
161     no_map_access,             /* map_access */
162     default_get_sd,            /* get_sd */
163     default_set_sd,            /* set_sd */
164     no_lookup_name,            /* lookup_name */
165     no_open_file,              /* open_file */
166     no_close_handle,           /* close_handle */
167     msg_queue_destroy          /* destroy */
168 };
169
170 static const struct fd_ops msg_queue_fd_ops =
171 {
172     NULL,                        /* get_poll_events */
173     msg_queue_poll_event,        /* poll_event */
174     NULL,                        /* flush */
175     NULL,                        /* get_fd_type */
176     NULL,                        /* ioctl */
177     NULL,                        /* queue_async */
178     NULL,                        /* reselect_async */
179     NULL                         /* cancel async */
180 };
181
182
183 static const struct object_ops thread_input_ops =
184 {
185     sizeof(struct thread_input),  /* size */
186     thread_input_dump,            /* dump */
187     no_get_type,                  /* get_type */
188     no_add_queue,                 /* add_queue */
189     NULL,                         /* remove_queue */
190     NULL,                         /* signaled */
191     NULL,                         /* satisfied */
192     no_signal,                    /* signal */
193     no_get_fd,                    /* get_fd */
194     no_map_access,                /* map_access */
195     default_get_sd,               /* get_sd */
196     default_set_sd,               /* set_sd */
197     no_lookup_name,               /* lookup_name */
198     no_open_file,                 /* open_file */
199     no_close_handle,              /* close_handle */
200     thread_input_destroy          /* destroy */
201 };
202
203 /* pointer to input structure of foreground thread */
204 static unsigned int last_input_time;
205
206 static void queue_hardware_message( struct desktop *desktop, struct message *msg );
207 static void free_message( struct message *msg );
208
209 /* set the caret window in a given thread input */
210 static void set_caret_window( struct thread_input *input, user_handle_t win )
211 {
212     if (!win || win != input->caret)
213     {
214         input->caret_rect.left   = 0;
215         input->caret_rect.top    = 0;
216         input->caret_rect.right  = 0;
217         input->caret_rect.bottom = 0;
218     }
219     input->caret             = win;
220     input->caret_hide        = 1;
221     input->caret_state       = 0;
222 }
223
224 /* create a thread input object */
225 static struct thread_input *create_thread_input( struct thread *thread )
226 {
227     struct thread_input *input;
228
229     if ((input = alloc_object( &thread_input_ops )))
230     {
231         input->focus        = 0;
232         input->capture      = 0;
233         input->active       = 0;
234         input->menu_owner   = 0;
235         input->move_size    = 0;
236         input->cursor       = 0;
237         input->cursor_count = 0;
238         list_init( &input->msg_list );
239         set_caret_window( input, 0 );
240         memset( input->keystate, 0, sizeof(input->keystate) );
241
242         if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ )))
243         {
244             release_object( input );
245             return NULL;
246         }
247     }
248     return input;
249 }
250
251 /* create a message queue object */
252 static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input )
253 {
254     struct thread_input *new_input = NULL;
255     struct msg_queue *queue;
256     int i;
257
258     if (!input)
259     {
260         if (!(new_input = create_thread_input( thread ))) return NULL;
261         input = new_input;
262     }
263
264     if ((queue = alloc_object( &msg_queue_ops )))
265     {
266         queue->fd              = NULL;
267         queue->wake_bits       = 0;
268         queue->wake_mask       = 0;
269         queue->changed_bits    = 0;
270         queue->changed_mask    = 0;
271         queue->paint_count     = 0;
272         queue->quit_message    = 0;
273         queue->cursor_count    = 0;
274         queue->recv_result     = NULL;
275         queue->next_timer_id   = 0x7fff;
276         queue->timeout         = NULL;
277         queue->input           = (struct thread_input *)grab_object( input );
278         queue->hooks           = NULL;
279         queue->last_get_msg    = current_time;
280         list_init( &queue->send_result );
281         list_init( &queue->callback_result );
282         list_init( &queue->pending_timers );
283         list_init( &queue->expired_timers );
284         for (i = 0; i < NB_MSG_KINDS; i++) list_init( &queue->msg_list[i] );
285
286         thread->queue = queue;
287     }
288     if (new_input) release_object( new_input );
289     return queue;
290 }
291
292 /* free the message queue of a thread at thread exit */
293 void free_msg_queue( struct thread *thread )
294 {
295     remove_thread_hooks( thread );
296     if (!thread->queue) return;
297     release_object( thread->queue );
298     thread->queue = NULL;
299 }
300
301 /* change the thread input data of a given thread */
302 static int assign_thread_input( struct thread *thread, struct thread_input *new_input )
303 {
304     struct msg_queue *queue = thread->queue;
305
306     if (!queue)
307     {
308         thread->queue = create_msg_queue( thread, new_input );
309         return thread->queue != NULL;
310     }
311     if (queue->input)
312     {
313         queue->input->cursor_count -= queue->cursor_count;
314         release_object( queue->input );
315     }
316     queue->input = (struct thread_input *)grab_object( new_input );
317     new_input->cursor_count += queue->cursor_count;
318     return 1;
319 }
320
321 /* get the hook table for a given thread */
322 struct hook_table *get_queue_hooks( struct thread *thread )
323 {
324     if (!thread->queue) return NULL;
325     return thread->queue->hooks;
326 }
327
328 /* set the hook table for a given thread, allocating the queue if needed */
329 void set_queue_hooks( struct thread *thread, struct hook_table *hooks )
330 {
331     struct msg_queue *queue = thread->queue;
332     if (!queue && !(queue = create_msg_queue( thread, NULL ))) return;
333     if (queue->hooks) release_object( queue->hooks );
334     queue->hooks = hooks;
335 }
336
337 /* check the queue status */
338 static inline int is_signaled( struct msg_queue *queue )
339 {
340     return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask));
341 }
342
343 /* set some queue bits */
344 static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits )
345 {
346     queue->wake_bits |= bits;
347     queue->changed_bits |= bits;
348     if (is_signaled( queue )) wake_up( &queue->obj, 0 );
349 }
350
351 /* clear some queue bits */
352 static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits )
353 {
354     queue->wake_bits &= ~bits;
355     queue->changed_bits &= ~bits;
356 }
357
358 /* check whether msg is a keyboard message */
359 static inline int is_keyboard_msg( struct message *msg )
360 {
361     return (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST);
362 }
363
364 /* check if message is matched by the filter */
365 static inline int check_msg_filter( unsigned int msg, unsigned int first, unsigned int last )
366 {
367     return (msg >= first && msg <= last);
368 }
369
370 /* check whether a message filter contains at least one potential hardware message */
371 static inline int filter_contains_hw_range( unsigned int first, unsigned int last )
372 {
373     /* hardware message ranges are (in numerical order):
374      *   WM_NCMOUSEFIRST .. WM_NCMOUSELAST
375      *   WM_KEYFIRST .. WM_KEYLAST
376      *   WM_MOUSEFIRST .. WM_MOUSELAST
377      */
378     if (last < WM_NCMOUSEFIRST) return 0;
379     if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
380     if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
381     if (first > WM_MOUSELAST) return 0;
382     return 1;
383 }
384
385 /* get the QS_* bit corresponding to a given hardware message */
386 static inline int get_hardware_msg_bit( struct message *msg )
387 {
388     if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
389     if (is_keyboard_msg( msg )) return QS_KEY;
390     return QS_MOUSEBUTTON;
391 }
392
393 /* get the current thread queue, creating it if needed */
394 static inline struct msg_queue *get_current_queue(void)
395 {
396     struct msg_queue *queue = current->queue;
397     if (!queue) queue = create_msg_queue( current, NULL );
398     return queue;
399 }
400
401 /* get a (pseudo-)unique id to tag hardware messages */
402 static inline unsigned int get_unique_id(void)
403 {
404     static unsigned int id;
405     if (!++id) id = 1;  /* avoid an id of 0 */
406     return id;
407 }
408
409 /* try to merge a message with the last in the list; return 1 if successful */
410 static int merge_message( struct thread_input *input, const struct message *msg )
411 {
412     struct message *prev;
413     struct list *ptr = list_tail( &input->msg_list );
414
415     if (!ptr) return 0;
416     prev = LIST_ENTRY( ptr, struct message, entry );
417     if (prev->result) return 0;
418     if (prev->win && msg->win && prev->win != msg->win) return 0;
419     if (prev->msg != msg->msg) return 0;
420     if (prev->type != msg->type) return 0;
421     /* now we can merge it */
422     prev->wparam  = msg->wparam;
423     prev->lparam  = msg->lparam;
424     prev->time    = msg->time;
425     if (msg->type == MSG_HARDWARE && prev->data && msg->data)
426     {
427         struct hardware_msg_data *prev_data = prev->data;
428         struct hardware_msg_data *msg_data = msg->data;
429         prev_data->x     = msg_data->x;
430         prev_data->y     = msg_data->y;
431         prev_data->info  = msg_data->info;
432     }
433     return 1;
434 }
435
436 /* free a result structure */
437 static void free_result( struct message_result *result )
438 {
439     if (result->timeout) remove_timeout_user( result->timeout );
440     free( result->data );
441     if (result->callback_msg) free_message( result->callback_msg );
442     if (result->hardware_msg) free_message( result->hardware_msg );
443     if (result->desktop) release_object( result->desktop );
444     free( result );
445 }
446
447 /* remove the result from the sender list it is on */
448 static inline void remove_result_from_sender( struct message_result *result )
449 {
450     assert( result->sender );
451
452     list_remove( &result->sender_entry );
453     result->sender = NULL;
454     if (!result->receiver) free_result( result );
455 }
456
457 /* store the message result in the appropriate structure */
458 static void store_message_result( struct message_result *res, lparam_t result, unsigned int error )
459 {
460     res->result  = result;
461     res->error   = error;
462     res->replied = 1;
463     if (res->timeout)
464     {
465         remove_timeout_user( res->timeout );
466         res->timeout = NULL;
467     }
468
469     if (res->hardware_msg)
470     {
471         if (!error && result)  /* rejected by the hook */
472             free_message( res->hardware_msg );
473         else
474             queue_hardware_message( res->desktop, res->hardware_msg );
475
476         res->hardware_msg = NULL;
477     }
478
479     if (res->sender)
480     {
481         if (res->callback_msg)
482         {
483             /* queue the callback message in the sender queue */
484             struct callback_msg_data *data = res->callback_msg->data;
485             data->result = result;
486             list_add_tail( &res->sender->msg_list[SEND_MESSAGE], &res->callback_msg->entry );
487             set_queue_bits( res->sender, QS_SENDMESSAGE );
488             res->callback_msg = NULL;
489             remove_result_from_sender( res );
490         }
491         else
492         {
493             /* wake sender queue if waiting on this result */
494             if (list_head(&res->sender->send_result) == &res->sender_entry)
495                 set_queue_bits( res->sender, QS_SMRESULT );
496         }
497     }
498     else if (!res->receiver) free_result( res );
499 }
500
501 /* free a message when deleting a queue or window */
502 static void free_message( struct message *msg )
503 {
504     struct message_result *result = msg->result;
505     if (result)
506     {
507         result->msg = NULL;
508         result->receiver = NULL;
509         store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
510     }
511     free( msg->data );
512     free( msg );
513 }
514
515 /* remove (and free) a message from a message list */
516 static void remove_queue_message( struct msg_queue *queue, struct message *msg,
517                                   enum message_kind kind )
518 {
519     list_remove( &msg->entry );
520     switch(kind)
521     {
522     case SEND_MESSAGE:
523         if (list_empty( &queue->msg_list[kind] )) clear_queue_bits( queue, QS_SENDMESSAGE );
524         break;
525     case POST_MESSAGE:
526         if (list_empty( &queue->msg_list[kind] ) && !queue->quit_message)
527             clear_queue_bits( queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
528         break;
529     }
530     free_message( msg );
531 }
532
533 /* message timed out without getting a reply */
534 static void result_timeout( void *private )
535 {
536     struct message_result *result = private;
537
538     assert( !result->replied );
539
540     result->timeout = NULL;
541
542     if (result->msg)  /* not received yet */
543     {
544         struct message *msg = result->msg;
545
546         result->msg = NULL;
547         msg->result = NULL;
548         remove_queue_message( result->receiver, msg, SEND_MESSAGE );
549         result->receiver = NULL;
550     }
551     store_message_result( result, 0, STATUS_TIMEOUT );
552 }
553
554 /* allocate and fill a message result structure */
555 static struct message_result *alloc_message_result( struct msg_queue *send_queue,
556                                                     struct msg_queue *recv_queue,
557                                                     struct message *msg, timeout_t timeout )
558 {
559     struct message_result *result = mem_alloc( sizeof(*result) );
560     if (result)
561     {
562         result->msg          = msg;
563         result->sender       = send_queue;
564         result->receiver     = recv_queue;
565         result->replied      = 0;
566         result->data         = NULL;
567         result->data_size    = 0;
568         result->timeout      = NULL;
569         result->hardware_msg = NULL;
570         result->desktop      = NULL;
571         result->callback_msg = NULL;
572
573         if (msg->type == MSG_CALLBACK)
574         {
575             struct message *callback_msg = mem_alloc( sizeof(*callback_msg) );
576
577             if (!callback_msg)
578             {
579                 free( result );
580                 return NULL;
581             }
582             callback_msg->type      = MSG_CALLBACK_RESULT;
583             callback_msg->win       = msg->win;
584             callback_msg->msg       = msg->msg;
585             callback_msg->wparam    = 0;
586             callback_msg->lparam    = 0;
587             callback_msg->time      = get_tick_count();
588             callback_msg->result    = NULL;
589             /* steal the data from the original message */
590             callback_msg->data      = msg->data;
591             callback_msg->data_size = msg->data_size;
592             msg->data = NULL;
593             msg->data_size = 0;
594
595             result->callback_msg = callback_msg;
596             list_add_head( &send_queue->callback_result, &result->sender_entry );
597         }
598         else if (send_queue) list_add_head( &send_queue->send_result, &result->sender_entry );
599
600         if (timeout != TIMEOUT_INFINITE)
601             result->timeout = add_timeout_user( timeout, result_timeout, result );
602     }
603     return result;
604 }
605
606 /* receive a message, removing it from the sent queue */
607 static void receive_message( struct msg_queue *queue, struct message *msg,
608                              struct get_message_reply *reply )
609 {
610     struct message_result *result = msg->result;
611
612     reply->total = msg->data_size;
613     if (msg->data_size > get_reply_max_size())
614     {
615         set_error( STATUS_BUFFER_OVERFLOW );
616         return;
617     }
618     reply->type   = msg->type;
619     reply->win    = msg->win;
620     reply->msg    = msg->msg;
621     reply->wparam = msg->wparam;
622     reply->lparam = msg->lparam;
623     reply->time   = msg->time;
624
625     if (msg->data) set_reply_data_ptr( msg->data, msg->data_size );
626
627     list_remove( &msg->entry );
628     /* put the result on the receiver result stack */
629     if (result)
630     {
631         result->msg = NULL;
632         result->recv_next  = queue->recv_result;
633         queue->recv_result = result;
634     }
635     free( msg );
636     if (list_empty( &queue->msg_list[SEND_MESSAGE] )) clear_queue_bits( queue, QS_SENDMESSAGE );
637 }
638
639 /* set the result of the current received message */
640 static void reply_message( struct msg_queue *queue, lparam_t result,
641                            unsigned int error, int remove, const void *data, data_size_t len )
642 {
643     struct message_result *res = queue->recv_result;
644
645     if (remove)
646     {
647         queue->recv_result = res->recv_next;
648         res->receiver = NULL;
649         if (!res->sender && !res->hardware_msg)  /* no one waiting for it */
650         {
651             free_result( res );
652             return;
653         }
654     }
655     if (!res->replied)
656     {
657         if (len && (res->data = memdup( data, len ))) res->data_size = len;
658         store_message_result( res, result, error );
659     }
660 }
661
662 static int match_window( user_handle_t win, user_handle_t msg_win )
663 {
664     if (!win) return 1;
665     if (win == -1 || win == 1) return !msg_win;
666     if (msg_win == win) return 1;
667     return is_child_window( win, msg_win );
668 }
669
670 /* retrieve a posted message */
671 static int get_posted_message( struct msg_queue *queue, user_handle_t win,
672                                unsigned int first, unsigned int last, unsigned int flags,
673                                struct get_message_reply *reply )
674 {
675     struct message *msg;
676
677     /* check against the filters */
678     LIST_FOR_EACH_ENTRY( msg, &queue->msg_list[POST_MESSAGE], struct message, entry )
679     {
680         if (!match_window( win, msg->win )) continue;
681         if (!check_msg_filter( msg->msg, first, last )) continue;
682         goto found; /* found one */
683     }
684     return 0;
685
686     /* return it to the app */
687 found:
688     reply->total = msg->data_size;
689     if (msg->data_size > get_reply_max_size())
690     {
691         set_error( STATUS_BUFFER_OVERFLOW );
692         return 1;
693     }
694     reply->type   = msg->type;
695     reply->win    = msg->win;
696     reply->msg    = msg->msg;
697     reply->wparam = msg->wparam;
698     reply->lparam = msg->lparam;
699     reply->time   = msg->time;
700
701     if (flags & PM_REMOVE)
702     {
703         if (msg->data)
704         {
705             set_reply_data_ptr( msg->data, msg->data_size );
706             msg->data = NULL;
707             msg->data_size = 0;
708         }
709         remove_queue_message( queue, msg, POST_MESSAGE );
710     }
711     else if (msg->data) set_reply_data( msg->data, msg->data_size );
712
713     return 1;
714 }
715
716 static int get_quit_message( struct msg_queue *queue, unsigned int flags,
717                              struct get_message_reply *reply )
718 {
719     if (queue->quit_message)
720     {
721         reply->total  = 0;
722         reply->type   = MSG_POSTED;
723         reply->win    = 0;
724         reply->msg    = WM_QUIT;
725         reply->wparam = queue->exit_code;
726         reply->lparam = 0;
727         reply->time   = get_tick_count();
728
729         if (flags & PM_REMOVE)
730         {
731             queue->quit_message = 0;
732             if (list_empty( &queue->msg_list[POST_MESSAGE] ))
733                 clear_queue_bits( queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
734         }
735         return 1;
736     }
737     else
738         return 0;
739 }
740
741 /* empty a message list and free all the messages */
742 static void empty_msg_list( struct list *list )
743 {
744     struct list *ptr;
745
746     while ((ptr = list_head( list )) != NULL)
747     {
748         struct message *msg = LIST_ENTRY( ptr, struct message, entry );
749         list_remove( &msg->entry );
750         free_message( msg );
751     }
752 }
753
754 /* cleanup all pending results when deleting a queue */
755 static void cleanup_results( struct msg_queue *queue )
756 {
757     struct list *entry;
758
759     while ((entry = list_head( &queue->send_result )) != NULL)
760     {
761         remove_result_from_sender( LIST_ENTRY( entry, struct message_result, sender_entry ) );
762     }
763
764     while ((entry = list_head( &queue->callback_result )) != NULL)
765     {
766         remove_result_from_sender( LIST_ENTRY( entry, struct message_result, sender_entry ) );
767     }
768
769     while (queue->recv_result)
770         reply_message( queue, 0, STATUS_ACCESS_DENIED /*FIXME*/, 1, NULL, 0 );
771 }
772
773 /* check if the thread owning the queue is hung (not checking for messages) */
774 static int is_queue_hung( struct msg_queue *queue )
775 {
776     struct wait_queue_entry *entry;
777
778     if (current_time - queue->last_get_msg <= 5 * TICKS_PER_SEC)
779         return 0;  /* less than 5 seconds since last get message -> not hung */
780
781     LIST_FOR_EACH_ENTRY( entry, &queue->obj.wait_queue, struct wait_queue_entry, entry )
782     {
783         if (entry->thread->queue == queue)
784             return 0;  /* thread is waiting on queue -> not hung */
785     }
786     return 1;
787 }
788
789 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
790 {
791     struct msg_queue *queue = (struct msg_queue *)obj;
792     struct process *process = entry->thread->process;
793
794     /* a thread can only wait on its own queue */
795     if (entry->thread->queue != queue)
796     {
797         set_error( STATUS_ACCESS_DENIED );
798         return 0;
799     }
800     if (process->idle_event && !(queue->wake_mask & QS_SMRESULT)) set_event( process->idle_event );
801
802     if (queue->fd && list_empty( &obj->wait_queue ))  /* first on the queue */
803         set_fd_events( queue->fd, POLLIN );
804     add_queue( obj, entry );
805     return 1;
806 }
807
808 static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
809 {
810     struct msg_queue *queue = (struct msg_queue *)obj;
811
812     remove_queue( obj, entry );
813     if (queue->fd && list_empty( &obj->wait_queue ))  /* last on the queue is gone */
814         set_fd_events( queue->fd, 0 );
815 }
816
817 static void msg_queue_dump( struct object *obj, int verbose )
818 {
819     struct msg_queue *queue = (struct msg_queue *)obj;
820     fprintf( stderr, "Msg queue bits=%x mask=%x\n",
821              queue->wake_bits, queue->wake_mask );
822 }
823
824 static int msg_queue_signaled( struct object *obj, struct thread *thread )
825 {
826     struct msg_queue *queue = (struct msg_queue *)obj;
827     int ret = 0;
828
829     if (queue->fd)
830     {
831         if ((ret = check_fd_events( queue->fd, POLLIN )))
832             /* stop waiting on select() if we are signaled */
833             set_fd_events( queue->fd, 0 );
834         else if (!list_empty( &obj->wait_queue ))
835             /* restart waiting on poll() if we are no longer signaled */
836             set_fd_events( queue->fd, POLLIN );
837     }
838     return ret || is_signaled( queue );
839 }
840
841 static int msg_queue_satisfied( struct object *obj, struct thread *thread )
842 {
843     struct msg_queue *queue = (struct msg_queue *)obj;
844     queue->wake_mask = 0;
845     queue->changed_mask = 0;
846     return 0;  /* Not abandoned */
847 }
848
849 static void msg_queue_destroy( struct object *obj )
850 {
851     struct msg_queue *queue = (struct msg_queue *)obj;
852     struct list *ptr;
853     int i;
854
855     cleanup_results( queue );
856     for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] );
857
858     while ((ptr = list_head( &queue->pending_timers )))
859     {
860         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
861         list_remove( &timer->entry );
862         free( timer );
863     }
864     while ((ptr = list_head( &queue->expired_timers )))
865     {
866         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
867         list_remove( &timer->entry );
868         free( timer );
869     }
870     if (queue->timeout) remove_timeout_user( queue->timeout );
871     if (queue->input)
872     {
873         queue->input->cursor_count -= queue->cursor_count;
874         release_object( queue->input );
875     }
876     if (queue->hooks) release_object( queue->hooks );
877     if (queue->fd) release_object( queue->fd );
878 }
879
880 static void msg_queue_poll_event( struct fd *fd, int event )
881 {
882     struct msg_queue *queue = get_fd_user( fd );
883     assert( queue->obj.ops == &msg_queue_ops );
884
885     if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 );
886     else set_fd_events( queue->fd, 0 );
887     wake_up( &queue->obj, 0 );
888 }
889
890 static void thread_input_dump( struct object *obj, int verbose )
891 {
892     struct thread_input *input = (struct thread_input *)obj;
893     fprintf( stderr, "Thread input focus=%08x capture=%08x active=%08x\n",
894              input->focus, input->capture, input->active );
895 }
896
897 static void thread_input_destroy( struct object *obj )
898 {
899     struct thread_input *input = (struct thread_input *)obj;
900
901     empty_msg_list( &input->msg_list );
902     if (input->desktop)
903     {
904         if (input->desktop->foreground_input == input) input->desktop->foreground_input = NULL;
905         release_object( input->desktop );
906     }
907 }
908
909 /* fix the thread input data when a window is destroyed */
910 static inline void thread_input_cleanup_window( struct msg_queue *queue, user_handle_t window )
911 {
912     struct thread_input *input = queue->input;
913
914     if (window == input->focus) input->focus = 0;
915     if (window == input->capture) input->capture = 0;
916     if (window == input->active) input->active = 0;
917     if (window == input->menu_owner) input->menu_owner = 0;
918     if (window == input->move_size) input->move_size = 0;
919     if (window == input->caret) set_caret_window( input, 0 );
920 }
921
922 /* check if the specified window can be set in the input data of a given queue */
923 static int check_queue_input_window( struct msg_queue *queue, user_handle_t window )
924 {
925     struct thread *thread;
926     int ret = 0;
927
928     if (!window) return 1;  /* we can always clear the data */
929
930     if ((thread = get_window_thread( window )))
931     {
932         ret = (queue->input == thread->queue->input);
933         if (!ret) set_error( STATUS_ACCESS_DENIED );
934         release_object( thread );
935     }
936     else set_error( STATUS_INVALID_HANDLE );
937
938     return ret;
939 }
940
941 /* make sure the specified thread has a queue */
942 int init_thread_queue( struct thread *thread )
943 {
944     if (thread->queue) return 1;
945     return (create_msg_queue( thread, NULL ) != NULL);
946 }
947
948 /* attach two thread input data structures */
949 int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
950 {
951     struct desktop *desktop;
952     struct thread_input *input;
953     int ret;
954
955     if (!thread_to->queue && !(thread_to->queue = create_msg_queue( thread_to, NULL ))) return 0;
956     if (!(desktop = get_thread_desktop( thread_from, 0 ))) return 0;
957     input = (struct thread_input *)grab_object( thread_to->queue->input );
958     if (input->desktop != desktop)
959     {
960         set_error( STATUS_ACCESS_DENIED );
961         release_object( input );
962         release_object( desktop );
963         return 0;
964     }
965     release_object( desktop );
966
967     ret = assign_thread_input( thread_from, input );
968     if (ret) memset( input->keystate, 0, sizeof(input->keystate) );
969     release_object( input );
970     return ret;
971 }
972
973 /* detach two thread input data structures */
974 void detach_thread_input( struct thread *thread_from )
975 {
976     struct thread_input *input;
977
978     if ((input = create_thread_input( thread_from )))
979     {
980         assign_thread_input( thread_from, input );
981         release_object( input );
982     }
983 }
984
985
986 /* set the next timer to expire */
987 static void set_next_timer( struct msg_queue *queue )
988 {
989     struct list *ptr;
990
991     if (queue->timeout)
992     {
993         remove_timeout_user( queue->timeout );
994         queue->timeout = NULL;
995     }
996     if ((ptr = list_head( &queue->pending_timers )))
997     {
998         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
999         queue->timeout = add_timeout_user( timer->when, timer_callback, queue );
1000     }
1001     /* set/clear QS_TIMER bit */
1002     if (list_empty( &queue->expired_timers ))
1003         clear_queue_bits( queue, QS_TIMER );
1004     else
1005         set_queue_bits( queue, QS_TIMER );
1006 }
1007
1008 /* find a timer from its window and id */
1009 static struct timer *find_timer( struct msg_queue *queue, user_handle_t win,
1010                                  unsigned int msg, lparam_t id )
1011 {
1012     struct list *ptr;
1013
1014     /* we need to search both lists */
1015
1016     LIST_FOR_EACH( ptr, &queue->pending_timers )
1017     {
1018         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1019         if (timer->win == win && timer->msg == msg && timer->id == id) return timer;
1020     }
1021     LIST_FOR_EACH( ptr, &queue->expired_timers )
1022     {
1023         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1024         if (timer->win == win && timer->msg == msg && timer->id == id) return timer;
1025     }
1026     return NULL;
1027 }
1028
1029 /* callback for the next timer expiration */
1030 static void timer_callback( void *private )
1031 {
1032     struct msg_queue *queue = private;
1033     struct list *ptr;
1034
1035     queue->timeout = NULL;
1036     /* move on to the next timer */
1037     ptr = list_head( &queue->pending_timers );
1038     list_remove( ptr );
1039     list_add_tail( &queue->expired_timers, ptr );
1040     set_next_timer( queue );
1041 }
1042
1043 /* link a timer at its rightful place in the queue list */
1044 static void link_timer( struct msg_queue *queue, struct timer *timer )
1045 {
1046     struct list *ptr;
1047
1048     for (ptr = queue->pending_timers.next; ptr != &queue->pending_timers; ptr = ptr->next)
1049     {
1050         struct timer *t = LIST_ENTRY( ptr, struct timer, entry );
1051         if (t->when >= timer->when) break;
1052     }
1053     list_add_before( ptr, &timer->entry );
1054 }
1055
1056 /* remove a timer from the queue timer list and free it */
1057 static void free_timer( struct msg_queue *queue, struct timer *timer )
1058 {
1059     list_remove( &timer->entry );
1060     free( timer );
1061     set_next_timer( queue );
1062 }
1063
1064 /* restart an expired timer */
1065 static void restart_timer( struct msg_queue *queue, struct timer *timer )
1066 {
1067     list_remove( &timer->entry );
1068     while (timer->when <= current_time) timer->when += (timeout_t)timer->rate * 10000;
1069     link_timer( queue, timer );
1070     set_next_timer( queue );
1071 }
1072
1073 /* find an expired timer matching the filtering parameters */
1074 static struct timer *find_expired_timer( struct msg_queue *queue, user_handle_t win,
1075                                          unsigned int get_first, unsigned int get_last,
1076                                          int remove )
1077 {
1078     struct list *ptr;
1079
1080     LIST_FOR_EACH( ptr, &queue->expired_timers )
1081     {
1082         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1083         if (win && timer->win != win) continue;
1084         if (check_msg_filter( timer->msg, get_first, get_last ))
1085         {
1086             if (remove) restart_timer( queue, timer );
1087             return timer;
1088         }
1089     }
1090     return NULL;
1091 }
1092
1093 /* add a timer */
1094 static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
1095 {
1096     struct timer *timer = mem_alloc( sizeof(*timer) );
1097     if (timer)
1098     {
1099         timer->rate = max( rate, 1 );
1100         timer->when = current_time + (timeout_t)timer->rate * 10000;
1101         link_timer( queue, timer );
1102         /* check if we replaced the next timer */
1103         if (list_head( &queue->pending_timers ) == &timer->entry) set_next_timer( queue );
1104     }
1105     return timer;
1106 }
1107
1108 /* change the input key state for a given key */
1109 static void set_input_key_state( unsigned char *keystate, unsigned char key, int down )
1110 {
1111     if (down)
1112     {
1113         if (!(keystate[key] & 0x80)) keystate[key] ^= 0x01;
1114         keystate[key] |= down;
1115     }
1116     else keystate[key] &= ~0x80;
1117 }
1118
1119 /* update the input key state for a keyboard message */
1120 static void update_input_key_state( struct desktop *desktop, unsigned char *keystate,
1121                                     const struct message *msg )
1122 {
1123     unsigned char key;
1124     int down = 0;
1125
1126     switch (msg->msg)
1127     {
1128     case WM_LBUTTONDOWN:
1129         down = (keystate == desktop->keystate) ? 0xc0 : 0x80;
1130         /* fall through */
1131     case WM_LBUTTONUP:
1132         set_input_key_state( keystate, VK_LBUTTON, down );
1133         break;
1134     case WM_MBUTTONDOWN:
1135         down = (keystate == desktop->keystate) ? 0xc0 : 0x80;
1136         /* fall through */
1137     case WM_MBUTTONUP:
1138         set_input_key_state( keystate, VK_MBUTTON, down );
1139         break;
1140     case WM_RBUTTONDOWN:
1141         down = (keystate == desktop->keystate) ? 0xc0 : 0x80;
1142         /* fall through */
1143     case WM_RBUTTONUP:
1144         set_input_key_state( keystate, VK_RBUTTON, down );
1145         break;
1146     case WM_XBUTTONDOWN:
1147         down = (keystate == desktop->keystate) ? 0xc0 : 0x80;
1148         /* fall through */
1149     case WM_XBUTTONUP:
1150         if (msg->wparam >> 16 == XBUTTON1) set_input_key_state( keystate, VK_XBUTTON1, down );
1151         else if (msg->wparam >> 16 == XBUTTON2) set_input_key_state( keystate, VK_XBUTTON2, down );
1152         break;
1153     case WM_KEYDOWN:
1154     case WM_SYSKEYDOWN:
1155         down = (keystate == desktop->keystate) ? 0xc0 : 0x80;
1156         /* fall through */
1157     case WM_KEYUP:
1158     case WM_SYSKEYUP:
1159         key = (unsigned char)msg->wparam;
1160         set_input_key_state( keystate, key, down );
1161         switch(key)
1162         {
1163         case VK_LCONTROL:
1164         case VK_RCONTROL:
1165             down = (keystate[VK_LCONTROL] | keystate[VK_RCONTROL]) & 0x80;
1166             set_input_key_state( keystate, VK_CONTROL, down );
1167             break;
1168         case VK_LMENU:
1169         case VK_RMENU:
1170             down = (keystate[VK_LMENU] | keystate[VK_RMENU]) & 0x80;
1171             set_input_key_state( keystate, VK_MENU, down );
1172             break;
1173         case VK_LSHIFT:
1174         case VK_RSHIFT:
1175             down = (keystate[VK_LSHIFT] | keystate[VK_RSHIFT]) & 0x80;
1176             set_input_key_state( keystate, VK_SHIFT, down );
1177             break;
1178         }
1179         break;
1180     }
1181 }
1182
1183 /* release the hardware message currently being processed by the given thread */
1184 static void release_hardware_message( struct msg_queue *queue, unsigned int hw_id,
1185                                       int remove, user_handle_t new_win )
1186 {
1187     struct thread_input *input = queue->input;
1188     struct message *msg;
1189
1190     LIST_FOR_EACH_ENTRY( msg, &input->msg_list, struct message, entry )
1191     {
1192         if (msg->unique_id == hw_id) break;
1193     }
1194     if (&msg->entry == &input->msg_list) return;  /* not found */
1195
1196     /* clear the queue bit for that message */
1197     if (remove || new_win)
1198     {
1199         struct message *other;
1200         int clr_bit;
1201
1202         clr_bit = get_hardware_msg_bit( msg );
1203         LIST_FOR_EACH_ENTRY( other, &input->msg_list, struct message, entry )
1204         {
1205             if (other != msg && get_hardware_msg_bit( other ) == clr_bit)
1206             {
1207                 clr_bit = 0;
1208                 break;
1209             }
1210         }
1211         if (clr_bit) clear_queue_bits( queue, clr_bit );
1212     }
1213
1214     if (new_win)  /* set the new window */
1215     {
1216         struct thread *owner = get_window_thread( new_win );
1217         if (owner)
1218         {
1219             msg->win = new_win;
1220             if (owner->queue->input != input)
1221             {
1222                 list_remove( &msg->entry );
1223                 if (msg->msg == WM_MOUSEMOVE && merge_message( owner->queue->input, msg ))
1224                 {
1225                     free_message( msg );
1226                     release_object( owner );
1227                     return;
1228                 }
1229                 list_add_tail( &owner->queue->input->msg_list, &msg->entry );
1230             }
1231             set_queue_bits( owner->queue, get_hardware_msg_bit( msg ));
1232             remove = 0;
1233             release_object( owner );
1234         }
1235     }
1236     if (remove)
1237     {
1238         update_input_key_state( input->desktop, input->keystate, msg );
1239         list_remove( &msg->entry );
1240         free_message( msg );
1241     }
1242 }
1243
1244 /* find the window that should receive a given hardware message */
1245 static user_handle_t find_hardware_message_window( struct desktop *desktop, struct thread_input *input,
1246                                                    struct message *msg, unsigned int *msg_code )
1247 {
1248     struct hardware_msg_data *data = msg->data;
1249     user_handle_t win = 0;
1250
1251     *msg_code = msg->msg;
1252     if (is_keyboard_msg( msg ))
1253     {
1254         if (input && !(win = input->focus))
1255         {
1256             win = input->active;
1257             if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
1258         }
1259     }
1260     else  /* mouse message */
1261     {
1262         if (!input || !(win = input->capture))
1263         {
1264             if (!(win = msg->win) || !is_window_visible( win ) || is_window_transparent( win ))
1265                 win = window_from_point( desktop, data->x, data->y );
1266         }
1267     }
1268     return win;
1269 }
1270
1271 /* set the cursor position, clipping to the cursor clip rect */
1272 static void set_cursor_pos( struct desktop *desktop, int x, int y )
1273 {
1274     desktop->cursor_x = min( max( x, desktop->cursor_clip.left ), desktop->cursor_clip.right - 1 );
1275     desktop->cursor_y = min( max( y, desktop->cursor_clip.top ), desktop->cursor_clip.bottom - 1 );
1276 }
1277
1278 /* queue a hardware message into a given thread input */
1279 static void queue_hardware_message( struct desktop *desktop, struct message *msg )
1280 {
1281     user_handle_t win;
1282     struct thread *thread;
1283     struct thread_input *input;
1284     unsigned int msg_code;
1285     struct hardware_msg_data *data = msg->data;
1286
1287     update_input_key_state( desktop, desktop->keystate, msg );
1288     last_input_time = get_tick_count();
1289
1290     if (is_keyboard_msg( msg ))
1291     {
1292         if (desktop->keystate[VK_MENU] & 0x80) msg->lparam |= KF_ALTDOWN << 16;
1293         if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT)
1294             msg->lparam &= ~(KF_EXTENDED << 16);
1295     }
1296     else
1297     {
1298         if (msg->msg == WM_MOUSEMOVE) set_cursor_pos( desktop, data->x, data->y );
1299         if (desktop->keystate[VK_LBUTTON] & 0x80)  msg->wparam |= MK_LBUTTON;
1300         if (desktop->keystate[VK_MBUTTON] & 0x80)  msg->wparam |= MK_MBUTTON;
1301         if (desktop->keystate[VK_RBUTTON] & 0x80)  msg->wparam |= MK_RBUTTON;
1302         if (desktop->keystate[VK_SHIFT] & 0x80)    msg->wparam |= MK_SHIFT;
1303         if (desktop->keystate[VK_CONTROL] & 0x80)  msg->wparam |= MK_CONTROL;
1304         if (desktop->keystate[VK_XBUTTON1] & 0x80) msg->wparam |= MK_XBUTTON1;
1305         if (desktop->keystate[VK_XBUTTON2] & 0x80) msg->wparam |= MK_XBUTTON2;
1306     }
1307     data->x = desktop->cursor_x;
1308     data->y = desktop->cursor_y;
1309
1310     if (msg->win && (thread = get_window_thread( msg->win )))
1311     {
1312         input = thread->queue->input;
1313         release_object( thread );
1314     }
1315     else input = desktop->foreground_input;
1316
1317     win = find_hardware_message_window( desktop, input, msg, &msg_code );
1318     if (!win || !(thread = get_window_thread(win)))
1319     {
1320         if (input) update_input_key_state( input->desktop, input->keystate, msg );
1321         free( msg );
1322         return;
1323     }
1324     input = thread->queue->input;
1325
1326     if (msg->msg == WM_MOUSEMOVE && merge_message( input, msg )) free( msg );
1327     else
1328     {
1329         msg->unique_id = 0;  /* will be set once we return it to the app */
1330         list_add_tail( &input->msg_list, &msg->entry );
1331         set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
1332     }
1333     release_object( thread );
1334 }
1335
1336 /* send the low-level hook message for a given hardware message */
1337 static int send_hook_ll_message( struct desktop *desktop, struct message *hardware_msg,
1338                                  const hw_input_t *input, struct msg_queue *sender )
1339 {
1340     struct thread *hook_thread;
1341     struct msg_queue *queue;
1342     struct message *msg;
1343     timeout_t timeout = 2000 * -10000;  /* FIXME: load from registry */
1344     int id = (input->type == INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
1345
1346     if (!(hook_thread = get_first_global_hook( id ))) return 0;
1347     if (!(queue = hook_thread->queue)) return 0;
1348
1349     if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
1350
1351     msg->type      = MSG_HOOK_LL;
1352     msg->win       = 0;
1353     msg->msg       = id;
1354     msg->wparam    = hardware_msg->msg;
1355     msg->time      = hardware_msg->time;
1356     msg->data_size = hardware_msg->data_size;
1357     msg->result    = NULL;
1358
1359     if (input->type == INPUT_KEYBOARD)
1360     {
1361         unsigned short vkey = input->kbd.vkey;
1362         if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET;
1363         msg->lparam = (input->kbd.scan << 16) | vkey;
1364     }
1365     else msg->lparam = input->mouse.data << 16;
1366
1367     if (!(msg->data = memdup( hardware_msg->data, hardware_msg->data_size )) ||
1368         !(msg->result = alloc_message_result( sender, queue, msg, timeout )))
1369     {
1370         free_message( msg );
1371         return 0;
1372     }
1373     msg->result->hardware_msg = hardware_msg;
1374     msg->result->desktop = (struct desktop *)grab_object( desktop );
1375     list_add_tail( &queue->msg_list[SEND_MESSAGE], &msg->entry );
1376     set_queue_bits( queue, QS_SENDMESSAGE );
1377     return 1;
1378 }
1379
1380 /* queue a hardware message for a mouse event */
1381 static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
1382                                 unsigned int hook_flags, struct msg_queue *sender )
1383 {
1384     struct hardware_msg_data *msg_data;
1385     struct message *msg;
1386     unsigned int i, time, flags;
1387     int wait = 0, x, y;
1388
1389     static const unsigned int messages[] =
1390     {
1391         WM_MOUSEMOVE,    /* 0x0001 = MOUSEEVENTF_MOVE */
1392         WM_LBUTTONDOWN,  /* 0x0002 = MOUSEEVENTF_LEFTDOWN */
1393         WM_LBUTTONUP,    /* 0x0004 = MOUSEEVENTF_LEFTUP */
1394         WM_RBUTTONDOWN,  /* 0x0008 = MOUSEEVENTF_RIGHTDOWN */
1395         WM_RBUTTONUP,    /* 0x0010 = MOUSEEVENTF_RIGHTUP */
1396         WM_MBUTTONDOWN,  /* 0x0020 = MOUSEEVENTF_MIDDLEDOWN */
1397         WM_MBUTTONUP,    /* 0x0040 = MOUSEEVENTF_MIDDLEUP */
1398         WM_XBUTTONDOWN,  /* 0x0080 = MOUSEEVENTF_XDOWN */
1399         WM_XBUTTONUP,    /* 0x0100 = MOUSEEVENTF_XUP */
1400         0,               /* 0x0200 = unused */
1401         0,               /* 0x0400 = unused */
1402         WM_MOUSEWHEEL,   /* 0x0800 = MOUSEEVENTF_WHEEL */
1403         WM_MOUSEHWHEEL   /* 0x1000 = MOUSEEVENTF_HWHEEL */
1404     };
1405
1406     flags = input->mouse.flags;
1407     time  = input->mouse.time;
1408     if (!time) time = get_tick_count();
1409
1410     if (flags & MOUSEEVENTF_MOVE)
1411     {
1412         if (flags & MOUSEEVENTF_ABSOLUTE)
1413         {
1414             x = input->mouse.x;
1415             y = input->mouse.y;
1416             if (flags & ~(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE) &&
1417                 x == desktop->cursor_x && y == desktop->cursor_y)
1418                 flags &= ~MOUSEEVENTF_MOVE;
1419         }
1420         else
1421         {
1422             x = desktop->cursor_x + input->mouse.x;
1423             y = desktop->cursor_y + input->mouse.y;
1424         }
1425     }
1426     else
1427     {
1428         x = desktop->cursor_x;
1429         y = desktop->cursor_y;
1430     }
1431
1432     for (i = 0; i < sizeof(messages)/sizeof(messages[0]); i++)
1433     {
1434         if (!messages[i]) continue;
1435         if (!(flags & (1 << i))) continue;
1436         flags &= ~(1 << i);
1437
1438         if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
1439         if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
1440         {
1441             free( msg );
1442             return 0;
1443         }
1444         memset( msg_data, 0, sizeof(*msg_data) );
1445
1446         msg->type      = MSG_HARDWARE;
1447         msg->win       = get_user_full_handle( win );
1448         msg->msg       = messages[i];
1449         msg->wparam    = input->mouse.data << 16;
1450         msg->lparam    = 0;
1451         msg->time      = time;
1452         msg->result    = NULL;
1453         msg->data      = msg_data;
1454         msg->data_size = sizeof(*msg_data);
1455         msg_data->x    = x;
1456         msg_data->y    = y;
1457         msg_data->info = input->mouse.info;
1458         if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLMHF_INJECTED;
1459
1460         /* specify a sender only when sending the last message */
1461         if (!(flags & ((1 << sizeof(messages)/sizeof(messages[0])) - 1)))
1462         {
1463             if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
1464                 queue_hardware_message( desktop, msg );
1465         }
1466         else if (!send_hook_ll_message( desktop, msg, input, NULL ))
1467             queue_hardware_message( desktop, msg );
1468     }
1469     return wait;
1470 }
1471
1472 /* queue a hardware message for a keyboard event */
1473 static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
1474                                    unsigned int hook_flags, struct msg_queue *sender )
1475 {
1476     struct hardware_msg_data *msg_data;
1477     struct message *msg;
1478     unsigned char vkey = input->kbd.vkey;
1479     int wait;
1480
1481     if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
1482     if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
1483     {
1484         free( msg );
1485         return 0;
1486     }
1487     memset( msg_data, 0, sizeof(*msg_data) );
1488
1489     msg->type      = MSG_HARDWARE;
1490     msg->win       = get_user_full_handle( win );
1491     msg->lparam    = (input->kbd.scan << 16) | 1; /* repeat count */
1492     msg->time      = input->kbd.time;
1493     msg->result    = NULL;
1494     msg->data      = msg_data;
1495     msg->data_size = sizeof(*msg_data);
1496     msg_data->info = input->kbd.info;
1497     if (!msg->time) msg->time = get_tick_count();
1498     if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLKHF_INJECTED;
1499
1500     if (input->kbd.flags & KEYEVENTF_UNICODE)
1501     {
1502         msg->wparam = VK_PACKET;
1503     }
1504     else
1505     {
1506         unsigned int flags = 0;
1507         switch (vkey)
1508         {
1509         case VK_MENU:
1510         case VK_LMENU:
1511         case VK_RMENU:
1512             vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
1513             break;
1514         case VK_CONTROL:
1515         case VK_LCONTROL:
1516         case VK_RCONTROL:
1517             vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
1518             break;
1519         case VK_SHIFT:
1520         case VK_LSHIFT:
1521         case VK_RSHIFT:
1522             vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
1523             break;
1524         }
1525         if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
1526         /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
1527         if (input->kbd.flags & KEYEVENTF_KEYUP) flags |= KF_REPEAT | KF_UP;
1528         else if (desktop->keystate[vkey] & 0x80) flags |= KF_REPEAT;
1529
1530         msg->wparam = vkey;
1531         msg->lparam |= flags << 16;
1532         msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
1533     }
1534
1535     msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
1536
1537     switch (vkey)
1538     {
1539     case VK_LMENU:
1540     case VK_RMENU:
1541         if (input->kbd.flags & KEYEVENTF_KEYUP)
1542         {
1543             /* send WM_SYSKEYUP if Alt still pressed and no other key in between */
1544             /* we use 0x02 as a flag to track if some other SYSKEYUP was sent already */
1545             if ((desktop->keystate[VK_MENU] & 0x82) != 0x82) break;
1546             msg->msg = WM_SYSKEYUP;
1547             desktop->keystate[VK_MENU] &= ~0x02;
1548         }
1549         else
1550         {
1551             /* send WM_SYSKEYDOWN for Alt except with Ctrl */
1552             if (desktop->keystate[VK_CONTROL] & 0x80) break;
1553             msg->msg = WM_SYSKEYDOWN;
1554             desktop->keystate[VK_MENU] |= 0x02;
1555         }
1556         break;
1557
1558     case VK_LCONTROL:
1559     case VK_RCONTROL:
1560         /* send WM_SYSKEYUP on release if Alt still pressed */
1561         if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break;
1562         if (!(desktop->keystate[VK_MENU] & 0x80)) break;
1563         msg->msg = WM_SYSKEYUP;
1564         desktop->keystate[VK_MENU] &= ~0x02;
1565         break;
1566
1567     default:
1568         /* send WM_SYSKEY for Alt-anykey and for F10 */
1569         if (desktop->keystate[VK_CONTROL] & 0x80) break;
1570         if (!(desktop->keystate[VK_MENU] & 0x80)) break;
1571         /* fall through */
1572     case VK_F10:
1573         msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN;
1574         desktop->keystate[VK_MENU] &= ~0x02;
1575         break;
1576     }
1577     if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
1578         queue_hardware_message( desktop, msg );
1579
1580     return wait;
1581 }
1582
1583 /* queue a hardware message for a custom type of event */
1584 static void queue_custom_hardware_message( struct desktop *desktop, user_handle_t win,
1585                                            const hw_input_t *input )
1586 {
1587     struct hardware_msg_data *msg_data;
1588     struct message *msg;
1589
1590     if (!(msg = mem_alloc( sizeof(*msg) ))) return;
1591     if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
1592     {
1593         free( msg );
1594         return;
1595     }
1596     memset( msg_data, 0, sizeof(*msg_data) );
1597
1598     msg->type      = MSG_HARDWARE;
1599     msg->win       = get_user_full_handle( win );
1600     msg->msg       = input->hw.msg;
1601     msg->wparam    = 0;
1602     msg->lparam    = input->hw.lparam;
1603     msg->time      = get_tick_count();
1604     msg->result    = NULL;
1605     msg->data      = msg_data;
1606     msg->data_size = sizeof(*msg_data);
1607
1608     queue_hardware_message( desktop, msg );
1609 }
1610
1611 /* check message filter for a hardware message */
1612 static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
1613                                     user_handle_t filter_win, unsigned int first, unsigned int last )
1614 {
1615     if (msg_code >= WM_KEYFIRST && msg_code <= WM_KEYLAST)
1616     {
1617         /* we can only test the window for a keyboard message since the
1618          * dest window for a mouse message depends on hittest */
1619         if (filter_win && win != filter_win && !is_child_window( filter_win, win ))
1620             return 0;
1621         /* the message code is final for a keyboard message, we can simply check it */
1622         return check_msg_filter( msg_code, first, last );
1623     }
1624     else  /* mouse message */
1625     {
1626         /* we need to check all possible values that the message can have in the end */
1627
1628         if (check_msg_filter( msg_code, first, last )) return 1;
1629         if (msg_code == WM_MOUSEWHEEL) return 0;  /* no other possible value for this one */
1630
1631         /* all other messages can become non-client messages */
1632         if (check_msg_filter( msg_code + (WM_NCMOUSEFIRST - WM_MOUSEFIRST), first, last )) return 1;
1633
1634         /* clicks can become double-clicks or non-client double-clicks */
1635         if (msg_code == WM_LBUTTONDOWN || msg_code == WM_MBUTTONDOWN ||
1636             msg_code == WM_RBUTTONDOWN || msg_code == WM_XBUTTONDOWN)
1637         {
1638             if (check_msg_filter( msg_code + (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN), first, last )) return 1;
1639             if (check_msg_filter( msg_code + (WM_NCLBUTTONDBLCLK - WM_LBUTTONDOWN), first, last )) return 1;
1640         }
1641         return 0;
1642     }
1643 }
1644
1645
1646 /* find a hardware message for the given queue */
1647 static int get_hardware_message( struct thread *thread, unsigned int hw_id, user_handle_t filter_win,
1648                                  unsigned int first, unsigned int last, struct get_message_reply *reply )
1649 {
1650     struct thread_input *input = thread->queue->input;
1651     struct thread *win_thread;
1652     struct list *ptr;
1653     user_handle_t win;
1654     int clear_bits, got_one = 0;
1655     unsigned int msg_code;
1656
1657     ptr = list_head( &input->msg_list );
1658     if (hw_id)
1659     {
1660         while (ptr)
1661         {
1662             struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1663             if (msg->unique_id == hw_id) break;
1664             ptr = list_next( &input->msg_list, ptr );
1665         }
1666         if (!ptr) ptr = list_head( &input->msg_list );
1667         else ptr = list_next( &input->msg_list, ptr );  /* start from the next one */
1668     }
1669
1670     if (ptr == list_head( &input->msg_list ))
1671         clear_bits = QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON;
1672     else
1673         clear_bits = 0;  /* don't clear bits if we don't go through the whole list */
1674
1675     while (ptr)
1676     {
1677         struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1678         struct hardware_msg_data *data = msg->data;
1679
1680         ptr = list_next( &input->msg_list, ptr );
1681         win = find_hardware_message_window( input->desktop, input, msg, &msg_code );
1682         if (!win || !(win_thread = get_window_thread( win )))
1683         {
1684             /* no window at all, remove it */
1685             update_input_key_state( input->desktop, input->keystate, msg );
1686             list_remove( &msg->entry );
1687             free_message( msg );
1688             continue;
1689         }
1690         if (win_thread != thread)
1691         {
1692             if (win_thread->queue->input == input)
1693             {
1694                 /* wake the other thread */
1695                 set_queue_bits( win_thread->queue, get_hardware_msg_bit(msg) );
1696                 got_one = 1;
1697             }
1698             else
1699             {
1700                 /* for another thread input, drop it */
1701                 update_input_key_state( input->desktop, input->keystate, msg );
1702                 list_remove( &msg->entry );
1703                 free_message( msg );
1704             }
1705             release_object( win_thread );
1706             continue;
1707         }
1708         release_object( win_thread );
1709
1710         /* if we already got a message for another thread, or if it doesn't
1711          * match the filter we skip it */
1712         if (got_one || !check_hw_message_filter( win, msg_code, filter_win, first, last ))
1713         {
1714             clear_bits &= ~get_hardware_msg_bit( msg );
1715             continue;
1716         }
1717         /* now we can return it */
1718         if (!msg->unique_id) msg->unique_id = get_unique_id();
1719         reply->type   = MSG_HARDWARE;
1720         reply->win    = win;
1721         reply->msg    = msg_code;
1722         reply->wparam = msg->wparam;
1723         reply->lparam = msg->lparam;
1724         reply->time   = msg->time;
1725
1726         data->hw_id = msg->unique_id;
1727         set_reply_data( msg->data, msg->data_size );
1728         return 1;
1729     }
1730     /* nothing found, clear the hardware queue bits */
1731     clear_queue_bits( thread->queue, clear_bits );
1732     return 0;
1733 }
1734
1735 /* increment (or decrement if 'incr' is negative) the queue paint count */
1736 void inc_queue_paint_count( struct thread *thread, int incr )
1737 {
1738     struct msg_queue *queue = thread->queue;
1739
1740     assert( queue );
1741
1742     if ((queue->paint_count += incr) < 0) queue->paint_count = 0;
1743
1744     if (queue->paint_count)
1745         set_queue_bits( queue, QS_PAINT );
1746     else
1747         clear_queue_bits( queue, QS_PAINT );
1748 }
1749
1750
1751 /* remove all messages and timers belonging to a certain window */
1752 void queue_cleanup_window( struct thread *thread, user_handle_t win )
1753 {
1754     struct msg_queue *queue = thread->queue;
1755     struct list *ptr;
1756     int i;
1757
1758     if (!queue) return;
1759
1760     /* remove timers */
1761
1762     ptr = list_head( &queue->pending_timers );
1763     while (ptr)
1764     {
1765         struct list *next = list_next( &queue->pending_timers, ptr );
1766         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1767         if (timer->win == win) free_timer( queue, timer );
1768         ptr = next;
1769     }
1770     ptr = list_head( &queue->expired_timers );
1771     while (ptr)
1772     {
1773         struct list *next = list_next( &queue->expired_timers, ptr );
1774         struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
1775         if (timer->win == win) free_timer( queue, timer );
1776         ptr = next;
1777     }
1778
1779     /* remove messages */
1780     for (i = 0; i < NB_MSG_KINDS; i++)
1781     {
1782         struct list *ptr, *next;
1783
1784         LIST_FOR_EACH_SAFE( ptr, next, &queue->msg_list[i] )
1785         {
1786             struct message *msg = LIST_ENTRY( ptr, struct message, entry );
1787             if (msg->win == win) remove_queue_message( queue, msg, i );
1788         }
1789     }
1790
1791     thread_input_cleanup_window( queue, win );
1792 }
1793
1794 /* post a message to a window; used by socket handling */
1795 void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lparam_t lparam )
1796 {
1797     struct message *msg;
1798     struct thread *thread = get_window_thread( win );
1799
1800     if (!thread) return;
1801
1802     if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
1803     {
1804         msg->type      = MSG_POSTED;
1805         msg->win       = get_user_full_handle( win );
1806         msg->msg       = message;
1807         msg->wparam    = wparam;
1808         msg->lparam    = lparam;
1809         msg->time      = get_tick_count();
1810         msg->result    = NULL;
1811         msg->data      = NULL;
1812         msg->data_size = 0;
1813
1814         list_add_tail( &thread->queue->msg_list[POST_MESSAGE], &msg->entry );
1815         set_queue_bits( thread->queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
1816     }
1817     release_object( thread );
1818 }
1819
1820 /* post a win event */
1821 void post_win_event( struct thread *thread, unsigned int event,
1822                      user_handle_t win, unsigned int object_id,
1823                      unsigned int child_id, client_ptr_t hook_proc,
1824                      const WCHAR *module, data_size_t module_size,
1825                      user_handle_t hook)
1826 {
1827     struct message *msg;
1828
1829     if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
1830     {
1831         struct winevent_msg_data *data;
1832
1833         msg->type      = MSG_WINEVENT;
1834         msg->win       = get_user_full_handle( win );
1835         msg->msg       = event;
1836         msg->wparam    = object_id;
1837         msg->lparam    = child_id;
1838         msg->time      = get_tick_count();
1839         msg->result    = NULL;
1840
1841         if ((data = malloc( sizeof(*data) + module_size )))
1842         {
1843             data->hook = hook;
1844             data->tid  = get_thread_id( current );
1845             data->hook_proc = hook_proc;
1846             memcpy( data + 1, module, module_size );
1847
1848             msg->data = data;
1849             msg->data_size = sizeof(*data) + module_size;
1850
1851             if (debug_level > 1)
1852                 fprintf( stderr, "post_win_event: tid %04x event %04x win %08x object_id %d child_id %d\n",
1853                          get_thread_id(thread), event, win, object_id, child_id );
1854             list_add_tail( &thread->queue->msg_list[SEND_MESSAGE], &msg->entry );
1855             set_queue_bits( thread->queue, QS_SENDMESSAGE );
1856         }
1857         else
1858             free( msg );
1859     }
1860 }
1861
1862
1863 /* check if the thread owning the window is hung */
1864 DECL_HANDLER(is_window_hung)
1865 {
1866     struct thread *thread;
1867
1868     thread = get_window_thread( req->win );
1869     if (thread)
1870     {
1871         reply->is_hung = is_queue_hung( thread->queue );
1872         release_object( thread );
1873     }
1874     else reply->is_hung = 0;
1875 }
1876
1877
1878 /* get the message queue of the current thread */
1879 DECL_HANDLER(get_msg_queue)
1880 {
1881     struct msg_queue *queue = get_current_queue();
1882
1883     reply->handle = 0;
1884     if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
1885 }
1886
1887
1888 /* set the file descriptor associated to the current thread queue */
1889 DECL_HANDLER(set_queue_fd)
1890 {
1891     struct msg_queue *queue = get_current_queue();
1892     struct file *file;
1893     int unix_fd;
1894
1895     if (queue->fd)  /* fd can only be set once */
1896     {
1897         set_error( STATUS_ACCESS_DENIED );
1898         return;
1899     }
1900     if (!(file = get_file_obj( current->process, req->handle, SYNCHRONIZE ))) return;
1901
1902     if ((unix_fd = get_file_unix_fd( file )) != -1)
1903     {
1904         if ((unix_fd = dup( unix_fd )) != -1)
1905             queue->fd = create_anonymous_fd( &msg_queue_fd_ops, unix_fd, &queue->obj, 0 );
1906         else
1907             file_set_error();
1908     }
1909     release_object( file );
1910 }
1911
1912
1913 /* set the current message queue wakeup mask */
1914 DECL_HANDLER(set_queue_mask)
1915 {
1916     struct msg_queue *queue = get_current_queue();
1917
1918     if (queue)
1919     {
1920         queue->wake_mask    = req->wake_mask;
1921         queue->changed_mask = req->changed_mask;
1922         reply->wake_bits    = queue->wake_bits;
1923         reply->changed_bits = queue->changed_bits;
1924         if (is_signaled( queue ))
1925         {
1926             /* if skip wait is set, do what would have been done in the subsequent wait */
1927             if (req->skip_wait) msg_queue_satisfied( &queue->obj, current );
1928             else wake_up( &queue->obj, 0 );
1929         }
1930     }
1931 }
1932
1933
1934 /* get the current message queue status */
1935 DECL_HANDLER(get_queue_status)
1936 {
1937     struct msg_queue *queue = current->queue;
1938     if (queue)
1939     {
1940         reply->wake_bits    = queue->wake_bits;
1941         reply->changed_bits = queue->changed_bits;
1942         if (req->clear) queue->changed_bits = 0;
1943     }
1944     else reply->wake_bits = reply->changed_bits = 0;
1945 }
1946
1947
1948 /* send a message to a thread queue */
1949 DECL_HANDLER(send_message)
1950 {
1951     struct message *msg;
1952     struct msg_queue *send_queue = get_current_queue();
1953     struct msg_queue *recv_queue = NULL;
1954     struct thread *thread = NULL;
1955
1956     if (!(thread = get_thread_from_id( req->id ))) return;
1957
1958     if (!(recv_queue = thread->queue))
1959     {
1960         set_error( STATUS_INVALID_PARAMETER );
1961         release_object( thread );
1962         return;
1963     }
1964     if ((req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
1965     {
1966         set_error( STATUS_TIMEOUT );
1967         release_object( thread );
1968         return;
1969     }
1970
1971     if ((msg = mem_alloc( sizeof(*msg) )))
1972     {
1973         msg->type      = req->type;
1974         msg->win       = get_user_full_handle( req->win );
1975         msg->msg       = req->msg;
1976         msg->wparam    = req->wparam;
1977         msg->lparam    = req->lparam;
1978         msg->time      = get_tick_count();
1979         msg->result    = NULL;
1980         msg->data      = NULL;
1981         msg->data_size = get_req_data_size();
1982
1983         if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
1984         {
1985             free( msg );
1986             release_object( thread );
1987             return;
1988         }
1989
1990         switch(msg->type)
1991         {
1992         case MSG_OTHER_PROCESS:
1993         case MSG_ASCII:
1994         case MSG_UNICODE:
1995         case MSG_CALLBACK:
1996             if (!(msg->result = alloc_message_result( send_queue, recv_queue, msg, req->timeout )))
1997             {
1998                 free_message( msg );
1999                 break;
2000             }
2001             /* fall through */
2002         case MSG_NOTIFY:
2003             list_add_tail( &recv_queue->msg_list[SEND_MESSAGE], &msg->entry );
2004             set_queue_bits( recv_queue, QS_SENDMESSAGE );
2005             break;
2006         case MSG_POSTED:
2007             list_add_tail( &recv_queue->msg_list[POST_MESSAGE], &msg->entry );
2008             set_queue_bits( recv_queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
2009             break;
2010         case MSG_HARDWARE:  /* should use send_hardware_message instead */
2011         case MSG_CALLBACK_RESULT:  /* cannot send this one */
2012         case MSG_HOOK_LL:  /* generated internally */
2013         default:
2014             set_error( STATUS_INVALID_PARAMETER );
2015             free( msg );
2016             break;
2017         }
2018     }
2019     release_object( thread );
2020 }
2021
2022 /* send a hardware message to a thread queue */
2023 DECL_HANDLER(send_hardware_message)
2024 {
2025     struct thread *thread = NULL;
2026     struct desktop *desktop;
2027     struct msg_queue *sender = get_current_queue();
2028
2029     if (req->win)
2030     {
2031         if (!(thread = get_window_thread( req->win ))) return;
2032         desktop = (struct desktop *)grab_object( thread->queue->input->desktop );
2033     }
2034     else if (!(desktop = get_thread_desktop( current, 0 ))) return;
2035
2036     switch (req->input.type)
2037     {
2038     case INPUT_MOUSE:
2039         reply->wait = queue_mouse_message( desktop, req->win, &req->input, req->flags, sender );
2040         break;
2041     case INPUT_KEYBOARD:
2042         reply->wait = queue_keyboard_message( desktop, req->win, &req->input, req->flags, sender );
2043         break;
2044     case INPUT_HARDWARE:
2045         queue_custom_hardware_message( desktop, req->win, &req->input );
2046         break;
2047     default:
2048         set_error( STATUS_INVALID_PARAMETER );
2049     }
2050     if (thread) release_object( thread );
2051     release_object( desktop );
2052 }
2053
2054 /* post a quit message to the current queue */
2055 DECL_HANDLER(post_quit_message)
2056 {
2057     struct msg_queue *queue = get_current_queue();
2058
2059     if (!queue)
2060         return;
2061
2062     queue->quit_message = 1;
2063     queue->exit_code = req->exit_code;
2064     set_queue_bits( queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
2065 }
2066
2067 /* get a message from the current queue */
2068 DECL_HANDLER(get_message)
2069 {
2070     struct timer *timer;
2071     struct list *ptr;
2072     struct msg_queue *queue = get_current_queue();
2073     user_handle_t get_win = get_user_full_handle( req->get_win );
2074     unsigned int filter = req->flags >> 16;
2075
2076     reply->active_hooks = get_active_hooks();
2077
2078     if (!queue) return;
2079     queue->last_get_msg = current_time;
2080     if (!filter) filter = QS_ALLINPUT;
2081
2082     /* first check for sent messages */
2083     if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))
2084     {
2085         struct message *msg = LIST_ENTRY( ptr, struct message, entry );
2086         receive_message( queue, msg, reply );
2087         return;
2088     }
2089
2090     /* clear changed bits so we can wait on them if we don't find a message */
2091     if (filter & QS_POSTMESSAGE)
2092     {
2093         queue->changed_bits &= ~(QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER);
2094         if (req->get_first == 0 && req->get_last == ~0U) queue->changed_bits &= ~QS_ALLPOSTMESSAGE;
2095     }
2096     if (filter & QS_INPUT) queue->changed_bits &= ~QS_INPUT;
2097     if (filter & QS_PAINT) queue->changed_bits &= ~QS_PAINT;
2098
2099     /* then check for posted messages */
2100     if ((filter & QS_POSTMESSAGE) &&
2101         get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
2102         return;
2103
2104     /* only check for quit messages if not posted messages pending.
2105      * note: the quit message isn't filtered */
2106     if (get_quit_message( queue, req->flags, reply ))
2107         return;
2108
2109     /* then check for any raw hardware message */
2110     if ((filter & QS_INPUT) &&
2111         filter_contains_hw_range( req->get_first, req->get_last ) &&
2112         get_hardware_message( current, req->hw_id, get_win, req->get_first, req->get_last, reply ))
2113         return;
2114
2115     /* now check for WM_PAINT */
2116     if ((filter & QS_PAINT) &&
2117         queue->paint_count &&
2118         check_msg_filter( WM_PAINT, req->get_first, req->get_last ) &&
2119         (reply->win = find_window_to_repaint( get_win, current )))
2120     {
2121         reply->type   = MSG_POSTED;
2122         reply->msg    = WM_PAINT;
2123         reply->wparam = 0;
2124         reply->lparam = 0;
2125         reply->time   = get_tick_count();
2126         return;
2127     }
2128
2129     /* now check for timer */
2130     if ((filter & QS_TIMER) &&
2131         (timer = find_expired_timer( queue, get_win, req->get_first,
2132                                      req->get_last, (req->flags & PM_REMOVE) )))
2133     {
2134         reply->type   = MSG_POSTED;
2135         reply->win    = timer->win;
2136         reply->msg    = timer->msg;
2137         reply->wparam = timer->id;
2138         reply->lparam = timer->lparam;
2139         reply->time   = get_tick_count();
2140         if (!(req->flags & PM_NOYIELD) && current->process->idle_event)
2141             set_event( current->process->idle_event );
2142         return;
2143     }
2144
2145     if (get_win == -1 && current->process->idle_event) set_event( current->process->idle_event );
2146     queue->wake_mask = req->wake_mask;
2147     queue->changed_mask = req->changed_mask;
2148     set_error( STATUS_PENDING );  /* FIXME */
2149 }
2150
2151
2152 /* reply to a sent message */
2153 DECL_HANDLER(reply_message)
2154 {
2155     if (!current->queue) set_error( STATUS_ACCESS_DENIED );
2156     else if (current->queue->recv_result)
2157         reply_message( current->queue, req->result, 0, req->remove,
2158                        get_req_data(), get_req_data_size() );
2159 }
2160
2161
2162 /* accept the current hardware message */
2163 DECL_HANDLER(accept_hardware_message)
2164 {
2165     if (current->queue)
2166         release_hardware_message( current->queue, req->hw_id, req->remove, req->new_win );
2167     else
2168         set_error( STATUS_ACCESS_DENIED );
2169 }
2170
2171
2172 /* retrieve the reply for the last message sent */
2173 DECL_HANDLER(get_message_reply)
2174 {
2175     struct message_result *result;
2176     struct list *entry;
2177     struct msg_queue *queue = current->queue;
2178
2179     if (queue)
2180     {
2181         set_error( STATUS_PENDING );
2182         reply->result = 0;
2183
2184         if (!(entry = list_head( &queue->send_result ))) return;  /* no reply ready */
2185
2186         result = LIST_ENTRY( entry, struct message_result, sender_entry );
2187         if (result->replied || req->cancel)
2188         {
2189             if (result->replied)
2190             {
2191                 reply->result = result->result;
2192                 set_error( result->error );
2193                 if (result->data)
2194                 {
2195                     data_size_t data_len = min( result->data_size, get_reply_max_size() );
2196                     set_reply_data_ptr( result->data, data_len );
2197                     result->data = NULL;
2198                     result->data_size = 0;
2199                 }
2200             }
2201             remove_result_from_sender( result );
2202
2203             entry = list_head( &queue->send_result );
2204             if (!entry) clear_queue_bits( queue, QS_SMRESULT );
2205             else
2206             {
2207                 result = LIST_ENTRY( entry, struct message_result, sender_entry );
2208                 if (!result->replied) clear_queue_bits( queue, QS_SMRESULT );
2209             }
2210         }
2211     }
2212     else set_error( STATUS_ACCESS_DENIED );
2213 }
2214
2215
2216 /* set a window timer */
2217 DECL_HANDLER(set_win_timer)
2218 {
2219     struct timer *timer;
2220     struct msg_queue *queue;
2221     struct thread *thread = NULL;
2222     user_handle_t win = 0;
2223     lparam_t id = req->id;
2224
2225     if (req->win)
2226     {
2227         if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
2228         {
2229             set_error( STATUS_INVALID_HANDLE );
2230             return;
2231         }
2232         if (thread->process != current->process)
2233         {
2234             release_object( thread );
2235             set_error( STATUS_ACCESS_DENIED );
2236             return;
2237         }
2238         queue = thread->queue;
2239         /* remove it if it existed already */
2240         if ((timer = find_timer( queue, win, req->msg, id ))) free_timer( queue, timer );
2241     }
2242     else
2243     {
2244         queue = get_current_queue();
2245         /* look for a timer with this id */
2246         if (id && (timer = find_timer( queue, 0, req->msg, id )))
2247         {
2248             /* free and reuse id */
2249             free_timer( queue, timer );
2250         }
2251         else
2252         {
2253             /* find a free id for it */
2254             do
2255             {
2256                 id = queue->next_timer_id;
2257                 if (--queue->next_timer_id <= 0x100) queue->next_timer_id = 0x7fff;
2258             }
2259             while (find_timer( queue, 0, req->msg, id ));
2260         }
2261     }
2262
2263     if ((timer = set_timer( queue, req->rate )))
2264     {
2265         timer->win    = win;
2266         timer->msg    = req->msg;
2267         timer->id     = id;
2268         timer->lparam = req->lparam;
2269         reply->id     = id;
2270     }
2271     if (thread) release_object( thread );
2272 }
2273
2274 /* kill a window timer */
2275 DECL_HANDLER(kill_win_timer)
2276 {
2277     struct timer *timer;
2278     struct thread *thread;
2279     user_handle_t win = 0;
2280
2281     if (req->win)
2282     {
2283         if (!(win = get_user_full_handle( req->win )) || !(thread = get_window_thread( win )))
2284         {
2285             set_error( STATUS_INVALID_HANDLE );
2286             return;
2287         }
2288         if (thread->process != current->process)
2289         {
2290             release_object( thread );
2291             set_error( STATUS_ACCESS_DENIED );
2292             return;
2293         }
2294     }
2295     else thread = (struct thread *)grab_object( current );
2296
2297     if (thread->queue && (timer = find_timer( thread->queue, win, req->msg, req->id )))
2298         free_timer( thread->queue, timer );
2299     else
2300         set_error( STATUS_INVALID_PARAMETER );
2301
2302     release_object( thread );
2303 }
2304
2305
2306 /* attach (or detach) thread inputs */
2307 DECL_HANDLER(attach_thread_input)
2308 {
2309     struct thread *thread_from = get_thread_from_id( req->tid_from );
2310     struct thread *thread_to = get_thread_from_id( req->tid_to );
2311
2312     if (!thread_from || !thread_to)
2313     {
2314         if (thread_from) release_object( thread_from );
2315         if (thread_to) release_object( thread_to );
2316         return;
2317     }
2318     if (thread_from != thread_to)
2319     {
2320         if (req->attach) attach_thread_input( thread_from, thread_to );
2321         else
2322         {
2323             if (thread_from->queue && thread_to->queue &&
2324                 thread_from->queue->input == thread_to->queue->input)
2325                 detach_thread_input( thread_from );
2326             else
2327                 set_error( STATUS_ACCESS_DENIED );
2328         }
2329     }
2330     else set_error( STATUS_ACCESS_DENIED );
2331     release_object( thread_from );
2332     release_object( thread_to );
2333 }
2334
2335
2336 /* get thread input data */
2337 DECL_HANDLER(get_thread_input)
2338 {
2339     struct thread *thread = NULL;
2340     struct desktop *desktop;
2341     struct thread_input *input;
2342
2343     if (req->tid)
2344     {
2345         if (!(thread = get_thread_from_id( req->tid ))) return;
2346         if (!(desktop = get_thread_desktop( thread, 0 )))
2347         {
2348             release_object( thread );
2349             return;
2350         }
2351         input = thread->queue ? thread->queue->input : NULL;
2352     }
2353     else
2354     {
2355         if (!(desktop = get_thread_desktop( current, 0 ))) return;
2356         input = desktop->foreground_input;  /* get the foreground thread info */
2357     }
2358
2359     if (input)
2360     {
2361         reply->focus      = input->focus;
2362         reply->capture    = input->capture;
2363         reply->active     = input->active;
2364         reply->menu_owner = input->menu_owner;
2365         reply->move_size  = input->move_size;
2366         reply->caret      = input->caret;
2367         reply->cursor     = input->cursor;
2368         reply->show_count = input->cursor_count;
2369         reply->rect       = input->caret_rect;
2370     }
2371
2372     /* foreground window is active window of foreground thread */
2373     reply->foreground = desktop->foreground_input ? desktop->foreground_input->active : 0;
2374     if (thread) release_object( thread );
2375     release_object( desktop );
2376 }
2377
2378
2379 /* retrieve queue keyboard state for a given thread */
2380 DECL_HANDLER(get_key_state)
2381 {
2382     struct thread *thread;
2383     struct desktop *desktop;
2384     data_size_t size = min( 256, get_reply_max_size() );
2385
2386     if (!req->tid)  /* get global async key state */
2387     {
2388         if (!(desktop = get_thread_desktop( current, 0 ))) return;
2389         if (req->key >= 0)
2390         {
2391             reply->state = desktop->keystate[req->key & 0xff];
2392             desktop->keystate[req->key & 0xff] &= ~0x40;
2393         }
2394         set_reply_data( desktop->keystate, size );
2395         release_object( desktop );
2396     }
2397     else
2398     {
2399         if (!(thread = get_thread_from_id( req->tid ))) return;
2400         if (thread->queue)
2401         {
2402             if (req->key >= 0) reply->state = thread->queue->input->keystate[req->key & 0xff];
2403             set_reply_data( thread->queue->input->keystate, size );
2404         }
2405         release_object( thread );
2406     }
2407 }
2408
2409
2410 /* set queue keyboard state for a given thread */
2411 DECL_HANDLER(set_key_state)
2412 {
2413     struct thread *thread;
2414     struct desktop *desktop;
2415     data_size_t size = min( 256, get_req_data_size() );
2416
2417     if (!req->tid)  /* set global async key state */
2418     {
2419         if (!(desktop = get_thread_desktop( current, 0 ))) return;
2420         memcpy( desktop->keystate, get_req_data(), size );
2421         release_object( desktop );
2422     }
2423     else
2424     {
2425         if (!(thread = get_thread_from_id( req->tid ))) return;
2426         if (thread->queue) memcpy( thread->queue->input->keystate, get_req_data(), size );
2427         release_object( thread );
2428     }
2429 }
2430
2431
2432 /* set the system foreground window */
2433 DECL_HANDLER(set_foreground_window)
2434 {
2435     struct thread *thread = NULL;
2436     struct desktop *desktop;
2437     struct msg_queue *queue = get_current_queue();
2438
2439     if (!(desktop = get_thread_desktop( current, 0 ))) return;
2440     reply->previous = desktop->foreground_input ? desktop->foreground_input->active : 0;
2441     reply->send_msg_old = (reply->previous && desktop->foreground_input != queue->input);
2442     reply->send_msg_new = FALSE;
2443
2444     if (is_top_level_window( req->handle ) &&
2445         ((thread = get_window_thread( req->handle ))) &&
2446         (thread->queue->input->desktop == desktop))
2447     {
2448         desktop->foreground_input = thread->queue->input;
2449         reply->send_msg_new = (desktop->foreground_input != queue->input);
2450     }
2451     else set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
2452
2453     if (thread) release_object( thread );
2454     release_object( desktop );
2455 }
2456
2457
2458 /* set the current thread focus window */
2459 DECL_HANDLER(set_focus_window)
2460 {
2461     struct msg_queue *queue = get_current_queue();
2462
2463     reply->previous = 0;
2464     if (queue && check_queue_input_window( queue, req->handle ))
2465     {
2466         reply->previous = queue->input->focus;
2467         queue->input->focus = get_user_full_handle( req->handle );
2468     }
2469 }
2470
2471
2472 /* set the current thread active window */
2473 DECL_HANDLER(set_active_window)
2474 {
2475     struct msg_queue *queue = get_current_queue();
2476
2477     reply->previous = 0;
2478     if (queue && check_queue_input_window( queue, req->handle ))
2479     {
2480         if (!req->handle || make_window_active( req->handle ))
2481         {
2482             reply->previous = queue->input->active;
2483             queue->input->active = get_user_full_handle( req->handle );
2484         }
2485         else set_error( STATUS_INVALID_HANDLE );
2486     }
2487 }
2488
2489
2490 /* set the current thread capture window */
2491 DECL_HANDLER(set_capture_window)
2492 {
2493     struct msg_queue *queue = get_current_queue();
2494
2495     reply->previous = reply->full_handle = 0;
2496     if (queue && check_queue_input_window( queue, req->handle ))
2497     {
2498         struct thread_input *input = queue->input;
2499
2500         /* if in menu mode, reject all requests to change focus, except if the menu bit is set */
2501         if (input->menu_owner && !(req->flags & CAPTURE_MENU))
2502         {
2503             set_error(STATUS_ACCESS_DENIED);
2504             return;
2505         }
2506         reply->previous = input->capture;
2507         input->capture = get_user_full_handle( req->handle );
2508         input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
2509         input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
2510         reply->full_handle = input->capture;
2511     }
2512 }
2513
2514
2515 /* Set the current thread caret window */
2516 DECL_HANDLER(set_caret_window)
2517 {
2518     struct msg_queue *queue = get_current_queue();
2519
2520     reply->previous = 0;
2521     if (queue && check_queue_input_window( queue, req->handle ))
2522     {
2523         struct thread_input *input = queue->input;
2524
2525         reply->previous  = input->caret;
2526         reply->old_rect  = input->caret_rect;
2527         reply->old_hide  = input->caret_hide;
2528         reply->old_state = input->caret_state;
2529
2530         set_caret_window( input, get_user_full_handle(req->handle) );
2531         input->caret_rect.right  = input->caret_rect.left + req->width;
2532         input->caret_rect.bottom = input->caret_rect.top + req->height;
2533     }
2534 }
2535
2536
2537 /* Set the current thread caret information */
2538 DECL_HANDLER(set_caret_info)
2539 {
2540     struct msg_queue *queue = get_current_queue();
2541     struct thread_input *input;
2542
2543     if (!queue) return;
2544     input = queue->input;
2545     reply->full_handle = input->caret;
2546     reply->old_rect    = input->caret_rect;
2547     reply->old_hide    = input->caret_hide;
2548     reply->old_state   = input->caret_state;
2549
2550     if (req->handle && get_user_full_handle(req->handle) != input->caret)
2551     {
2552         set_error( STATUS_ACCESS_DENIED );
2553         return;
2554     }
2555     if (req->flags & SET_CARET_POS)
2556     {
2557         input->caret_rect.right  += req->x - input->caret_rect.left;
2558         input->caret_rect.bottom += req->y - input->caret_rect.top;
2559         input->caret_rect.left = req->x;
2560         input->caret_rect.top  = req->y;
2561     }
2562     if (req->flags & SET_CARET_HIDE)
2563     {
2564         input->caret_hide += req->hide;
2565         if (input->caret_hide < 0) input->caret_hide = 0;
2566     }
2567     if (req->flags & SET_CARET_STATE)
2568     {
2569         if (req->state == -1) input->caret_state = !input->caret_state;
2570         else input->caret_state = !!req->state;
2571     }
2572 }
2573
2574
2575 /* get the time of the last input event */
2576 DECL_HANDLER(get_last_input_time)
2577 {
2578     reply->time = last_input_time;
2579 }
2580
2581 /* set/get the current cursor */
2582 DECL_HANDLER(set_cursor)
2583 {
2584     struct msg_queue *queue = get_current_queue();
2585     struct thread_input *input;
2586
2587     if (!queue) return;
2588     input = queue->input;
2589
2590     reply->prev_handle = input->cursor;
2591     reply->prev_count  = input->cursor_count;
2592
2593     if (req->flags & SET_CURSOR_HANDLE)
2594     {
2595         if (req->handle && !get_user_object( req->handle, USER_CLIENT ))
2596         {
2597             set_win32_error( ERROR_INVALID_CURSOR_HANDLE );
2598             return;
2599         }
2600         input->cursor = req->handle;
2601     }
2602     if (req->flags & SET_CURSOR_COUNT)
2603     {
2604         queue->cursor_count += req->show_count;
2605         input->cursor_count += req->show_count;
2606     }
2607     if (req->flags & SET_CURSOR_POS)
2608     {
2609         set_cursor_pos( input->desktop, req->x, req->y );
2610     }
2611     if (req->flags & SET_CURSOR_CLIP)
2612     {
2613         rectangle_t top_rect;
2614         get_top_window_rectangle( input->desktop, &top_rect );
2615         if (!intersect_rect( &input->desktop->cursor_clip, &top_rect, &req->clip ))
2616             input->desktop->cursor_clip = top_rect;
2617     }
2618
2619     reply->new_x    = input->desktop->cursor_x;
2620     reply->new_y    = input->desktop->cursor_y;
2621     reply->new_clip = input->desktop->cursor_clip;
2622 }