Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. | |
3 | * | |
4 | *Permission is hereby granted, free of charge, to any person obtaining | |
5 | * a copy of this software and associated documentation files (the | |
6 | *"Software"), to deal in the Software without restriction, including | |
7 | *without limitation the rights to use, copy, modify, merge, publish, | |
8 | *distribute, sublicense, and/or sell copies of the Software, and to | |
9 | *permit persons to whom the Software is furnished to do so, subject to | |
10 | *the following conditions: | |
11 | * | |
12 | *The above copyright notice and this permission notice shall be | |
13 | *included in all copies or substantial portions of the Software. | |
14 | * | |
15 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
16 | *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
17 | *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
18 | *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR | |
19 | *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
20 | *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
21 | *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
22 | * | |
23 | *Except as contained in this notice, the name of the XFree86 Project | |
24 | *shall not be used in advertising or otherwise to promote the sale, use | |
25 | *or other dealings in this Software without prior written authorization | |
26 | *from the XFree86 Project. | |
27 | * | |
28 | * Authors: Early Ehlinger | |
29 | * Harold L Hunt II | |
30 | */ | |
31 | ||
32 | #ifdef HAVE_XWIN_CONFIG_H | |
33 | #include <xwin-config.h> | |
34 | #endif | |
35 | #include "win.h" | |
36 | #include <shellapi.h> | |
37 | #include "winprefs.h" | |
38 | ||
39 | /* | |
40 | * Initialize the tray icon | |
41 | */ | |
42 | ||
43 | void | |
44 | winInitNotifyIcon(winPrivScreenPtr pScreenPriv) | |
45 | { | |
46 | winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; | |
47 | NOTIFYICONDATA nid = { 0 }; | |
48 | ||
49 | nid.cbSize = sizeof(NOTIFYICONDATA); | |
50 | nid.hWnd = pScreenPriv->hwndScreen; | |
51 | nid.uID = pScreenInfo->dwScreen; | |
52 | nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; | |
53 | nid.uCallbackMessage = WM_TRAYICON; | |
54 | nid.hIcon = winTaskbarIcon(); | |
55 | ||
56 | /* Save handle to the icon so it can be freed later */ | |
57 | pScreenPriv->hiconNotifyIcon = nid.hIcon; | |
58 | ||
59 | /* Set display and screen-specific tooltip text */ | |
60 | snprintf(nid.szTip, | |
61 | sizeof(nid.szTip), | |
62 | PROJECT_NAME " Server:%s.%d", | |
63 | display, (int) pScreenInfo->dwScreen); | |
64 | ||
65 | /* Add the tray icon */ | |
66 | if (!Shell_NotifyIcon(NIM_ADD, &nid)) | |
67 | ErrorF("winInitNotifyIcon - Shell_NotifyIcon Failed\n"); | |
68 | } | |
69 | ||
70 | /* | |
71 | * Delete the tray icon | |
72 | */ | |
73 | ||
74 | void | |
75 | winDeleteNotifyIcon(winPrivScreenPtr pScreenPriv) | |
76 | { | |
77 | winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; | |
78 | NOTIFYICONDATA nid = { 0 }; | |
79 | ||
80 | #if 0 | |
81 | ErrorF("winDeleteNotifyIcon\n"); | |
82 | #endif | |
83 | ||
84 | nid.cbSize = sizeof(NOTIFYICONDATA); | |
85 | nid.hWnd = pScreenPriv->hwndScreen; | |
86 | nid.uID = pScreenInfo->dwScreen; | |
87 | ||
88 | /* Delete the tray icon */ | |
89 | if (!Shell_NotifyIcon(NIM_DELETE, &nid)) { | |
90 | ErrorF("winDeleteNotifyIcon - Shell_NotifyIcon failed\n"); | |
91 | return; | |
92 | } | |
93 | ||
94 | /* Free the icon that was loaded */ | |
95 | if (pScreenPriv->hiconNotifyIcon != NULL | |
96 | && DestroyIcon(pScreenPriv->hiconNotifyIcon) == 0) { | |
97 | ErrorF("winDeleteNotifyIcon - DestroyIcon failed\n"); | |
98 | } | |
99 | pScreenPriv->hiconNotifyIcon = NULL; | |
100 | } | |
101 | ||
102 | /* | |
103 | * Process messages intended for the tray icon | |
104 | */ | |
105 | ||
106 | LRESULT | |
107 | winHandleIconMessage(HWND hwnd, UINT message, | |
108 | WPARAM wParam, LPARAM lParam, winPrivScreenPtr pScreenPriv) | |
109 | { | |
110 | #if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_MULTIWINDOW) | |
111 | winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; | |
112 | #endif | |
113 | ||
114 | switch (lParam) { | |
115 | case WM_LBUTTONUP: | |
116 | /* Restack and bring all windows to top */ | |
117 | SetForegroundWindow (pScreenPriv->hwndScreen); | |
118 | ||
119 | #ifdef XWIN_MULTIWINDOWEXTWM | |
120 | if (pScreenInfo->fMWExtWM) | |
121 | winMWExtWMRestackWindows(pScreenInfo->pScreen); | |
122 | #endif | |
123 | break; | |
124 | ||
125 | case WM_LBUTTONDBLCLK: | |
126 | /* Display Exit dialog box */ | |
127 | winDisplayExitDialog(pScreenPriv); | |
128 | break; | |
129 | ||
130 | case WM_RBUTTONUP: | |
131 | { | |
132 | POINT ptCursor; | |
133 | HMENU hmenuPopup; | |
134 | HMENU hmenuTray; | |
135 | ||
136 | /* Get cursor position */ | |
137 | GetCursorPos(&ptCursor); | |
138 | ||
139 | /* Load tray icon menu resource */ | |
140 | hmenuPopup = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_TRAYICON_MENU)); | |
141 | if (!hmenuPopup) | |
142 | ErrorF("winHandleIconMessage - LoadMenu failed\n"); | |
143 | ||
144 | /* Get actual tray icon menu */ | |
145 | hmenuTray = GetSubMenu(hmenuPopup, 0); | |
146 | ||
147 | #ifdef XWIN_MULTIWINDOW | |
148 | /* Check for MultiWindow mode */ | |
149 | if (pScreenInfo->fMultiWindow) { | |
150 | MENUITEMINFO mii = { 0 }; | |
151 | ||
152 | /* Root is shown, remove the check box */ | |
153 | ||
154 | /* Setup menu item info structure */ | |
155 | mii.cbSize = sizeof(MENUITEMINFO); | |
156 | mii.fMask = MIIM_STATE; | |
157 | mii.fState = MFS_CHECKED; | |
158 | ||
159 | /* Unheck box if root is shown */ | |
160 | if (pScreenPriv->fRootWindowShown) | |
161 | mii.fState = MFS_UNCHECKED; | |
162 | ||
163 | /* Set menu state */ | |
164 | SetMenuItemInfo(hmenuTray, ID_APP_HIDE_ROOT, FALSE, &mii); | |
165 | } | |
166 | else | |
167 | #endif | |
168 | { | |
169 | /* Remove Hide Root Window button */ | |
170 | RemoveMenu(hmenuTray, ID_APP_HIDE_ROOT, MF_BYCOMMAND); | |
171 | } | |
172 | ||
173 | SetupRootMenu(hmenuTray); | |
174 | ||
175 | /* | |
176 | * NOTE: This three-step procedure is required for | |
177 | * proper popup menu operation. Without the | |
178 | * call to SetForegroundWindow the | |
179 | * popup menu will often not disappear when you click | |
180 | * outside of it. Without the PostMessage the second | |
181 | * time you display the popup menu it might immediately | |
182 | * disappear. | |
183 | */ | |
184 | SetForegroundWindow(hwnd); | |
185 | TrackPopupMenuEx(hmenuTray, | |
186 | TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, | |
187 | ptCursor.x, ptCursor.y, hwnd, NULL); | |
188 | PostMessage(hwnd, WM_NULL, 0, 0); | |
189 | ||
190 | /* Free menu */ | |
191 | DestroyMenu(hmenuPopup); | |
192 | } | |
193 | break; | |
194 | } | |
195 | ||
196 | return 0; | |
197 | } |