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    UId;
    118118                // icon ID
    119119    HPOINTER    hIcon;
     
    123123    PSZ         pszToolTip;
    124124                // icon tooltip (NULL if none)
     125
     126
     127
    125128
    126129} ICONDATA, *PICONDATA;
     
    147150    size_t      cIconsMax;
    148151                // maximum number of icons pIcons can fit
     152
     153
    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
     174
     175
     176
     177
     178
     179
     180
    163181
    164182static
     
    299317{
    300318    pData->hwnd = NULLHANDLE;
    301     pData->ulId = 0;
     319    pData->uId = 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                       U     // 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].uId)
    334352        {
    335353            if (pIdx)
     
    342360        *pIdx = i;
    343361    return NULL;
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
     462
     463
     464
     465
     466
     467
     468
     469
     470
     471
     472
     473
     474
     475
     476
     477
     478
     479
     480
    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, l;
    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->lIcon) / 2;
    484639
    485640        if (bLeftToRight)
     
    488643            x = swp.cx - pSysTrayData->lIconPad - pSysTrayData->lIconWidth;
    489644
    490         lTotalWidth = pSysTrayData->lIconWidth + pSysTrayData->lIconPad * 2;
     645        l;
    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 / l;
     651            x = pSysTrayData->lIconPad + i * l;
    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
     677
     678
     679
     680
     681
     682
     683
     684
     685
     686
     687
     688
     689
     690
     691
     692
     693
     694
     695
     696
     697
     698
     699
     700
     701
     702
     703
     704
     705
     706
     707
     708
     709
     710
     711
     712
     713
     714
     715
     716
     717
     718
     719
     720
     721
     722
     723
     724
     725
     726
     727
     728
     729
     730
     731
     732
     733
     734
     735
     736
     737
     738
     739
     740
     741
     742
     743
     744
     745
     746
     747
     748
     749
     750
     751
     752
     753
     754
     755
     756
     757
     758
     759
     760
     761
     762
     763
     764
     765
     766
     767
     768
     769
     770
     771
     772
     773
     774
     775
     776
     777
     778
     779
     780
     781
     782
     783
     784
     785
     786
     787
     788
     789
     790
     791
     792
     793
     794
     795
     796
     797
     798
     799
     800
     801
     802
     803
     804
     805
     806
     807
     808
     809
     810
    519811}
    520812
     
    562854
    563855            PSYSTRAYDATA pSysTrayData = NULL;
     856
    564857
    565858            WinSetWindowPtr(hwnd, QWL_USER, mp1);
     
    575868
    576869            // initialize the SYSTRAYDATA structure
     870
    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                (pSysTrayData);
    586880                return (MRESULT)TRUE;
    587881            }
    588882            pSysTrayData->cIcons = 0;
     883
     884
     885
     886
     887
     888
     889
     890
     891
     892
     893
     894
     895
     896
     897
     898
     899
     900
     901
     902
     903
     904
     905
     906
     907
     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
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
     1000
     1001
     1002
     1003
     1004
     1005
     1006
     1007
     1008
     1009
     1010
     1011
     1012
     1013
     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((" uId));
    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.uId, &i);
    7881117            if (pData)
    7891118            {
     
    8251154
    8261155                pData = &pSysTrayData->pIcons[i];
     1156
     1157
    8271158                pData->hwnd = pCtlData->hwndSender;
    828                 pData->ulId = pCtlData->u.icon.ulId;
     1159                pData->uId;
    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((" uId));
    8471178
    8481179            pCtlData->bAcknowledged = TRUE;
    8491180
    8501181            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
    851                                  pCtlData->u.icon.ulId, &i);
     1182                                 pCtlData->u.icon.uId, &i);
    8521183            if (pData)
    8531184            {
     
    8931224{
    8941225    PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
     1226
     1227
     1228
    8951229
    8961230    if (usTimerId == TID_CHECKALIVE)
     
    9041238            if (!WinIsWindow(pWidget->habWidget, pSysTrayData->pIcons[i].hwnd))
    9051239            {
     1240
     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();
     1267                // hwnd is NULLHANDLE here
    9141268            }
    9151269        }
     
    11281482        }
    11291483
     1484
     1485
     1486
     1487
     1488
     1489
     1490
    11301491        // no error:
    11311492        // return widget classes array
Note: See TracChangeset for help on using the changeset viewer.