Poll X events in GetInputState the same way as in GetQueueStatus.
[wine] / windows / queue.c
1 /*
2  * Message queues related functions
3  *
4  * Copyright 1993, 1994 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 <string.h>
22 #include <signal.h>
23 #include <assert.h>
24 #include "windef.h"
25 #include "wingdi.h"
26 #include "winerror.h"
27 #include "wine/winbase16.h"
28 #include "wine/winuser16.h"
29 #include "message.h"
30 #include "win.h"
31 #include "user.h"
32 #include "thread.h"
33 #include "wine/debug.h"
34 #include "wine/server.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(msg);
37
38
39 /***********************************************************************
40  *           QUEUE_CreateMsgQueue
41  *
42  * Creates a message queue. Doesn't link it into queue list!
43  */
44 static HQUEUE16 QUEUE_CreateMsgQueue(void)
45 {
46     HQUEUE16 hQueue;
47     HANDLE handle;
48     MESSAGEQUEUE * msgQueue;
49
50     TRACE_(msg)("(): Creating message queue...\n");
51
52     if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT,
53                                   sizeof(MESSAGEQUEUE) )))
54         return 0;
55
56     msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
57     if ( !msgQueue )
58         return 0;
59
60     SERVER_START_REQ( get_msg_queue )
61     {
62         wine_server_call_err( req );
63         handle = reply->handle;
64     }
65     SERVER_END_REQ;
66     if (!handle)
67     {
68         ERR_(msg)("Cannot get thread queue");
69         GlobalFree16( hQueue );
70         return 0;
71     }
72     msgQueue->server_queue = handle;
73     msgQueue->self = hQueue;
74     return hQueue;
75 }
76
77
78 /***********************************************************************
79  *           QUEUE_Current
80  *
81  * Get the current thread queue, creating it if required.
82  * QUEUE_Unlock is not needed since the queue can only be deleted by
83  * the current thread anyway.
84  */
85 MESSAGEQUEUE *QUEUE_Current(void)
86 {
87     HQUEUE16 hQueue = NtCurrentTeb()->queue;
88
89     if (!hQueue)
90     {
91         if (!(hQueue = QUEUE_CreateMsgQueue())) return NULL;
92         SetThreadQueue16( 0, hQueue );
93     }
94
95     return GlobalLock16( hQueue );
96 }
97
98
99
100 /***********************************************************************
101  *           QUEUE_DeleteMsgQueue
102  *
103  * Delete a message queue.
104  */
105 void QUEUE_DeleteMsgQueue(void)
106 {
107     HQUEUE16 hQueue = NtCurrentTeb()->queue;
108     MESSAGEQUEUE * msgQueue;
109
110     if (!hQueue) return;  /* thread doesn't have a queue */
111
112     TRACE("(): Deleting message queue %04x\n", hQueue);
113
114     if (!(msgQueue = GlobalLock16( hQueue )))
115     {
116         ERR("invalid thread queue\n");
117         return;
118     }
119
120     SetThreadQueue16( 0, 0 );
121     CloseHandle( msgQueue->server_queue );
122     GlobalFree16( hQueue );
123 }
124
125
126 /***********************************************************************
127  *              InitThreadInput   (USER.409)
128  */
129 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
130 {
131     MESSAGEQUEUE *queue = QUEUE_Current();
132     return queue ? queue->self : 0;
133 }
134
135 /***********************************************************************
136  *              GetQueueStatus (USER32.@)
137  */
138 DWORD WINAPI GetQueueStatus( UINT flags )
139 {
140     DWORD ret = 0;
141
142     /* check for pending X events */
143     if (USER_Driver.pMsgWaitForMultipleObjectsEx)
144         USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
145
146     SERVER_START_REQ( get_queue_status )
147     {
148         req->clear = 1;
149         wine_server_call( req );
150         ret = MAKELONG( reply->changed_bits & flags, reply->wake_bits & flags );
151     }
152     SERVER_END_REQ;
153     return ret;
154 }
155
156
157 /***********************************************************************
158  *              GetInputState   (USER32.@)
159  */
160 BOOL WINAPI GetInputState(void)
161 {
162     DWORD ret = 0;
163
164     /* check for pending X events */
165     if (USER_Driver.pMsgWaitForMultipleObjectsEx)
166         USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
167
168     SERVER_START_REQ( get_queue_status )
169     {
170         req->clear = 0;
171         wine_server_call( req );
172         ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON);
173     }
174     SERVER_END_REQ;
175     return ret;
176 }
177
178 /***********************************************************************
179  *              GetMessagePos (USER.119)
180  *              GetMessagePos (USER32.@)
181  *
182  * The GetMessagePos() function returns a long value representing a
183  * cursor position, in screen coordinates, when the last message
184  * retrieved by the GetMessage() function occurs. The x-coordinate is
185  * in the low-order word of the return value, the y-coordinate is in
186  * the high-order word. The application can use the MAKEPOINT()
187  * macro to obtain a POINT structure from the return value.
188  *
189  * For the current cursor position, use GetCursorPos().
190  *
191  * RETURNS
192  *
193  * Cursor position of last message on success, zero on failure.
194  *
195  * CONFORMANCE
196  *
197  * ECMA-234, Win32
198  *
199  */
200 DWORD WINAPI GetMessagePos(void)
201 {
202     MESSAGEQUEUE *queue;
203
204     if (!(queue = QUEUE_Current())) return 0;
205     return queue->GetMessagePosVal;
206 }
207
208
209 /***********************************************************************
210  *              GetMessageTime (USER.120)
211  *              GetMessageTime (USER32.@)
212  *
213  * GetMessageTime() returns the message time for the last message
214  * retrieved by the function. The time is measured in milliseconds with
215  * the same offset as GetTickCount().
216  *
217  * Since the tick count wraps, this is only useful for moderately short
218  * relative time comparisons.
219  *
220  * RETURNS
221  *
222  * Time of last message on success, zero on failure.
223  *
224  * CONFORMANCE
225  *
226  * ECMA-234, Win32
227  *
228  */
229 LONG WINAPI GetMessageTime(void)
230 {
231     MESSAGEQUEUE *queue;
232
233     if (!(queue = QUEUE_Current())) return 0;
234     return queue->GetMessageTimeVal;
235 }
236
237
238 /***********************************************************************
239  *              GetMessageExtraInfo (USER.288)
240  *              GetMessageExtraInfo (USER32.@)
241  */
242 LONG WINAPI GetMessageExtraInfo(void)
243 {
244     MESSAGEQUEUE *queue;
245
246     if (!(queue = QUEUE_Current())) return 0;
247     return queue->GetMessageExtraInfoVal;
248 }