ReactOS  0.4.15-dev-3303-g1ade494
display.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * PURPOSE: Video initialization and display settings
5  * FILE: win32ss/user/ntuser/display.c
6  * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7  */
8 
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(UserDisplay);
11 
14 
15 static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
16 
17 VOID
19 {
20  RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel);
21  RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth);
22  RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight);
23  RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags);
24  RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency);
25  RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth);
26  RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight);
27  RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation);
28  RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput);
29  RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x);
30  RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y);
31 // RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->);
32 }
33 
34 VOID
36 {
37  DWORD dwValue;
38 
39  /* Zero out the structure */
40  RtlZeroMemory(pdm, sizeof(DEVMODEW));
41 
42 /* Helper macro */
43 #define READ(field, str, flag) \
44  if (RegReadDWORD(hkey, L##str, &dwValue)) \
45  { \
46  pdm->field = dwValue; \
47  pdm->dmFields |= flag; \
48  }
49 
50  /* Read all present settings */
51  READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL);
52  READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH);
53  READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT);
54  READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS);
55  READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY);
56  READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH);
57  READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT);
58  READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION);
59  READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT);
60  READ(dmPosition.x, "Attach.RelativeX", DM_POSITION);
61  READ(dmPosition.y, "Attach.RelativeY", DM_POSITION);
62 }
63 
65 NTAPI
68  IN PWSTR pwszRegKey)
69 {
70  PGRAPHICS_DEVICE pGraphicsDevice;
71  UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
73  WCHAR awcBuffer[128];
74  ULONG cbSize;
75  HKEY hkey;
76  DEVMODEW dmDefault;
77  DWORD dwVga;
78 
79  TRACE("InitDisplayDriver(%S, %S);\n",
80  pwszDeviceName, pwszRegKey);
81 
82  /* Open the driver's registry key */
83  Status = RegOpenKey(pwszRegKey, &hkey);
84  if (!NT_SUCCESS(Status))
85  {
86  ERR("Failed to open registry key: %ls\n", pwszRegKey);
87  return NULL;
88  }
89 
90  /* Query the diplay drivers */
91  cbSize = sizeof(awcBuffer) - 10;
92  Status = RegQueryValue(hkey,
93  L"InstalledDisplayDrivers",
95  awcBuffer,
96  &cbSize);
97  if (!NT_SUCCESS(Status))
98  {
99  ERR("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
100  ZwClose(hkey);
101  return NULL;
102  }
103 
104  /* Initialize the UNICODE_STRING */
105  ustrDisplayDrivers.Buffer = awcBuffer;
106  ustrDisplayDrivers.MaximumLength = (USHORT)cbSize;
107  ustrDisplayDrivers.Length = (USHORT)cbSize;
108 
109  /* Set Buffer for description and size of remaining buffer */
110  ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR));
111  cbSize = sizeof(awcBuffer) - cbSize;
112 
113  /* Query the device string */
114  Status = RegQueryValue(hkey,
115  L"Device Description",
116  REG_SZ,
117  ustrDescription.Buffer,
118  &cbSize);
119  if (NT_SUCCESS(Status))
120  {
121  ustrDescription.MaximumLength = (USHORT)cbSize;
122  ustrDescription.Length = (USHORT)cbSize;
123  }
124  else
125  {
126  RtlInitUnicodeString(&ustrDescription, L"<unknown>");
127  }
128 
129  /* Query the default settings */
130  RegReadDisplaySettings(hkey, &dmDefault);
131 
132  /* Query if this is a VGA compatible driver */
133  cbSize = sizeof(DWORD);
134  Status = RegQueryValue(hkey, L"VgaCompatible", REG_DWORD, &dwVga, &cbSize);
135  if (!NT_SUCCESS(Status)) dwVga = 0;
136 
137  /* Close the registry key */
138  ZwClose(hkey);
139 
140  /* Register the device with GDI */
141  RtlInitUnicodeString(&ustrDeviceName, pwszDeviceName);
142  pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
143  &ustrDisplayDrivers,
144  &ustrDescription,
145  &dmDefault);
146  if (pGraphicsDevice && dwVga)
147  {
148  pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_VGA_COMPATIBLE;
149  }
150 
151  return pGraphicsDevice;
152 }
153 
154 NTSTATUS
155 NTAPI
157 {
159  HKEY hkey;
160 
161  TRACE("----------------------------- InitVideo() -------------------------------\n");
162 
163  /* Check if VGA mode is requested, by finding the special volatile key created by VIDEOPRT */
164  Status = RegOpenKey(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\BaseVideo", &hkey);
165  if (NT_SUCCESS(Status))
166  ZwClose(hkey);
168  if (gbBaseVideo)
169  ERR("VGA mode requested.\n");
170 
171  /* Initialize all display devices */
173  if (!NT_SUCCESS(Status))
174  return Status;
175 
176  /* Check if we had any success */
178  {
179  /* Check if there is a VGA device we skipped */
181  {
182  /* There is, use the VGA device */
184  }
185  else
186  {
187  ERR("No usable display driver was found.\n");
188  return STATUS_UNSUCCESSFUL;
189  }
190  }
191 
192  InitSysParams();
193 
194  return STATUS_SUCCESS;
195 }
196 
197 VOID
199 {
200  ULONG_PTR ulResult;
201  // PVOID pvOldCursor;
202 
203  // TODO: Re-enable the cursor reset code once this function becomes called
204  // from within a Win32 thread... Indeed UserSetCursor() requires this, but
205  // at the moment this function is directly called from a separate thread
206  // from within videoprt, instead of by a separate win32k system thread.
207 
208  if (!ppdev)
209  return;
210 
211  PDEVOBJ_vReference(ppdev);
212 
213  /* Remove mouse pointer */
214  // pvOldCursor = UserSetCursor(NULL, TRUE);
215 
216  /* Do the mode switch -- Use the actual same current mode */
217  ulResult = PDEVOBJ_bSwitchMode(ppdev, ppdev->pdmwDev);
218  ASSERT(ulResult);
219 
220  /* Restore mouse pointer, no hooks called */
221  // pvOldCursor = UserSetCursor(pvOldCursor, TRUE);
222  // ASSERT(pvOldCursor == NULL);
223 
224  /* Update the system metrics */
225  InitMetrics();
226 
227  /* Set new size of the monitor */
228  // UserUpdateMonitorSize((HDEV)ppdev);
229 
230  //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
232 
233  PDEVOBJ_vRelease(ppdev);
234 }
235 
236 NTSTATUS
237 NTAPI
239  PUNICODE_STRING pustrDevice,
240  DWORD iDevNum,
241  PDISPLAY_DEVICEW pdispdev,
242  DWORD dwFlags)
243 {
244  PGRAPHICS_DEVICE pGraphicsDevice;
245  ULONG cbSize;
246  HKEY hkey;
248 
249  if (!pustrDevice)
250  {
251  /* Check if some devices have been added since last time */
253  }
254 
255  /* Ask gdi for the GRAPHICS_DEVICE */
256  pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0);
257  if (!pGraphicsDevice)
258  {
259  /* No device found */
260  ERR("No GRAPHICS_DEVICE found for '%wZ', iDevNum %lu\n", pustrDevice, iDevNum);
261  return STATUS_UNSUCCESSFUL;
262  }
263 
264  /* Open the device map registry key */
265  Status = RegOpenKey(KEY_VIDEO, &hkey);
266  if (!NT_SUCCESS(Status))
267  {
268  /* No device found */
269  ERR("Could not open reg key\n");
270  return STATUS_UNSUCCESSFUL;
271  }
272 
273  /* Query the registry path */
274  cbSize = sizeof(pdispdev->DeviceKey);
275  RegQueryValue(hkey,
276  pGraphicsDevice->szNtDeviceName,
277  REG_SZ,
278  pdispdev->DeviceKey,
279  &cbSize);
280 
281  /* Close registry key */
282  ZwClose(hkey);
283 
284  /* Copy device name, device string and StateFlags */
285  RtlStringCbCopyW(pdispdev->DeviceName, sizeof(pdispdev->DeviceName), pGraphicsDevice->szWinDeviceName);
286  RtlStringCbCopyW(pdispdev->DeviceString, sizeof(pdispdev->DeviceString), pGraphicsDevice->pwszDescription);
287  pdispdev->StateFlags = pGraphicsDevice->StateFlags;
288  // FIXME: fill in DEVICE ID
289  pdispdev->DeviceID[0] = UNICODE_NULL;
290 
291  return STATUS_SUCCESS;
292 }
293 
294 //NTSTATUS
295 BOOL
296 NTAPI
298  PUNICODE_STRING pustrDevice,
299  DWORD iDevNum,
300  PDISPLAY_DEVICEW pDisplayDevice,
301  DWORD dwFlags)
302 {
303  UNICODE_STRING ustrDevice;
304  WCHAR awcDevice[CCHDEVICENAME];
305  DISPLAY_DEVICEW dispdev;
307 
308  TRACE("Enter NtUserEnumDisplayDevices(%wZ, %lu)\n",
309  pustrDevice, iDevNum);
310 
311  dispdev.cb = sizeof(dispdev);
312 
313  if (pustrDevice)
314  {
315  /* Initialize destination string */
316  RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
317 
318  _SEH2_TRY
319  {
320  /* Probe the UNICODE_STRING and the buffer */
321  ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
322  ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
323 
324  /* Copy the string */
325  RtlCopyUnicodeString(&ustrDevice, pustrDevice);
326  }
328  {
329 // _SEH2_YIELD(return _SEH2_GetExceptionCode());
331  }
332  _SEH2_END
333 
334  if (ustrDevice.Length > 0)
335  pustrDevice = &ustrDevice;
336  else
337  pustrDevice = NULL;
338  }
339 
340  /* If name is given only iDevNum==0 gives results */
341  if (pustrDevice && iDevNum != 0)
342  return FALSE;
343 
344  /* Acquire global USER lock */
345  UserEnterShared();
346 
347  /* Call the internal function */
348  Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);
349 
350  /* Release lock */
351  UserLeave();
352 
353  /* On success copy data to caller */
354  if (NT_SUCCESS(Status))
355  {
356  /* Enter SEH */
357  _SEH2_TRY
358  {
359  /* First probe the cb field */
360  ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);
361 
362  /* Check the buffer size */
363  if (pDisplayDevice->cb)
364  {
365  /* Probe the output buffer */
366  pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
367  ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);
368 
369  /* Copy as much as the given buffer allows */
370  RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
371  }
372  }
374  {
376  }
377  _SEH2_END
378  }
379 
380  TRACE("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
381  /* Return the result */
382 // return Status;
383  return NT_SUCCESS(Status); // FIXME
384 }
385 
386 NTSTATUS
387 NTAPI
389  PUNICODE_STRING pustrDevice,
390  PDEVMODEW *ppdm)
391 {
392  PPDEVOBJ ppdev;
393 
394  /* Get the PDEV for the device */
395  ppdev = EngpGetPDEV(pustrDevice);
396  if (!ppdev)
397  {
398  /* No device found */
399  ERR("No PDEV found!\n");
401  }
402 
403  *ppdm = ppdev->pdmwDev;
404  PDEVOBJ_vRelease(ppdev);
405 
406  return STATUS_SUCCESS;
407 }
408 
409 NTSTATUS
410 NTAPI
412  PUNICODE_STRING pustrDevice,
413  DWORD iModeNum,
414  LPDEVMODEW *ppdm,
415  DWORD dwFlags)
416 {
417  PGRAPHICS_DEVICE pGraphicsDevice;
418  PDEVMODEENTRY pdmentry;
419  ULONG i, iFoundMode;
420  PPDEVOBJ ppdev;
421 
422  TRACE("Enter UserEnumDisplaySettings('%wZ', %lu)\n",
423  pustrDevice, iModeNum);
424 
425  /* Ask GDI for the GRAPHICS_DEVICE */
426  pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
427  ppdev = EngpGetPDEV(pustrDevice);
428 
429  if (!pGraphicsDevice || !ppdev)
430  {
431  /* No device found */
432  ERR("No device found!\n");
434  }
435 
436  /* let's politely ask the driver for an updated mode list,
437  just in case there's something new in there (vbox) */
438 
440  PDEVOBJ_vRelease(ppdev);
441 
442  iFoundMode = 0;
443  for (i = 0; i < pGraphicsDevice->cDevModes; i++)
444  {
445  pdmentry = &pGraphicsDevice->pDevModeList[i];
446 
447  /* FIXME: Consider EDS_RAWMODE */
448 #if 0
449  if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) ||!
450  (dwFlags & EDS_RAWMODE))
451 #endif
452  {
453  /* Is this the one we want? */
454  if (iFoundMode == iModeNum)
455  {
456  *ppdm = pdmentry->pdm;
457  return STATUS_SUCCESS;
458  }
459 
460  /* Increment number of found modes */
461  iFoundMode++;
462  }
463  }
464 
465  /* Nothing was found */
467 }
468 
469 NTSTATUS
470 NTAPI
472  OUT PHKEY phkey,
473  IN PUNICODE_STRING pustrDevice,
474  IN BOOL bGlobal)
475 {
476  HKEY hkey;
477  DISPLAY_DEVICEW dispdev;
479 
480  /* Get device info */
481  Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0);
482  if (!NT_SUCCESS(Status))
483  return Status;
484 
485  if (bGlobal)
486  {
487  // FIXME: Need to fix the registry key somehow
488  }
489 
490  /* Open the registry key */
491  Status = RegOpenKey(dispdev.DeviceKey, &hkey);
492  if (!NT_SUCCESS(Status))
493  return Status;
494 
495  *phkey = hkey;
496 
497  return Status;
498 }
499 
500 NTSTATUS
501 NTAPI
503  IN PUNICODE_STRING pustrDevice,
504  OUT LPDEVMODEW pdm)
505 {
506  HKEY hkey;
507  NTSTATUS Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, 0);
508  if(NT_SUCCESS(Status))
509  {
510  RegReadDisplaySettings(hkey, pdm);
511  ZwClose(hkey);
512  return STATUS_SUCCESS;
513  }
514  return Status;
515 }
516 
517 NTSTATUS
518 APIENTRY
520  IN PUNICODE_STRING pustrDevice,
521  IN DWORD iModeNum,
523  IN DWORD dwFlags)
524 {
525  UNICODE_STRING ustrDeviceUser;
526  UNICODE_STRING ustrDevice;
527  WCHAR awcDevice[CCHDEVICENAME];
529  ULONG cbSize, cbExtra;
530  DEVMODEW dmReg, *pdm;
531 
532  TRACE("Enter NtUserEnumDisplaySettings(%wZ, %lu, %p, 0x%lx)\n",
533  pustrDevice, iModeNum, lpDevMode, dwFlags);
534 
535  _SEH2_TRY
536  {
537  ProbeForRead(lpDevMode, sizeof(DEVMODEW), sizeof(UCHAR));
538 
539  cbSize = lpDevMode->dmSize;
540  cbExtra = lpDevMode->dmDriverExtra;
541 
542  ProbeForWrite(lpDevMode, cbSize + cbExtra, sizeof(UCHAR));
543  }
545  {
547  }
548  _SEH2_END;
549 
550  if (cbSize != sizeof(DEVMODEW))
551  {
553  }
554 
555  if (pustrDevice)
556  {
557  /* Initialize destination string */
558  RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
559 
560  _SEH2_TRY
561  {
562  /* Probe the UNICODE_STRING and the buffer */
563  ustrDeviceUser = ProbeForReadUnicodeString(pustrDevice);
564 
565  if (!ustrDeviceUser.Length || !ustrDeviceUser.Buffer)
567 
568  ProbeForRead(ustrDeviceUser.Buffer,
569  ustrDeviceUser.Length,
570  sizeof(UCHAR));
571 
572  /* Copy the string */
573  RtlCopyUnicodeString(&ustrDevice, &ustrDeviceUser);
574  }
576  {
578  }
579  _SEH2_END;
580 
581  pustrDevice = &ustrDevice;
582  }
583 
584  /* Acquire global USER lock */
585  UserEnterShared();
586 
588  {
589  /* Get the registry settings */
590  Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
591  pdm = &dmReg;
592  pdm->dmSize = sizeof(DEVMODEW);
593  }
594  else if (iModeNum == ENUM_CURRENT_SETTINGS)
595  {
596  /* Get the current settings */
597  Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
598  }
599  else
600  {
601  /* Get specified settings */
602  Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
603  }
604 
605  /* Release lock */
606  UserLeave();
607 
608  /* Did we succeed? */
609  if (NT_SUCCESS(Status))
610  {
611  /* Copy some information back */
612  _SEH2_TRY
613  {
614  /* Output what we got */
615  RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize));
616 
617  /* Output private/extra driver data */
618  if (cbExtra > 0 && pdm->dmDriverExtra > 0)
619  {
620  RtlCopyMemory((PCHAR)lpDevMode + cbSize,
621  (PCHAR)pdm + pdm->dmSize,
622  min(cbExtra, pdm->dmDriverExtra));
623  }
624  }
626  {
628  }
629  _SEH2_END;
630  }
631 
632  return Status;
633 }
634 
635 VOID
637  DWORD flags)
638 {
639  if (flags & CDS_FULLSCREEN)
641  else
642  gpFullscreen = NULL;
643 }
644 
645 LONG
646 APIENTRY
648  PUNICODE_STRING pustrDevice,
649  LPDEVMODEW pdm,
650  DWORD flags,
651  LPVOID lParam)
652 {
653  DEVMODEW dm;
654  LONG lResult = DISP_CHANGE_SUCCESSFUL;
655  HKEY hkey;
657  PPDEVOBJ ppdev;
658  WORD OrigBC;
659  //PDESKTOP pdesk;
660 
661  /* If no DEVMODE is given, use registry settings */
662  if (!pdm)
663  {
664  /* Get the registry settings */
665  Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm);
666  if (!NT_SUCCESS(Status))
667  {
668  ERR("Could not load registry settings\n");
669  return DISP_CHANGE_BADPARAM;
670  }
671  }
672  else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
673  {
674  return DISP_CHANGE_BADMODE; /* This is what WinXP SP3 returns */
675  }
676  else
677  {
678  dm = *pdm;
679  }
680 
681  /* Save original bit count */
682  OrigBC = gpsi->BitCount;
683 
684  /* Check params */
686  {
687  ERR("Devmode doesn't specify the resolution.\n");
688  return DISP_CHANGE_BADMODE;
689  }
690 
691  /* Get the PDEV */
692  ppdev = EngpGetPDEV(pustrDevice);
693  if (!ppdev)
694  {
695  ERR("Failed to get PDEV\n");
696  return DISP_CHANGE_BADPARAM;
697  }
698 
699  /* Fixup values */
700  if (dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL))
701  {
702  dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel;
703  dm.dmFields |= DM_BITSPERPEL;
704  }
705 
706  if ((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0))
708 
709  /* Look for the requested DEVMODE */
710  pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
711  if (!pdm)
712  {
713  ERR("Could not find a matching DEVMODE\n");
714  lResult = DISP_CHANGE_BADMODE;
715  goto leave;
716  }
717  else if (flags & CDS_TEST)
718  {
719  /* It's possible, go ahead! */
720  lResult = DISP_CHANGE_SUCCESSFUL;
721  goto leave;
722  }
723 
724  /* Shall we update the registry? */
726  {
727  /* Open the local or global settings key */
728  Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
729  if (NT_SUCCESS(Status))
730  {
731  /* Store the settings */
732  RegWriteDisplaySettings(hkey, pdm);
733 
734  /* Close the registry key */
735  ZwClose(hkey);
736  }
737  else
738  {
739  ERR("Could not open registry key\n");
740  lResult = DISP_CHANGE_NOTUPDATED;
741  }
742  }
743 
744  /* Check if DEVMODE matches the current mode */
745  if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
746  {
747  ERR("DEVMODE matches, nothing to do\n");
748  goto leave;
749  }
750 
751  /* Shall we apply the settings? */
752  if (!(flags & CDS_NORESET))
753  {
754  ULONG_PTR ulResult;
755  PVOID pvOldCursor;
756  TEXTMETRICW tmw;
757 
758  /* Remove mouse pointer */
759  pvOldCursor = UserSetCursor(NULL, TRUE);
760 
761  /* Do the mode switch */
762  ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
763 
764  /* Restore mouse pointer, no hooks called */
765  pvOldCursor = UserSetCursor(pvOldCursor, TRUE);
766  ASSERT(pvOldCursor == NULL);
767 
768  /* Check for success or failure */
769  if (!ulResult)
770  {
771  /* Setting mode failed */
772  ERR("Failed to set mode\n");
773 
774  /* Set the correct return value */
775  if ((flags & CDS_UPDATEREGISTRY) && (lResult != DISP_CHANGE_NOTUPDATED))
776  lResult = DISP_CHANGE_RESTART;
777  else
778  lResult = DISP_CHANGE_FAILED;
779  }
780  else
781  {
782  /* Setting mode succeeded */
783  lResult = DISP_CHANGE_SUCCESSFUL;
784 
786 
787  /* Update the system metrics */
788  InitMetrics();
789 
790  /* Set new size of the monitor */
791  UserUpdateMonitorSize((HDEV)ppdev);
792 
793  /* Update the SERVERINFO */
794  gpsi->dmLogPixels = ppdev->gdiinfo.ulLogPixelsY;
795  gpsi->Planes = ppdev->gdiinfo.cPlanes;
796  gpsi->BitsPixel = ppdev->gdiinfo.cBitsPixel;
797  gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
798  gpsi->aiSysMet[SM_CXSCREEN] = ppdev->gdiinfo.ulHorzRes;
799  gpsi->aiSysMet[SM_CYSCREEN] = ppdev->gdiinfo.ulVertRes;
800  if (ppdev->gdiinfo.flRaster & RC_PALETTE)
801  {
802  gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
803  }
804  else
805  {
806  gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
807  }
808  // Font is realized and this dc was previously set to internal DC_ATTR.
809  gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
810  gpsi->tmSysFont = tmw;
811  }
812 
813  /*
814  * Refresh the display on success and even on failure,
815  * since the display may have been messed up.
816  */
817 
818  /* Remove all cursor clipping */
820 
821  //pdesk = IntGetActiveDesktop();
822  //IntHideDesktop(pdesk);
823 
824  /* Send WM_DISPLAYCHANGE to all toplevel windows */
826  WM_DISPLAYCHANGE,
827  gpsi->BitCount,
828  MAKELONG(gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN]),
829  SMTO_NORMAL,
830  100,
831  &ulResult );
832 
833  ERR("BitCount New %d Orig %d ChkNew %d\n",gpsi->BitCount,OrigBC,ppdev->gdiinfo.cBitsPixel);
834 
835  /* Not full screen and different bit count, send messages */
836  if (!(flags & CDS_FULLSCREEN) &&
837  gpsi->BitCount != OrigBC)
838  {
839  ERR("Detect settings changed.\n");
842  }
843 
844  //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
845 
847  }
848 
849 leave:
850  /* Release the PDEV */
851  PDEVOBJ_vRelease(ppdev);
852 
853  return lResult;
854 }
855 
856 VOID
858  PPROCESSINFO ppiCurrent)
859 {
860  if (ppiCurrent == gpFullscreen)
861  {
863  if (gpFullscreen)
864  ERR("Failed to restore display mode!\n");
865  }
866 }
867 
868 LONG
869 APIENTRY
871  PUNICODE_STRING pustrDevice,
873  DWORD dwflags,
874  LPVOID lParam)
875 {
876  WCHAR awcDevice[CCHDEVICENAME];
877  UNICODE_STRING ustrDevice;
878  DEVMODEW dmLocal;
879  LONG lRet;
880 
881  /* Check arguments */
882  if ((dwflags != CDS_VIDEOPARAMETERS) && (lParam != NULL))
883  {
885  return DISP_CHANGE_BADPARAM;
886  }
887 
888  /* Check flags */
890  {
891  return DISP_CHANGE_BADFLAGS;
892  }
893 
894  if ((dwflags & CDS_RESET) && (dwflags & CDS_NORESET))
895  {
896  return DISP_CHANGE_BADFLAGS;
897  }
898 
899  /* Copy the device name */
900  if (pustrDevice)
901  {
902  /* Initialize destination string */
903  RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
904 
905  _SEH2_TRY
906  {
907  /* Probe the UNICODE_STRING and the buffer */
908  ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
909  ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
910 
911  /* Copy the string */
912  RtlCopyUnicodeString(&ustrDevice, pustrDevice);
913  }
915  {
916  /* Set and return error */
919  }
920  _SEH2_END
921 
922  pustrDevice = &ustrDevice;
923  }
924 
925  /* Copy devmode */
926  if (lpDevMode)
927  {
928  _SEH2_TRY
929  {
930  /* Probe the size field of the structure */
931  ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);
932 
933  /* Calculate usable size */
934  dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);
935 
936  /* Probe and copy the full DEVMODE */
937  ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
938  RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
939  }
941  {
942  /* Set and return error */
945  }
946  _SEH2_END
947 
948  /* Check for extra parameters */
949  if (dmLocal.dmDriverExtra > 0)
950  {
951  /* FIXME: TODO */
952  ERR("lpDevMode->dmDriverExtra is IGNORED!\n");
953  dmLocal.dmDriverExtra = 0;
954  }
955 
956  /* Use the local structure */
957  lpDevMode = &dmLocal;
958  }
959 
960  // FIXME: Copy videoparameters
961 
962  /* Acquire global USER lock */
964 
965  /* Call internal function */
966  lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, dwflags, NULL);
967 
968  /* Release lock */
969  UserLeave();
970 
971  return lRet;
972 }
BOOL NTAPI PDEVOBJ_bSwitchMode(PPDEVOBJ ppdev, PDEVMODEW pdm)
Definition: pdevobj.c:510
signed char * PCHAR
Definition: retypes.h:7
static const PWCHAR KEY_VIDEO
Definition: display.c:15
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:239
#define IN
Definition: typedefs.h:39
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1609
#define READ(field, str, flag)
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225
#define DISP_CHANGE_BADFLAGS
Definition: winuser.h:192
#define DISP_CHANGE_RESTART
Definition: winuser.h:191
DWORD dmFields
Definition: wingdi.h:1622
USHORT MaximumLength
Definition: env_spec_w32.h:370
WORD dmSize
Definition: wingdi.h:1568
WCHAR szWinDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:60
FORCEINLINE VOID PDEVOBJ_vReference(_In_ PPDEVOBJ ppdev)
Definition: pdevobj.h:167
WCHAR szNtDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:59
DWORD dmDisplayOrientation
Definition: wingdi.h:1636
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
POINTL dmPosition
Definition: wingdi.h:1635
GDIINFO gdiinfo
Definition: pdevobj.h:124
WORD dmDriverExtra
Definition: wingdi.h:1569
DWORD StateFlags
Definition: pdevobj.h:66
WCHAR DeviceString[128]
Definition: wingdi.h:2819
#define CDS_FULLSCREEN
Definition: winuser.h:183
#define DM_PANNINGWIDTH
Definition: wingdi.h:1277
LONG NTSTATUS
Definition: precomp.h:26
BOOL FASTCALL UserSendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:2037
#define DISP_CHANGE_BADMODE
Definition: winuser.h:195
WORD dmDriverExtra
Definition: wingdi.h:1621
#define ExRaiseStatus
Definition: ntoskrnl.h:104
PDEVMODEENTRY pDevModeList
Definition: pdevobj.h:70
VOID RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
Definition: display.c:18
PGRAPHICS_DEVICE gpVgaGraphicsDevice
Definition: device.c:16
NTSTATUS NTAPI UserEnumRegistryDisplaySettings(IN PUNICODE_STRING pustrDevice, OUT LPDEVMODEW pdm)
Definition: display.c:502
uint16_t * PWCHAR
Definition: typedefs.h:56
VOID UserDisplayNotifyShutdown(PPROCESSINFO ppiCurrent)
Definition: display.c:857
DWORD dmBitsPerPel
Definition: wingdi.h:1647
PGRAPHICS_DEVICE NTAPI InitDisplayDriver(IN PWSTR pwszDeviceName, IN PWSTR pwszRegKey)
Definition: display.c:66
PGRAPHICS_DEVICE gpPrimaryGraphicsDevice
Definition: device.c:15
#define DWORD
Definition: nt_native.h:44
PSERVERINFO gpsi
Definition: main.c:27
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
WCHAR DeviceName[32]
Definition: wingdi.h:2818
PDEVMODEW pdm
Definition: pdevobj.h:53
#define ENUM_CURRENT_SETTINGS
Definition: winuser.h:179
#define WM_SETTINGCHANGE
Definition: winuser.h:1612
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LONG y
Definition: windef.h:330
#define SMTO_NORMAL
Definition: winuser.h:1211
_SEH2_TRY
Definition: create.c:4226
#define CDS_RESET
Definition: winuser.h:187
BOOL NTAPI NtUserEnumDisplayDevices(PUNICODE_STRING pustrDevice, DWORD iDevNum, PDISPLAY_DEVICEW pDisplayDevice, DWORD dwFlags)
Definition: display.c:297
#define DM_PELSWIDTH
Definition: wingdi.h:1269
PPROCESSINFO ppi
Definition: win32.h:89
uint32_t ULONG_PTR
Definition: typedefs.h:65
PGRAPHICS_DEVICE NTAPI EngpRegisterGraphicsDevice(_In_ PUNICODE_STRING pustrDeviceName, _In_ PUNICODE_STRING pustrDiplayDrivers, _In_ PUNICODE_STRING pustrDescription, _In_ PDEVMODEW pdmDefault)
Definition: device.c:316
#define SM_CXSCREEN
Definition: winuser.h:949
#define DM_POSITION
Definition: wingdi.h:1255
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum, _In_ DWORD dwFlags)
Definition: device.c:469
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define CDS_UPDATEREGISTRY
Definition: winuser.h:181
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
WCHAR DeviceID[128]
Definition: wingdi.h:2821
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static _In_ DWORD iModeNum
Definition: dispmode.c:77
NTSTATUS NTAPI UserEnumDisplayDevices(PUNICODE_STRING pustrDevice, DWORD iDevNum, PDISPLAY_DEVICEW pdispdev, DWORD dwFlags)
Definition: display.c:238
DWORD FASTCALL IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
Definition: font.c:329
static PPROCESSINFO gpFullscreen
Definition: display.c:13
#define DISP_CHANGE_FAILED
Definition: winuser.h:194
#define DISP_CHANGE_BADPARAM
Definition: winuser.h:193
LPWSTR pwszDescription
Definition: pdevobj.h:72
#define DISP_CHANGE_NOTUPDATED
Definition: winuser.h:196
#define MAKELONG(a, b)
Definition: typedefs.h:249
DWORD dmDisplayFixedOutput
Definition: wingdi.h:1637
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
NTSTATUS NTAPI UserEnumCurrentDisplaySettings(PUNICODE_STRING pustrDevice, PDEVMODEW *ppdm)
Definition: display.c:388
BOOL InitSysParams(VOID)
Definition: sysparams.c:348
BOOL gbBaseVideo
Definition: display.c:12
#define leave
Definition: seh.h:23
NTSTATUS NTAPI InitVideo(VOID)
Definition: display.c:156
static _In_ DWORD _Inout_ PDEVMODEA lpDevMode
Definition: dispmode.c:77
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
PDEVMODEW pdmwDev
Definition: pdevobj.h:130
#define CDS_GLOBAL
Definition: winuser.h:184
VOID RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
Definition: display.c:35
VOID UserUpdateFullscreen(DWORD flags)
Definition: display.c:636
BOOL APIENTRY UserClipCursor(RECTL *prcl)
Definition: cursoricon.c:700
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
Status
Definition: gdiplustypes.h:24
#define SM_CYSCREEN
Definition: winuser.h:950
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS APIENTRY NtUserEnumDisplaySettings(IN PUNICODE_STRING pustrDevice, IN DWORD iModeNum, OUT LPDEVMODEW lpDevMode, IN DWORD dwFlags)
Definition: display.c:519
HDC hSystemBM
Definition: stockobj.c:52
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
ULONG cDevModes
Definition: pdevobj.h:69
#define CDS_VIDEOPARAMETERS
Definition: winuser.h:186
#define RC_PALETTE
Definition: wingdi.h:790
WORD dmSize
Definition: wingdi.h:1620
BOOL NTAPI InitMetrics(VOID)
Definition: metric.c:19
LRESULT FASTCALL co_IntSendMessageTimeout(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uFlags, UINT uTimeout, ULONG_PTR *uResult)
Definition: message.c:1654
#define DISP_CHANGE_SUCCESSFUL
Definition: winuser.h:190
VOID NTAPI RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
Definition: registry.c:140
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
LONG x
Definition: windef.h:329
LONG APIENTRY UserChangeDisplaySettings(PUNICODE_STRING pustrDevice, LPDEVMODEW pdm, DWORD flags, LPVOID lParam)
Definition: display.c:647
GLbitfield flags
Definition: glext.h:7161
DWORD dmPelsWidth
Definition: wingdi.h:1648
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
DWORD StateFlags
Definition: wingdi.h:2820
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define DM_DISPLAYFREQUENCY
Definition: wingdi.h:1272
static _In_ DWORD dwflags
Definition: dispmode.c:64
ULONG cBitsPixel
Definition: winddi.h:884
PDEVMODEW NTAPI PDEVOBJ_pdmMatchDevMode(PPDEVOBJ ppdev, PDEVMODEW pdm)
Definition: pdevobj.c:307
WCHAR DeviceKey[128]
Definition: wingdi.h:2822
VOID APIENTRY UserRedrawDesktop(VOID)
Definition: desktop.c:1565
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR pwszDeviceName
Definition: winddi.h:3553
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
DWORD dmDisplayFrequency
Definition: wingdi.h:1654
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:36
_SEH2_END
Definition: create.c:4400
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CCHDEVICENAME
Definition: ddrawi.h:63
VOID UserRefreshDisplay(IN PPDEVOBJ ppdev)
Definition: display.c:198
unsigned short USHORT
Definition: pedump.c:61
DBG_DEFAULT_CHANNEL(UserDisplay)
#define DM_PELSHEIGHT
Definition: wingdi.h:1270
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
NTSTATUS NTAPI UserOpenDisplaySettingsKey(OUT PHKEY phkey, IN PUNICODE_STRING pustrDevice, IN BOOL bGlobal)
Definition: display.c:471
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define CDS_NORESET
Definition: winuser.h:189
#define DISPLAY_DEVICE_VGA_COMPATIBLE
Definition: wingdi.h:1400
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
DWORD dmPelsHeight
Definition: wingdi.h:1649
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:963
#define OUT
Definition: typedefs.h:40
#define RegQueryValue
Definition: winreg.h:523
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI PDEVOBJ_vRefreshModeList(PPDEVOBJ ppdev)
Definition: pdevobj.c:264
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
DWORD dwFlags
Definition: pdevobj.h:52
NTSTATUS NTAPI UserEnumDisplaySettings(PUNICODE_STRING pustrDevice, DWORD iModeNum, LPDEVMODEW *ppdm, DWORD dwFlags)
Definition: display.c:411
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DM_BITSPERPEL
Definition: wingdi.h:1268
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
struct _devicemodeW DEVMODEW
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define DM_DISPLAYORIENTATION
Definition: wingdi.h:1257
#define CDS_TEST
Definition: winuser.h:182
DWORD dmDisplayFlags
Definition: wingdi.h:1651
VOID NTAPI PDEVOBJ_vRelease(_Inout_ PPDEVOBJ ppdev)
Definition: pdevobj.c:93
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
#define DM_PANNINGHEIGHT
Definition: wingdi.h:1278
#define RegOpenKey
Definition: winreg.h:519
LONG APIENTRY NtUserChangeDisplaySettings(PUNICODE_STRING pustrDevice, LPDEVMODEW lpDevMode, DWORD dwflags, LPVOID lParam)
Definition: display.c:870
#define REG_DWORD
Definition: sdbapi.c:596
#define HWND_BROADCAST
Definition: winuser.h:1190
#define ENUM_REGISTRY_SETTINGS
Definition: winuser.h:180
LPARAM lParam
Definition: combotst.c:139
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
#define DM_DISPLAYFLAGS
Definition: wingdi.h:1271
#define APIENTRY
Definition: api.h:79
PPDEVOBJ NTAPI EngpGetPDEV(_In_opt_ PUNICODE_STRING pustrDeviceName)
Definition: pdevobj.c:596
#define REG_SZ
Definition: layer.c:22