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
27 #include "wine/winbase16.h"
28 #include "wine/winuser16.h"
34 #include "wine/debug.h"
35 #include "wine/server.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
41 /***********************************************************************
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
)
53 HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
54 queue
= GlobalLock16( hQueue
);
55 if ( !queue
|| (queue
->magic
!= QUEUE_MAGIC
) )
57 HeapUnlock( GetProcessHeap() );
62 HeapUnlock( GetProcessHeap() );
67 /***********************************************************************
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)
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
;
92 /***********************************************************************
95 * Use with QUEUE_Lock to get a thread safe access to message queue
98 void QUEUE_Unlock( MESSAGEQUEUE
*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
)
125 MESSAGEQUEUE
* msgQueue
;
127 TRACE_(msg
)("(): Creating message queue...\n");
129 if (!(hQueue
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
,
130 sizeof(MESSAGEQUEUE
) )))
133 msgQueue
= (MESSAGEQUEUE
*) GlobalLock16( hQueue
);
139 SERVER_START_REQ( get_msg_queue
)
141 wine_server_call_err( req
);
142 handle
= reply
->handle
;
147 ERR_(msg
)("Cannot get thread queue");
148 GlobalFree16( hQueue
);
151 msgQueue
->server_queue
= handle
;
154 msgQueue
->self
= hQueue
;
155 msgQueue
->lockCount
= 1;
156 msgQueue
->magic
= QUEUE_MAGIC
;
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");
186 SetThreadQueue16( 0, 0 );
188 /* free up resource used by MESSAGEQUEUE structure */
189 msgQueue
->lockCount
--;
190 QUEUE_Unlock( msgQueue
);
194 /***********************************************************************
195 * InitThreadInput (USER.409)
197 HQUEUE16 WINAPI
InitThreadInput16( WORD unknown
, WORD flags
)
199 MESSAGEQUEUE
*queuePtr
;
200 HQUEUE16 hQueue
= NtCurrentTeb()->queue
;
204 /* Create thread message queue */
205 if( !(hQueue
= QUEUE_CreateMsgQueue( TRUE
)))
207 ERR_(msg
)("failed!\n");
211 /* Link new queue into list */
212 queuePtr
= QUEUE_Lock( hQueue
);
214 HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
215 SetThreadQueue16( 0, hQueue
);
216 NtCurrentTeb()->queue
= hQueue
;
217 HeapUnlock( GetProcessHeap() );
219 QUEUE_Unlock( queuePtr
);
225 /***********************************************************************
226 * GetQueueStatus (USER32.@)
228 DWORD WINAPI
GetQueueStatus( UINT flags
)
232 SERVER_START_REQ( get_queue_status
)
235 wine_server_call( req
);
236 ret
= MAKELONG( reply
->changed_bits
& flags
, reply
->wake_bits
& flags
);
243 /***********************************************************************
244 * GetInputState (USER32.@)
246 BOOL WINAPI
GetInputState(void)
250 SERVER_START_REQ( get_queue_status
)
253 wine_server_call( req
);
254 ret
= reply
->wake_bits
& (QS_KEY
| QS_MOUSEBUTTON
);
260 /***********************************************************************
261 * GetMessagePos (USER.119)
262 * GetMessagePos (USER32.@)
264 * The GetMessagePos() function returns a long value representing a
265 * cursor position, in screen coordinates, when the last message
266 * retrieved by the GetMessage() function occurs. The x-coordinate is
267 * in the low-order word of the return value, the y-coordinate is in
268 * the high-order word. The application can use the MAKEPOINT()
269 * macro to obtain a POINT structure from the return value.
271 * For the current cursor position, use GetCursorPos().
275 * Cursor position of last message on success, zero on failure.
282 DWORD WINAPI
GetMessagePos(void)
286 if (!(queue
= QUEUE_Current())) return 0;
287 return queue
->GetMessagePosVal
;
291 /***********************************************************************
292 * GetMessageTime (USER.120)
293 * GetMessageTime (USER32.@)
295 * GetMessageTime() returns the message time for the last message
296 * retrieved by the function. The time is measured in milliseconds with
297 * the same offset as GetTickCount().
299 * Since the tick count wraps, this is only useful for moderately short
300 * relative time comparisons.
304 * Time of last message on success, zero on failure.
311 LONG WINAPI
GetMessageTime(void)
315 if (!(queue
= QUEUE_Current())) return 0;
316 return queue
->GetMessageTimeVal
;
320 /***********************************************************************
321 * GetMessageExtraInfo (USER.288)
322 * GetMessageExtraInfo (USER32.@)
324 LONG WINAPI
GetMessageExtraInfo(void)
328 if (!(queue
= QUEUE_Current())) return 0;
329 return queue
->GetMessageExtraInfoVal
;