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