Changeset 256 for trunk/src/3rdparty/os2/xsystray
- Timestamp:
- Oct 27, 2009, 2:36:55 AM (16 years ago)
- Location:
- trunk/src/3rdparty/os2/xsystray
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/3rdparty/os2/xsystray/xsystray.c
r255 r256 40 40 #include <stdio.h> 41 41 #include <string.h> 42 #include <stdlib.h> 43 #include <stdarg.h> 42 44 43 45 // generic headers … … 73 75 #pragma hdrstop // VAC++ keeps crashing otherwise 74 76 77 // primitive debug logging to a file 78 #if 1 79 static void __LOG_WORKER(const char *fmt, ...) 80 { 81 static FILE *f = NULL; 82 if (f == NULL) 83 { 84 f = fopen("c:\\xsystray.dbg", "a"); 85 setbuf(f, NULL); 86 } 87 if (f != NULL) 88 { 89 va_list vl; 90 va_start(vl, fmt); 91 vfprintf(f, fmt, vl); 92 va_end(vl); 93 } 94 } 95 #define LOG(m) do { __LOG_WORKER m; } while(0) 96 #define LOGF(m) do { __LOG_WORKER("%s: ", __FUNCTION__); __LOG_WORKER m; } while(0) 97 #else 98 #define LOG(m) do {} while (0) 99 #define LOGF(m) do {} while (0) 100 #endif 101 75 102 /* ****************************************************************** 76 103 * … … 79 106 ********************************************************************/ 80 107 81 // None currently. 108 /* 109 *@@ ICONDATA: 110 * Per-icon data. 111 */ 112 113 typedef struct _ICONDATA 114 { 115 HWND hwnd; 116 // associated window 117 ULONG ulId; 118 // icon ID 119 HPOINTER hIcon; 120 // icon handle 121 ULONG ulMsgId; 122 // message ID for notifications 123 PSZ pszToolTip; 124 // icon tooltip (NULL if none) 125 126 } ICONDATA, *PICONDATA; 127 128 /* 129 *@@ SYSTRAYDATA: 130 * Global system tray data. 131 */ 132 133 typedef struct 134 { 135 PICONDATA pIcons; 136 // array of icons currently shown in the system tray 137 // (left to right) 138 size_t cIcons; 139 // number of icons in the pIcons array 140 size_t cIconsMax; 141 // maximum number of icons pIcons can fit 142 143 } SYSTRAYDATA, *PSYSTRAYDATA; 144 145 ULONG QWL_USER_SERVER_DATA = 0; 82 146 83 147 /* ****************************************************************** … … 196 260 */ 197 261 262 static 198 263 BOOL WgtControl(PXCENTERWIDGET pWidget, 199 264 MPARAM mp1, … … 240 305 */ 241 306 307 static 242 308 VOID WgtPaint(HWND hwnd, 243 309 PXCENTERWIDGET pWidget) … … 274 340 /* 275 341 *@@ fnwpXSysTray: 276 * window procedure for the winlistwidget class.342 * window procedure for the Extended system tray widget class. 277 343 * 278 344 * There are a few rules which widget window procs … … 311 377 312 378 case WM_CREATE: 379 { 380 PSYSTRAYDATA pSysTrayData = NULL; 381 382 mrc = (MPARAM)TRUE; // being pessimistic gives more compact code 383 313 384 WinSetWindowPtr(hwnd, QWL_USER, mp1); 314 385 if ( (!(pWidget = (PXCENTERWIDGET)mp1)) … … 316 387 ) 317 388 // shouldn't happen... stop window creation!! 318 mrc = (MPARAM)TRUE; 389 break; 390 391 pSysTrayData = malloc(sizeof(*pSysTrayData)); 392 if (pSysTrayData == NULL) 393 break; 394 395 // initialize the SYSTRAYDATA structure 396 pSysTrayData->cIconsMax = 4; 397 pSysTrayData->pIcons = malloc(sizeof(*pSysTrayData->pIcons) * 398 pSysTrayData->cIconsMax); 399 if (pSysTrayData->pIcons == NULL) 400 { 401 free(pSysTrayData); 402 break; 403 } 404 pSysTrayData->cIcons = 0; 405 pWidget->pUser = pSysTrayData; 406 407 // create the "server" window (note that we pass the XCENTERWIDGET 408 // pointer on to it) 409 HWND hwndServer = 410 WinCreateWindow(HWND_DESKTOP, WNDCLASS_WIDGET_XSYSTRAY_SERVER, 411 NULL, WS_MINIMIZED, 412 0, 0, 0, 0, 413 HWND_DESKTOP, HWND_BOTTOM, 414 0, mp1, NULL); 415 if (hwndServer == NULLHANDLE) 416 break; 417 418 mrc = FALSE; // confirm success 419 } 319 420 break; 320 421 … … 353 454 354 455 case WM_DESTROY: 355 // If we had any user data allocated in WM_CREATE 356 // or elsewhere, we'd clean this up here. 456 { 457 // free all system tray data 458 PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser; 459 size_t i; 460 for (i = 0; i < pSysTrayData->cIcons; ++i) 461 { 462 if (pSysTrayData->pIcons[i].pszToolTip) 463 free(pSysTrayData->pIcons[i].pszToolTip); 464 } 465 free(pSysTrayData->pIcons); 466 free(pSysTrayData); 467 pWidget->pUser = NULL; 357 468 // We _MUST_ pass this on, or the default widget proc 358 469 // cannot clean up. 359 470 mrc = pWidget->pfnwpDefWidgetProc(hwnd, msg, mp1, mp2); 471 } 360 472 break; 361 473 … … 363 475 mrc = pWidget->pfnwpDefWidgetProc(hwnd, msg, mp1, mp2); 364 476 477 } // end switch(msg) 478 479 return mrc; 480 } 481 482 /* 483 *@@ WgtXSysTrayControl: 484 * implementation for WM_XST_CONTROL in fnwpXSysTrayServer. 485 * 486 * Serves as an entry point for all client-side requests to the Extended 487 * system tray. 488 * 489 * Note that this message is being sent from another process which is 490 * awaiting for an answer, so it must return as far as possible (by 491 * rescheduling any potentially long term operation for another cycle). 492 */ 493 494 static 495 BOOL WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget, 496 PSYSTRAYCTLDATA pCtlData) 497 { 498 BOOL brc = FALSE; 499 500 switch (pCtlData->ulCommand) 501 { 502 case SYSTRAYCMD_GETVERSION: 503 { 504 LOGF(("SYSTRAYCMD_GETVERSION\n")); 505 506 pCtlData->bAcknowledged = TRUE; 507 pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MAJOR; 508 pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MINOR; 509 pCtlData->u.version.ulRevision = XSYSTRAY_VERSION_REVISION; 510 brc = TRUE; 511 } 512 break; 513 514 default: 515 break; 516 } 517 518 return brc; 519 } 520 521 /* 522 *@@ fnwpXSysTrayServer: 523 * window procedure for the Extended system tray server window class. 524 * 525 * A separate "server" class is necessary because we need a CS_FRAME 526 * top-level window for DDE (which we need to support to be backward 527 * compatible with the System tray wdget from the SysTray/WPS package) and 528 * also to make ourselves discoverable for the client-side implementation 529 * of our new extended API (which queries the class of each top-level 530 * window to find the system tray server). 531 */ 532 533 static 534 MRESULT EXPENTRY fnwpXSysTrayServer(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 535 { 536 MRESULT mrc = 0; 537 // get widget data from QWL_USER_SERVER_DATA (stored there by WM_CREATE) 538 PXCENTERWIDGET pWidget = 539 (PXCENTERWIDGET)WinQueryWindowPtr(hwnd, QWL_USER_SERVER_DATA); 540 // this ptr is valid after WM_CREATE 541 542 switch (msg) 543 { 544 case WM_CREATE: 545 WinSetWindowPtr(hwnd, QWL_USER_SERVER_DATA, mp1); 546 break; 547 548 /* 549 * WM_XST_CONTROL: 550 * This is the message sent to us by the clinet-side implementation 551 * of the API to request some function. mp1 points to a 552 * SYSTRAYCTLDATA structure. 553 */ 554 555 case WM_XST_CONTROL: 556 mrc = (MRESULT)WgtXSysTrayControl(hwnd, pWidget, 557 (PSYSTRAYCTLDATA)mp1); 558 break; 559 560 default: 561 mrc = WinDefWindowProc(hwnd, msg, mp1, mp2); 365 562 } // end switch(msg) 366 563 … … 428 625 PSZ pszErrorMsg) // if 0 is returned, 500 bytes of error msg 429 626 { 430 ULONG ulrc = 0; 431 432 // register our PM window class 433 if (!WinRegisterClass(hab, 434 WNDCLASS_WIDGET_XSYSTRAY, 435 fnwpXSysTray, 436 CS_PARENTCLIP | CS_SIZEREDRAW | CS_SYNCPAINT, 437 sizeof(PVOID)) 627 ULONG ulrc = 0; 628 CLASSINFO ClassInfo; 629 630 LOGF(("hmodPlugin %x\n", hmodPlugin)); 631 632 do 633 { 634 // register our PM window class 635 if (!WinRegisterClass(hab, 636 WNDCLASS_WIDGET_XSYSTRAY, 637 fnwpXSysTray, 638 CS_PARENTCLIP | CS_SIZEREDRAW | CS_SYNCPAINT, 639 sizeof(PVOID)) 438 640 // extra memory to reserve for QWL_USER 439 ) 440 // error registering class: report error then 441 strcpy(pszErrorMsg, "WinRegisterClass failed."); 442 else 443 { 641 ) 642 { 643 LOG(("WinRegisterClass(%s) failed with %lX", 644 WNDCLASS_WIDGET_XSYSTRAY, WinGetLastError(hab))); 645 break; 646 } 647 648 // get the window data size for the WC_FRAME class (any window class 649 // that specifies CS_FRAME must have at least this number, otherise 650 // WinRegisterClass returns 0x1003 651 if (!WinQueryClassInfo(hab, (PSZ)WC_FRAME, &ClassInfo)) 652 break; 653 QWL_USER_SERVER_DATA = ClassInfo.cbWindowData; 654 655 if (!WinRegisterClass(hab, 656 WNDCLASS_WIDGET_XSYSTRAY_SERVER, 657 fnwpXSysTrayServer, 658 CS_FRAME, 659 QWL_USER_SERVER_DATA + sizeof(PVOID)) 660 // extra memory to reserve for QWL_USER 661 ) 662 { 663 // error registering class: report error then 664 snprintf(pszErrorMsg, 500, "WinRegisterClass(%s) failed with %lX", 665 WNDCLASS_WIDGET_XSYSTRAY_SERVER, WinGetLastError(hab)); 666 break; 667 } 668 444 669 // no error: 445 670 // return widget classes array … … 449 674 ulrc = sizeof(G_WidgetClasses) / sizeof(G_WidgetClasses[0]); 450 675 } 676 while (0); 677 678 LOGF(("pszErrorMsg %s\n", pszErrorMsg)); 679 LOGF(("ulrc %d\n", ulrc)); 451 680 452 681 return ulrc; … … 489 718 { 490 719 *pulMajor = 0; 491 *pulMinor = 1;492 *pulRevision = 0;493 } 494 720 *pulMinor = 9; 721 *pulRevision = 9; 722 } 723 -
trunk/src/3rdparty/os2/xsystray/xsystray.h
r255 r256 16 16 #ifndef XSYSTRAY_HEADER_INCLUDED 17 17 #define XSYSTRAY_HEADER_INCLUDED 18 19 #define XSYSTRAY_VERSION_MAJOR 0 20 #define XSYSTRAY_VERSION_MINOR 1 21 #define XSYSTRAY_VERSION_REVISION 0 18 22 19 23 #define WNDCLASS_WIDGET_XSYSTRAY_SERVER "XWPCenterExtendedSysTrayServer" … … 35 39 } SYSTRAYCMD; 36 40 37 // NOTE: the idea is to fit SYSTRAY MSGDATA into a page (4K) since this is the41 // NOTE: the idea is to fit SYSTRAYCTLDATA into a page (4K) since this is the 38 42 // smallest piece DosAllocSharedMem() allocates anyway. 39 43 typedef struct … … 73 77 // set to true by the recipient if it processes the message 74 78 75 } SYSTRAY MSGDATA, *PSYSTRAYMSGDATA;79 } SYSTRAYCTLDATA, *PSYSTRAYCTLDATA; 76 80 77 81 #endif // XSYSTRAY_HEADER_INCLUDED -
trunk/src/3rdparty/os2/xsystray/xsystray_api.c
r255 r256 27 27 28 28 static HWND G_hwndSysTray = NULLHANDLE; 29 static int G_itlsSysTray MsgData = -1;29 static int G_itlsSysTrayCtlData = -1; 30 30 31 31 static HWND FindSysTrayWindow() … … 46 46 } 47 47 48 static BOOL SendSysTrayCtlMsg(PSYSTRAY MSGDATA pData)48 static BOOL SendSysTrayCtlMsg(PSYSTRAYCTLDATA pData) 49 49 { 50 50 APIRET arc; … … 70 70 arc = ERROR_INVALID_HANDLE; 71 71 if (WinQueryWindowProcess(G_hwndSysTray, &pid, &tid)) 72 arc = DosGiveSharedMem(__libc_TLSGet(G_itlsSysTray MsgData),72 arc = DosGiveSharedMem(__libc_TLSGet(G_itlsSysTrayCtlData), 73 73 pid, PAG_READ | PAG_WRITE); 74 74 if (arc != NO_ERROR) … … 80 80 mrc = WinSendMsg(G_hwndSysTray, WM_XST_CONTROL, pData, NULL); 81 81 if (mrc == (MRESULT)TRUE && pData->bAcknowledged) 82 break;82 return TRUE; 83 83 84 84 // if we failed to send the message, it may mean that XCenter was restarted … … 98 98 } 99 99 100 static PSYSTRAY MSGDATA GetSysTrayMsgDataPtr()100 static PSYSTRAYCTLDATA GetSysTrayCtlDataPtr() 101 101 { 102 102 APIRET arc; 103 103 104 104 // allocate a thread local storage entry if not done so 105 if (G_itlsSysTray MsgData == -1)105 if (G_itlsSysTrayCtlData == -1) 106 106 { 107 107 // @todo does XWorkplace have its own TLS? Not? Use … … 109 109 // to the lack of space in that area) 110 110 int itls = __libc_TLSAlloc(); 111 if (!__atomic_cmpxchg32(&G_itlsSysTray MsgData, itls, -1))111 if (!__atomic_cmpxchg32(&G_itlsSysTrayCtlData, itls, -1)) 112 112 { 113 113 // another thread has already got an entry, discard our try … … 116 116 } 117 117 118 if (G_itlsSysTray MsgData == -1)118 if (G_itlsSysTrayCtlData == -1) 119 119 return NULL; 120 120 } 121 121 122 // allocate a SYSTRAY MSGDATA struct for this thread if not done so123 PSYSTRAY MSGDATA pData = __libc_TLSGet(G_itlsSysTrayMsgData);124 if (!pData) 125 { 126 arc = DosAllocSharedMem((PVOID)&pData, NULL, sizeof(SYSTRAY MSGDATA),122 // allocate a SYSTRAYCTLDATA struct for this thread if not done so 123 PSYSTRAYCTLDATA pData = __libc_TLSGet(G_itlsSysTrayCtlData); 124 if (!pData) 125 { 126 arc = DosAllocSharedMem((PVOID)&pData, NULL, sizeof(SYSTRAYCTLDATA), 127 127 PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE); 128 128 if (arc != NO_ERROR) 129 129 return NULL; 130 130 131 __libc_TLSSet(G_itlsSysTray MsgData, pData);131 __libc_TLSSet(G_itlsSysTrayCtlData, pData); 132 132 133 133 // note that we don't ever free the allocated block since our API doesn't … … 159 159 PULONG pulRevision) // out: revision number 160 160 { 161 PSYSTRAY MSGDATA pData = GetSysTrayMsgDataPtr();161 PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr(); 162 162 if (!pData) 163 163 return FALSE; … … 166 166 pData->hwndSender = NULLHANDLE; 167 167 168 BOOL rc = SendSysTrayCtlMsg(pData);169 if ( rc)168 BOOL brc = SendSysTrayCtlMsg(pData); 169 if (brc) 170 170 { 171 171 if (pulMajor) … … 177 177 } 178 178 179 return rc;179 return brc; 180 180 } 181 181 … … 215 215 ULONG ulFlags) // in: flags (not currently used, must be 0) 216 216 { 217 PSYSTRAY MSGDATA pData = GetSysTrayMsgDataPtr();217 PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr(); 218 218 if (!pData) 219 219 return FALSE; … … 240 240 ULONG ulId) // in: icon ID to remove 241 241 { 242 PSYSTRAY MSGDATA pData = GetSysTrayMsgDataPtr();242 PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr(); 243 243 if (!pData) 244 244 return FALSE; … … 272 272 PSZ pszText) // in: tooltip text 273 273 { 274 PSYSTRAY MSGDATA pData = GetSysTrayMsgDataPtr();274 PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr(); 275 275 if (!pData) 276 276 return FALSE; … … 361 361 ULONG xstGetSysTrayMaxTextLen() 362 362 { 363 return sizeof(((PSYSTRAY MSGDATA)0)->u.tooltip.szText);364 } 365 363 return sizeof(((PSYSTRAYCTLDATA)0)->u.tooltip.szText); 364 } 365 -
trunk/src/3rdparty/os2/xsystray/xsystray_api.h
r255 r256 21 21 #endif 22 22 23 // notification code constants for WM_XST_NOTIFY, refer to xstAddSysTrayIcon() 23 // notification code constants for the notification messages sent by the system 24 // tray (refer to xstAddSysTrayIcon() for details) 24 25 #define XST_IN_MOUSE 0x0001 25 26
Note:
See TracChangeset
for help on using the changeset viewer.