Ignore:
Timestamp:
Mar 18, 2011, 11:37:52 PM (14 years ago)
Author:
dmik
Message:

shell32: Implemented xsystray support (#16).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/systray.c

    r21591 r21592  
    88 *  X11DRV_WND_DockWindow.
    99 *
    10  *  Modified by ErOs2 for usage with systray_os2.c
     10 *  Modified by ErOs2 and Dmitriy Kuminov for usage with systray_os2.c
    1111 *
    1212 */
     
    3434
    3535struct _SystrayItem {
    36   HWND                  hWnd;
    37   HWND                  hWndToolTip;
    38   NOTIFYICONDATAA       notifyIcon;
    39   struct _SystrayItem   *nextTrayItem;
     36    HWND                  hWnd;
     37    HWND                  hWndToolTip;
     38    NOTIFYICONDATAA       notifyIcon;
     39    UINT                  uIdx;
     40    struct _SystrayItem   *nextTrayItem;
    4041};
    4142
    42 static SystrayItem *systray=NULL;
     43static SystrayItem *systray = NULL;
    4344
    4445BOOL (*SYSTRAY_ItemInit)(SystrayItem *ptrayItem) = 0;
    4546void (*SYSTRAY_ItemTerm)(SystrayItem *ptrayItem) = 0;
    46 void (*SYSTRAY_ItemSetMessage)(SystrayItem *ptrayItem, ULONG uCallbackMessage) = 0;
    47 void (*SYSTRAY_ItemSetIcon)(SystrayItem *ptrayItem, HICON hIcon) = 0;
    48 void (*SYSTRAY_ItemSetTip)(SystrayItem *ptrayItem, CHAR* szTip, int modify) = 0;
    49 
     47void (*SYSTRAY_ItemUpdate)(SystrayItem *ptrayItem, ULONG uFlags) = 0;
    5048
    5149static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
    5250{
    53   if (pnid1->hWnd != pnid2->hWnd) return FALSE;
    54   if (pnid1->uID  != pnid2->uID)  return FALSE;
    55   return TRUE;
    56 }
    57 
     51    if (pnid1->hWnd != pnid2->hWnd) return FALSE;
     52    if (pnid1->uID  != pnid2->uID)  return FALSE;
     53    return TRUE;
     54}
    5855
    5956static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
    6057{
    61   SystrayItem **ptrayItem = &systray;
    62 
    63   /* Find last element. */
    64   while( *ptrayItem ) {
    65     if ( SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon) )
    66       return FALSE;
    67     ptrayItem = &((*ptrayItem)->nextTrayItem);
    68   }
    69   /* Allocate SystrayItem for element and add to end of list. */
    70   (*ptrayItem) = ( SystrayItem *)malloc( sizeof(SystrayItem) );
    71 
    72   /* Initialize and set data for the tray element. */
    73   SYSTRAY_ItemInit( (*ptrayItem) );
    74   (*ptrayItem)->notifyIcon.uID = pnid->uID; /* only needed for callback message */
    75   (*ptrayItem)->notifyIcon.hWnd = pnid->hWnd; /* only needed for callback message */
    76   SYSTRAY_ItemSetIcon   (*ptrayItem, (pnid->uFlags&NIF_ICON)   ?GetOS2Icon(pnid->hIcon)  :0);
    77   SYSTRAY_ItemSetMessage(*ptrayItem, (pnid->uFlags&NIF_MESSAGE)?pnid->uCallbackMessage:0);
    78   SYSTRAY_ItemSetTip    (*ptrayItem, (pnid->uFlags&NIF_TIP)    ?pnid->szTip           :"", FALSE);
    79 
    80   TRACE("SYSTRAY_Add %p: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",  (*ptrayItem),
    81         (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.hIcon,
    82         pnid->uCallbackMessage, (*ptrayItem)->notifyIcon.uCallbackMessage,
    83         pnid->szTip );
    84   return TRUE;
    85 }
    86 
     58    SystrayItem *pItem = systray, *pPrevItem = NULL, *ptrayItem;
     59    ULONG uIdx = 0;
     60
     61    /* Search for the first free index and also check if already in list */
     62    while (pItem)
     63    {
     64        if (SYSTRAY_ItemIsEqual(pnid, &pItem->notifyIcon))
     65          return FALSE;
     66
     67        uIdx = pPrevItem->uIdx + 1;
     68
     69        if (pPrevItem && pItem->uIdx - pPrevItem->uIdx > 1)
     70        {
     71            /* found a hole in the index row, will insert here */
     72            break;
     73        }
     74
     75        pPrevItem = pItem;
     76        pItem = pItem->nextTrayItem;
     77    }
     78
     79    /* check the rest (if any) for duplicates */
     80    ptrayItem = pItem;
     81    while (ptrayItem)
     82    {
     83        if (SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon))
     84            return FALSE;
     85        ptrayItem = ptrayItem->nextTrayItem;
     86    }
     87
     88    /* Allocate SystrayItem for the new element and insert it */
     89    ptrayItem = ( SystrayItem *)malloc(sizeof(SystrayItem));
     90    memset(ptrayItem, 0, sizeof(SystrayItem));
     91    ptrayItem->nextTrayItem = pItem;
     92
     93    if (pPrevItem)
     94    {
     95        pPrevItem->nextTrayItem = ptrayItem;
     96        ptrayItem->uIdx = pPrevItem->uIdx + 1;
     97    }
     98    else
     99    {
     100        systray = ptrayItem;
     101        ptrayItem->uIdx = 0;
     102    }
     103
     104    /* Initialize and set data for the tray element. */
     105    ptrayItem->uIdx = uIdx;
     106
     107    ptrayItem->notifyIcon.uID = pnid->uID;
     108    ptrayItem->notifyIcon.hWnd = pnid->hWnd;
     109
     110    ptrayItem->notifyIcon.hIcon =
     111        (pnid->uFlags & NIF_ICON) ? GetOS2Icon(pnid->hIcon) : 0;
     112    ptrayItem->notifyIcon.uCallbackMessage =
     113        (pnid->uFlags & NIF_MESSAGE) ? pnid->uCallbackMessage : 0;
     114
     115    if (pnid->uFlags & NIF_TIP)
     116        CharToOemA(pnid->szTip, ptrayItem->notifyIcon.szTip);
     117    else
     118        ptrayItem->notifyIcon.szTip[0] = '\0';
     119
     120    /* Implementation specific initialization */
     121    if (!SYSTRAY_ItemInit(ptrayItem))
     122    {
     123        free(ptrayItem);
     124        if (pPrevItem)
     125            pPrevItem->nextTrayItem = pItem;
     126        else
     127            systray = NULL;
     128        return FALSE;
     129    }
     130
     131    /* Trigger the data update (flags = 0 means it's the first time) */
     132    SYSTRAY_ItemUpdate(ptrayItem, 0);
     133
     134    TRACE("SYSTRAY_Add %p: uIdx %u, hWnd 0x%08x, uID %d, hIcon 0x%08x, "
     135          "uCallbackMessage 0x%08x, szTip [%s]\n",
     136          ptrayItem, ptrayItem->uIdx, ptrayItem->hWnd, ptrayItem->notifyIcon.uID,
     137          ptrayItem->notifyIcon.hIcon,ptrayItem->notifyIcon.uCallbackMessage,
     138          ptrayItem->notifyIcon.szTip);
     139
     140    return TRUE;
     141}
    87142
    88143static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
    89144{
    90   SystrayItem *ptrayItem = systray;
    91 
    92   while ( ptrayItem ) {
    93     if ( SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon) ) {
    94       if (pnid->uFlags & NIF_ICON)
    95         SYSTRAY_ItemSetIcon(ptrayItem, GetOS2Icon(pnid->hIcon) );
    96       if (pnid->uFlags & NIF_MESSAGE)
    97         SYSTRAY_ItemSetMessage(ptrayItem, pnid->uCallbackMessage);
    98       if (pnid->uFlags & NIF_TIP)
    99         SYSTRAY_ItemSetTip(ptrayItem, pnid->szTip, TRUE);
    100 
    101       TRACE("SYSTRAY_Modify %p: 0x%08x %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, pnid->szTip);
    102       return TRUE;
    103     }
    104     ptrayItem = ptrayItem->nextTrayItem;
    105   }
    106   return FALSE; /* not found */
    107 }
    108 
     145    SystrayItem *ptrayItem = systray;
     146
     147    while (ptrayItem)
     148    {
     149        if (SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon))
     150        {
     151            if (pnid->uFlags & NIF_ICON)
     152                ptrayItem->notifyIcon.hIcon = GetOS2Icon(pnid->hIcon);
     153            if (pnid->uFlags & NIF_MESSAGE)
     154                ptrayItem->notifyIcon.uCallbackMessage = pnid->uCallbackMessage;
     155            if (pnid->uFlags & NIF_TIP)
     156                CharToOemA(pnid->szTip, ptrayItem->notifyIcon.szTip);
     157
     158            SYSTRAY_ItemUpdate(ptrayItem, pnid->uFlags);
     159
     160            TRACE("SYSTRAY_Modify %p: uIdx %u, hWnd 0x%08x, uID %d, hIcon 0x%08x, "
     161                  "uCallbackMessage 0x%08x, szTip [%s]\n",
     162                  ptrayItem, ptrayItem->uIdx, ptrayItem->hWnd, ptrayItem->notifyIcon.uID,
     163                  ptrayItem->notifyIcon.hIcon,ptrayItem->notifyIcon.uCallbackMessage,
     164                  ptrayItem->notifyIcon.szTip);
     165
     166            return TRUE;
     167        }
     168        ptrayItem = ptrayItem->nextTrayItem;
     169    }
     170
     171    return FALSE; /* not found */
     172}
    109173
    110174static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid)
    111175{
    112   SystrayItem **ptrayItem = &systray;
    113 
    114   while (*ptrayItem) {
    115     if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
    116       SystrayItem *next = (*ptrayItem)->nextTrayItem;
    117       TRACE("%p: 0x%08x %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.szTip);
    118       SYSTRAY_ItemTerm(*ptrayItem);
    119 
    120       free(*ptrayItem);
    121       *ptrayItem = next;
    122 
    123       return TRUE;
    124     }
    125     ptrayItem = &((*ptrayItem)->nextTrayItem);
    126   }
    127 
    128   return FALSE; /* not found */
     176    SystrayItem **ptrayItem = &systray;
     177
     178    while (*ptrayItem)
     179    {
     180        if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon))
     181        {
     182            SystrayItem *next = (*ptrayItem)->nextTrayItem;
     183
     184            TRACE("SYSTRAY_Delete %p: uIdx %u, hWnd 0x%08x, uID %d\n",
     185                  *ptrayItem, (*ptrayItem)->uIdx, (*ptrayItem)->notifyIcon.hWnd,
     186                  (*ptrayItem)->notifyIcon.uID);
     187
     188            SYSTRAY_ItemTerm(*ptrayItem);
     189
     190            free(*ptrayItem);
     191            *ptrayItem = next;
     192
     193            return TRUE;
     194        }
     195        ptrayItem = &((*ptrayItem)->nextTrayItem);
     196    }
     197
     198    return FALSE; /* not found */
    129199}
    130200
     
    135205BOOL SYSTRAY_Init(void)
    136206{
    137   return TRUE;
     207    return TRUE;
    138208}
    139209#endif
    140210
    141211/*************************************************************************
     212 *
     213 */
     214SystrayItem *SYSTRAY_FindItem(ULONG uIdx)
     215{
     216    SystrayItem *ptrayItem = systray;
     217
     218    while (ptrayItem)
     219    {
     220        if (ptrayItem->uIdx == uIdx)
     221            return ptrayItem;
     222
     223        ptrayItem = ptrayItem->nextTrayItem;
     224    }
     225
     226    return NULL; /* not found */
     227}
     228
     229/*************************************************************************
    142230 * Shell_NotifyIconA            [SHELL32.297][SHELL32.296]
    143231 */
    144232BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
    145233{
    146   BOOL flag=FALSE;
    147   TRACE("enter %d %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
    148   switch(dwMessage) {
    149   case NIM_ADD:
    150     flag = SYSTRAY_Add(pnid);
    151     break;
    152   case NIM_MODIFY:
    153     flag = SYSTRAY_Modify(pnid);
    154     break;
    155   case NIM_DELETE:
    156     flag = SYSTRAY_Delete(pnid);
    157     break;
    158   }
    159   TRACE("leave %d %d %ld=%d\n", pnid->hWnd, pnid->uID, dwMessage, flag);
    160   return flag;
     234    BOOL flag = FALSE;
     235    switch(dwMessage)
     236    {
     237        case NIM_ADD:
     238            flag = SYSTRAY_Add(pnid);
     239            break;
     240        case NIM_MODIFY:
     241            flag = SYSTRAY_Modify(pnid);
     242            break;
     243        case NIM_DELETE:
     244            flag = SYSTRAY_Delete(pnid);
     245            break;
     246    }
     247    return flag;
    161248}
    162249
     
    192279}
    193280
    194 BOOL DoWin32CharToOem(const char *s, char *t)
    195 {
    196         return CharToOemA( s , t );
    197 }
    198 
    199281#endif
Note: See TracChangeset for help on using the changeset viewer.