Changeset 281 for trunk/src


Ignore:
Timestamp:
Nov 2, 2009, 11:32:16 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

3rdparty: os2/xsystray: Implemented array of HMQ to track HK_INPUT hook installation/removal.

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

Legend:

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

    r280 r281  
    10711071
    10721072static
    1073 BOOL WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget,
    1074                         PSYSTRAYCTLDATA pCtlData)
    1075 {
    1076     BOOL brc = FALSE;
     1073ULONG WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget,
     1074                         PSYSTRAYCTLDATA pCtlData)
     1075{
     1076    BOOL    brc = FALSE;
     1077    ULONG   xrc = XST_FAIL;
     1078
    10771079    PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
    10781080
     
    10871089            pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MINOR;
    10881090            pCtlData->u.version.ulRevision = XSYSTRAY_VERSION_REVISION;
    1089             brc = TRUE;
     1091            xrc = XST_OK;
    10901092        }
    10911093        break;
     
    11121114            hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &Info);
    11131115            if (hIcon == NULLHANDLE)
    1114             {
    1115                 brc = FALSE;
    11161116                break;
    1117             }
    11181117
    11191118            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
     
    11291128                // we didn't change the number of icons so simply invalidate
    11301129                WinInvalidateRect(pWidget->hwndWidget, NULL, FALSE);
     1130
     1131                xrc = XST_REPLACED;
    11311132            }
    11321133            else
     
    11661167
    11671168                WgtXSysTrayUpdateAfterIconAddRemove(pWidget);
     1169
     1170                xrc = XST_OK;
    11681171            }
    1169 
    1170             brc = TRUE;
    11711172        }
    11721173        break;
     
    12011202                WgtXSysTrayUpdateAfterIconAddRemove(pWidget);
    12021203
    1203                 brc = TRUE;
     1204                xrc = XST_OK;
    12041205            }
    12051206            else
     
    12131214
    12141215    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;
    12181219}
    12191220
  • trunk/src/3rdparty/os2/xsystray/xsystray.h

    r280 r281  
    4040
    4141#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
    4345typedef enum
    4446{
     
    5052    SYSTRAYCMD_HIDEBALLOON,
    5153} 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
    5259
    5360/*
  • trunk/src/3rdparty/os2/xsystray/xsystray_api.c

    r280 r281  
    2626#define INCL_WINPOINTERS
    2727#define INCL_WINHOOKS
     28#define INCL_WINWINDOWMGR
    2829#include <os2.h>
    2930
     
    3334#include <string.h>
    3435#include <sys/builtin.h>        // atomics
     36#include <sys/fmutex.h>         // fast mutex
     37#include <sys/smutex.h>         // simple mutex
    3538
    3639static ULONG WM_XST_CREATED = 0;
     
    5659        // sounds sane
    5760
     61typedef struct
     62{
     63    HMQ         hmq;
     64    unsigned    cRefs;
     65} HMQREFS, *PHMQREFS;
     66
     67static PHMQREFS G_pHmqRefs = NULL;
     68                // array of references to each HMQ that we make
     69static size_t   G_cHmqRefs = 0;
     70                // number of elements in G_pHmqRefs
     71static size_t   G_cHmqRefsMax = 0;
     72                // maximum number of elements in G_pHmqRefs
     73static _fmutex  G_fmtx;
     74                // fast mutex to protect
     75static _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
    5880// @todo to be on the safe side with casting in __atomic_cmpxchg32() we need
    5981// compile-time assertions like this:
     
    78100}
    79101
    80 static BOOL SendSysTrayCtlMsg(PSYSTRAYCTLDATA pData)
     102static ULONG SendSysTrayCtlMsg(PSYSTRAYCTLDATA pData)
    81103{
    82104    APIRET arc;
     
    112134
    113135        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;
    116138
    117139        // if we failed to send the message, it may mean that XCenter was restarted
     
    126148        break;
    127149    }
    128     while (TRUE);
    129 
    130     return FALSE;
     150    while (1);
     151
     152    return XST_FAIL;
    131153}
    132154
     
    183205/*
    184206 *@@ InputHook:
    185  *      This is used to intercept posted XST_NOTIFY messages and apply special
    186  *      processing to them (compose a client window-specific notification
    187  *      message, free the NOTIFYDATA structure and post the composed message to
    188  *      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).
    189211 */
    190212
     
    243265    pData->hwndSender = NULLHANDLE;
    244266
    245     brc = SendSysTrayCtlMsg(pData);
     267    brc = SendSysTrayCtlMsg(pData) == XST_OK;
    246268    if (brc)
    247269    {
     
    302324                       ULONG ulFlags)   // in: flags (not currently used, must be 0)
    303325{
    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
    306333    PSYSTRAYCTLDATA pData = AllocSysTrayCtlDataPtr();
    307334    if (!pData)
    308335        return FALSE;
    309336
    310     // install the message hook if not already done so
    311     // @todo the code is temporary and incorrect, it's just for testing
    312     // (we should use an array of HMQ to check if we already installed the filter)
    313337    if (WM_XST_NOTIFY == 0)
    314     {
    315338        WM_XST_NOTIFY = WinAddAtom(WinQuerySystemAtomTable(),
    316339                                   WM_XST_NOTIFY_ATOM);
    317340
    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))
    321353            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);
    323361
    324362    // give all processes temporary access to hIcon
     
    332370        pData->u.icon.ulMsgId = ulMsgId;
    333371
    334         brc = SendSysTrayCtlMsg(pData);
     372        xrc = SendSysTrayCtlMsg(pData);
     373        brc = xrc == XST_OK || xrc == XST_REPLACED;
    335374
    336375        // revoke temporary access to hIcon
     
    341380    FreeSysTrayCtlDataPtr(pData);
    342381
     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
    343423    return brc;
    344424}
     
    355435BOOL xstRemoveSysTrayIcon(HWND hwnd,    // in: window handle associated with the icon
    356436                          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
     500BOOL 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
    357503{
    358504    BOOL brc;
     
    361507        return FALSE;
    362508
    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 text
    378  *      is shown when the mouse pointer is held still over the icon area for
    379  *      some time.
    380  *
    381  *      If pszText is NULL, the tooltip text is reset and will not be shown next
    382  *      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) is
    387  *      limited to a value returned by xstGetSysTrayMaxTextLen(). If the
    388  *      supplied string is longer, it will be truncated.
    389  */
    390 
    391 BOOL xstSetSysTrayIconToolTip(HWND hwnd,    // in: window handle associated with the icon
    392                               USHORT usId,  // in: icon ID to set the tooltip for
    393                               PSZ pszText)  // in: tooltip text
    394 {
    395     BOOL brc;
    396     PSYSTRAYCTLDATA pData = AllocSysTrayCtlDataPtr();
    397     if (!pData)
    398         return FALSE;
    399 
    400509    pData->ulCommand = SYSTRAYCMD_SETTOOLTIP;
    401510    pData->hwndSender = hwnd;
     
    412521    }
    413522
    414     brc = SendSysTrayCtlMsg(pData);
     523    brc = SendSysTrayCtlMsg(pData) == XST_OK;
    415524
    416525    FreeSysTrayCtlDataPtr(pData);
Note: See TracChangeset for help on using the changeset viewer.