Ignore:
Timestamp:
Oct 27, 2009, 2:36:55 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: xsystray: Further coding (established communication channel between the clients and the server, some bug fixes).

File:
1 edited

Legend:

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

    r255 r256  
    4040#include <stdio.h>
    4141#include <string.h>
     42#include <stdlib.h>
     43#include <stdarg.h>
    4244
    4345// generic headers
     
    7375#pragma hdrstop                     // VAC++ keeps crashing otherwise
    7476
     77// primitive debug logging to a file
     78#if 1
     79static void __LOG_WORKER(const char *fmt, ...)
     80{
     81    static FILE *f = NULL;
     82    if (f == NULL)
     83    {
     84        f = fopen("c:\\xsystray.dbg", "a");
     85        setbuf(f, NULL);
     86    }
     87    if (f != NULL)
     88    {
     89        va_list vl;
     90        va_start(vl, fmt);
     91        vfprintf(f, fmt, vl);
     92        va_end(vl);
     93    }
     94}
     95#define LOG(m)  do { __LOG_WORKER m; } while(0)
     96#define LOGF(m) do { __LOG_WORKER("%s: ", __FUNCTION__); __LOG_WORKER m; } while(0)
     97#else
     98#define LOG(m)  do {} while (0)
     99#define LOGF(m) do {} while (0)
     100#endif
     101
    75102/* ******************************************************************
    76103 *
     
    79106 ********************************************************************/
    80107
    81 // None currently.
     108/*
     109 *@@ ICONDATA:
     110 *      Per-icon data.
     111 */
     112
     113typedef struct _ICONDATA
     114{
     115    HWND        hwnd;
     116                // associated window
     117    ULONG       ulId;
     118                // icon ID
     119    HPOINTER    hIcon;
     120                // icon handle
     121    ULONG       ulMsgId;
     122                // message ID for notifications
     123    PSZ         pszToolTip;
     124                // icon tooltip (NULL if none)
     125
     126} ICONDATA, *PICONDATA;
     127
     128/*
     129 *@@ SYSTRAYDATA:
     130 *      Global system tray data.
     131 */
     132
     133typedef struct
     134{
     135    PICONDATA   pIcons;
     136                // array of icons currently shown in the system tray
     137                // (left to right)
     138    size_t      cIcons;
     139                // number of icons in the pIcons array
     140    size_t      cIconsMax;
     141                // maximum number of icons pIcons can fit
     142
     143} SYSTRAYDATA, *PSYSTRAYDATA;
     144
     145ULONG QWL_USER_SERVER_DATA = 0;
    82146
    83147/* ******************************************************************
     
    196260 */
    197261
     262static
    198263BOOL WgtControl(PXCENTERWIDGET pWidget,
    199264                MPARAM mp1,
     
    240305 */
    241306
     307static
    242308VOID WgtPaint(HWND hwnd,
    243309              PXCENTERWIDGET pWidget)
     
    274340/*
    275341 *@@ fnwpXSysTray:
    276  *      window procedure for the winlist widget class.
     342 *      window procedure for the Extended system tray widget class.
    277343 *
    278344 *      There are a few rules which widget window procs
     
    311377
    312378        case WM_CREATE:
     379        {
     380            PSYSTRAYDATA pSysTrayData = NULL;
     381
     382            mrc = (MPARAM)TRUE; // being pessimistic gives more compact code
     383
    313384            WinSetWindowPtr(hwnd, QWL_USER, mp1);
    314385            if (    (!(pWidget = (PXCENTERWIDGET)mp1))
     
    316387               )
    317388                // shouldn't happen... stop window creation!!
    318                 mrc = (MPARAM)TRUE;
     389                break;
     390
     391            pSysTrayData = malloc(sizeof(*pSysTrayData));
     392            if (pSysTrayData == NULL)
     393                break;
     394
     395            // initialize the SYSTRAYDATA structure
     396            pSysTrayData->cIconsMax = 4;
     397            pSysTrayData->pIcons = malloc(sizeof(*pSysTrayData->pIcons) *
     398                                          pSysTrayData->cIconsMax);
     399            if (pSysTrayData->pIcons == NULL)
     400            {
     401                free(pSysTrayData);
     402                break;
     403            }
     404            pSysTrayData->cIcons = 0;
     405            pWidget->pUser = pSysTrayData;
     406
     407            // create the "server" window (note that we pass the XCENTERWIDGET
     408            // pointer on to it)
     409            HWND hwndServer =
     410                WinCreateWindow(HWND_DESKTOP, WNDCLASS_WIDGET_XSYSTRAY_SERVER,
     411                                NULL, WS_MINIMIZED,
     412                                0, 0, 0, 0,
     413                                HWND_DESKTOP, HWND_BOTTOM,
     414                                0, mp1, NULL);
     415            if (hwndServer == NULLHANDLE)
     416                break;
     417
     418            mrc = FALSE; // confirm success
     419        }
    319420        break;
    320421
     
    353454
    354455        case WM_DESTROY:
    355             // If we had any user data allocated in WM_CREATE
    356             // or elsewhere, we'd clean this up here.
     456        {
     457            // free all system tray data
     458            PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
     459            size_t i;
     460            for (i = 0; i < pSysTrayData->cIcons; ++i)
     461            {
     462                if (pSysTrayData->pIcons[i].pszToolTip)
     463                    free(pSysTrayData->pIcons[i].pszToolTip);
     464            }
     465            free(pSysTrayData->pIcons);
     466            free(pSysTrayData);
     467            pWidget->pUser = NULL;
    357468            // We _MUST_ pass this on, or the default widget proc
    358469            // cannot clean up.
    359470            mrc = pWidget->pfnwpDefWidgetProc(hwnd, msg, mp1, mp2);
     471        }
    360472        break;
    361473
     
    363475            mrc = pWidget->pfnwpDefWidgetProc(hwnd, msg, mp1, mp2);
    364476
     477    } // end switch(msg)
     478
     479    return mrc;
     480}
     481
     482/*
     483 *@@ WgtXSysTrayControl:
     484 *      implementation for WM_XST_CONTROL in fnwpXSysTrayServer.
     485 *
     486 *      Serves as an entry point for all client-side requests to the Extended
     487 *      system tray.
     488 *
     489 *      Note that this message is being sent from another process which is
     490 *      awaiting for an answer, so it must return as far as possible (by
     491 *      rescheduling any potentially long term operation for another cycle).
     492 */
     493
     494static
     495BOOL WgtXSysTrayControl(HWND hwnd, PXCENTERWIDGET pWidget,
     496                        PSYSTRAYCTLDATA pCtlData)
     497{
     498    BOOL brc = FALSE;
     499
     500    switch (pCtlData->ulCommand)
     501    {
     502        case SYSTRAYCMD_GETVERSION:
     503        {
     504            LOGF(("SYSTRAYCMD_GETVERSION\n"));
     505
     506            pCtlData->bAcknowledged = TRUE;
     507            pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MAJOR;
     508            pCtlData->u.version.ulMajor = XSYSTRAY_VERSION_MINOR;
     509            pCtlData->u.version.ulRevision = XSYSTRAY_VERSION_REVISION;
     510            brc = TRUE;
     511        }
     512        break;
     513
     514        default:
     515            break;
     516    }
     517
     518    return brc;
     519}
     520
     521/*
     522 *@@ fnwpXSysTrayServer:
     523 *      window procedure for the Extended system tray server window class.
     524 *
     525 *      A separate "server" class is necessary because we need a CS_FRAME
     526 *      top-level window for DDE (which we need to support to be backward
     527 *      compatible with the System tray wdget from the SysTray/WPS package) and
     528 *      also to make ourselves discoverable for the client-side implementation
     529 *      of our new extended API (which queries the class of each top-level
     530 *      window to find the system tray server).
     531 */
     532
     533static
     534MRESULT EXPENTRY fnwpXSysTrayServer(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     535{
     536    MRESULT mrc = 0;
     537    // get widget data from QWL_USER_SERVER_DATA (stored there by WM_CREATE)
     538    PXCENTERWIDGET pWidget =
     539        (PXCENTERWIDGET)WinQueryWindowPtr(hwnd, QWL_USER_SERVER_DATA);
     540                    // this ptr is valid after WM_CREATE
     541
     542    switch (msg)
     543    {
     544        case WM_CREATE:
     545            WinSetWindowPtr(hwnd, QWL_USER_SERVER_DATA, mp1);
     546        break;
     547
     548        /*
     549         * WM_XST_CONTROL:
     550         *      This is the message sent to us by the clinet-side implementation
     551         *      of the API to request some function. mp1 points to a
     552         *      SYSTRAYCTLDATA structure.
     553         */
     554
     555        case WM_XST_CONTROL:
     556            mrc = (MRESULT)WgtXSysTrayControl(hwnd, pWidget,
     557                                              (PSYSTRAYCTLDATA)mp1);
     558        break;
     559
     560        default:
     561            mrc = WinDefWindowProc(hwnd, msg, mp1, mp2);
    365562    } // end switch(msg)
    366563
     
    428625                             PSZ pszErrorMsg)       // if 0 is returned, 500 bytes of error msg
    429626{
    430     ULONG   ulrc = 0;
    431 
    432     // register our PM window class
    433     if (!WinRegisterClass(hab,
    434                           WNDCLASS_WIDGET_XSYSTRAY,
    435                           fnwpXSysTray,
    436                           CS_PARENTCLIP | CS_SIZEREDRAW | CS_SYNCPAINT,
    437                           sizeof(PVOID))
     627    ULONG       ulrc = 0;
     628    CLASSINFO   ClassInfo;
     629
     630    LOGF(("hmodPlugin %x\n", hmodPlugin));
     631
     632    do
     633    {
     634        // register our PM window class
     635        if (!WinRegisterClass(hab,
     636                             WNDCLASS_WIDGET_XSYSTRAY,
     637                             fnwpXSysTray,
     638                             CS_PARENTCLIP | CS_SIZEREDRAW | CS_SYNCPAINT,
     639                             sizeof(PVOID))
    438640                                // extra memory to reserve for QWL_USER
    439                          )
    440         // error registering class: report error then
    441         strcpy(pszErrorMsg, "WinRegisterClass failed.");
    442     else
    443     {
     641            )
     642        {
     643            LOG(("WinRegisterClass(%s) failed with %lX",
     644                 WNDCLASS_WIDGET_XSYSTRAY, WinGetLastError(hab)));
     645            break;
     646        }
     647
     648        // get the window data size for the WC_FRAME class (any window class
     649        // that specifies CS_FRAME must have at least this number, otherise
     650        // WinRegisterClass returns 0x1003
     651        if (!WinQueryClassInfo(hab, (PSZ)WC_FRAME, &ClassInfo))
     652            break;
     653        QWL_USER_SERVER_DATA = ClassInfo.cbWindowData;
     654
     655        if (!WinRegisterClass(hab,
     656                              WNDCLASS_WIDGET_XSYSTRAY_SERVER,
     657                              fnwpXSysTrayServer,
     658                              CS_FRAME,
     659                              QWL_USER_SERVER_DATA + sizeof(PVOID))
     660                                // extra memory to reserve for QWL_USER
     661            )
     662        {
     663            // error registering class: report error then
     664            snprintf(pszErrorMsg, 500, "WinRegisterClass(%s) failed with %lX",
     665                     WNDCLASS_WIDGET_XSYSTRAY_SERVER, WinGetLastError(hab));
     666            break;
     667        }
     668
    444669        // no error:
    445670        // return widget classes array
     
    449674        ulrc = sizeof(G_WidgetClasses) / sizeof(G_WidgetClasses[0]);
    450675    }
     676    while (0);
     677
     678    LOGF(("pszErrorMsg %s\n", pszErrorMsg));
     679    LOGF(("ulrc %d\n", ulrc));
    451680
    452681    return ulrc;
     
    489718{
    490719    *pulMajor = 0;
    491     *pulMinor = 1;
    492     *pulRevision = 0;
    493 }
    494 
     720    *pulMinor = 9;
     721    *pulRevision = 9;
     722}
     723
Note: See TracChangeset for help on using the changeset viewer.