source: trunk/src/shell32/systray_os2ex.c@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1/*
2 * OS/2 System Tray support.
3 * A better implementaiton using the xsystray XCenter/eCenter widget API.
4 *
5 * Author: Dmitriy Kuminov
6 */
7
8#define INCL_PM
9#define INCL_DOS
10#define INCL_DOSERRORS
11#include <os2wrap.h> // Odin32 OS/2 api wrappers
12
13#include <win32api.h>
14
15#include <string.h>
16
17// declare function pointers for dynamic linking to xsystray DLL
18#define XSTAPI_FPTRS_STATIC
19#include "xsystray.h"
20
21#include "systray_os2.h"
22
23#include "dbglog.h"
24
25#define WM_XST_MYNOTIFY (WM_USER + 1000)
26
27static ULONG WM_XST_CREATED = 0;
28static ULONG WM_TASKBARCREATED_W = 0;
29
30static HWND hwndProxy = NULLHANDLE;
31static ULONG hwndProxyRefs = 0;
32
33static PFNWP OldProxyWndProc = NULL;
34
35static MRESULT EXPENTRY ProxyWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
36{
37 switch (msg)
38 {
39 case WM_XST_MYNOTIFY:
40 {
41 USHORT usIconID = SHORT1FROMMP(mp1);
42 USHORT usNotifyCode = SHORT2FROMMP(mp1);
43
44 SystrayItem *ptrayItem = SYSTRAY_FindItem(usIconID);
45 if (!ptrayItem)
46 return (MRESULT)FALSE;
47
48 switch (usNotifyCode)
49 {
50 case XST_IN_MOUSE:
51 {
52 PXSTMOUSEMSG pmmsg = (PXSTMOUSEMSG)mp2;
53 ULONG winMsg = 0;
54
55 switch (pmmsg->ulMouseMsg)
56 {
57 case WM_BUTTON1DBLCLK: winMsg = WM_LBUTTONDBLCLK_W; break;
58 case WM_BUTTON2DBLCLK: winMsg = WM_RBUTTONDBLCLK_W; break;
59 case WM_BUTTON3DBLCLK: winMsg = WM_MBUTTONDBLCLK_W; break;
60 case WM_BUTTON1UP: winMsg = WM_LBUTTONUP_W; break;
61 case WM_BUTTON2UP: winMsg = WM_RBUTTONUP_W; break;
62 case WM_BUTTON3UP: winMsg = WM_MBUTTONUP_W; break;
63 case WM_BUTTON1DOWN: winMsg = WM_LBUTTONDOWN_W; break;
64 case WM_BUTTON2DOWN: winMsg = WM_RBUTTONDOWN_W; break;
65 case WM_BUTTON3DOWN: winMsg = WM_MBUTTONDOWN_W; break;
66 default: break;
67 }
68
69 if (winMsg)
70 {
71 PostMessageA(ptrayItem->notifyIcon.hWnd,
72 ptrayItem->notifyIcon.uCallbackMessage,
73 (WPARAM)ptrayItem->notifyIcon.uID,
74 (LPARAM)winMsg);
75 return (MRESULT)TRUE;
76 }
77 break;
78 }
79 case XST_IN_CONTEXT:
80 {
81 PostMessageA(ptrayItem->notifyIcon.hWnd,
82 ptrayItem->notifyIcon.uCallbackMessage,
83 (WPARAM)ptrayItem->notifyIcon.uID,
84 (LPARAM)WM_CONTEXTMENU_W);
85 return (MRESULT)TRUE;
86 }
87 default:
88 break;
89 }
90
91 return (MRESULT)FALSE;
92 }
93 default:
94 {
95 if (msg == WM_XST_CREATED)
96 {
97 // xCenter was restarted, no icons are shown; remove all items
98 // and broadcast TaskbarCreated to let applications recreate them
99 SYSTRAY_PruneAllItems();
100
101 dprintf(("SHELL32: SYSTRAY: Broadcasting \"TaskbarCreated\" (%x)",
102 WM_TASKBARCREATED_W));
103 PostMessageA(HWND_BROADCAST_W, WM_TASKBARCREATED_W,
104 (WPARAM)0, (LPARAM)0);
105 return (MRESULT)TRUE;
106 }
107 break;
108 }
109 }
110
111 return WinDefWindowProc(hWnd, msg, mp1, mp2);
112}
113
114static BOOL SYSTRAY_Ex_ItemInit(SystrayItem *ptrayItem)
115{
116 if (hwndProxyRefs == 0)
117 {
118 if (!WinRegisterClass(NULLHANDLE, "OdinXSysTrayProxy", ProxyWndProc,
119 0, 0))
120 {
121 dprintf(("SHELL32: SYSTRAY: WinRegisterClass() failed with %x",
122 WinGetLastError(0)));
123 return FALSE;
124 }
125
126 hwndProxy = WinCreateWindow(HWND_DESKTOP, "OdinXSysTrayProxy", NULL,
127 0, 0, 0, 0, 0, NULLHANDLE, HWND_BOTTOM, 0,
128 NULL, NULL);
129
130 if (hwndProxy == NULLHANDLE)
131 {
132 dprintf(("SHELL32: SYSTRAY: WinCreateWindow() failed with %x",
133 WinGetLastError(0)));
134 return FALSE;
135 }
136 }
137
138 ++ hwndProxyRefs;
139
140 return TRUE;
141}
142
143static void SYSTRAY_Ex_ItemTerm(SystrayItem *ptrayItem)
144{
145 xstRemoveSysTrayIcon(hwndProxy, ptrayItem->uIdx);
146
147 if (-- hwndProxyRefs == 0)
148 {
149 WinDestroyWindow(hwndProxy);
150 hwndProxy = NULLHANDLE;
151 }
152}
153
154static void SYSTRAY_Ex_ItemUpdate(SystrayItem *ptrayItem, ULONG uFlags)
155{
156 if (uFlags == 0 || (uFlags & (NIF_ICON | NIF_TIP) == NIF_ICON | NIF_TIP))
157 {
158 // uFlags = 0 means it's the first time so add the icon. The other case
159 // is true when a bunch of the parameters is changed at once so use
160 // xstAdd... too to save a few IPC calls.
161 xstAddSysTrayIcon(hwndProxy, ptrayItem->uIdx,
162 ptrayItem->notifyIcon.hIcon,
163 ptrayItem->notifyIcon.szTip,
164 WM_XST_MYNOTIFY,
165 XST_IN_MOUSE | XST_IN_CONTEXT);
166 return;
167 }
168
169 if (uFlags & NIF_ICON)
170 {
171 xstReplaceSysTrayIcon(hwndProxy, ptrayItem->uIdx,
172 ptrayItem->notifyIcon.hIcon);
173 }
174 if (uFlags & NIF_TIP)
175 {
176 xstSetSysTrayIconToolTip(hwndProxy, ptrayItem->uIdx,
177 ptrayItem->notifyIcon.szTip);
178 }
179}
180
181BOOL SYSTRAY_Ex_Init(void)
182{
183 static BOOL tried = FALSE;
184 if (!tried) {
185 char err[CCHMAXPATH];
186 HMODULE hmod;
187
188 tried = TRUE;
189
190 // link to the xsystray DLL at runtime
191 if (DosLoadModule(err, sizeof(err), "XSYSTRAY", &hmod) != NO_ERROR)
192 return FALSE;
193
194 #define R(f) if (DosQueryProcAddr(hmod, 0, #f, (PFN*)&f) != NO_ERROR) return FALSE
195
196 R(xstQuerySysTrayVersion);
197 R(xstAddSysTrayIcon);
198 R(xstReplaceSysTrayIcon);
199 R(xstRemoveSysTrayIcon);
200 R(xstSetSysTrayIconToolTip);
201 R(xstQuerySysTrayIconRect);
202 R(xstGetSysTrayCreatedMsgId);
203 R(xstGetSysTrayMaxTextLen);
204
205 #undef R
206 }
207
208 // check if xsystray is there
209 if (!xstQuerySysTrayVersion(NULL, NULL, NULL))
210 return FALSE;
211
212 // initialize some constants
213 WM_XST_CREATED = xstGetSysTrayCreatedMsgId();
214
215 WM_TASKBARCREATED_W = RegisterWindowMessageA("TaskbarCreated");
216
217 SYSTRAY_ItemInit = SYSTRAY_Ex_ItemInit;
218 SYSTRAY_ItemTerm = SYSTRAY_Ex_ItemTerm;
219 SYSTRAY_ItemUpdate = SYSTRAY_Ex_ItemUpdate;
220
221 return TRUE;
222}
223
Note: See TracBrowser for help on using the repository browser.