queue.c 6.7 KB

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