VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp@ 44824

Last change on this file since 44824 was 35907, checked in by vboxsync, 14 years ago

Main/Frontends: Also use facilities for guest features (seamless, graphics), added facility-state-to-name to VBoxManage, some renaming.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1/** @file
2 * helpers - Guest Additions Service helper functions
3 */
4
5/*
6 * Copyright (C) 2006-2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <malloc.h>
18#include <windows.h>
19
20#include <iprt/string.h>
21#include <VBox/Log.h>
22#include <VBox/VBoxGuestLib.h>
23
24#include <VBoxGuestInternal.h>
25
26#include "VBoxHelpers.h"
27#include "resource.h"
28
29
30int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent)
31{
32 int rc = VbglR3ReportAdditionsStatus(VBoxGuestFacilityType_VBoxTrayClient,
33 statusCurrent,
34 0 /* Flags */);
35 if (RT_FAILURE(rc))
36 Log(("VBoxTray: Could not report VBoxTray status \"%ld\", rc=%Rrc\n", statusCurrent, rc));
37 return rc;
38}
39
40/**
41 * Attempt to force Windows to reload the cursor image by attaching to the
42 * thread of the window currently under the mouse, hiding the cursor and
43 * showing it again. This could fail to work in any number of ways (no
44 * window under the cursor, the cursor has moved to a different window while
45 * we are processing), but we just accept this, as the cursor will be reloaded
46 * at some point anyway.
47 */
48void hlpReloadCursor(void)
49{
50 POINT mousePos;
51 HWND hWin;
52 DWORD hThread, hCurrentThread;
53
54 GetCursorPos(&mousePos);
55 hWin = WindowFromPoint(mousePos);
56 if (hWin)
57 {
58 hThread = GetWindowThreadProcessId(hWin, NULL);
59 hCurrentThread = GetCurrentThreadId();
60 if (hCurrentThread != hThread)
61 AttachThreadInput(hCurrentThread, hThread, TRUE);
62 }
63 ShowCursor(false);
64 ShowCursor(true);
65 if (hWin && (hCurrentThread != hThread))
66 AttachThreadInput(hCurrentThread, hThread, FALSE);
67}
68
69static unsigned hlpNextAdjacentRectXP(RECTL *paRects, unsigned nRects, unsigned uRect)
70{
71 unsigned i;
72 for (i = 0; i < nRects; i++)
73 {
74 if (paRects[uRect].right == paRects[i].left)
75 return i;
76 }
77 return ~0;
78}
79
80static unsigned hlpNextAdjacentRectXN(RECTL *paRects, unsigned nRects, unsigned uRect)
81{
82 unsigned i;
83 for (i = 0; i < nRects; i++)
84 {
85 if (paRects[uRect].left == paRects[i].right)
86 return i;
87 }
88 return ~0;
89}
90
91static unsigned hlpNextAdjacentRectYP(RECTL *paRects, unsigned nRects, unsigned uRect)
92{
93 unsigned i;
94 for (i = 0; i < nRects; i++)
95 {
96 if (paRects[uRect].bottom == paRects[i].top)
97 return i;
98 }
99 return ~0;
100}
101
102static unsigned hlpNextAdjacentRectYN(RECTL *paRects, unsigned nRects, unsigned uRect)
103{
104 unsigned i;
105 for (i = 0; i < nRects; i++)
106 {
107 if (paRects[uRect].top == paRects[i].bottom)
108 return i;
109 }
110 return ~0;
111}
112
113void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary,
114 unsigned uResized, int iNewWidth, int iNewHeight)
115{
116 DDCLOG(("nRects %d, iPrimary %d, iResized %d, NewWidth %d, NewHeight %d\n", nRects, uPrimary, uResized, iNewWidth, iNewHeight));
117
118 RECTL *paNewRects = (RECTL *)alloca (sizeof (RECTL) * nRects);
119 memcpy (paNewRects, paRects, sizeof (RECTL) * nRects);
120 paNewRects[uResized].right += iNewWidth - (paNewRects[uResized].right - paNewRects[uResized].left);
121 paNewRects[uResized].bottom += iNewHeight - (paNewRects[uResized].bottom - paNewRects[uResized].top);
122
123 /* Verify all pairs of originally adjacent rectangles for all 4 directions.
124 * If the pair has a "good" delta (that is the first rectangle intersects the second)
125 * at a direction and the second rectangle is not primary one (which can not be moved),
126 * move the second rectangle to make it adjacent to the first one.
127 */
128
129 /* X positive. */
130 unsigned iRect;
131 for (iRect = 0; iRect < nRects; iRect++)
132 {
133 /* Find the next adjacent original rect in x positive direction. */
134 unsigned iNextRect = hlpNextAdjacentRectXP(paRects, nRects, iRect);
135 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
136
137 if (iNextRect == ~0 || iNextRect == uPrimary)
138 {
139 continue;
140 }
141
142 /* Check whether there is an X intersection between these adjacent rects in the new rectangles
143 * and fix the intersection if delta is "good".
144 */
145 int delta = paNewRects[iRect].right - paNewRects[iNextRect].left;
146
147 if (delta != 0)
148 {
149 DDCLOG(("XP intersection right %d left %d, diff %d\n",
150 paNewRects[iRect].right, paNewRects[iNextRect].left,
151 delta));
152
153 paNewRects[iNextRect].left += delta;
154 paNewRects[iNextRect].right += delta;
155 }
156 }
157
158 /* X negative. */
159 for (iRect = 0; iRect < nRects; iRect++)
160 {
161 /* Find the next adjacent original rect in x negative direction. */
162 unsigned iNextRect = hlpNextAdjacentRectXN(paRects, nRects, iRect);
163 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
164
165 if (iNextRect == ~0 || iNextRect == uPrimary)
166 {
167 continue;
168 }
169
170 /* Check whether there is an X intersection between these adjacent rects in the new rectangles
171 * and fix the intersection if delta is "good".
172 */
173 int delta = paNewRects[iRect].left - paNewRects[iNextRect].right;
174
175 if (delta != 0)
176 {
177 DDCLOG(("XN intersection left %d right %d, diff %d\n",
178 paNewRects[iRect].left, paNewRects[iNextRect].right,
179 delta));
180
181 paNewRects[iNextRect].left += delta;
182 paNewRects[iNextRect].right += delta;
183 }
184 }
185
186 /* Y positive (in the computer sense, top->down). */
187 for (iRect = 0; iRect < nRects; iRect++)
188 {
189 /* Find the next adjacent original rect in y positive direction. */
190 unsigned iNextRect = hlpNextAdjacentRectYP(paRects, nRects, iRect);
191 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
192
193 if (iNextRect == ~0 || iNextRect == uPrimary)
194 {
195 continue;
196 }
197
198 /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
199 * and fix the intersection if delta is "good".
200 */
201 int delta = paNewRects[iRect].bottom - paNewRects[iNextRect].top;
202
203 if (delta != 0)
204 {
205 DDCLOG(("YP intersection bottom %d top %d, diff %d\n",
206 paNewRects[iRect].bottom, paNewRects[iNextRect].top,
207 delta));
208
209 paNewRects[iNextRect].top += delta;
210 paNewRects[iNextRect].bottom += delta;
211 }
212 }
213
214 /* Y negative (in the computer sense, down->top). */
215 for (iRect = 0; iRect < nRects; iRect++)
216 {
217 /* Find the next adjacent original rect in x negative direction. */
218 unsigned iNextRect = hlpNextAdjacentRectYN(paRects, nRects, iRect);
219 DDCLOG(("next %d -> %d\n", iRect, iNextRect));
220
221 if (iNextRect == ~0 || iNextRect == uPrimary)
222 {
223 continue;
224 }
225
226 /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
227 * and fix the intersection if delta is "good".
228 */
229 int delta = paNewRects[iRect].top - paNewRects[iNextRect].bottom;
230
231 if (delta != 0)
232 {
233 DDCLOG(("YN intersection top %d bottom %d, diff %d\n",
234 paNewRects[iRect].top, paNewRects[iNextRect].bottom,
235 delta));
236
237 paNewRects[iNextRect].top += delta;
238 paNewRects[iNextRect].bottom += delta;
239 }
240 }
241
242 memcpy (paRects, paNewRects, sizeof (RECTL) * nRects);
243 return;
244}
245
246int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID,
247 const char *pszMsg, const char *pszTitle,
248 UINT uTimeout, DWORD dwInfoFlags)
249{
250 NOTIFYICONDATA niData;
251 ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
252 niData.cbSize = sizeof(NOTIFYICONDATA);
253 niData.uFlags = NIF_INFO; /* Display a balloon notification. */
254 niData.hWnd = hWnd;
255 niData.uID = uID;
256 /* If not timeout set, set it to 5sec. */
257 if (uTimeout == 0)
258 uTimeout = 5000;
259 niData.uTimeout = uTimeout;
260 /* If no info flag (info, warning, error) set,
261 * set it to info by default. */
262 if (dwInfoFlags == 0)
263 dwInfoFlags = NIIF_INFO;
264 niData.dwInfoFlags = dwInfoFlags;
265
266 /* Do we want to have */
267
268 /* Get running OS version. */
269 OSVERSIONINFO osInfo;
270 osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
271 if (FALSE == GetVersionEx(&osInfo))
272 return RTErrConvertFromWin32(GetLastError());
273
274 /* Is the current OS supported (at least WinXP) for displaying
275 * our own icon and do we actually *want* to display our own stuff? */
276 if ( osInfo.dwMajorVersion >= 5
277 && (dwInfoFlags & NIIF_INFO))
278 {
279 /* Load (or retrieve handle of) the app's icon. */
280 HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_VIRTUALBOX));
281 if (hIcon)
282 niData.dwInfoFlags = NIIF_USER; /* Use an own notification icon. */
283
284 if ( osInfo.dwMajorVersion == 5
285 && osInfo.dwMinorVersion == 1) /* WinXP. */
286 {
287 /* Use an own icon instead of the default one. */
288 niData.hIcon = hIcon;
289 }
290 else if (osInfo.dwMajorVersion == 6) /* Vista and up. */
291 {
292 /* Use an own icon instead of the default one. */
293 niData.dwInfoFlags |= NIIF_LARGE_ICON; /* Use a large icon if available! */
294 niData.hIcon = hIcon;
295 niData.hBalloonIcon = hIcon;
296 }
297 }
298 else
299 {
300 /* This might be a warning, error message or a to old OS. Use the
301 * standard icons provided by Windows (if any). */
302 }
303
304 strcpy(niData.szInfo, pszMsg ? pszMsg : "-");
305 strcpy(niData.szInfoTitle, pszTitle ? pszTitle : "Information");
306
307 if (!Shell_NotifyIcon(NIM_MODIFY, &niData))
308 {
309 DWORD dwErr = GetLastError();
310 return RTErrConvertFromWin32(dwErr);
311 }
312 return VINF_SUCCESS;
313}
314
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette