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