Ignore:
Timestamp:
Nov 2, 2009, 3:10:29 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

3rdparty: os2/xsystray: Use custom shared memory pool for structures posted by the server to the client windows. Process mouse/wheel and context menu messages in the icon area and post them to the respective client windows. Use smaller spacing between icons (one pad unit instead of two).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/3rdparty/os2/xsystray/xsystray.c

    r270 r273  
    111111 */
    112112
    113 typedef struct _ICONDATA
     113typedef struct
    114114{
    115115    HWND        hwnd;
    116116                // associated window
    117     ULONG       ulId;
     117    USHORT      usId;
    118118                // icon ID
    119119    HPOINTER    hIcon;
     
    123123    PSZ         pszToolTip;
    124124                // icon tooltip (NULL if none)
     125    BOOL        bMemoryPoolGiven;
     126                // TRUE if SYSTRAYDATA::pvMemoryPool is already given to
     127                // the process hwnd belongs to
    125128
    126129} ICONDATA, *PICONDATA;
     
    147150    size_t      cIconsMax;
    148151                // maximum number of icons pIcons can fit
     152    PVOID       pvMemoryPool;
     153                // memory pool for NOTIFYDATA structures
    149154
    150155} SYSTRAYDATA, *PSYSTRAYDATA;
     
    154159        // space for the newly added icon
    155160
    156 static ULONG QWL_USER_SERVER_DATA = 0;
    157              // offset to the PXCENTERWIDGET pointer in the widget data array
     161#define SERVER_MEMORYPOOL_SIZE 65536
     162        // taking NOTIFYDATA size into account (<=32 B), this is enough for at
     163        // least 2048 simultaneous notification messages, which (even taking
     164        // slowly responsing clients into account) sounds sane since in most
     165        // cases the structure is freed once it reaches the target event queue
     166        // and before a message created as a copy of it is sent to the target
     167        // window procedure
    158168
    159169#define TID_CHECKALIVE          1
     
    161171#define TID_CHECKALIVE_TIMEOUT  2000 // ms
    162172         // how often to perform alive checks
     173
     174static ULONG WM_XST_CREATED = 0;
     175             // identity of the WM_XST_CREATED message taken from the atom table
     176static ULONG WM_XST_NOTIFY = 0;
     177             // identity of the WM_XST_NOTIFY message taken from the atom table
     178
     179static ULONG QWL_USER_SERVER_DATA = 0;
     180             // offset to the PXCENTERWIDGET pointer in the widget data array
    163181
    164182static
     
    299317{
    300318    pData->hwnd = NULLHANDLE;
    301     pData->ulId = 0;
     319    pData->usId = 0;
    302320    if (pData->hIcon != NULLHANDLE)
    303321    {
     
    323341PICONDATA FindIconData(PSYSTRAYDATA pSysTrayData,
    324342                       HWND hwnd,       // in: associated window handle
    325                        ULONG ulId,      // in: icon ID
     343                       USHORT usId,     // in: icon ID
    326344                       size_t *pIdx)    // out: index of the icon in the icon array
    327345                                        // (optional, may be NULL)
     
    331349    {
    332350        if (pSysTrayData->pIcons[i].hwnd == hwnd &&
    333             pSysTrayData->pIcons[i].ulId == ulId)
     351            pSysTrayData->pIcons[i].usId == usId)
    334352        {
    335353            if (pIdx)
     
    342360        *pIdx = i;
    343361    return NULL;
     362}
     363
     364/*
     365 *@@ AllocNotifyDataPtr:
     366 *      Allocates a SYSTRAYCTLDATA struct in the pool of shared memory on belalf
     367 *      of the client window identified by pIconData->hwnd.
     368 *
     369 *      If there is no free space in the pool, it returns NULL. On success,
     370 *      fills in msg and mp1 fields of the returned structure using the
     371 *      information provided in pIconData.
     372 *
     373 *      Note that the allocated structure is supposed to be freed using
     374 *      FreeNotifyDataPtr by the client-side API implementation in another
     375 *      process.
     376 */
     377static
     378PNOTIFYDATA AllocNotifyDataPtr(PVOID pvMemoryPool,  // in: memory pool base address
     379                               PICONDATA pIconData) // in: icon data
     380{
     381    // NOTE: we cannot use DosSubAllocMem() and friends since we want to be able
     382    // to free blocks allocated to clients which death we detect but we cannot
     383    // be sure about the layout of memory DosSub API uses. Therefore, we provide
     384    // our own sub-allocation scheme which is rather simple because we need to
     385    // allocate equally sized blocks (each is NOTIFYDATA struct). The memory
     386    // pool is laid out as follows: MEMPOOLHDR followed by a number of
     387    // MEMPOOLBLK.
     388
     389    APIRET arc;
     390    PID pid;
     391    TID tid;
     392    PMEMPOOLHDR pHdr;
     393    ULONG ulMax, ulNeedsCommit, ulNext, ulCurr;
     394    PNOTIFYDATA pData;
     395
     396    LOGF(("pvMemoryPool %p\n", pvMemoryPool));
     397    LOGF(("hwnd         %p\n", pIconData->hwnd));
     398
     399    if (!pIconData->bMemoryPoolGiven)
     400    {
     401        LOGF(("Giving memory pool to %lx\n", pIconData->hwnd));
     402
     403        arc = ERROR_INVALID_HANDLE;
     404        if (WinQueryWindowProcess(pIconData->hwnd, &pid, &tid))
     405            arc = DosGiveSharedMem(pvMemoryPool, pid, PAG_READ | PAG_WRITE);
     406        if (arc != NO_ERROR)
     407            return NULL;
     408
     409        pIconData->bMemoryPoolGiven = TRUE;
     410    }
     411
     412    pHdr = (PMEMPOOLHDR)pvMemoryPool;
     413
     414    // maximum address that is still enough for a block
     415    ulMax = pHdr->ulBeyond - sizeof(MEMPOOLBLK);
     416
     417    ulNeedsCommit = pHdr->ulNeedsCommit;
     418    ulNext = pHdr->ulNext;
     419    ulCurr = ulNext;
     420
     421    LOGF(("ulNeedsCommit %p\n", ulNeedsCommit));
     422    LOGF(("ulNext        %p\n", ulNext));
     423
     424    do
     425    {
     426        if (ulCurr >= ulNeedsCommit)
     427        {
     428            // commit more memory; it's OK two or more threads will do the same
     429            DosSetMem((PVOID)ulNeedsCommit, 4096,
     430                      PAG_COMMIT | PAG_READ | PAG_WRITE);
     431            // advance the address (only if nobody has already done so -- they
     432            // could already commit more than we did)
     433            __atomic_cmpxchg32((uint32_t *)&pHdr->ulNeedsCommit,
     434                               ulNeedsCommit + 4096, ulNeedsCommit);
     435        }
     436
     437        if (__atomic_cmpxchg32((uint32_t *)ulCurr, pIconData->hwnd, NULLHANDLE))
     438            break;
     439
     440        ulCurr += sizeof(MEMPOOLBLK);
     441        if (ulCurr > ulMax)
     442            // start over
     443            ulCurr = ((ULONG)pvMemoryPool) + sizeof(MEMPOOLHDR);
     444
     445        if (ulCurr == ulNext)
     446            return NULL; // no free blocks!
     447    }
     448    while (1);
     449
     450    LOGF(("ulCurr        %p\n", ulCurr));
     451
     452    // advance to the next possibly free block
     453    ulCurr += sizeof(MEMPOOLBLK);
     454    if (ulCurr > ulMax)
     455        // start over
     456        ulCurr = ((ULONG)pvMemoryPool) + sizeof(MEMPOOLHDR);
     457
     458    // store the new next address until someone else has already done that
     459    __atomic_cmpxchg32((uint32_t *)&pHdr->ulNext, ulCurr, ulNext);
     460
     461    pData = &((PMEMPOOLBLK)ulCurr)->NotifyData;
     462    memset(pData, sizeof(*pData), 0);
     463
     464    pData->msg = pIconData->ulMsgId;
     465    pData->mp1 = MPFROMSHORT(pIconData->usId);
     466
     467    return pData;
     468}
     469
     470/*
     471 *@@ PostNotifyMsg:
     472 *      Posts WM_XST_NOTIFY to the given client window. Frees pNotifyData if
     473 *      posting fails.
     474 */
     475
     476VOID PostNotifyMsg(PSYSTRAYDATA pSysTrayData, HWND hwnd,
     477                   PNOTIFYDATA *pNotifyData)
     478{
     479    if (!WinPostMsg(hwnd, WM_XST_NOTIFY, pNotifyData, pSysTrayData->pvMemoryPool))
     480        FreeNotifyDataPtr(pSysTrayData->pvMemoryPool, hwnd, pNotifyData);
    344481}
    345482
     
    404541            {
    405542                PSIZEL pszl = (PSIZEL)mp2;
    406                 LONG pad2 = pSysTrayData->lIconPad * 2;
    407                 pszl->cx = (pSysTrayData->lIconWidth + pad2) * pSysTrayData->cIcons; // desired width
    408                 pszl->cy = pSysTrayData->lIconHeight + pad2; // desired minimum height
     543                LONG pad = pSysTrayData->lIconPad;
     544                size_t cnt = pSysTrayData->cIcons;
     545                // desired width
     546                if (cnt)
     547                    pszl->cx = pad + (pSysTrayData->lIconWidth + pad) * cnt;
     548                else
     549                    pszl->cx = 0;
     550                // desired minimum height
     551                pszl->cy = pSysTrayData->lIconHeight + pad * 2;
    409552                brc = TRUE;
    410553            }
     
    421564 *      implementation for WM_PAINT in fnwpXSysTray.
    422565 *
    423  *      This really does nothing, except painting a
    424  *      3D rectangle and printing a question mark.
     566 *      Draws all the icons. If the widget's center is located to the left from
     567 *      the XCenter's center, icons go left to right. Otherwise, they go right
     568 *      to left.
     569 */
     570/*
     571        +---------------------------+  p = lIconPad
     572        |     p                     |  w = lIconWidth
     573        |   +-------+   +-------+   |  h = lIconHeight
     574        | p |   w   | p |   w   | p |
     575        |   |      h|   |      h|   |
     576        |   |       |   |       |   |  If "Frame around statics" is on in XCenter
     577        |   +-------+   +-------+   |  properties, then a 1 px 3D frame is drawn
     578        |     p                     |  within the pad area. So, lIconPad must
     579        +---------------------------+  be at least 2 px.
    425580 */
    426581
     
    438593        RECTL   rcl;
    439594        BOOL    bLeftToRight;
    440         LONG    x, y, lTotalWidth;
     595        LONG    x, y, lIconStep;
    441596        size_t  i;
    442597
     
    481636        // always center the icon vertically (we may be given more height than
    482637        // we requested)
    483         y = (swp.cy - pSysTrayData->lIconWidth) / 2;
     638        y = (swp.cy - pSysTrayData->lIconHeight) / 2;
    484639
    485640        if (bLeftToRight)
     
    488643            x = swp.cx - pSysTrayData->lIconPad - pSysTrayData->lIconWidth;
    489644
    490         lTotalWidth = pSysTrayData->lIconWidth + pSysTrayData->lIconPad * 2;
     645        lIconStep = pSysTrayData->lIconWidth + pSysTrayData->lIconPad;
    491646
    492647        // where to start from?
    493648        if (bLeftToRight)
    494649        {
    495             i = rclPaint.xLeft / lTotalWidth;
    496             x = pSysTrayData->lIconPad + i * lTotalWidth;
     650            i = rclPaint.xLeft / lIconStep;
     651            x = pSysTrayData->lIconPad + i * lIconStep;
    497652        }
    498653        else
    499654        {
    500             i = (swp.cx - rclPaint.xRight) / lTotalWidth;
    501             x = swp.cx - (i + 1) * lTotalWidth + pSysTrayData->lIconPad;
     655            i = (swp.cx - rclPaint.xRight) / lIconStep;
     656            x = swp.cx - (i + 1) * lIconStep;
     657            // negate the step, for convenience
     658            lIconStep = -lIconStep;
    502659        }
    503660
    504661        // draw as many icons as we can / need
    505         for (i = 0; i < pSysTrayData->cIcons; ++i)
     662        for (; i < pSysTrayData->cIcons; ++i)
    506663        {
    507664            if (x >= rclPaint.xRight)
     
    509666
    510667            DrawPointer(hps, x, y, pSysTrayData->pIcons[i].hIcon, DP_MINI);
    511             if (bLeftToRight)
    512                 x += lTotalWidth;
    513             else
    514                 x -= lTotalWidth;
     668            x += lIconStep;
    515669        }
    516670
    517671        WinEndPaint(hps);
    518672    }
     673}
     674
     675/*
     676 *@@ WgtMouse:
     677 *      implementation for WM_BUTTONxyyy in fnwpXSysTray.
     678 *
     679 *      Posts a notification to the window associated with the icon and returns
     680 *      TRUE if this mouse message is within the icon bounds. Otherwise returns
     681 *      FALSE.
     682 *
     683 *      Refer to WgtPaint for more details about the widget geometry.
     684 */
     685
     686static
     687BOOL WgtMouse(HWND hwnd, ULONG msg, MRESULT mp1, MRESULT mp2,
     688              PXCENTERWIDGET pWidget)
     689{
     690    PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
     691
     692    POINTL  ptl;
     693    SWP     swp;
     694    RECTL   rcl;
     695    BOOL    bLeftToRight;
     696    LONG    y, lIconStep;
     697    size_t  i;
     698
     699    PICONDATA   pIconData;
     700    PNOTIFYDATA pNotifyData;
     701
     702    ptl.x = ((PPOINTS)&mp1)->x;
     703    ptl.y = ((PPOINTS)&mp1)->y;
     704
     705    LOGF(("msg %x ptl %ld,%ld\n", msg, ptl.x, ptl.y));
     706
     707    WinQueryWindowPos(hwnd, &swp);
     708    WinQueryWindowRect(pWidget->pGlobals->hwndClient, &rcl);
     709
     710    y = (swp.cy - pSysTrayData->lIconHeight) / 2;
     711    if (ptl.y < y || ptl.y >= y + pSysTrayData->lIconHeight)
     712        return FALSE; // hit pad space
     713
     714    // detect the direction
     715    bLeftToRight = swp.x + swp.cx / 2 < (rcl.xRight / 2);
     716
     717    lIconStep = pSysTrayData->lIconWidth + pSysTrayData->lIconPad;
     718
     719    // which icon is that?
     720    if (bLeftToRight)
     721    {
     722        i = ptl.x / lIconStep;
     723        if (ptl.x % lIconStep < pSysTrayData->lIconPad)
     724            return FALSE; // hit pad space
     725    }
     726    else
     727    {
     728        i = (swp.cx - ptl.x - 1) / lIconStep;
     729        if ((swp.cx - ptl.x - 1) % lIconStep < pSysTrayData->lIconPad)
     730            return FALSE; // hit pad space
     731    }
     732    if (i >= pSysTrayData->cIcons)
     733        return FALSE; // hit pad space
     734
     735    pIconData = &pSysTrayData->pIcons[i];
     736
     737    LOGF(("hwnd  %x\n", pIconData->hwnd));
     738    LOGF(("usId  %d\n", pIconData->usId));
     739    LOGF(("hIcon %x\n", pIconData->hIcon));
     740
     741    // make the coordinates global
     742    WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1);
     743
     744    // allocate a NOTIFYDATA struct
     745    pNotifyData = AllocNotifyDataPtr(pSysTrayData->pvMemoryPool, pIconData);
     746    if (!pNotifyData)
     747        return FALSE;
     748
     749    switch (msg)
     750    {
     751        case WM_HSCROLL:
     752        case WM_VSCROLL:
     753            pNotifyData->mp1 += XST_IN_WHEEL << 16;
     754            pNotifyData->u.WheelMsg.ulWheelMsg = msg;
     755            pNotifyData->u.WheelMsg.ptsPointerPos.x = ptl.x;
     756            pNotifyData->u.WheelMsg.ptsPointerPos.y = ptl.y;
     757            pNotifyData->u.WheelMsg.usCmd = SHORT2FROMMP(mp2);
     758            pNotifyData->mp2 = &pNotifyData->u.WheelMsg;
     759        break;
     760
     761        case WM_CONTEXTMENU:
     762            pNotifyData->mp1 += XST_IN_CONTEXT << 16;
     763            pNotifyData->u.ContextMsg.ptsPointerPos.x = ptl.x;
     764            pNotifyData->u.ContextMsg.ptsPointerPos.y = ptl.y;
     765            pNotifyData->u.ContextMsg.fPointer = TRUE;
     766            pNotifyData->mp2 = &pNotifyData->u.ContextMsg;
     767        break;
     768
     769        default:
     770            pNotifyData->mp1 += XST_IN_MOUSE << 16;
     771            pNotifyData->u.MouseMsg.ulMouseMsg = msg;
     772            pNotifyData->u.MouseMsg.ptsPointerPos.x = ptl.x;
     773            pNotifyData->u.MouseMsg.ptsPointerPos.y = ptl.y;
     774            pNotifyData->u.MouseMsg.fsHitTestRes = SHORT1FROMMP(mp2);
     775            pNotifyData->u.MouseMsg.fsFlags = SHORT2FROMMP(mp2);
     776            pNotifyData->mp2 = &pNotifyData->u.MouseMsg;
     777        break;
     778    }
     779
     780    PostNotifyMsg(pSysTrayData, hwnd, pNotifyData);
     781
     782    return TRUE;
     783}
     784
     785static
     786VOID FreeSysTrayData(PSYSTRAYDATA pSysTrayData)
     787{
     788    // destroy the server
     789    if (pSysTrayData->hwndServer != NULLHANDLE)
     790    {
     791        WinDestroyWindow(pSysTrayData->hwndServer);
     792        pSysTrayData->hwndServer = NULLHANDLE;
     793    }
     794
     795    // free all system tray data
     796    if (pSysTrayData->pvMemoryPool)
     797    {
     798        DosFreeMem(pSysTrayData->pvMemoryPool);
     799    }
     800    if (pSysTrayData->pIcons)
     801    {
     802        size_t i;
     803        for (i = 0; i < pSysTrayData->cIcons; ++i)
     804            FreeIconData(&pSysTrayData->pIcons[i]);
     805        pSysTrayData->cIcons = 0;
     806        free(pSysTrayData->pIcons);
     807        pSysTrayData->pIcons = NULL;
     808    }
     809
     810    free(pSysTrayData);
    519811}
    520812
     
    562854
    563855            PSYSTRAYDATA pSysTrayData = NULL;
     856            APIRET arc;
    564857
    565858            WinSetWindowPtr(hwnd, QWL_USER, mp1);
     
    575868
    576869            // initialize the SYSTRAYDATA structure
     870            memset(pSysTrayData, sizeof(*pSysTrayData), 0);
    577871            pSysTrayData->lIconWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXICON) / 2;
    578872            pSysTrayData->lIconHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYICON) / 2;
     
    583877            if (pSysTrayData->pIcons == NULL)
    584878            {
    585                 free(pSysTrayData);
     879                FreeSysTrayData(pSysTrayData);
    586880                return (MRESULT)TRUE;
    587881            }
    588882            pSysTrayData->cIcons = 0;
     883
     884            // Allocate the memory pool for NOTIFYDATA structs (we don't
     885            // PAG_COMMIT all memory, AllocNotifyDataPtr() will do so as needed)
     886            arc = DosAllocSharedMem((PVOID)&pSysTrayData->pvMemoryPool, NULL,
     887                                    SERVER_MEMORYPOOL_SIZE,
     888                                    PAG_READ | PAG_WRITE | OBJ_GIVEABLE);
     889            if (arc == NO_ERROR)
     890            {
     891                PMEMPOOLHDR pHdr = (PMEMPOOLHDR)pSysTrayData->pvMemoryPool;
     892                arc = DosSetMem(pSysTrayData->pvMemoryPool, 4096,
     893                                PAG_COMMIT | PAG_READ | PAG_WRITE);
     894                if (arc == NO_ERROR)
     895                {
     896                    pHdr->ulBeyond = (ULONG)pSysTrayData->pvMemoryPool +
     897                                     SERVER_MEMORYPOOL_SIZE;
     898                    pHdr->ulNeedsCommit = (ULONG)pSysTrayData->pvMemoryPool +
     899                                           4096;
     900                    pHdr->ulNext = (ULONG)pSysTrayData->pvMemoryPool +
     901                                   sizeof(MEMPOOLHDR);
     902                }
     903            }
     904            if (arc != NO_ERROR)
     905            {
     906                FreeSysTrayData(pSysTrayData);
     907                return (MRESULT)TRUE;
     908            }
    589909
    590910            // create the "server" window (note that we pass the XCENTERWIDGET
     
    598918            if (pSysTrayData->hwndServer == NULLHANDLE)
    599919            {
    600                 free(pSysTrayData->pIcons);
    601                 free(pSysTrayData);
     920                FreeSysTrayData(pSysTrayData);
    602921                return (MRESULT)TRUE;
    603922            }
     
    606925
    607926            // inform all interested parties that we are fired up
    608             // (NOTE: keep in sync with xstGetSysTrayCreatedMsgId())
    609             WinBroadcastMsg(HWND_DESKTOP,
    610                             WinAddAtom(WinQuerySystemAtomTable(),
    611                                        "ExtendedSysTray.WM_XST_CREATED"),
    612                             NULL, NULL,
    613                             BMSG_POST);
     927            WinBroadcastMsg(HWND_DESKTOP, WM_XST_CREATED,
     928                            NULL, NULL, BMSG_POST);
    614929
    615930            return FALSE; // confirm success
     
    628943
    629944            PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
    630             size_t i;
    631 
    632             // destroy the server
    633             WinDestroyWindow(pSysTrayData->hwndServer);
    634             pSysTrayData->hwndServer = NULLHANDLE;
    635 
    636             // free all system tray data
    637             for (i = 0; i < pSysTrayData->cIcons; ++i)
    638                 FreeIconData(&pSysTrayData->pIcons[i]);
    639             pSysTrayData->cIcons = 0;
    640             free(pSysTrayData->pIcons);
    641             pSysTrayData->pIcons = NULL;
    642 
    643             // make sure we remove the check alive timer
    644             WgtXSysTrayUpdateAfterIconAddRemove(pWidget);
    645 
    646             free(pSysTrayData);
     945
     946            // stop the check alive timer
     947            WinStopTimer(pWidget->habWidget, pSysTrayData->hwndServer,
     948                         TID_CHECKALIVE);
     949
     950            FreeSysTrayData(pSysTrayData);
    647951            pWidget->pUser = NULL;
    648952
     
    680984        break; */
    681985
     986        /*
     987         * All mouse click and wheel events:
     988         *      Note that we hide WM_CONTEXTMENU from XCenter when it is within
     989         *      the icon bounds as it's a responsibility of the application
     990         *      owning the icon to show it.
     991         */
     992
     993        case WM_BUTTON1UP:
     994        case WM_BUTTON1DOWN:
     995        case WM_BUTTON1CLICK:
     996        case WM_BUTTON1DBLCLK:
     997        case WM_BUTTON2UP:
     998        case WM_BUTTON2DOWN:
     999        case WM_BUTTON2CLICK:
     1000        case WM_BUTTON2DBLCLK:
     1001        case WM_BUTTON3UP:
     1002        case WM_BUTTON3DOWN:
     1003        case WM_BUTTON3CLICK:
     1004        case WM_BUTTON3DBLCLK:
     1005        case WM_CONTEXTMENU:
     1006        case WM_VSCROLL:
     1007        case WM_HSCROLL:
     1008        {
     1009            if (WgtMouse(hwnd, msg, mp1, mp2, pWidget))
     1010                return (MRESULT)TRUE;
     1011            // we didn't hit the icon, pass it on to XCenter
     1012        }
     1013        break;
     1014
    6821015        default:
    6831016            break;
     
    7131046    }
    7141047
    715     if (pSysTrayData->pIcons != NULL)
    716     {
    717         // ask XCenter to take our new size into account (this will also
    718         // invalidate us). If pIcons is NULL it means that we are in WM_DESTROY,
    719         // in which case XCenter will do everything for us
    720         WinPostMsg(pWidget->pGlobals->hwndClient,
    721                    XCM_REFORMAT,
    722                    (MPARAM)XFMF_GETWIDGETSIZES,
    723                    0);
    724     }
     1048    // ask XCenter to take our new size into account (this will also
     1049    // invalidate us)
     1050    WinPostMsg(pWidget->pGlobals->hwndClient,
     1051               XCM_REFORMAT,
     1052               (MPARAM)XFMF_GETWIDGETSIZES,
     1053               0);
    7251054}
    7261055
     
    7671096            LOGF(("SYSTRAYCMD_ADDICON\n"));
    7681097            LOGF((" hwnd  %x\n", pCtlData->hwndSender));
    769             LOGF((" ulId  %ld\n", pCtlData->u.icon.ulId));
     1098            LOGF((" usId  %d\n", pCtlData->u.icon.usId));
    7701099            LOGF((" hIcon %x\n", pCtlData->u.icon.hIcon));
    7711100
     
    7851114
    7861115            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
    787                                  pCtlData->u.icon.ulId, &i);
     1116                                 pCtlData->u.icon.usId, &i);
    7881117            if (pData)
    7891118            {
     
    8251154
    8261155                pData = &pSysTrayData->pIcons[i];
     1156                memset(pData, sizeof(*pData), 0);
     1157
    8271158                pData->hwnd = pCtlData->hwndSender;
    828                 pData->ulId = pCtlData->u.icon.ulId;
     1159                pData->usId = pCtlData->u.icon.usId;
    8291160                pData->hIcon = hIcon;
    8301161                pData->ulMsgId = pCtlData->u.icon.ulMsgId;
     
    8441175            LOGF(("SYSTRAYCMD_REMOVEICON\n"));
    8451176            LOGF((" hwnd  %x\n", pCtlData->hwndSender));
    846             LOGF((" ulId  %ld\n", pCtlData->u.icon.ulId));
     1177            LOGF((" usId  %d\n", pCtlData->u.icon.usId));
    8471178
    8481179            pCtlData->bAcknowledged = TRUE;
    8491180
    8501181            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
    851                                  pCtlData->u.icon.ulId, &i);
     1182                                 pCtlData->u.icon.usId, &i);
    8521183            if (pData)
    8531184            {
     
    8931224{
    8941225    PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
     1226    PMEMPOOLHDR pMemPoolHdr = (PMEMPOOLHDR)pSysTrayData->pvMemoryPool;
     1227    PMEMPOOLBLK pMemPoolBlk;
     1228    ULONG ulMemPoolMax;
    8951229
    8961230    if (usTimerId == TID_CHECKALIVE)
     
    9041238            if (!WinIsWindow(pWidget->habWidget, pSysTrayData->pIcons[i].hwnd))
    9051239            {
     1240                PICONDATA pData = &pSysTrayData->pIcons[i];
     1241
    9061242                LOGF(("Removing icon of dead window!\n"));
    907                 LOGF((" hwnd  %x\n", pSysTrayData->pIcons[i].hwnd));
    908                 LOGF((" ulId  %ld\n", pSysTrayData->pIcons[i].ulId));
    909                 LOGF((" hIcon %x\n", pSysTrayData->pIcons[i].hIcon));
     1243                LOGF((" hwnd  %x\n", pData->hwnd));
     1244                LOGF((" usId  %ld\n", pData->usId));
     1245                LOGF((" hIcon %x\n", pData->hIcon));
     1246
     1247                // free memory blocks from the pool allocated for this client
     1248                ulMemPoolMax = pMemPoolHdr->ulBeyond;
     1249                if (ulMemPoolMax > pMemPoolHdr->ulNeedsCommit)
     1250                    ulMemPoolMax = pMemPoolHdr->ulNeedsCommit;
     1251                ulMemPoolMax -= sizeof(MEMPOOLBLK);
     1252
     1253                pMemPoolBlk = pMemPoolHdr->aBlocks;
     1254                while ((ULONG)pMemPoolBlk <= ulMemPoolMax)
     1255                {
     1256                    if (pMemPoolBlk->hwnd == pData->hwnd)
     1257                    {
     1258                        LOGF((" freeing memory block %p\n", pMemPoolBlk));
     1259                        __atomic_cmpxchg32((uint32_t *)&pMemPoolBlk->hwnd,
     1260                                           NULLHANDLE, hwnd);
     1261                    }
     1262                    ++pMemPoolBlk;
     1263                }
    9101264
    9111265                bAnyDead = TRUE;
    912                 FreeIconData(&pSysTrayData->pIcons[i]);
    913                 // hwnd is NULLHANDLE here
     1266                FreeIconData(pData);
     1267                // pData->hwnd is NULLHANDLE here
    9141268            }
    9151269        }
     
    11281482        }
    11291483
     1484        if (WM_XST_CREATED == 0)
     1485            WM_XST_CREATED = WinAddAtom(WinQuerySystemAtomTable(),
     1486                                        WM_XST_CREATED_ATOM);
     1487        if (WM_XST_NOTIFY == 0)
     1488            WM_XST_NOTIFY = WinAddAtom(WinQuerySystemAtomTable(),
     1489                                       WM_XST_NOTIFY_ATOM);
     1490
    11301491        // no error:
    11311492        // return widget classes array
Note: See TracChangeset for help on using the changeset viewer.