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