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