rundll32 requires a window for some functions to work, so create one.
[wine] / server / queue.c
1 /*
2  * Server-side message queues
3  *
4  * Copyright (C) 2000 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31
32 #include "handle.h"
33 #include "file.h"
34 #include "thread.h"
35 #include "process.h"
36 #include "request.h"
37 #include "user.h"
38
39 enum message_kind { SEND_MESSAGE, POST_MESSAGE };
40 #define NB_MSG_KINDS (POST_MESSAGE+1)
41
42
43 struct message_result
44 {
45     struct message_result *send_next;   /* next in sender list */
46     struct message_result *recv_next;   /* next in receiver list */
47     struct msg_queue      *sender;      /* sender queue */
48     struct msg_queue      *receiver;    /* receiver queue */
49     int                    replied;     /* has it been replied to? */
50     unsigned int           result;      /* reply result */
51     unsigned int           error;       /* error code to pass back to sender */
52     void                  *data;        /* message reply data */
53     unsigned int           data_size;   /* size of message reply data */
54     struct timeout_user   *timeout;     /* result timeout */
55 };
56
57 struct message
58 {
59     struct message        *next;      /* next message in list */
60     struct message        *prev;      /* prev message in list */
61     enum message_type      type;      /* message type */
62     user_handle_t          win;       /* window handle */
63     unsigned int           msg;       /* message code */
64     unsigned int           wparam;    /* parameters */
65     unsigned int           lparam;    /* parameters */
66     int                    x;         /* x position */
67     int                    y;         /* y position */
68     unsigned int           time;      /* message time */
69     unsigned int           info;      /* extra info */
70     void                  *data;      /* message data for sent messages */
71     unsigned int           data_size; /* size of message data */
72     struct message_result *result;    /* result in sender queue */
73 };
74
75 struct message_list
76 {
77     struct message *first;     /* head of list */
78     struct message *last;      /* tail of list */
79 };
80
81 struct timer
82 {
83     struct timer   *next;      /* next timer in list */
84     struct timer   *prev;      /* prev timer in list */
85     struct timeval  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     unsigned int    id;        /* timer id */
90     unsigned int    lparam;    /* lparam for message */
91 };
92
93 struct thread_input
94 {
95     struct object          obj;           /* object header */
96     user_handle_t          focus;         /* focus window */
97     user_handle_t          capture;       /* capture window */
98     user_handle_t          active;        /* active window */
99     user_handle_t          menu_owner;    /* current menu owner window */
100     user_handle_t          move_size;     /* current moving/resizing window */
101     user_handle_t          caret;         /* caret window */
102     rectangle_t            caret_rect;    /* caret rectangle */
103     int                    caret_hide;    /* caret hide count */
104     int                    caret_state;   /* caret on/off state */
105     struct message        *msg;           /* message currently processed */
106     struct thread         *msg_thread;    /* thread processing the message */
107     struct message_list    msg_list;      /* list of hardware messages */
108     unsigned char          keystate[256]; /* state of each key */
109 };
110
111 struct msg_queue
112 {
113     struct object          obj;           /* object header */
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     struct message_list    msg_list[NB_MSG_KINDS];  /* lists of messages */
120     struct message_result *send_result;   /* stack of sent messages waiting for result */
121     struct message_result *recv_result;   /* stack of received messages waiting for result */
122     struct timer          *first_timer;   /* head of timer list */
123     struct timer          *last_timer;    /* tail of timer list */
124     struct timer          *next_timer;    /* next timer to expire */
125     struct timeout_user   *timeout;       /* timeout for next timer to expire */
126     struct thread_input   *input;         /* thread input descriptor */
127     struct hook_table     *hooks;         /* hook table */
128     struct timeval         last_get_msg;  /* time of last get message call */
129 };
130
131 static void msg_queue_dump( struct object *obj, int verbose );
132 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
133 static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
134 static int msg_queue_signaled( struct object *obj, struct thread *thread );
135 static int msg_queue_satisfied( struct object *obj, struct thread *thread );
136 static void msg_queue_destroy( struct object *obj );
137 static void thread_input_dump( struct object *obj, int verbose );
138 static void thread_input_destroy( struct object *obj );
139 static void timer_callback( void *private );
140
141 static const struct object_ops msg_queue_ops =
142 {
143     sizeof(struct msg_queue),  /* size */
144     msg_queue_dump,            /* dump */
145     msg_queue_add_queue,       /* add_queue */
146     msg_queue_remove_queue,    /* remove_queue */
147     msg_queue_signaled,        /* signaled */
148     msg_queue_satisfied,       /* satisfied */
149     no_get_fd,                 /* get_fd */
150     msg_queue_destroy          /* destroy */
151 };
152
153
154 static const struct object_ops thread_input_ops =
155 {
156     sizeof(struct thread_input),  /* size */
157     thread_input_dump,            /* dump */
158     no_add_queue,                 /* add_queue */
159     NULL,                         /* remove_queue */
160     NULL,                         /* signaled */
161     NULL,                         /* satisfied */
162     no_get_fd,                    /* get_fd */
163     thread_input_destroy          /* destroy */
164 };
165
166 /* pointer to input structure of foreground thread */
167 static struct thread_input *foreground_input;
168
169
170 /* set the caret window in a given thread input */
171 static void set_caret_window( struct thread_input *input, user_handle_t win )
172 {
173     input->caret             = win;
174     input->caret_rect.left   = 0;
175     input->caret_rect.top    = 0;
176     input->caret_rect.right  = 0;
177     input->caret_rect.bottom = 0;
178     input->caret_hide        = 1;
179     input->caret_state       = 0;
180 }
181
182 /* create a thread input object */
183 static struct thread_input *create_thread_input(void)
184 {
185     struct thread_input *input;
186
187     if ((input = alloc_object( &thread_input_ops )))
188     {
189         input->focus       = 0;
190         input->capture     = 0;
191         input->active      = 0;
192         input->menu_owner  = 0;
193         input->move_size   = 0;
194         input->msg         = NULL;
195         input->msg_thread  = NULL;
196         input->msg_list.first = input->msg_list.last = NULL;
197         set_caret_window( input, 0 );
198         memset( input->keystate, 0, sizeof(input->keystate) );
199     }
200     return input;
201 }
202
203 /* create a message queue object */
204 static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input )
205 {
206     struct msg_queue *queue;
207     int i;
208
209     if (!input && !(input = create_thread_input())) return NULL;
210     if ((queue = alloc_object( &msg_queue_ops )))
211     {
212         queue->wake_bits       = 0;
213         queue->wake_mask       = 0;
214         queue->changed_bits    = 0;
215         queue->changed_mask    = 0;
216         queue->paint_count     = 0;
217         queue->send_result     = NULL;
218         queue->recv_result     = NULL;
219         queue->first_timer     = NULL;
220         queue->last_timer      = NULL;
221         queue->next_timer      = NULL;
222         queue->timeout         = NULL;
223         queue->input           = (struct thread_input *)grab_object( input );
224         queue->hooks           = NULL;
225         gettimeofday( &queue->last_get_msg, NULL );
226         for (i = 0; i < NB_MSG_KINDS; i++)
227             queue->msg_list[i].first = queue->msg_list[i].last = NULL;
228
229         thread->queue = queue;
230         if (!thread->process->queue)
231             thread->process->queue = (struct msg_queue *)grab_object( queue );
232     }
233     release_object( input );
234     return queue;
235 }
236
237 /* free the message queue of a thread at thread exit */
238 void free_msg_queue( struct thread *thread )
239 {
240     struct process *process = thread->process;
241
242     remove_thread_hooks( thread );
243     if (!thread->queue) return;
244     if (process->queue == thread->queue)  /* is it the process main queue? */
245     {
246         release_object( process->queue );
247         process->queue = NULL;
248         if (process->idle_event)
249         {
250             set_event( process->idle_event );
251             release_object( process->idle_event );
252             process->idle_event = NULL;
253         }
254     }
255     release_object( thread->queue );
256     thread->queue = NULL;
257 }
258
259 /* get the hook table for a given thread */
260 struct hook_table *get_queue_hooks( struct thread *thread )
261 {
262     if (!thread->queue) return NULL;
263     return thread->queue->hooks;
264 }
265
266 /* set the hook table for a given thread, allocating the queue if needed */
267 void set_queue_hooks( struct thread *thread, struct hook_table *hooks )
268 {
269     struct msg_queue *queue = thread->queue;
270     if (!queue) queue = create_msg_queue( thread, NULL );
271     if (queue->hooks) release_object( queue->hooks );
272     queue->hooks = hooks;
273 }
274
275 /* check the queue status */
276 inline static int is_signaled( struct msg_queue *queue )
277 {
278     return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask));
279 }
280
281 /* set some queue bits */
282 inline static void set_queue_bits( struct msg_queue *queue, unsigned int bits )
283 {
284     queue->wake_bits |= bits;
285     queue->changed_bits |= bits;
286     if (is_signaled( queue )) wake_up( &queue->obj, 0 );
287 }
288
289 /* clear some queue bits */
290 inline static void clear_queue_bits( struct msg_queue *queue, unsigned int bits )
291 {
292     queue->wake_bits &= ~bits;
293     queue->changed_bits &= ~bits;
294 }
295
296 /* check whether msg is a keyboard message */
297 inline static int is_keyboard_msg( struct message *msg )
298 {
299     return (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST);
300 }
301
302 /* get the QS_* bit corresponding to a given hardware message */
303 inline static int get_hardware_msg_bit( struct message *msg )
304 {
305     if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
306     if (is_keyboard_msg( msg )) return QS_KEY;
307     return QS_MOUSEBUTTON;
308 }
309
310 /* get the current thread queue, creating it if needed */
311 inline static struct msg_queue *get_current_queue(void)
312 {
313     struct msg_queue *queue = current->queue;
314     if (!queue) queue = create_msg_queue( current, NULL );
315     return queue;
316 }
317
318 /* append a message to the end of a list */
319 inline static void append_message( struct message_list *list, struct message *msg )
320 {
321     msg->next = NULL;
322     if ((msg->prev = list->last)) msg->prev->next = msg;
323     else list->first = msg;
324     list->last = msg;
325 }
326
327 /* unlink a message from a list it */
328 inline static void unlink_message( struct message_list *list, struct message *msg )
329 {
330     if (msg->next) msg->next->prev = msg->prev;
331     else list->last = msg->prev;
332     if (msg->prev) msg->prev->next = msg->next;
333     else list->first = msg->next;
334 }
335
336 /* try to merge a message with the last in the list; return 1 if successful */
337 static int merge_message( struct thread_input *input, const struct message *msg )
338 {
339     struct message *prev = input->msg_list.last;
340
341     if (!prev) return 0;
342     if (input->msg == prev) return 0;
343     if (prev->result) return 0;
344     if (prev->win != msg->win) return 0;
345     if (prev->msg != msg->msg) return 0;
346     if (prev->type != msg->type) return 0;
347     /* now we can merge it */
348     prev->wparam  = msg->wparam;
349     prev->lparam  = msg->lparam;
350     prev->x       = msg->x;
351     prev->y       = msg->y;
352     prev->time    = msg->time;
353     prev->info    = msg->info;
354     return 1;
355 }
356
357 /* free a result structure */
358 static void free_result( struct message_result *result )
359 {
360     if (result->timeout) remove_timeout_user( result->timeout );
361     if (result->data) free( result->data );
362     free( result );
363 }
364
365 /* store the message result in the appropriate structure */
366 static void store_message_result( struct message_result *res, unsigned int result,
367                                   unsigned int error )
368 {
369     res->result  = result;
370     res->error   = error;
371     res->replied = 1;
372     if (res->timeout)
373     {
374         remove_timeout_user( res->timeout );
375         res->timeout = NULL;
376     }
377     /* wake sender queue if waiting on this result */
378     if (res->sender && res->sender->send_result == res)
379         set_queue_bits( res->sender, QS_SMRESULT );
380 }
381
382 /* free a message when deleting a queue or window */
383 static void free_message( struct message *msg )
384 {
385     struct message_result *result = msg->result;
386     if (result)
387     {
388         if (result->sender)
389         {
390             result->receiver = NULL;
391             store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
392         }
393         else free_result( result );
394     }
395     if (msg->data) free( msg->data );
396     free( msg );
397 }
398
399 /* remove (and free) a message from a message list */
400 static void remove_queue_message( struct msg_queue *queue, struct message *msg,
401                                   enum message_kind kind )
402 {
403     unlink_message( &queue->msg_list[kind], msg );
404     switch(kind)
405     {
406     case SEND_MESSAGE:
407         if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_SENDMESSAGE );
408         break;
409     case POST_MESSAGE:
410         if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_POSTMESSAGE );
411         break;
412     }
413     free_message( msg );
414 }
415
416 /* message timed out without getting a reply */
417 static void result_timeout( void *private )
418 {
419     struct message_result *result = private;
420
421     assert( !result->replied );
422
423     result->timeout = NULL;
424     store_message_result( result, 0, STATUS_TIMEOUT );
425 }
426
427 /* allocate and fill a message result structure */
428 static struct message_result *alloc_message_result( struct msg_queue *send_queue,
429                                                     struct msg_queue *recv_queue,
430                                                     unsigned int timeout )
431 {
432     struct message_result *result = mem_alloc( sizeof(*result) );
433     if (result)
434     {
435         /* put the result on the sender result stack */
436         result->sender    = send_queue;
437         result->receiver  = recv_queue;
438         result->replied   = 0;
439         result->data      = NULL;
440         result->data_size = 0;
441         result->timeout   = NULL;
442         result->send_next = send_queue->send_result;
443         send_queue->send_result = result;
444         if (timeout != -1)
445         {
446             struct timeval when;
447             gettimeofday( &when, 0 );
448             add_timeout( &when, timeout );
449             result->timeout = add_timeout_user( &when, result_timeout, result );
450         }
451     }
452     return result;
453 }
454
455 /* receive a message, removing it from the sent queue */
456 static void receive_message( struct msg_queue *queue, struct message *msg,
457                              struct get_message_reply *reply )
458 {
459     struct message_result *result = msg->result;
460
461     reply->total = msg->data_size;
462     if (msg->data_size > get_reply_max_size())
463     {
464         set_error( STATUS_BUFFER_OVERFLOW );
465         return;
466     }
467     reply->type   = msg->type;
468     reply->win    = msg->win;
469     reply->msg    = msg->msg;
470     reply->wparam = msg->wparam;
471     reply->lparam = msg->lparam;
472     reply->x      = msg->x;
473     reply->y      = msg->y;
474     reply->time   = msg->time;
475     reply->info   = msg->info;
476
477     if (msg->data) set_reply_data_ptr( msg->data, msg->data_size );
478
479     unlink_message( &queue->msg_list[SEND_MESSAGE], msg );
480     /* put the result on the receiver result stack */
481     if (result)
482     {
483         result->recv_next  = queue->recv_result;
484         queue->recv_result = result;
485     }
486     free( msg );
487     if (!queue->msg_list[SEND_MESSAGE].first) clear_queue_bits( queue, QS_SENDMESSAGE );
488 }
489
490 /* set the result of the current received message */
491 static void reply_message( struct msg_queue *queue, unsigned int result,
492                            unsigned int error, int remove, const void *data, size_t len )
493 {
494     struct message_result *res = queue->recv_result;
495
496     if (remove)
497     {
498         queue->recv_result = res->recv_next;
499         res->receiver = NULL;
500         if (!res->sender)  /* no one waiting for it */
501         {
502             free_result( res );
503             return;
504         }
505     }
506     if (!res->replied)
507     {
508         if (len && (res->data = memdup( data, len ))) res->data_size = len;
509         store_message_result( res, result, error );
510     }
511 }
512
513 /* retrieve a posted message */
514 static int get_posted_message( struct msg_queue *queue, user_handle_t win,
515                                unsigned int first, unsigned int last, unsigned int flags,
516                                struct get_message_reply *reply )
517 {
518     struct message *msg;
519     struct message_list *list = &queue->msg_list[POST_MESSAGE];
520
521     /* check against the filters */
522     for (msg = list->first; msg; msg = msg->next)
523     {
524         if (msg->msg == WM_QUIT) break;  /* WM_QUIT is never filtered */
525         if (win && msg->win && msg->win != win && !is_child_window( win, msg->win )) continue;
526         if (msg->msg < first) continue;
527         if (msg->msg > last) continue;
528         break; /* found one */
529     }
530     if (!msg) return 0;
531
532     /* return it to the app */
533
534     reply->total = msg->data_size;
535     if (msg->data_size > get_reply_max_size())
536     {
537         set_error( STATUS_BUFFER_OVERFLOW );
538         return 1;
539     }
540     reply->type   = msg->type;
541     reply->win    = msg->win;
542     reply->msg    = msg->msg;
543     reply->wparam = msg->wparam;
544     reply->lparam = msg->lparam;
545     reply->x      = msg->x;
546     reply->y      = msg->y;
547     reply->time   = msg->time;
548     reply->info   = msg->info;
549
550     if (flags & GET_MSG_REMOVE)
551     {
552         if (msg->data)
553         {
554             set_reply_data_ptr( msg->data, msg->data_size );
555             msg->data = NULL;
556             msg->data_size = 0;
557         }
558         remove_queue_message( queue, msg, POST_MESSAGE );
559     }
560     else if (msg->data) set_reply_data( msg->data, msg->data_size );
561
562     return 1;
563 }
564
565 /* empty a message list and free all the messages */
566 static void empty_msg_list( struct message_list *list )
567 {
568     struct message *msg = list->first;
569     while (msg)
570     {
571         struct message *next = msg->next;
572         free_message( msg );
573         msg = next;
574     }
575 }
576
577 /* cleanup all pending results when deleting a queue */
578 static void cleanup_results( struct msg_queue *queue )
579 {
580     struct message_result *result, *next;
581
582     result = queue->send_result;
583     while (result)
584     {
585         next = result->send_next;
586         result->sender = NULL;
587         if (!result->receiver) free_result( result );
588         result = next;
589     }
590
591     while (queue->recv_result)
592         reply_message( queue, 0, STATUS_ACCESS_DENIED /*FIXME*/, 1, NULL, 0 );
593 }
594
595 /* check if the thread owning the queue is hung (not checking for messages) */
596 static int is_queue_hung( struct msg_queue *queue )
597 {
598     struct timeval now;
599     struct wait_queue_entry *entry;
600
601     gettimeofday( &now, NULL );
602     if (now.tv_sec - queue->last_get_msg.tv_sec <= 5)
603         return 0;  /* less than 5 seconds since last get message -> not hung */
604
605     for (entry = queue->obj.head; entry; entry = entry->next)
606     {
607         if (entry->thread->queue == queue)
608             return 0;  /* thread is waiting on queue -> not hung */
609     }
610     return 1;
611 }
612
613 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
614 {
615     struct msg_queue *queue = (struct msg_queue *)obj;
616     struct process *process = entry->thread->process;
617
618     /* a thread can only wait on its own queue */
619     if (entry->thread->queue != queue)
620     {
621         set_error( STATUS_ACCESS_DENIED );
622         return 0;
623     }
624     /* if waiting on the main process queue, set the idle event */
625     if (process->queue == queue)
626     {
627         if (process->idle_event) set_event( process->idle_event );
628     }
629     add_queue( obj, entry );
630     return 1;
631 }
632
633 static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
634 {
635     struct msg_queue *queue = (struct msg_queue *)obj;
636     struct process *process = entry->thread->process;
637
638     remove_queue( obj, entry );
639
640     assert( entry->thread->queue == queue );
641
642     /* if waiting on the main process queue, reset the idle event */
643     if (process->queue == queue)
644     {
645         if (process->idle_event) reset_event( process->idle_event );
646     }
647 }
648
649 static void msg_queue_dump( struct object *obj, int verbose )
650 {
651     struct msg_queue *queue = (struct msg_queue *)obj;
652     fprintf( stderr, "Msg queue bits=%x mask=%x\n",
653              queue->wake_bits, queue->wake_mask );
654 }
655
656 static int msg_queue_signaled( struct object *obj, struct thread *thread )
657 {
658     struct msg_queue *queue = (struct msg_queue *)obj;
659     return is_signaled( queue );
660 }
661
662 static int msg_queue_satisfied( struct object *obj, struct thread *thread )
663 {
664     struct msg_queue *queue = (struct msg_queue *)obj;
665     queue->wake_mask = 0;
666     queue->changed_mask = 0;
667     return 0;  /* Not abandoned */
668 }
669
670 static void msg_queue_destroy( struct object *obj )
671 {
672     struct msg_queue *queue = (struct msg_queue *)obj;
673     struct timer *timer = queue->first_timer;
674     int i;
675
676     cleanup_results( queue );
677     for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] );
678
679     while (timer)
680     {
681         struct timer *next = timer->next;
682         free( timer );
683         timer = next;
684     }
685     if (queue->timeout) remove_timeout_user( queue->timeout );
686     if (queue->input) release_object( queue->input );
687     if (queue->hooks) release_object( queue->hooks );
688 }
689
690 static void thread_input_dump( struct object *obj, int verbose )
691 {
692     struct thread_input *input = (struct thread_input *)obj;
693     fprintf( stderr, "Thread input focus=%p capture=%p active=%p\n",
694              input->focus, input->capture, input->active );
695 }
696
697 static void thread_input_destroy( struct object *obj )
698 {
699     struct thread_input *input = (struct thread_input *)obj;
700
701     if (foreground_input == input) foreground_input = NULL;
702     if (input->msg_thread) release_object( input->msg_thread );
703     empty_msg_list( &input->msg_list );
704 }
705
706 /* fix the thread input data when a window is destroyed */
707 inline static void thread_input_cleanup_window( struct msg_queue *queue, user_handle_t window )
708 {
709     struct thread_input *input = queue->input;
710
711     if (window == input->focus) input->focus = 0;
712     if (window == input->capture) input->capture = 0;
713     if (window == input->active) input->active = 0;
714     if (window == input->menu_owner) input->menu_owner = 0;
715     if (window == input->move_size) input->move_size = 0;
716     if (window == input->caret) set_caret_window( input, 0 );
717 }
718
719 /* check if the specified window can be set in the input data of a given queue */
720 static int check_queue_input_window( struct msg_queue *queue, user_handle_t window )
721 {
722     struct thread *thread;
723     int ret = 0;
724
725     if (!window) return 1;  /* we can always clear the data */
726
727     if ((thread = get_window_thread( window )))
728     {
729         ret = (queue->input == thread->queue->input);
730         if (!ret) set_error( STATUS_ACCESS_DENIED );
731         release_object( thread );
732     }
733     else set_error( STATUS_INVALID_HANDLE );
734
735     return ret;
736 }
737
738 /* attach two thread input data structures */
739 int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
740 {
741     struct thread_input *input;
742
743     if (!thread_to->queue && !(thread_to->queue = create_msg_queue( thread_to, NULL ))) return 0;
744     input = (struct thread_input *)grab_object( thread_to->queue->input );
745
746     if (thread_from->queue)
747     {
748         release_object( thread_from->queue->input );
749         thread_from->queue->input = input;
750     }
751     else
752     {
753         if (!(thread_from->queue = create_msg_queue( thread_from, input ))) return 0;
754     }
755     memset( input->keystate, 0, sizeof(input->keystate) );
756     return 1;
757 }
758
759 /* detach two thread input data structures */
760 static void detach_thread_input( struct thread *thread_from, struct thread *thread_to )
761 {
762     struct thread_input *input;
763
764     if (!thread_from->queue || !thread_to->queue ||
765         thread_from->queue->input != thread_to->queue->input)
766     {
767         set_error( STATUS_ACCESS_DENIED );
768         return;
769     }
770     if ((input = create_thread_input()))
771     {
772         release_object( thread_from->queue->input );
773         thread_from->queue->input = input;
774     }
775 }
776
777
778 /* set the next timer to expire */
779 static void set_next_timer( struct msg_queue *queue, struct timer *timer )
780 {
781     if (queue->timeout)
782     {
783         remove_timeout_user( queue->timeout );
784         queue->timeout = NULL;
785     }
786     if ((queue->next_timer = timer))
787         queue->timeout = add_timeout_user( &timer->when, timer_callback, queue );
788
789     /* set/clear QS_TIMER bit */
790     if (queue->next_timer == queue->first_timer)
791         clear_queue_bits( queue, QS_TIMER );
792     else
793         set_queue_bits( queue, QS_TIMER );
794 }
795
796 /* callback for the next timer expiration */
797 static void timer_callback( void *private )
798 {
799     struct msg_queue *queue = private;
800
801     queue->timeout = NULL;
802     /* move on to the next timer */
803     set_next_timer( queue, queue->next_timer->next );
804 }
805
806 /* link a timer at its rightful place in the queue list */
807 static void link_timer( struct msg_queue *queue, struct timer *timer )
808 {
809     struct timer *pos = queue->next_timer;
810
811     while (pos && time_before( &pos->when, &timer->when )) pos = pos->next;
812
813     if (pos) /* insert before pos */
814     {
815         if ((timer->prev = pos->prev)) timer->prev->next = timer;
816         else queue->first_timer = timer;
817         timer->next = pos;
818         pos->prev = timer;
819     }
820     else  /* insert at end */
821     {
822         timer->next = NULL;
823         timer->prev = queue->last_timer;
824         if (queue->last_timer) queue->last_timer->next = timer;
825         else queue->first_timer = timer;
826         queue->last_timer = timer;
827     }
828     /* check if we replaced the next timer */
829     if (pos == queue->next_timer) set_next_timer( queue, timer );
830 }
831
832 /* remove a timer from the queue timer list */
833 static void unlink_timer( struct msg_queue *queue, struct timer *timer )
834 {
835     if (timer->next) timer->next->prev = timer->prev;
836     else queue->last_timer = timer->prev;
837     if (timer->prev) timer->prev->next = timer->next;
838     else queue->first_timer = timer->next;
839     /* check if we removed the next timer */
840     if (queue->next_timer == timer) set_next_timer( queue, timer->next );
841     else if (queue->next_timer == queue->first_timer) clear_queue_bits( queue, QS_TIMER );
842 }
843
844 /* restart an expired timer */
845 static void restart_timer( struct msg_queue *queue, struct timer *timer )
846 {
847     struct timeval now;
848     unlink_timer( queue, timer );
849     gettimeofday( &now, 0 );
850     while (!time_before( &now, &timer->when )) add_timeout( &timer->when, timer->rate );
851     link_timer( queue, timer );
852 }
853
854 /* find an expired timer matching the filtering parameters */
855 static struct timer *find_expired_timer( struct msg_queue *queue, user_handle_t win,
856                                          unsigned int get_first, unsigned int get_last,
857                                          int remove )
858 {
859     struct timer *timer;
860     for (timer = queue->first_timer; (timer && timer != queue->next_timer); timer = timer->next)
861     {
862         if (win && timer->win != win) continue;
863         if (timer->msg >= get_first && timer->msg <= get_last)
864         {
865             if (remove) restart_timer( queue, timer );
866             return timer;
867         }
868     }
869     return NULL;
870 }
871
872 /* kill a timer */
873 static int kill_timer( struct msg_queue *queue, user_handle_t win,
874                        unsigned int msg, unsigned int id )
875 {
876     struct timer *timer;
877
878     for (timer = queue->first_timer; timer; timer = timer->next)
879     {
880         if (timer->win != win || timer->msg != msg || timer->id != id) continue;
881         unlink_timer( queue, timer );
882         free( timer );
883         return 1;
884     }
885     return 0;
886 }
887
888 /* add a timer */
889 static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
890 {
891     struct timer *timer = mem_alloc( sizeof(*timer) );
892     if (timer)
893     {
894         timer->rate  = rate;
895         gettimeofday( &timer->when, 0 );
896         add_timeout( &timer->when, rate );
897         link_timer( queue, timer );
898     }
899     return timer;
900 }
901
902 /* change the input key state for a given key */
903 static void set_input_key_state( struct thread_input *input, unsigned char key, int down )
904 {
905     if (down)
906     {
907         if (!(input->keystate[key] & 0x80)) input->keystate[key] ^= 0x01;
908         input->keystate[key] |= 0x80;
909     }
910     else input->keystate[key] &= ~0x80;
911 }
912
913 /* update the input key state for a keyboard message */
914 static void update_input_key_state( struct thread_input *input, const struct message *msg )
915 {
916     unsigned char key;
917     int down = 0, extended;
918
919     switch (msg->msg)
920     {
921     case WM_LBUTTONDOWN:
922         down = 1;
923         /* fall through */
924     case WM_LBUTTONUP:
925         set_input_key_state( input, VK_LBUTTON, down );
926         break;
927     case WM_MBUTTONDOWN:
928         down = 1;
929         /* fall through */
930     case WM_MBUTTONUP:
931         set_input_key_state( input, VK_MBUTTON, down );
932         break;
933     case WM_RBUTTONDOWN:
934         down = 1;
935         /* fall through */
936     case WM_RBUTTONUP:
937         set_input_key_state( input, VK_RBUTTON, down );
938         break;
939     case WM_KEYDOWN:
940     case WM_SYSKEYDOWN:
941         down = 1;
942         /* fall through */
943     case WM_KEYUP:
944     case WM_SYSKEYUP:
945         key = (unsigned char)msg->wparam;
946         extended = ((msg->lparam >> 16) & KF_EXTENDED) != 0;
947         set_input_key_state( input, key, down );
948         switch(key)
949         {
950         case VK_SHIFT:
951             set_input_key_state( input, extended ? VK_RSHIFT : VK_LSHIFT, down );
952             break;
953         case VK_CONTROL:
954             set_input_key_state( input, extended ? VK_RCONTROL : VK_LCONTROL, down );
955             break;
956         case VK_MENU:
957             set_input_key_state( input, extended ? VK_RMENU : VK_LMENU, down );
958             break;
959         }
960         break;
961     }
962 }
963
964 /* release the hardware message currently being processed by the given thread */
965 static void release_hardware_message( struct thread *thread, int remove )
966 {
967     struct thread_input *input = thread->queue->input;
968
969     if (input->msg_thread != thread) return;
970     if (remove)
971     {
972         struct message *other;
973         int clr_bit;
974
975         update_input_key_state( input, input->msg );
976         unlink_message( &input->msg_list, input->msg );
977         clr_bit = get_hardware_msg_bit( input->msg );
978         for (other = input->msg_list.first; other; other = other->next)
979             if (get_hardware_msg_bit( other ) == clr_bit) break;
980         if (!other) clear_queue_bits( thread->queue, clr_bit );
981         free_message( input->msg );
982     }
983     release_object( input->msg_thread );
984     input->msg = NULL;
985     input->msg_thread = NULL;
986 }
987
988 /* find the window that should receive a given hardware message */
989 static user_handle_t find_hardware_message_window( struct thread_input *input, struct message *msg,
990                                                    unsigned int *msg_code )
991 {
992     user_handle_t win = 0;
993
994     *msg_code = msg->msg;
995     if (is_keyboard_msg( msg ))
996     {
997         if (input && !(win = input->focus))
998         {
999             win = input->active;
1000             if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
1001         }
1002     }
1003     else  /* mouse message */
1004     {
1005         if (!input || !(win = input->capture))
1006         {
1007             if (!(win = msg->win)) win = window_from_point( msg->x, msg->y );
1008         }
1009     }
1010     return win;
1011 }
1012
1013 /* queue a hardware message into a given thread input */
1014 static void queue_hardware_message( struct msg_queue *queue, struct message *msg )
1015 {
1016     user_handle_t win;
1017     struct thread *thread;
1018     struct thread_input *input;
1019     unsigned int msg_code;
1020
1021     win = find_hardware_message_window( queue ? queue->input : foreground_input, msg, &msg_code );
1022     if (!win || !(thread = get_window_thread(win)))
1023     {
1024         free( msg );
1025         return;
1026     }
1027     input = thread->queue->input;
1028
1029     if (msg->msg == WM_MOUSEMOVE && merge_message( input, msg )) free( msg );
1030     else
1031     {
1032         append_message( &input->msg_list, msg );
1033         set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
1034     }
1035     release_object( thread );
1036 }
1037
1038 /* find a hardware message for the given queue */
1039 static int get_hardware_message( struct thread *thread, struct message *first,
1040                                  user_handle_t filter_win, struct get_message_reply *reply )
1041 {
1042     struct thread_input *input = thread->queue->input;
1043     struct thread *win_thread;
1044     struct message *msg;
1045     user_handle_t win;
1046     int clear_bits, got_one = 0;
1047     unsigned int msg_code;
1048
1049     if (input->msg_thread && input->msg_thread != thread)
1050         return 0;  /* locked by another thread */
1051
1052     if (!first)
1053     {
1054         msg = input->msg_list.first;
1055         clear_bits = QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON;
1056     }
1057     else
1058     {
1059         msg = first->next;
1060         clear_bits = 0;  /* don't clear bits if we don't go through the whole list */
1061     }
1062
1063     while (msg)
1064     {
1065         win = find_hardware_message_window( input, msg, &msg_code );
1066         if (!win || !(win_thread = get_window_thread( win )))
1067         {
1068             /* no window at all, remove it */
1069             struct message *next = msg->next;
1070             update_input_key_state( input, msg );
1071             unlink_message( &input->msg_list, msg );
1072             free_message( msg );
1073             msg = next;
1074             continue;
1075         }
1076         if (win_thread != thread)
1077         {
1078             /* wake the other thread */
1079             set_queue_bits( win_thread->queue, get_hardware_msg_bit(msg) );
1080             release_object( win_thread );
1081             got_one = 1;
1082             msg = msg->next;
1083             continue;
1084         }
1085         /* if we already got a message for another thread, or if it doesn't
1086          * match the filter we skip it (filter is only checked for keyboard
1087          * messages since the dest window for a mouse message depends on hittest)
1088          */
1089         if (got_one ||
1090             (filter_win && is_keyboard_msg(msg) &&
1091              win != filter_win && !is_child_window( filter_win, win )))
1092         {
1093             clear_bits &= ~get_hardware_msg_bit( msg );
1094             release_object( win_thread );
1095             msg = msg->next;
1096             continue;
1097         }
1098         /* now we can return it */
1099         if (!input->msg_thread) input->msg_thread = win_thread;
1100         else release_object( win_thread );
1101         input->msg = msg;
1102
1103         reply->type   = MSG_HARDWARE;
1104         reply->win    = win;
1105         reply->msg    = msg_code;
1106         reply->wparam = msg->wparam;
1107         reply->lparam = msg->lparam;
1108         reply->x      = msg->x;
1109         reply->y      = msg->y;
1110         reply->time   = msg->time;
1111         reply->info   = msg->info;
1112         return 1;
1113     }
1114     /* nothing found, clear the hardware queue bits */
1115     clear_queue_bits( thread->queue, clear_bits );
1116     if (input->msg_thread) release_object( input->msg_thread );
1117     input->msg = NULL;
1118     input->msg_thread = NULL;
1119     return 0;
1120 }
1121
1122 /* increment (or decrement if 'incr' is negative) the queue paint count */
1123 void inc_queue_paint_count( struct thread *thread, int incr )
1124 {
1125     struct msg_queue *queue = thread->queue;
1126
1127     assert( queue );
1128
1129     if ((queue->paint_count += incr) < 0) queue->paint_count = 0;
1130
1131     if (queue->paint_count)
1132         set_queue_bits( queue, QS_PAINT );
1133     else
1134         clear_queue_bits( queue, QS_PAINT );
1135 }
1136
1137
1138 /* remove all messages and timers belonging to a certain window */
1139 void queue_cleanup_window( struct thread *thread, user_handle_t win )
1140 {
1141     struct msg_queue *queue = thread->queue;
1142     struct timer *timer;
1143     struct message *msg;
1144     int i;
1145
1146     if (!queue) return;
1147
1148     /* remove timers */
1149     timer = queue->first_timer;
1150     while (timer)
1151     {
1152         struct timer *next = timer->next;
1153         if (timer->win == win)
1154         {
1155             unlink_timer( queue, timer );
1156             free( timer );
1157         }
1158         timer = next;
1159     }
1160
1161     /* remove messages */
1162     for (i = 0; i < NB_MSG_KINDS; i++)
1163     {
1164         msg = queue->msg_list[i].first;
1165         while (msg)
1166         {
1167             struct message *next = msg->next;
1168             if (msg->win == win) remove_queue_message( queue, msg, i );
1169             msg = next;
1170         }
1171     }
1172
1173     thread_input_cleanup_window( queue, win );
1174 }
1175
1176 /* post a message to a window; used by socket handling */
1177 void post_message( user_handle_t win, unsigned int message,
1178                    unsigned int wparam, unsigned int lparam )
1179 {
1180     struct message *msg;
1181     struct thread *thread = get_window_thread( win );
1182
1183     if (!thread) return;
1184
1185     if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
1186     {
1187         msg->type      = MSG_POSTED;
1188         msg->win       = get_user_full_handle( win );
1189         msg->msg       = message;
1190         msg->wparam    = wparam;
1191         msg->lparam    = lparam;
1192         msg->time      = get_tick_count();
1193         msg->x         = 0;
1194         msg->y         = 0;
1195         msg->info      = 0;
1196         msg->result    = NULL;
1197         msg->data      = NULL;
1198         msg->data_size = 0;
1199
1200         append_message( &thread->queue->msg_list[POST_MESSAGE], msg );
1201         set_queue_bits( thread->queue, QS_POSTMESSAGE );
1202     }
1203     release_object( thread );
1204 }
1205
1206
1207 /* get the message queue of the current thread */
1208 DECL_HANDLER(get_msg_queue)
1209 {
1210     struct msg_queue *queue = get_current_queue();
1211
1212     reply->handle = 0;
1213     if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
1214 }
1215
1216
1217 /* set the current message queue wakeup mask */
1218 DECL_HANDLER(set_queue_mask)
1219 {
1220     struct msg_queue *queue = get_current_queue();
1221
1222     if (queue)
1223     {
1224         queue->wake_mask    = req->wake_mask;
1225         queue->changed_mask = req->changed_mask;
1226         reply->wake_bits    = queue->wake_bits;
1227         reply->changed_bits = queue->changed_bits;
1228         if (is_signaled( queue ))
1229         {
1230             /* if skip wait is set, do what would have been done in the subsequent wait */
1231             if (req->skip_wait) msg_queue_satisfied( &queue->obj, current );
1232             else wake_up( &queue->obj, 0 );
1233         }
1234     }
1235 }
1236
1237
1238 /* get the current message queue status */
1239 DECL_HANDLER(get_queue_status)
1240 {
1241     struct msg_queue *queue = current->queue;
1242     if (queue)
1243     {
1244         reply->wake_bits    = queue->wake_bits;
1245         reply->changed_bits = queue->changed_bits;
1246         if (req->clear) queue->changed_bits = 0;
1247     }
1248     else reply->wake_bits = reply->changed_bits = 0;
1249 }
1250
1251
1252 /* send a message to a thread queue */
1253 DECL_HANDLER(send_message)
1254 {
1255     struct message *msg;
1256     struct msg_queue *send_queue = get_current_queue();
1257     struct msg_queue *recv_queue = NULL;
1258     struct thread *thread = NULL;
1259
1260     if (req->id)
1261     {
1262         if (!(thread = get_thread_from_id( req->id ))) return;
1263     }
1264     else if (req->type != MSG_HARDWARE)
1265     {
1266         /* only hardware messages are allowed without destination thread */
1267         set_error( STATUS_INVALID_PARAMETER );
1268         return;
1269     }
1270
1271     if (thread && !(recv_queue = thread->queue))
1272     {
1273         set_error( STATUS_INVALID_PARAMETER );
1274         release_object( thread );
1275         return;
1276     }
1277     if (recv_queue && (req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
1278     {
1279         set_error( STATUS_TIMEOUT );
1280         release_object( thread );
1281         return;
1282     }
1283
1284     if ((msg = mem_alloc( sizeof(*msg) )))
1285     {
1286         msg->type      = req->type;
1287         msg->win       = get_user_full_handle( req->win );
1288         msg->msg       = req->msg;
1289         msg->wparam    = req->wparam;
1290         msg->lparam    = req->lparam;
1291         msg->time      = req->time;
1292         msg->x         = req->x;
1293         msg->y         = req->y;
1294         msg->info      = req->info;
1295         msg->result    = NULL;
1296         msg->data      = NULL;
1297         msg->data_size = 0;
1298
1299         switch(msg->type)
1300         {
1301         case MSG_OTHER_PROCESS:
1302             msg->data_size = get_req_data_size();
1303             if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
1304             {
1305                 free( msg );
1306                 break;
1307             }
1308             /* fall through */
1309         case MSG_ASCII:
1310         case MSG_UNICODE:
1311         case MSG_CALLBACK:
1312             if (!(msg->result = alloc_message_result( send_queue, recv_queue, req->timeout )))
1313             {
1314                 free( msg );
1315                 break;
1316             }
1317             /* fall through */
1318         case MSG_NOTIFY:
1319             append_message( &recv_queue->msg_list[SEND_MESSAGE], msg );
1320             set_queue_bits( recv_queue, QS_SENDMESSAGE );
1321             break;
1322         case MSG_POSTED:
1323             /* needed for posted DDE messages */
1324             msg->data_size = get_req_data_size();
1325             if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
1326             {
1327                 free( msg );
1328                 break;
1329             }
1330             append_message( &recv_queue->msg_list[POST_MESSAGE], msg );
1331             set_queue_bits( recv_queue, QS_POSTMESSAGE );
1332             break;
1333         case MSG_HARDWARE:
1334             queue_hardware_message( recv_queue, msg );
1335             break;
1336         default:
1337             set_error( STATUS_INVALID_PARAMETER );
1338             free( msg );
1339             break;
1340         }
1341     }
1342     if (thread) release_object( thread );
1343 }
1344
1345
1346 /* get a message from the current queue */
1347 DECL_HANDLER(get_message)
1348 {
1349     struct timer *timer;
1350     struct message *msg;
1351     struct message *first_hw_msg = NULL;
1352     struct msg_queue *queue = get_current_queue();
1353     user_handle_t get_win = get_user_full_handle( req->get_win );
1354
1355     if (!queue) return;
1356     gettimeofday( &queue->last_get_msg, NULL );
1357
1358     /* first of all release the hardware input lock if we own it */
1359     /* we'll grab it again if we find a hardware message */
1360     if (queue->input->msg_thread == current)
1361     {
1362         first_hw_msg = queue->input->msg;
1363         release_hardware_message( current, 0 );
1364     }
1365
1366     /* first check for sent messages */
1367     if ((msg = queue->msg_list[SEND_MESSAGE].first))
1368     {
1369         receive_message( queue, msg, reply );
1370         return;
1371     }
1372     if (req->flags & GET_MSG_SENT_ONLY) goto done;  /* nothing else to check */
1373
1374     /* clear changed bits so we can wait on them if we don't find a message */
1375     queue->changed_bits = 0;
1376
1377     /* then check for posted messages */
1378     if (get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
1379         return;
1380
1381     /* then check for any raw hardware message */
1382     if (get_hardware_message( current, first_hw_msg, get_win, reply ))
1383         return;
1384
1385     /* now check for WM_PAINT */
1386     if (queue->paint_count &&
1387         (WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last) &&
1388         (reply->win = find_window_to_repaint( get_win, current )))
1389     {
1390         reply->type   = MSG_POSTED;
1391         reply->msg    = WM_PAINT;
1392         reply->wparam = 0;
1393         reply->lparam = 0;
1394         reply->x      = 0;
1395         reply->y      = 0;
1396         reply->time   = get_tick_count();
1397         reply->info   = 0;
1398         return;
1399     }
1400
1401     /* now check for timer */
1402     if ((timer = find_expired_timer( queue, get_win, req->get_first,
1403                                      req->get_last, (req->flags & GET_MSG_REMOVE) )))
1404     {
1405         reply->type   = MSG_POSTED;
1406         reply->win    = timer->win;
1407         reply->msg    = timer->msg;
1408         reply->wparam = timer->id;
1409         reply->lparam = timer->lparam;
1410         reply->x      = 0;
1411         reply->y      = 0;
1412         reply->time   = get_tick_count();
1413         reply->info   = 0;
1414         return;
1415     }
1416
1417  done:
1418     set_error( STATUS_PENDING );  /* FIXME */
1419 }
1420
1421
1422 /* reply to a sent message */
1423 DECL_HANDLER(reply_message)
1424 {
1425     if (!current->queue)
1426     {
1427         set_error( STATUS_ACCESS_DENIED );
1428         return;
1429     }
1430     if (req->type == MSG_HARDWARE)
1431     {
1432         struct thread_input *input = current->queue->input;
1433         if (input->msg_thread == current) release_hardware_message( current, req->remove );
1434         else set_error( STATUS_ACCESS_DENIED );
1435     }
1436     else if (current->queue->recv_result)
1437         reply_message( current->queue, req->result, 0, req->remove,
1438                        get_req_data(), get_req_data_size() );
1439 }
1440
1441
1442 /* retrieve the reply for the last message sent */
1443 DECL_HANDLER(get_message_reply)
1444 {
1445     struct msg_queue *queue = current->queue;
1446
1447     if (queue)
1448     {
1449         struct message_result *result = queue->send_result;
1450
1451         set_error( STATUS_PENDING );
1452         reply->result = 0;
1453
1454         if (result && (result->replied || req->cancel))
1455         {
1456             if (result->replied)
1457             {
1458                 reply->result = result->result;
1459                 set_error( result->error );
1460                 if (result->data)
1461                 {
1462                     size_t data_len = min( result->data_size, get_reply_max_size() );
1463                     set_reply_data_ptr( result->data, data_len );
1464                     result->data = NULL;
1465                     result->data_size = 0;
1466                 }
1467             }
1468             queue->send_result = result->send_next;
1469             result->sender = NULL;
1470             if (!result->receiver) free_result( result );
1471             if (!queue->send_result || !queue->send_result->replied)
1472                 clear_queue_bits( queue, QS_SMRESULT );
1473         }
1474     }
1475     else set_error( STATUS_ACCESS_DENIED );
1476 }
1477
1478
1479 /* set a window timer */
1480 DECL_HANDLER(set_win_timer)
1481 {
1482     struct timer *timer;
1483     struct msg_queue *queue = get_current_queue();
1484     user_handle_t win = get_user_full_handle( req->win );
1485
1486     if (!queue) return;
1487
1488     /* remove it if it existed already */
1489     if (win) kill_timer( queue, win, req->msg, req->id );
1490
1491     if ((timer = set_timer( queue, req->rate )))
1492     {
1493         timer->win    = win;
1494         timer->msg    = req->msg;
1495         timer->id     = req->id;
1496         timer->lparam = req->lparam;
1497     }
1498 }
1499
1500 /* kill a window timer */
1501 DECL_HANDLER(kill_win_timer)
1502 {
1503     struct msg_queue *queue = current->queue;
1504
1505     if (!queue || !kill_timer( queue, get_user_full_handle(req->win), req->msg, req->id ))
1506         set_error( STATUS_INVALID_PARAMETER );
1507 }
1508
1509
1510 /* attach (or detach) thread inputs */
1511 DECL_HANDLER(attach_thread_input)
1512 {
1513     struct thread *thread_from = get_thread_from_id( req->tid_from );
1514     struct thread *thread_to = get_thread_from_id( req->tid_to );
1515
1516     if (!thread_from || !thread_to)
1517     {
1518         if (thread_from) release_object( thread_from );
1519         if (thread_to) release_object( thread_to );
1520         return;
1521     }
1522     if (thread_from != thread_to)
1523     {
1524         if (req->attach) attach_thread_input( thread_from, thread_to );
1525         else detach_thread_input( thread_from, thread_to );
1526     }
1527     else set_error( STATUS_ACCESS_DENIED );
1528     release_object( thread_from );
1529     release_object( thread_to );
1530 }
1531
1532
1533 /* get thread input data */
1534 DECL_HANDLER(get_thread_input)
1535 {
1536     struct thread *thread = NULL;
1537     struct thread_input *input;
1538
1539     if (req->tid)
1540     {
1541         if (!(thread = get_thread_from_id( req->tid ))) return;
1542         input = thread->queue ? thread->queue->input : NULL;
1543     }
1544     else input = foreground_input;  /* get the foreground thread info */
1545
1546     if (input)
1547     {
1548         reply->focus      = input->focus;
1549         reply->capture    = input->capture;
1550         reply->active     = input->active;
1551         reply->menu_owner = input->menu_owner;
1552         reply->move_size  = input->move_size;
1553         reply->caret      = input->caret;
1554         reply->rect       = input->caret_rect;
1555     }
1556     else
1557     {
1558         reply->focus      = 0;
1559         reply->capture    = 0;
1560         reply->active     = 0;
1561         reply->menu_owner = 0;
1562         reply->move_size  = 0;
1563         reply->caret      = 0;
1564         reply->rect.left = reply->rect.top = reply->rect.right = reply->rect.bottom = 0;
1565     }
1566     /* foreground window is active window of foreground thread */
1567     reply->foreground = foreground_input ? foreground_input->active : 0;
1568     if (thread) release_object( thread );
1569 }
1570
1571
1572 /* retrieve queue keyboard state for a given thread */
1573 DECL_HANDLER(get_key_state)
1574 {
1575     struct thread *thread;
1576     struct thread_input *input;
1577
1578     if (!(thread = get_thread_from_id( req->tid ))) return;
1579     input = thread->queue ? thread->queue->input : NULL;
1580     if (input)
1581     {
1582         if (req->key >= 0) reply->state = input->keystate[req->key & 0xff];
1583         set_reply_data( input->keystate, min( get_reply_max_size(), sizeof(input->keystate) ));
1584     }
1585     release_object( thread );
1586 }
1587
1588
1589 /* set queue keyboard state for a given thread */
1590 DECL_HANDLER(set_key_state)
1591 {
1592     struct thread *thread = NULL;
1593     struct thread_input *input;
1594
1595     if (!(thread = get_thread_from_id( req->tid ))) return;
1596     input = thread->queue ? thread->queue->input : NULL;
1597     if (input)
1598     {
1599         size_t size = min( sizeof(input->keystate), get_req_data_size() );
1600         if (size) memcpy( input->keystate, get_req_data(), size );
1601     }
1602     release_object( thread );
1603 }
1604
1605
1606 /* set the system foreground window */
1607 DECL_HANDLER(set_foreground_window)
1608 {
1609     struct msg_queue *queue = get_current_queue();
1610
1611     reply->previous = foreground_input ? foreground_input->active : 0;
1612     reply->send_msg_old = (reply->previous && foreground_input != queue->input);
1613     reply->send_msg_new = FALSE;
1614
1615     if (req->handle)
1616     {
1617         struct thread *thread;
1618
1619         if (is_top_level_window( req->handle ) &&
1620             ((thread = get_window_thread( req->handle ))))
1621         {
1622             foreground_input = thread->queue->input;
1623             reply->send_msg_new = (foreground_input != queue->input);
1624             release_object( thread );
1625         }
1626         else set_error( STATUS_INVALID_HANDLE );
1627     }
1628     else foreground_input = NULL;
1629 }
1630
1631
1632 /* set the current thread focus window */
1633 DECL_HANDLER(set_focus_window)
1634 {
1635     struct msg_queue *queue = get_current_queue();
1636
1637     reply->previous = 0;
1638     if (queue && check_queue_input_window( queue, req->handle ))
1639     {
1640         reply->previous = queue->input->focus;
1641         queue->input->focus = get_user_full_handle( req->handle );
1642     }
1643 }
1644
1645
1646 /* set the current thread active window */
1647 DECL_HANDLER(set_active_window)
1648 {
1649     struct msg_queue *queue = get_current_queue();
1650
1651     reply->previous = 0;
1652     if (queue && check_queue_input_window( queue, req->handle ))
1653     {
1654         if (!req->handle || make_window_active( req->handle ))
1655         {
1656             reply->previous = queue->input->active;
1657             queue->input->active = get_user_full_handle( req->handle );
1658         }
1659         else set_error( STATUS_INVALID_HANDLE );
1660     }
1661 }
1662
1663
1664 /* set the current thread capture window */
1665 DECL_HANDLER(set_capture_window)
1666 {
1667     struct msg_queue *queue = get_current_queue();
1668
1669     reply->previous = reply->full_handle = 0;
1670     if (queue && check_queue_input_window( queue, req->handle ))
1671     {
1672         struct thread_input *input = queue->input;
1673
1674         reply->previous = input->capture;
1675         input->capture = get_user_full_handle( req->handle );
1676         input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
1677         input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
1678         reply->full_handle = input->capture;
1679     }
1680 }
1681
1682
1683 /* Set the current thread caret window */
1684 DECL_HANDLER(set_caret_window)
1685 {
1686     struct msg_queue *queue = get_current_queue();
1687
1688     reply->previous = 0;
1689     if (queue && check_queue_input_window( queue, req->handle ))
1690     {
1691         struct thread_input *input = queue->input;
1692
1693         reply->previous  = input->caret;
1694         reply->old_rect  = input->caret_rect;
1695         reply->old_hide  = input->caret_hide;
1696         reply->old_state = input->caret_state;
1697
1698         set_caret_window( input, get_user_full_handle(req->handle) );
1699         input->caret_rect.right  = req->width;
1700         input->caret_rect.bottom = req->height;
1701     }
1702 }
1703
1704
1705 /* Set the current thread caret information */
1706 DECL_HANDLER(set_caret_info)
1707 {
1708     struct msg_queue *queue = get_current_queue();
1709     struct thread_input *input;
1710
1711     if (!queue) return;
1712     input = queue->input;
1713     reply->full_handle = input->caret;
1714     reply->old_rect    = input->caret_rect;
1715     reply->old_hide    = input->caret_hide;
1716     reply->old_state   = input->caret_state;
1717
1718     if (req->handle && get_user_full_handle(req->handle) != input->caret)
1719     {
1720         set_error( STATUS_ACCESS_DENIED );
1721         return;
1722     }
1723     if (req->flags & SET_CARET_POS)
1724     {
1725         input->caret_rect.right  += req->x - input->caret_rect.left;
1726         input->caret_rect.bottom += req->y - input->caret_rect.top;
1727         input->caret_rect.left = req->x;
1728         input->caret_rect.top  = req->y;
1729     }
1730     if (req->flags & SET_CARET_HIDE)
1731     {
1732         input->caret_hide += req->hide;
1733         if (input->caret_hide < 0) input->caret_hide = 0;
1734     }
1735     if (req->flags & SET_CARET_STATE)
1736     {
1737         if (req->state == -1) input->caret_state = !input->caret_state;
1738         else input->caret_state = !!req->state;
1739     }
1740 }