Changeset 265 for trunk/src/3rdparty


Ignore:
Timestamp:
Oct 29, 2009, 2:13:16 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

3rdparty: os2/xsystray: Implemented adding an icon to the system tray (one icon so far) and automatically removing it if the associated window gets destroyed w/o doing so (for example, as a result of unexpected application termination).

Location:
trunk/src/3rdparty/os2/xsystray
Files:
2 edited

Legend:

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

    r256 r265  
    7676
    7777// primitive debug logging to a file
    78 #if 1
     78#if
    7979static void __LOG_WORKER(const char *fmt, ...)
    8080{
     
    133133typedef struct
    134134{
     135
     136
     137
     138
     139
     140
    135141    PICONDATA   pIcons;
    136142                // array of icons currently shown in the system tray
    137                 // (left to right)
    138143    size_t      cIcons;
    139144                // number of icons in the pIcons array
     
    143148} SYSTRAYDATA, *PSYSTRAYDATA;
    144149
    145 ULONG QWL_USER_SERVER_DATA = 0;
     150static ULONG QWL_USER_SERVER_DATA = 0;
     151             // offset to the PXCENTERWIDGET pointer in the widget data array
     152
     153#define TID_CHECKALIVE          1
     154         // check alive timer
     155#define TID_CHECKALIVE_TIMEOUT  1000 // ms
     156         // how often to check if windows associated with icons are still alive
    146157
    147158/* ******************************************************************
     
    240251/* ******************************************************************
    241252 *
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
    242277 *   PM window class implementation
    243278 *
     
    265300                MPARAM mp2)
    266301{
     302
    267303    BOOL brc = FALSE;
    268304
     
    285321            {
    286322                PSIZEL pszl = (PSIZEL)mp2;
    287                 pszl->cx = 30;      // desired width
    288                 pszl->cy = 20;      // desired minimum height
     323                LONG pad2 = pSysTrayData->lIconPad * 2;
     324                pszl->cx = (pSysTrayData->lIconWidth + pad2) * pSysTrayData->cIcons; // desired width
     325                pszl->cy = pSysTrayData->lIconHeight + pad2; // desired minimum height
    289326                brc = TRUE;
    290327            }
     
    297334}
    298335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
    299346/*
    300347 *@@ WgtPaint:
     
    309356              PXCENTERWIDGET pWidget)
    310357{
     358
    311359    HPS hps;
    312     if ((hps = WinBeginPaint(hwnd, NULLHANDLE, NULL)))
    313     {
    314         RECTL   rclWin;
     360    RECTL rclPaint;
     361
     362    if ((hps = WinBeginPaint(hwnd, NULLHANDLE, &rclPaint)))
     363    {
     364        SWP     swp;
     365        RECTL   rcl;
     366        BOOL    bLeftToRight;
     367        LONG    x, lTotalWidth;
     368        size_t  i;
     369
     370        WinQueryWindowPos(hwnd, &swp);
     371        WinQueryWindowRect(pWidget->pGlobals->hwndClient, &rcl);
     372
     373        // correct the paint area
     374        // @todo find out why it exceeds the window bounds
     375        if (rclPaint.xLeft < 0)
     376            rclPaint.xLeft = 0;
     377        if (rclPaint.xRight > swp.cx)
     378            rclPaint.xRight = swp.cx;
     379        if (rclPaint.yBottom < 0)
     380            rclPaint.yBottom = 0;
     381        if (rclPaint.yTop > swp.cy)
     382            rclPaint.yTop = swp.cy;
     383
     384        LOGF(("rclPaint %d,%d-%d,%d\n",
     385              rclPaint.xLeft, rclPaint.xRight, rclPaint.yBottom, rclPaint.yTop));
    315386
    316387        // switch HPS to RGB mode
    317388        GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
    318389
    319         // now paint
    320         WinQueryWindowRect(hwnd,
    321                            &rclWin);        // exclusive
    322 
    323         WinFillRect(hps,
    324                     &rclWin,                // exclusive
     390        // draw icons left to right if our center is closer to the left edge
     391        // of XCenter and right to left otherwise
     392        bLeftToRight = swp.x + swp.cx / 2 < (rcl.xRight / 2);
     393
     394        WinFillRect(hps, &rclPaint,
    325395                    WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0));
    326396
    327         // print question mark
    328         WinDrawText(hps,
    329                     1,
    330                     "?",
    331                     &rclWin,                // exclusive
    332                     WinQuerySysColor(HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0),
    333                     WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0),
    334                     DT_CENTER | DT_VCENTER);
     397        if (bLeftToRight)
     398            x = pSysTrayData->lIconPad;
     399        else
     400            x = swp.cx - pSysTrayData->lIconPad - pSysTrayData->lIconWidth;
     401
     402        lTotalWidth = pSysTrayData->lIconWidth + pSysTrayData->lIconPad * 2;
     403
     404        // where to start from?
     405        if (bLeftToRight)
     406        {
     407            i = rclPaint.xLeft / lTotalWidth;
     408            x = pSysTrayData->lIconPad + i * lTotalWidth;
     409        }
     410        else
     411        {
     412            i = (swp.cx - rclPaint.xRight) / lTotalWidth;
     413            x = swp.cx - (i + 1) * lTotalWidth + pSysTrayData->lIconPad;
     414        }
     415
     416        // draw as many icons as we can / need
     417        for (i = 0; i < pSysTrayData->cIcons; ++i)
     418        {
     419            if (x >= rclPaint.xRight)
     420                break;
     421
     422            DrawPointer(hps, x, pSysTrayData->lIconPad,
     423                        pSysTrayData->pIcons[i].hIcon, DP_MINI);
     424            if (bLeftToRight)
     425                x += lTotalWidth;
     426            else
     427                x -= lTotalWidth;
     428        }
    335429
    336430        WinEndPaint(hps);
     
    394488
    395489            // initialize the SYSTRAYDATA structure
     490
     491
     492
    396493            pSysTrayData->cIconsMax = 4;
    397494            pSysTrayData->pIcons = malloc(sizeof(*pSysTrayData->pIcons) *
     
    459556            size_t i;
    460557            for (i = 0; i < pSysTrayData->cIcons; ++i)
    461             {
    462                 if (pSysTrayData->pIcons[i].pszToolTip)
    463                     free(pSysTrayData->pIcons[i].pszToolTip);
    464             }
     558                FreeIconData(&pSysTrayData->pIcons[i]);
    465559            free(pSysTrayData->pIcons);
    466560            free(pSysTrayData);
     
    484578 *      implementation for WM_XST_CONTROL in fnwpXSysTrayServer.
    485579 *
    486  *      Serves as an entry point for all client-side requests to the Extended
    487  *      system tray.
     580 *      Serves as an entry point for all client-side
     581 *      system tray.
    488582 *
    489583 *      Note that this message is being sent from another process which is
     
    497591{
    498592    BOOL brc = FALSE;
     593
    499594
    500595    switch (pCtlData->ulCommand)
     
    512607        break;
    513608
     609
     610
     611
     612
     613
     614
     615
     616
     617
     618
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
     631
     632
     633
     634
     635
     636
     637
     638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
     650
     651
     652
     653
     654
     655
     656
     657
    514658        default:
    515659            break;
    516660    }
    517661
     662
     663
     664
    518665    return brc;
     666
     667
     668
     669
     670
     671
     672
     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
    519730}
    520731
     
    556767            mrc = (MRESULT)WgtXSysTrayControl(hwnd, pWidget,
    557768                                              (PSYSTRAYCTLDATA)mp1);
     769
     770
     771
     772
     773
     774
     775
     776
     777
    558778        break;
    559779
  • trunk/src/3rdparty/os2/xsystray/xsystray_api.c

    r256 r265  
    1515
    1616#define INCL_DOSERRORS
     17
    1718#define INCL_WINWINDOWMGR
    1819#define INCL_WINATOM
     20
    1921#include <os2.h>
    2022
     
    98100}
    99101
     102
     103
     104
     105
    100106static PSYSTRAYCTLDATA GetSysTrayCtlDataPtr()
    101107{
     
    105111    if (G_itlsSysTrayCtlData == -1)
    106112    {
    107         // @todo does XWorkplace have its own TLS? Not? Use
    108         // DosAllocThreadLocalMemory() directly then (though it's not nice due
    109         // to the lack of space in that area)
     113        // @todo does XWorkplace have its own TLS?
     114        // e
     115        // space in that area)
    110116        int itls = __libc_TLSAlloc();
    111117        if (!__atomic_cmpxchg32(&G_itlsSysTrayCtlData, itls, -1))
     
    159165                            PULONG pulRevision) // out: revision number
    160166{
     167
    161168    PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr();
    162169    if (!pData)
     
    166173    pData->hwndSender = NULLHANDLE;
    167174
    168     BOOL brc = SendSysTrayCtlMsg(pData);
     175    brc = SendSysTrayCtlMsg(pData);
    169176    if (brc)
    170177    {
     
    215222                       ULONG ulFlags)   // in: flags (not currently used, must be 0)
    216223{
     224
     225
    217226    PSYSTRAYCTLDATA pData = GetSysTrayCtlDataPtr();
    218227    if (!pData)
     228
     229
     230
     231
     232
    219233        return FALSE;
    220234
     
    225239    pData->u.icon.ulMsgId = ulMsgId;
    226240
    227     return SendSysTrayCtlMsg(pData);
     241    brc = SendSysTrayCtlMsg(pData);
     242
     243    // revoke temporary access to hIcon
     244    DosGetInfoBlocks(NULL, &ppib);
     245    WinSetPointerOwner(hIcon, ppib->pib_ulpid, TRUE);
     246
     247    return brc;
    228248}
    229249
Note: See TracChangeset for help on using the changeset viewer.