Changeset 281
- Timestamp:
- Nov 2, 2009, 11:32:16 PM (16 years ago)
- Location:
- trunk/src/3rdparty/os2/xsystray
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/3rdparty/os2/xsystray/xsystray.c
r280 r281 1071 1071 1072 1072 static 1073 BOOL WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget, 1074 PSYSTRAYCTLDATA pCtlData) 1075 { 1076 BOOL brc = FALSE; 1073 ULONG WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget, 1074 PSYSTRAYCTLDATA pCtlData) 1075 { 1076 BOOL brc = FALSE; 1077 ULONG xrc = XST_FAIL; 1078 1077 1079 PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser; 1078 1080 … … 1087 1089 pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MINOR; 1088 1090 pCtlData->u.version.ulRevision = XSYSTRAY_VERSION_REVISION; 1089 brc = TRUE;1091 xrc = XST_OK; 1090 1092 } 1091 1093 break; … … 1112 1114 hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &Info); 1113 1115 if (hIcon == NULLHANDLE) 1114 {1115 brc = FALSE;1116 1116 break; 1117 }1118 1117 1119 1118 pData = FindIconData(pSysTrayData, pCtlData->hwndSender, … … 1129 1128 // we didn't change the number of icons so simply invalidate 1130 1129 WinInvalidateRect(pWidget->hwndWidget, NULL, FALSE); 1130 1131 xrc = XST_REPLACED; 1131 1132 } 1132 1133 else … … 1166 1167 1167 1168 WgtXSysTrayUpdateAfterIconAddRemove(pWidget); 1169 1170 xrc = XST_OK; 1168 1171 } 1169 1170 brc = TRUE;1171 1172 } 1172 1173 break; … … 1201 1202 WgtXSysTrayUpdateAfterIconAddRemove(pWidget); 1202 1203 1203 brc = TRUE;1204 xrc = XST_OK; 1204 1205 } 1205 1206 else … … 1213 1214 1214 1215 LOGF(("return %d (WinGetLastError is %x)\n", 1215 brc, WinGetLastError(pWidget->habWidget)));1216 1217 return brc;1216 xrc, WinGetLastError(pWidget->habWidget))); 1217 1218 return xrc; 1218 1219 } 1219 1220 -
trunk/src/3rdparty/os2/xsystray/xsystray.h
r280 r281 40 40 41 41 #define WM_XST_CONTROL (WM_USER + 0) 42 42 // message sent to the system tray server to request an action 43 44 // server action commands 43 45 typedef enum 44 46 { … … 50 52 SYSTRAYCMD_HIDEBALLOON, 51 53 } SYSTRAYCMD; 54 55 // server responses to WM_XST_CONTROL 56 #define XST_OK 0 // command succeeded 57 #define XST_FAIL 1 // command failed 58 #define XST_REPLACED 2 // SYSTRAYCMD_ADDICON replaced the existing icon 52 59 53 60 /* -
trunk/src/3rdparty/os2/xsystray/xsystray_api.c
r280 r281 26 26 #define INCL_WINPOINTERS 27 27 #define INCL_WINHOOKS 28 #define INCL_WINWINDOWMGR 28 29 #include <os2.h> 29 30 … … 33 34 #include <string.h> 34 35 #include <sys/builtin.h> // atomics 36 #include <sys/fmutex.h> // fast mutex 37 #include <sys/smutex.h> // simple mutex 35 38 36 39 static ULONG WM_XST_CREATED = 0; … … 56 59 // sounds sane 57 60 61 typedef struct 62 { 63 HMQ hmq; 64 unsigned cRefs; 65 } HMQREFS, *PHMQREFS; 66 67 static PHMQREFS G_pHmqRefs = NULL; 68 // array of references to each HMQ that we make 69 static size_t G_cHmqRefs = 0; 70 // number of elements in G_pHmqRefs 71 static size_t G_cHmqRefsMax = 0; 72 // maximum number of elements in G_pHmqRefs 73 static _fmutex G_fmtx; 74 // fast mutex to protect 75 static _smutex G_smtx = 0; 76 // simple mutex for xstAddSysTrayIcon() 77 #define HMQREFS_GROW 4 78 // how fast G_pHmqRefs grows when more space is necessary 79 58 80 // @todo to be on the safe side with casting in __atomic_cmpxchg32() we need 59 81 // compile-time assertions like this: … … 78 100 } 79 101 80 static BOOLSendSysTrayCtlMsg(PSYSTRAYCTLDATA pData)102 static ULONG SendSysTrayCtlMsg(PSYSTRAYCTLDATA pData) 81 103 { 82 104 APIRET arc; … … 112 134 113 135 mrc = WinSendMsg(G_hwndSysTray, WM_XST_CONTROL, pData, NULL); 114 if ( mrc == (MRESULT)TRUE &&pData->bAcknowledged)115 return TRUE;136 if (pData->bAcknowledged) 137 return (ULONG)mrc; 116 138 117 139 // if we failed to send the message, it may mean that XCenter was restarted … … 126 148 break; 127 149 } 128 while ( TRUE);129 130 return FALSE;150 while (1); 151 152 return XST_FAIL; 131 153 } 132 154 … … 183 205 /* 184 206 *@@ InputHook: 185 * This is used to intercept posted XST_NOTIFY messages and apply special186 * processing to them (compose a client window-specific notification187 * message, free the NOTIFYDATA structure and post the composed message to188 * the target window).207 * This is used to intercept posted WM_XST_NOTIFY messages and apply 208 * special processing to them (compose a client window-specific 209 * notification message, free the NOTIFYDATA structure and post the 210 * composed message to the target window). 189 211 */ 190 212 … … 243 265 pData->hwndSender = NULLHANDLE; 244 266 245 brc = SendSysTrayCtlMsg(pData) ;267 brc = SendSysTrayCtlMsg(pData) == XST_OK; 246 268 if (brc) 247 269 { … … 302 324 ULONG ulFlags) // in: flags (not currently used, must be 0) 303 325 { 304 BOOL brc; 305 PPIB ppib; 326 BOOL brc; 327 ULONG xrc; 328 PPIB ppib; 329 HAB hab; 330 HMQ hmq; 331 size_t i; 332 306 333 PSYSTRAYCTLDATA pData = AllocSysTrayCtlDataPtr(); 307 334 if (!pData) 308 335 return FALSE; 309 336 310 // install the message hook if not already done so311 // @todo the code is temporary and incorrect, it's just for testing312 // (we should use an array of HMQ to check if we already installed the filter)313 337 if (WM_XST_NOTIFY == 0) 314 {315 338 WM_XST_NOTIFY = WinAddAtom(WinQuerySystemAtomTable(), 316 339 WM_XST_NOTIFY_ATOM); 317 340 318 brc = WinSetHook(WinQueryAnchorBlock(hwnd), 319 HMQ_CURRENT, HK_INPUT, (PFN)InputHook, NULLHANDLE); 320 if (!brc) 341 hab = WinQueryAnchorBlock(hwnd); 342 hmq = WinQueryWindowULong(hwnd, QWL_HMQ); 343 if (hmq == NULLHANDLE) 344 return FALSE; 345 346 // initialize the HMQ refs array 347 // @todo remove _smutex usage when we get into the DLL and initialize 348 // _fmutex + array in the DLL init routine 349 _smutex_request(&G_smtx); 350 if (!G_pHmqRefs) 351 { 352 if (_fmutex_create(&G_fmtx, 0)) 321 353 return FALSE; 322 } 354 G_pHmqRefs = malloc(sizeof(*G_pHmqRefs) * HMQREFS_GROW); 355 if (!G_pHmqRefs) 356 return FALSE; 357 G_cHmqRefs = 0; 358 G_cHmqRefsMax = HMQREFS_GROW; 359 } 360 _smutex_release(&G_smtx); 323 361 324 362 // give all processes temporary access to hIcon … … 332 370 pData->u.icon.ulMsgId = ulMsgId; 333 371 334 brc = SendSysTrayCtlMsg(pData); 372 xrc = SendSysTrayCtlMsg(pData); 373 brc = xrc == XST_OK || xrc == XST_REPLACED; 335 374 336 375 // revoke temporary access to hIcon … … 341 380 FreeSysTrayCtlDataPtr(pData); 342 381 382 if (xrc == XST_OK) 383 { 384 // install the message hook for the new icon to intercept WM_XST_NOTIFY 385 // messages or increase the reference count if already done so 386 brc = FALSE; 387 _fmutex_request(&G_fmtx, _FMR_IGNINT); 388 do 389 { 390 for (i = 0; i < G_cHmqRefs; ++i) 391 if (G_pHmqRefs[i].hmq == hmq) 392 break; 393 if (i < G_cHmqRefs) 394 ++G_pHmqRefs[i].cRefs; 395 else 396 { 397 if (i == G_cHmqRefsMax) 398 { 399 PHMQREFS pNewRefs = realloc(G_pHmqRefs, 400 sizeof(*G_pHmqRefs) * 401 (G_cHmqRefsMax + HMQREFS_GROW)); 402 if (!pNewRefs) 403 break; 404 G_pHmqRefs = pNewRefs; 405 G_cHmqRefsMax += HMQREFS_GROW; 406 } 407 brc = WinSetHook(hab, hmq, HK_INPUT, (PFN)InputHook, NULLHANDLE); 408 if (!brc) 409 break; 410 ++G_cHmqRefs; 411 G_pHmqRefs[i].hmq = hmq; 412 G_pHmqRefs[i].cRefs = 1; 413 } 414 brc = TRUE; 415 } 416 while (0); 417 _fmutex_release(&G_fmtx); 418 419 if (!brc) 420 xstRemoveSysTrayIcon(hwnd, usId); 421 } 422 343 423 return brc; 344 424 } … … 355 435 BOOL xstRemoveSysTrayIcon(HWND hwnd, // in: window handle associated with the icon 356 436 USHORT usId) // in: icon ID to remove 437 { 438 BOOL brc; 439 HAB hab; 440 HMQ hmq; 441 size_t i; 442 443 PSYSTRAYCTLDATA pData = AllocSysTrayCtlDataPtr(); 444 if (!pData) 445 return FALSE; 446 447 hab = WinQueryAnchorBlock(hwnd); 448 hmq = WinQueryWindowULong(hwnd, QWL_HMQ); 449 if (hmq == NULLHANDLE) 450 return FALSE; 451 452 pData->ulCommand = SYSTRAYCMD_REMOVEICON; 453 pData->hwndSender = hwnd; 454 pData->u.icon.usId = usId; 455 456 brc = SendSysTrayCtlMsg(pData) == XST_OK; 457 458 FreeSysTrayCtlDataPtr(pData); 459 460 if (brc) 461 { 462 // remove the message hook if it's the last reference to the HMQ 463 _fmutex_request(&G_fmtx, _FMR_IGNINT); 464 do 465 { 466 for (i = 0; i < G_cHmqRefs; ++i) 467 if (G_pHmqRefs[i].hmq == hmq) 468 break; 469 if (i == G_cHmqRefs) 470 // unknown HMQ?? 471 break; 472 473 if (--G_pHmqRefs[i].cRefs == 0) 474 WinReleaseHook(hab, hmq, HK_INPUT, (PFN)InputHook, NULLHANDLE); 475 } 476 while (0); 477 _fmutex_release(&G_fmtx); 478 } 479 480 return brc; 481 } 482 483 /* 484 *@@ xstSetSysTrayIconToolTip: 485 * 486 * Sets the tooltip text for the given icon in the system tray. This text 487 * is shown when the mouse pointer is held still over the icon area for 488 * some time. 489 * 490 * If pszText is NULL, the tooltip text is reset and will not be shown next 491 * time. The old tooltip is hidden if it is being currently shown. 492 * 493 * Returns TRUE on success and FALSE otherwise. 494 * 495 * NOTE: The maximum tooltip text length (including terminating null) is 496 * limited to a value returned by xstGetSysTrayMaxTextLen(). If the 497 * supplied string is longer, it will be truncated. 498 */ 499 500 BOOL xstSetSysTrayIconToolTip(HWND hwnd, // in: window handle associated with the icon 501 USHORT usId, // in: icon ID to set the tooltip for 502 PSZ pszText) // in: tooltip text 357 503 { 358 504 BOOL brc; … … 361 507 return FALSE; 362 508 363 pData->ulCommand = SYSTRAYCMD_REMOVEICON;364 pData->hwndSender = hwnd;365 pData->u.icon.usId = usId;366 367 brc = SendSysTrayCtlMsg(pData);368 369 FreeSysTrayCtlDataPtr(pData);370 371 return brc;372 }373 374 /*375 *@@ xstSetSysTrayIconToolTip:376 *377 * Sets the tooltip text for the given icon in the system tray. This text378 * is shown when the mouse pointer is held still over the icon area for379 * some time.380 *381 * If pszText is NULL, the tooltip text is reset and will not be shown next382 * time. The old tooltip is hidden if it is being currently shown.383 *384 * Returns TRUE on success and FALSE otherwise.385 *386 * NOTE: The maximum tooltip text length (including terminating null) is387 * limited to a value returned by xstGetSysTrayMaxTextLen(). If the388 * supplied string is longer, it will be truncated.389 */390 391 BOOL xstSetSysTrayIconToolTip(HWND hwnd, // in: window handle associated with the icon392 USHORT usId, // in: icon ID to set the tooltip for393 PSZ pszText) // in: tooltip text394 {395 BOOL brc;396 PSYSTRAYCTLDATA pData = AllocSysTrayCtlDataPtr();397 if (!pData)398 return FALSE;399 400 509 pData->ulCommand = SYSTRAYCMD_SETTOOLTIP; 401 510 pData->hwndSender = hwnd; … … 412 521 } 413 522 414 brc = SendSysTrayCtlMsg(pData) ;523 brc = SendSysTrayCtlMsg(pData) == XST_OK; 415 524 416 525 FreeSysTrayCtlDataPtr(pData);
Note:
See TracChangeset
for help on using the changeset viewer.