VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxService/VBoxDisplay.cpp@ 8396

Last change on this file since 8396 was 8396, checked in by vboxsync, 17 years ago

Correctly process the default BPP value for mode change request in the Windows Additions.

  • Property svn:eol-style set to native
File size: 24.1 KB
Line 
1/** @file
2 *
3 * VBoxSeamless - Display notifications
4 *
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22#define _WIN32_WINNT 0x0500
23#include <windows.h>
24#include "VBoxService.h"
25#include "VBoxSeamless.h"
26#include <VBoxHook.h>
27#include <VBoxDisplay.h>
28#include <VBox/VBoxDev.h>
29#include <iprt/assert.h>
30#include "helpers.h"
31#include <malloc.h>
32
33typedef struct _VBOXDISPLAYCONTEXT
34{
35 const VBOXSERVICEENV *pEnv;
36
37 /* ChangeDisplaySettingsEx does not exist in NT. ResizeDisplayDevice uses the function. */
38 LONG (WINAPI * pfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
39
40 /* EnumDisplayDevices does not exist in NT. isVBoxDisplayDriverActive et al. are using these functions. */
41 BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags);
42
43} VBOXDISPLAYCONTEXT;
44
45static VBOXDISPLAYCONTEXT gCtx = {0};
46
47int VBoxDisplayInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
48{
49 OSVERSIONINFO OSinfo;
50 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
51 GetVersionEx (&OSinfo);
52
53 HMODULE hUser = GetModuleHandle("USER32");
54
55 gCtx.pEnv = pEnv;
56
57 if (NULL == hUser)
58 {
59 dprintf(("VBoxService: Could not get module handle of USER32.DLL!\n"));
60 return VERR_NOT_IMPLEMENTED;
61 }
62 else if (OSinfo.dwMajorVersion >= 5) /* APIs available only on W2K and up! */
63 {
64 *(uintptr_t *)&gCtx.pfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
65 dprintf(("VBoxService: pfnChangeDisplaySettingsEx = %p\n", gCtx.pfnChangeDisplaySettingsEx));
66
67 *(uintptr_t *)&gCtx.pfnEnumDisplayDevices = (uintptr_t)GetProcAddress(hUser, "EnumDisplayDevicesA");
68 dprintf(("VBoxService: pfnEnumDisplayDevices = %p\n", gCtx.pfnEnumDisplayDevices));
69 }
70 else if (OSinfo.dwMajorVersion <= 4) /* Windows NT 4.0 */
71 {
72 /* Nothing to do here yet */
73 }
74 else /* Unsupported platform */
75 {
76 dprintf(("VBoxService: Warning, display for platform not handled yet!\n"));
77 return VERR_NOT_IMPLEMENTED;
78 }
79
80 dprintf(("VBoxService: Display init successful.\n"));
81
82 *pfStartThread = true;
83 *ppInstance = (void *)&gCtx;
84 return VINF_SUCCESS;
85}
86
87void VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance)
88{
89 return;
90}
91
92static bool isVBoxDisplayDriverActive (VBOXDISPLAYCONTEXT *pCtx)
93{
94 bool result = false;
95
96 if( pCtx->pfnEnumDisplayDevices )
97 {
98 INT devNum = 0;
99 DISPLAY_DEVICE dispDevice;
100 FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
101 dispDevice.cb = sizeof(DISPLAY_DEVICE);
102
103 dprintf(("Checking for active VBox display driver (W2K+)...\n"));
104
105 while (EnumDisplayDevices(NULL,
106 devNum,
107 &dispDevice,
108 0))
109 {
110 dprintf(("DevNum:%d\nName:%s\nString:%s\nID:%s\nKey:%s\nFlags=%08X\n\n",
111 devNum,
112 &dispDevice.DeviceName[0],
113 &dispDevice.DeviceString[0],
114 &dispDevice.DeviceID[0],
115 &dispDevice.DeviceKey[0],
116 dispDevice.StateFlags));
117
118 if (dispDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
119 {
120 dprintf(("Primary device.\n"));
121
122 if (strcmp(&dispDevice.DeviceString[0], "VirtualBox Graphics Adapter") == 0)
123 result = true;
124
125 break;
126 }
127
128 FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
129
130 dispDevice.cb = sizeof(DISPLAY_DEVICE);
131
132 devNum++;
133 }
134 }
135 else /* This must be NT 4 or something really old, so don't use EnumDisplayDevices() here ... */
136 {
137 dprintf(("Checking for active VBox display driver (NT or older)...\n"));
138
139 DEVMODE tempDevMode;
140 ZeroMemory (&tempDevMode, sizeof (tempDevMode));
141 tempDevMode.dmSize = sizeof(DEVMODE);
142 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &tempDevMode); /* Get current display device settings */
143
144 /* Check for the short name, because all long stuff would be truncated */
145 if (strcmp((char*)&tempDevMode.dmDeviceName[0], "VBoxDisp") == 0)
146 result = true;
147 }
148
149 return result;
150}
151
152/* Returns TRUE to try again. */
153static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)
154{
155 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0);
156
157 DISPLAY_DEVICE DisplayDevice;
158
159 ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
160 DisplayDevice.cb = sizeof(DisplayDevice);
161
162 /* Find out how many display devices the system has */
163 DWORD NumDevices = 0;
164 DWORD i = 0;
165 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
166 {
167 dprintf(("[%d] %s\n", i, DisplayDevice.DeviceName));
168
169 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
170 {
171 dprintf(("Found primary device. err %d\n", GetLastError ()));
172 NumDevices++;
173 }
174 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
175 {
176
177 dprintf(("Found secondary device. err %d\n", GetLastError ()));
178 NumDevices++;
179 }
180
181 ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
182 DisplayDevice.cb = sizeof(DisplayDevice);
183 i++;
184 }
185
186 dprintf(("Found total %d devices. err %d\n", NumDevices, GetLastError ()));
187
188 if (NumDevices == 0 || Id >= NumDevices)
189 {
190 dprintf(("Requested identifier %d is invalid. err %d\n", Id, GetLastError ()));
191 return FALSE;
192 }
193
194 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices);
195 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices);
196 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices);
197
198 /* Fetch information about current devices and modes. */
199 DWORD DevNum = 0;
200 DWORD DevPrimaryNum = 0;
201
202 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
203 DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
204
205 i = 0;
206 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
207 {
208 dprintf(("[%d(%d)] %s\n", i, DevNum, DisplayDevice.DeviceName));
209
210 BOOL bFetchDevice = FALSE;
211
212 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
213 {
214 dprintf(("Found primary device. err %d\n", GetLastError ()));
215 DevPrimaryNum = DevNum;
216 bFetchDevice = TRUE;
217 }
218 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
219 {
220
221 dprintf(("Found secondary device. err %d\n", GetLastError ()));
222 bFetchDevice = TRUE;
223 }
224
225 if (bFetchDevice)
226 {
227 if (DevNum >= NumDevices)
228 {
229 dprintf(("%d >= %d\n", NumDevices, DevNum));
230 return FALSE;
231 }
232
233 paDisplayDevices[DevNum] = DisplayDevice;
234
235 ZeroMemory(&paDeviceModes[DevNum], sizeof(DEVMODE));
236 paDeviceModes[DevNum].dmSize = sizeof(DEVMODE);
237 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,
238 ENUM_REGISTRY_SETTINGS, &paDeviceModes[DevNum]))
239 {
240 dprintf(("EnumDisplaySettings err %d\n", GetLastError ()));
241 return FALSE;
242 }
243
244 dprintf(("%dx%d at %d,%d\n",
245 paDeviceModes[DevNum].dmPelsWidth,
246 paDeviceModes[DevNum].dmPelsHeight,
247 paDeviceModes[DevNum].dmPosition.x,
248 paDeviceModes[DevNum].dmPosition.y));
249
250 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x;
251 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y;
252 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth;
253 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight;
254 DevNum++;
255 }
256
257 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
258 DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
259 i++;
260 }
261
262 /* Width, height or BPP equal to 0 means that this value must be not changed.
263 * Update input parameters if necessary.
264 */
265 if (Width == 0)
266 {
267 Width = paRects[Id].right - paRects[Id].left;
268 }
269
270 if (Height == 0)
271 {
272 Height = paRects[Id].bottom - paRects[Id].top;
273 }
274
275 if (BitsPerPixel == 0)
276 {
277 BitsPerPixel = paDeviceModes[Id].dmBitsPerPel;
278 }
279
280 /* Check whether a mode reset or a change is requested. */
281 if ( !fModeReset
282 && paRects[Id].right - paRects[Id].left == Width
283 && paRects[Id].bottom - paRects[Id].top == Height
284 && paDeviceModes[Id].dmBitsPerPel == BitsPerPixel)
285 {
286 dprintf(("VBoxDisplayThread : already at desired resolution.\n"));
287 return FALSE;
288 }
289
290 resizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height);
291#ifdef dprintf
292 for (i = 0; i < NumDevices; i++)
293 {
294 dprintf(("[%d]: %d,%d %dx%d\n",
295 i, paRects[i].left, paRects[i].top,
296 paRects[i].right - paRects[i].left,
297 paRects[i].bottom - paRects[i].top));
298 }
299#endif /* dprintf */
300
301 /* Without this, Windows will not ask the miniport for its
302 * mode table but uses an internal cache instead.
303 */
304 DEVMODE tempDevMode;
305 ZeroMemory (&tempDevMode, sizeof (tempDevMode));
306 tempDevMode.dmSize = sizeof(DEVMODE);
307 EnumDisplaySettings(NULL, 0xffffff, &tempDevMode);
308
309 /* Assign the new rectangles to displays. */
310 for (i = 0; i < NumDevices; i++)
311 {
312 paDeviceModes[i].dmPosition.x = paRects[i].left;
313 paDeviceModes[i].dmPosition.y = paRects[i].top;
314 paDeviceModes[i].dmPelsWidth = paRects[i].right - paRects[i].left;
315 paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top;
316
317 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH;
318
319 if ( i == Id
320 && BitsPerPixel != 0)
321 {
322 paDeviceModes[i].dmFields |= DM_BITSPERPEL;
323 paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
324 }
325
326 dprintf(("calling pfnChangeDisplaySettingsEx %x\n", gCtx.pfnChangeDisplaySettingsEx));
327
328 gCtx.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,
329 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
330
331 dprintf(("ChangeDisplaySettings position err %d\n", GetLastError ()));
332 }
333
334 /* A second call to ChangeDisplaySettings updates the monitor. */
335 LONG status = ChangeDisplaySettings(NULL, 0);
336 dprintf(("ChangeDisplaySettings update status %d\n", status));
337 if (status == DISP_CHANGE_SUCCESSFUL || status == DISP_CHANGE_BADMODE)
338 {
339 /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */
340 return FALSE;
341 }
342
343 /* Retry the request. */
344 return TRUE;
345}
346
347/**
348 * Thread function to wait for and process display change
349 * requests
350 */
351unsigned __stdcall VBoxDisplayThread (void *pInstance)
352{
353 VBOXDISPLAYCONTEXT *pCtx = (VBOXDISPLAYCONTEXT *)pInstance;
354 HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
355 bool fTerminate = false;
356 VBoxGuestFilterMaskInfo maskInfo;
357 DWORD cbReturned;
358
359 maskInfo.u32OrMask = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
360 maskInfo.u32NotMask = 0;
361 if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
362 {
363 dprintf(("VBoxDisplayThread : DeviceIOControl(CtlMask - or) succeeded\n"));
364 }
365 else
366 {
367 dprintf(("VBoxDisplayThread : DeviceIOControl(CtlMask) failed, DisplayChangeThread exited\n"));
368 return -1;
369 }
370
371 do
372 {
373 /* wait for a display change event */
374 VBoxGuestWaitEventInfo waitEvent;
375 waitEvent.u32TimeoutIn = 1000;
376 waitEvent.u32EventMaskIn = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
377 if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
378 {
379 dprintf(("VBoxDisplayThread : DeviceIOControl succeded\n"));
380
381 /* are we supposed to stop? */
382 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
383 break;
384
385 dprintf(("VBoxDisplayThread : checking event\n"));
386
387 /* did we get the right event? */
388 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST)
389 {
390 dprintf(("VBoxDisplayThread : going to get display change information.\n"));
391
392 /* We got at least one event. Read the requested resolution
393 * and try to set it until success. New events will not be seen
394 * but a new resolution will be read in this poll loop.
395 */
396 for (;;)
397 {
398 /* get the display change request */
399 VMMDevDisplayChangeRequest2 displayChangeRequest = {0};
400 displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequest2);
401 displayChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
402 displayChangeRequest.header.requestType = VMMDevReq_GetDisplayChangeRequest2;
403 displayChangeRequest.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
404 BOOL fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest2),
405 &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest2), &cbReturned, NULL);
406 if (!fDisplayChangeQueried)
407 {
408 /* Try the old version of the request for old VBox hosts. */
409 displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequest);
410 displayChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
411 displayChangeRequest.header.requestType = VMMDevReq_GetDisplayChangeRequest;
412 displayChangeRequest.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
413 fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest),
414 &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest), &cbReturned, NULL);
415 displayChangeRequest.display = 0;
416 }
417
418 if (fDisplayChangeQueried)
419 {
420 dprintf(("VBoxDisplayThread : VMMDevReq_GetDisplayChangeRequest2: %dx%dx%d at %d\n", displayChangeRequest.xres, displayChangeRequest.yres, displayChangeRequest.bpp, displayChangeRequest.display));
421
422 /* Horizontal resolution must be a multiple of 8, round down. */
423 displayChangeRequest.xres &= 0xfff8;
424
425 /*
426 * Only try to change video mode if the active display driver is VBox additions.
427 */
428 if (isVBoxDisplayDriverActive (pCtx))
429 {
430 dprintf(("VBoxDisplayThread : Display driver is active!\n"));
431
432 if (pCtx->pfnChangeDisplaySettingsEx != 0)
433 {
434 dprintf(("VBoxDisplayThread : Detected W2K or later."));
435
436 /* W2K or later. */
437 if (!ResizeDisplayDevice(displayChangeRequest.display,
438 displayChangeRequest.xres,
439 displayChangeRequest.yres,
440 displayChangeRequest.bpp))
441 {
442 break;
443 }
444 }
445 else
446 {
447 dprintf(("VBoxDisplayThread : Detected NT.\n"));
448
449 /* Single monitor NT. */
450 DEVMODE devMode;
451 memset (&devMode, 0, sizeof (devMode));
452 devMode.dmSize = sizeof(DEVMODE);
453
454 /* get the current screen setup */
455 if (EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &devMode))
456 {
457 dprintf(("VBoxDisplayThread : Current mode: %dx%dx%d at %d,%d\n", devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmPosition.x, devMode.dmPosition.y));
458
459 /* Check whether a mode reset or a change is requested. */
460 if (displayChangeRequest.xres || displayChangeRequest.yres || displayChangeRequest.bpp)
461 {
462 /* A change is requested.
463 * Set values which are not to be changed to the current values.
464 */
465 if (!displayChangeRequest.xres)
466 displayChangeRequest.xres = devMode.dmPelsWidth;
467 if (!displayChangeRequest.yres)
468 displayChangeRequest.yres = devMode.dmPelsHeight;
469 if (!displayChangeRequest.bpp)
470 displayChangeRequest.bpp = devMode.dmBitsPerPel;
471 }
472 else
473 {
474 /* All zero values means a forced mode reset. Do nothing. */
475 dprintf(("VBoxDisplayThread : Forced mode reset.\n"));
476 }
477
478 /* Verify that the mode is indeed changed. */
479 if ( devMode.dmPelsWidth == displayChangeRequest.xres
480 && devMode.dmPelsHeight == displayChangeRequest.yres
481 && devMode.dmBitsPerPel == displayChangeRequest.bpp)
482 {
483 dprintf(("VBoxDisplayThread : already at desired resolution.\n"));
484 break;
485 }
486
487 // without this, Windows will not ask the miniport for its
488 // mode table but uses an internal cache instead
489 DEVMODE tempDevMode = {0};
490 tempDevMode.dmSize = sizeof(DEVMODE);
491 EnumDisplaySettings(NULL, 0xffffff, &tempDevMode);
492
493 /* adjust the values that are supposed to change */
494 if (displayChangeRequest.xres)
495 devMode.dmPelsWidth = displayChangeRequest.xres;
496 if (displayChangeRequest.yres)
497 devMode.dmPelsHeight = displayChangeRequest.yres;
498 if (displayChangeRequest.bpp)
499 devMode.dmBitsPerPel = displayChangeRequest.bpp;
500
501 dprintf(("VBoxDisplayThread : setting the new mode %dx%dx%d\n", devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel));
502
503 /* set the new mode */
504 LONG status = ChangeDisplaySettings(&devMode, CDS_UPDATEREGISTRY);
505 if (status != DISP_CHANGE_SUCCESSFUL)
506 {
507 dprintf(("VBoxDisplayThread : error from ChangeDisplaySettings: %d\n", status));
508
509 if (status == DISP_CHANGE_BADMODE)
510 {
511 /* Our driver can not set the requested mode. Stop trying. */
512 break;
513 }
514 }
515 else
516 {
517 /* Successfully set new video mode. */
518 break;
519 }
520 }
521 else
522 {
523 dprintf(("VBoxDisplayThread : error from EnumDisplaySettings: %d\n", GetLastError ()));
524 break;
525 }
526 }
527 }
528 else
529 {
530 dprintf(("VBoxDisplayThread : vboxDisplayDriver is not active.\n"));
531 }
532
533 /* Retry the change a bit later. */
534 /* are we supposed to stop? */
535 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
536 {
537 fTerminate = true;
538 break;
539 }
540 }
541 else
542 {
543 dprintf(("VBoxDisplayThread : error from DeviceIoControl IOCTL_VBOXGUEST_VMMREQUEST\n"));
544 /* sleep a bit to not eat too much CPU while retrying */
545 /* are we supposed to stop? */
546 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0)
547 {
548 fTerminate = true;
549 break;
550 }
551 }
552 }
553 }
554 } else
555 {
556 dprintf(("VBoxDisplayThread : error 0 from DeviceIoControl IOCTL_VBOXGUEST_WAITEVENT\n"));
557 /* sleep a bit to not eat too much CPU in case the above call always fails */
558 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
559 {
560 fTerminate = true;
561 break;
562 }
563 }
564 } while (!fTerminate);
565
566 maskInfo.u32OrMask = 0;
567 maskInfo.u32NotMask = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
568 if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
569 {
570 dprintf(("VBoxDisplayThread : DeviceIOControl(CtlMask - not) succeeded\n"));
571 }
572 else
573 {
574 dprintf(("VBoxDisplayThread : DeviceIOControl(CtlMask) failed\n"));
575 }
576
577 dprintf(("VBoxDisplayThread : finished display change request thread\n"));
578 return 0;
579}
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