Compile the mpr dll with STRICT defined.
[wine/wine-kai.git] / windows / queue.c
blobf6d5bb8e9b88bdc6517e7b0151f0da87d613b32b
1 /*
2 * Message queues related functions
4 * Copyright 1993, 1994 Alexandre Julliard
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.
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.
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
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 "queue.h"
30 #include "win.h"
31 #include "user.h"
32 #include "hook.h"
33 #include "thread.h"
34 #include "wine/debug.h"
35 #include "wine/server.h"
36 #include "spy.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msg);
41 /***********************************************************************
42 * QUEUE_Lock
44 * Function for getting a 32 bit pointer on queue structure. For thread
45 * safeness programmers should use this function instead of GlobalLock to
46 * retrieve a pointer on the structure. QUEUE_Unlock should also be called
47 * when access to the queue structure is not required anymore.
49 MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue )
51 MESSAGEQUEUE *queue;
53 HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
54 queue = GlobalLock16( hQueue );
55 if ( !queue || (queue->magic != QUEUE_MAGIC) )
57 HeapUnlock( GetProcessHeap() );
58 return NULL;
61 queue->lockCount++;
62 HeapUnlock( GetProcessHeap() );
63 return queue;
67 /***********************************************************************
68 * QUEUE_Current
70 * Get the current thread queue, creating it if required.
71 * QUEUE_Unlock is not needed since the queue can only be deleted by
72 * the current thread anyway.
74 MESSAGEQUEUE *QUEUE_Current(void)
76 MESSAGEQUEUE *queue;
77 HQUEUE16 hQueue;
79 if (!(hQueue = GetThreadQueue16(0)))
81 if (!(hQueue = InitThreadInput16( 0, 0 ))) return NULL;
84 if ((queue = GlobalLock16( hQueue )))
86 if (queue->magic != QUEUE_MAGIC) queue = NULL;
88 return queue;
92 /***********************************************************************
93 * QUEUE_Unlock
95 * Use with QUEUE_Lock to get a thread safe access to message queue
96 * structure
98 void QUEUE_Unlock( MESSAGEQUEUE *queue )
100 if (queue)
102 HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
104 if ( --queue->lockCount == 0 )
106 if (queue->server_queue)
107 CloseHandle( queue->server_queue );
108 GlobalFree16( queue->self );
111 HeapUnlock( GetProcessHeap() );
116 /***********************************************************************
117 * QUEUE_CreateMsgQueue
119 * Creates a message queue. Doesn't link it into queue list!
121 static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
123 HQUEUE16 hQueue;
124 HANDLE handle;
125 MESSAGEQUEUE * msgQueue;
127 TRACE_(msg)("(): Creating message queue...\n");
129 if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT,
130 sizeof(MESSAGEQUEUE) )))
131 return 0;
133 msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
134 if ( !msgQueue )
135 return 0;
137 if (bCreatePerQData)
139 SERVER_START_REQ( get_msg_queue )
141 wine_server_call_err( req );
142 handle = reply->handle;
144 SERVER_END_REQ;
145 if (!handle)
147 ERR_(msg)("Cannot get thread queue");
148 GlobalFree16( hQueue );
149 return 0;
151 msgQueue->server_queue = handle;
154 msgQueue->self = hQueue;
155 msgQueue->lockCount = 1;
156 msgQueue->magic = QUEUE_MAGIC;
157 return hQueue;
161 /***********************************************************************
162 * QUEUE_DeleteMsgQueue
164 * Unlinks and deletes a message queue.
166 * Note: We need to mask asynchronous events to make sure PostMessage works
167 * even in the signal handler.
169 void QUEUE_DeleteMsgQueue(void)
171 HQUEUE16 hQueue = GetThreadQueue16(0);
172 MESSAGEQUEUE * msgQueue;
174 if (!hQueue) return; /* thread doesn't have a queue */
176 TRACE("(): Deleting message queue %04x\n", hQueue);
178 if (!(msgQueue = QUEUE_Lock(hQueue)))
180 ERR("invalid thread queue\n");
181 return;
184 msgQueue->magic = 0;
185 msgQueue->self = 0;
186 SetThreadQueue16( 0, 0 );
188 /* free up resource used by MESSAGEQUEUE structure */
189 msgQueue->lockCount--;
190 QUEUE_Unlock( msgQueue );
194 /***********************************************************************
195 * GetWindowTask (USER.224)
197 HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
199 HTASK16 retvalue;
200 MESSAGEQUEUE *queue;
202 WND *wndPtr = WIN_FindWndPtr16( hwnd );
203 if (!wndPtr) return 0;
205 queue = QUEUE_Lock( wndPtr->hmemTaskQ );
206 WIN_ReleaseWndPtr(wndPtr);
208 if (!queue) return 0;
210 retvalue = queue->teb->htask16;
211 QUEUE_Unlock( queue );
213 return retvalue;
216 /***********************************************************************
217 * InitThreadInput (USER.409)
219 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
221 MESSAGEQUEUE *queuePtr;
222 HQUEUE16 hQueue = NtCurrentTeb()->queue;
224 if ( !hQueue )
226 /* Create thread message queue */
227 if( !(hQueue = QUEUE_CreateMsgQueue( TRUE )))
229 ERR_(msg)("failed!\n");
230 return FALSE;
233 /* Link new queue into list */
234 queuePtr = QUEUE_Lock( hQueue );
235 queuePtr->teb = NtCurrentTeb();
237 HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
238 SetThreadQueue16( 0, hQueue );
239 NtCurrentTeb()->queue = hQueue;
240 HeapUnlock( GetProcessHeap() );
242 QUEUE_Unlock( queuePtr );
245 return hQueue;
248 /***********************************************************************
249 * GetQueueStatus (USER32.@)
251 DWORD WINAPI GetQueueStatus( UINT flags )
253 DWORD ret = 0;
255 SERVER_START_REQ( get_queue_status )
257 req->clear = 1;
258 wine_server_call( req );
259 ret = MAKELONG( reply->changed_bits & flags, reply->wake_bits & flags );
261 SERVER_END_REQ;
262 return ret;
266 /***********************************************************************
267 * GetInputState (USER32.@)
269 BOOL WINAPI GetInputState(void)
271 DWORD ret = 0;
273 SERVER_START_REQ( get_queue_status )
275 req->clear = 0;
276 wine_server_call( req );
277 ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON);
279 SERVER_END_REQ;
280 return ret;
283 /***********************************************************************
284 * GetMessagePos (USER.119)
285 * GetMessagePos (USER32.@)
287 * The GetMessagePos() function returns a long value representing a
288 * cursor position, in screen coordinates, when the last message
289 * retrieved by the GetMessage() function occurs. The x-coordinate is
290 * in the low-order word of the return value, the y-coordinate is in
291 * the high-order word. The application can use the MAKEPOINT()
292 * macro to obtain a POINT structure from the return value.
294 * For the current cursor position, use GetCursorPos().
296 * RETURNS
298 * Cursor position of last message on success, zero on failure.
300 * CONFORMANCE
302 * ECMA-234, Win32
305 DWORD WINAPI GetMessagePos(void)
307 MESSAGEQUEUE *queue;
309 if (!(queue = QUEUE_Current())) return 0;
310 return queue->GetMessagePosVal;
314 /***********************************************************************
315 * GetMessageTime (USER.120)
316 * GetMessageTime (USER32.@)
318 * GetMessageTime() returns the message time for the last message
319 * retrieved by the function. The time is measured in milliseconds with
320 * the same offset as GetTickCount().
322 * Since the tick count wraps, this is only useful for moderately short
323 * relative time comparisons.
325 * RETURNS
327 * Time of last message on success, zero on failure.
329 * CONFORMANCE
331 * ECMA-234, Win32
334 LONG WINAPI GetMessageTime(void)
336 MESSAGEQUEUE *queue;
338 if (!(queue = QUEUE_Current())) return 0;
339 return queue->GetMessageTimeVal;
343 /***********************************************************************
344 * GetMessageExtraInfo (USER.288)
345 * GetMessageExtraInfo (USER32.@)
347 LONG WINAPI GetMessageExtraInfo(void)
349 MESSAGEQUEUE *queue;
351 if (!(queue = QUEUE_Current())) return 0;
352 return queue->GetMessageExtraInfoVal;