[WIN32K]
[reactos.git] / reactos / win32ss / user / user32 / misc / display.c
1 /*
2 * PROJECT: ReactOS user32.dll
3 * FILE: lib/user32/misc/dde.c
4 * PURPOSE: DDE
5 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 */
7
8 /* INCLUDES ******************************************************************/
9
10 #include <user32.h>
11
12 #include <wine/debug.h>
13 WINE_DEFAULT_DEBUG_CHANNEL(user32);
14
15 #define SIZEOF_DEVMODEA_300 124
16 #define SIZEOF_DEVMODEA_400 148
17 #define SIZEOF_DEVMODEA_500 156
18 #define SIZEOF_DEVMODEW_300 188
19 #define SIZEOF_DEVMODEW_400 212
20 #define SIZEOF_DEVMODEW_500 220
21
22 /* FUNCTIONS *****************************************************************/
23
24 /*
25 * @implemented
26 */
27 BOOL WINAPI
28 EnumDisplayDevicesA(
29 LPCSTR lpDevice,
30 DWORD iDevNum,
31 PDISPLAY_DEVICEA lpDisplayDevice,
32 DWORD dwFlags)
33 {
34 BOOL rc;
35 UNICODE_STRING Device;
36 DISPLAY_DEVICEW DisplayDeviceW;
37
38 if (!RtlCreateUnicodeStringFromAsciiz(&Device, (PCSZ)lpDevice))
39 {
40 SetLastError(ERROR_OUTOFMEMORY);
41 return FALSE;
42 }
43
44 RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW));
45 DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW);
46 rc = NtUserEnumDisplayDevices(&Device,
47 iDevNum,
48 &DisplayDeviceW,
49 dwFlags);
50 if (rc)
51 {
52 /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */
53 lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags;
54 WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1,
55 lpDisplayDevice->DeviceName,
56 sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]),
57 NULL, NULL);
58 WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1,
59 lpDisplayDevice->DeviceString,
60 sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]),
61 NULL, NULL);
62 WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1,
63 lpDisplayDevice->DeviceID,
64 sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]),
65 NULL, NULL);
66 WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1,
67 lpDisplayDevice->DeviceKey,
68 sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]),
69 NULL, NULL);
70 }
71
72 RtlFreeUnicodeString(&Device);
73
74 return rc;
75 }
76
77
78 /*
79 * @implemented
80 */
81 BOOL
82 WINAPI
83 EnumDisplayDevicesW(
84 LPCWSTR lpDevice,
85 DWORD iDevNum,
86 PDISPLAY_DEVICEW lpDisplayDevice,
87 DWORD dwFlags)
88 {
89 UNICODE_STRING Device;
90 BOOL rc;
91
92 RtlInitUnicodeString(&Device, lpDevice);
93
94 rc = NtUserEnumDisplayDevices(
95 &Device,
96 iDevNum,
97 lpDisplayDevice,
98 dwFlags);
99
100 return rc;
101 }
102
103
104 /*
105 * @implemented
106 */
107 BOOL
108 WINAPI
109 EnumDisplayMonitors(
110 HDC hdc,
111 LPCRECT lprcClip,
112 MONITORENUMPROC lpfnEnum,
113 LPARAM dwData)
114 {
115 INT iCount, i;
116 HMONITOR *hMonitorList;
117 LPRECT pRectList;
118 HANDLE hHeap;
119 BOOL ret = FALSE;
120
121 /* get list of monitors/rects */
122 iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0);
123 if (iCount < 0)
124 {
125 /* FIXME: SetLastError() */
126 return FALSE;
127 }
128 if (iCount == 0)
129 {
130 return TRUE;
131 }
132
133 hHeap = GetProcessHeap();
134 hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount);
135 if (hMonitorList == NULL)
136 {
137 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
138 return FALSE;
139 }
140 pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount);
141 if (pRectList == NULL)
142 {
143 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
144 goto cleanup;
145 }
146
147 iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount);
148 if (iCount <= 0)
149 {
150 /* FIXME: SetLastError() */
151 goto cleanup;
152 }
153
154 /* enumerate list */
155 for (i = 0; i < iCount; i++)
156 {
157 HMONITOR hMonitor = hMonitorList[i];
158 LPRECT pMonitorRect = pRectList + i;
159 HDC hMonitorDC = NULL;
160
161 if (hdc != NULL)
162 {
163 /* make monitor DC */
164 hMonitorDC = hdc;
165 }
166
167 if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData))
168 goto cleanup; /* return FALSE */
169 }
170
171 ret = TRUE;
172
173 cleanup:
174 if(hMonitorList)
175 HeapFree(hHeap, 0, hMonitorList);
176 if(pRectList)
177 HeapFree(hHeap, 0, pRectList);
178 return ret;
179 }
180
181
182 /*
183 * @implemented
184 */
185 BOOL
186 WINAPI
187 EnumDisplaySettingsExA(
188 LPCSTR lpszDeviceName,
189 DWORD iModeNum,
190 LPDEVMODEA lpDevMode,
191 DWORD dwFlags)
192 {
193 NTSTATUS Status;
194 UNICODE_STRING usDeviceName, *pusDeviceName = NULL;
195 DEVMODEW DevModeW;
196
197 if (lpszDeviceName)
198 {
199 if (!RtlCreateUnicodeStringFromAsciiz(&usDeviceName, (PCSZ)lpszDeviceName))
200 {
201 SetLastError(ERROR_OUTOFMEMORY);
202 return FALSE;
203 }
204 pusDeviceName = &usDeviceName;
205 }
206
207 memset(&DevModeW,0, sizeof(DEVMODEW));
208 DevModeW.dmSize = sizeof(DEVMODEW);
209
210 Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, &DevModeW, dwFlags);
211
212 if (pusDeviceName)
213 {
214 RtlFreeUnicodeString (&usDeviceName);
215 }
216
217 if (!NT_SUCCESS(Status))
218 {
219 return FALSE;
220 }
221
222 #define COPYS(f,len) WideCharToMultiByte( CP_THREAD_ACP, 0, DevModeW.f, len, (LPSTR)lpDevMode->f, len, NULL, NULL )
223 #define COPYN(f) lpDevMode->f = DevModeW.f
224 COPYS(dmDeviceName, CCHDEVICENAME );
225 COPYN(dmSpecVersion);
226 COPYN(dmDriverVersion);
227 switch (lpDevMode->dmSize)
228 {
229 case SIZEOF_DEVMODEA_300:
230 case SIZEOF_DEVMODEA_400:
231 case SIZEOF_DEVMODEA_500:
232 break;
233 default:
234 lpDevMode->dmSize = SIZEOF_DEVMODEA_300;
235 break;
236 }
237 COPYN(dmDriverExtra);
238 COPYN(dmFields);
239 COPYN(dmPosition.x);
240 COPYN(dmPosition.y);
241 COPYN(dmScale);
242 COPYN(dmCopies);
243 COPYN(dmDefaultSource);
244 COPYN(dmPrintQuality);
245 COPYN(dmColor);
246 COPYN(dmDuplex);
247 COPYN(dmYResolution);
248 COPYN(dmTTOption);
249 COPYN(dmCollate);
250 COPYS(dmFormName,CCHFORMNAME);
251 COPYN(dmLogPixels);
252 COPYN(dmBitsPerPel);
253 COPYN(dmPelsWidth);
254 COPYN(dmPelsHeight);
255 COPYN(dmDisplayFlags); // aka dmNup
256 COPYN(dmDisplayFrequency);
257
258 if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_300)
259 return TRUE; // we're done with 0x300 fields
260
261 COPYN(dmICMMethod);
262 COPYN(dmICMIntent);
263 COPYN(dmMediaType);
264 COPYN(dmDitherType);
265 COPYN(dmReserved1);
266 COPYN(dmReserved2);
267
268 if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_400)
269 return TRUE; // we're done with 0x400 fields
270
271 COPYN(dmPanningWidth);
272 COPYN(dmPanningHeight);
273
274 return TRUE;
275 }
276
277
278 /*
279 * @implemented
280 */
281 BOOL
282 WINAPI
283 EnumDisplaySettingsA(
284 LPCSTR lpszDeviceName,
285 DWORD iModeNum,
286 LPDEVMODEA lpDevMode)
287 {
288 return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 );
289 }
290
291
292 /*
293 * @implemented
294 */
295 BOOL
296 WINAPI
297 EnumDisplaySettingsExW(
298 LPCWSTR lpszDeviceName,
299 DWORD iModeNum,
300 LPDEVMODEW lpDevMode,
301 DWORD dwFlags)
302 {
303 NTSTATUS Status;
304 UNICODE_STRING usDeviceName, *pusDeviceName = NULL;
305
306 if (lpszDeviceName)
307 {
308 RtlInitUnicodeString(&usDeviceName, lpszDeviceName);
309 pusDeviceName = &usDeviceName;
310 }
311
312 Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpDevMode, dwFlags);
313
314 return NT_SUCCESS(Status);
315 }
316
317
318 /*
319 * @implemented
320 */
321 BOOL
322 WINAPI
323 EnumDisplaySettingsW(
324 LPCWSTR lpszDeviceName,
325 DWORD iModeNum,
326 LPDEVMODEW lpDevMode)
327 {
328 return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 );
329 }
330
331
332 /*
333 * @implemented
334 */
335 BOOL
336 WINAPI
337 GetMonitorInfoA(
338 HMONITOR hMonitor,
339 LPMONITORINFO lpmi)
340 {
341 if (lpmi->cbSize == sizeof (MONITORINFO))
342 {
343 return NtUserGetMonitorInfo(hMonitor, lpmi);
344 }
345 else if (lpmi->cbSize != sizeof (MONITORINFOEXA))
346 {
347 SetLastError(ERROR_INVALID_PARAMETER);
348 return FALSE;
349 }
350 else
351 {
352 MONITORINFOEXW miExW;
353 INT res;
354
355 miExW.cbSize = sizeof (MONITORINFOEXW);
356 if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW))
357 {
358 return FALSE;
359 }
360 memcpy(lpmi, &miExW, sizeof (MONITORINFO));
361 res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1,
362 ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME,
363 NULL, NULL);
364 if (res == 0)
365 {
366 WARN("WideCharToMultiByte() failed!\n");
367 return FALSE;
368 }
369 }
370
371 return TRUE;
372 }
373
374
375 /*
376 * @implemented
377 */
378 BOOL
379 WINAPI
380 GetMonitorInfoW(
381 HMONITOR hMonitor,
382 LPMONITORINFO lpmi)
383 {
384 return NtUserGetMonitorInfo(hMonitor, lpmi);
385 }
386
387
388 /*
389 * @implemented
390 */
391 HMONITOR
392 WINAPI
393 MonitorFromPoint(
394 IN POINT ptPoint,
395 IN DWORD dwFlags )
396 {
397 return NtUserMonitorFromPoint(ptPoint, dwFlags);
398 }
399
400
401 /*
402 * @implemented
403 */
404 HMONITOR
405 WINAPI
406 MonitorFromRect(
407 IN LPCRECT lpcRect,
408 IN DWORD dwFlags )
409 {
410 return NtUserMonitorFromRect(lpcRect, dwFlags);
411 }
412
413
414 /*
415 * @implemented
416 */
417 HMONITOR
418 WINAPI
419 MonitorFromWindow(
420 IN HWND hWnd,
421 IN DWORD dwFlags )
422 {
423 return NtUserMonitorFromWindow(hWnd, dwFlags);
424 }
425
426
427 /*
428 * @implemented
429 */
430 LONG
431 WINAPI
432 ChangeDisplaySettingsExA(
433 LPCSTR lpszDeviceName,
434 LPDEVMODEA lpDevMode,
435 HWND hwnd,
436 DWORD dwflags,
437 LPVOID lParam)
438 {
439 LONG rc;
440 UNICODE_STRING DeviceName;
441 PUNICODE_STRING pDeviceName = &DeviceName;
442
443 if (lpszDeviceName != NULL)
444 {
445 if (!RtlCreateUnicodeStringFromAsciiz(pDeviceName, (PCSZ)lpszDeviceName))
446 {
447 SetLastError(ERROR_OUTOFMEMORY);
448 return DISP_CHANGE_BADPARAM; /* FIXME what to return? */
449 }
450 }
451 else
452 pDeviceName = NULL;
453
454 if (lpDevMode != NULL)
455 {
456 LPDEVMODEW pDevModeW;
457 pDevModeW = GdiConvertToDevmodeW(lpDevMode);
458 if(pDevModeW)
459 {
460 rc = NtUserChangeDisplaySettings(pDeviceName, pDevModeW, hwnd, dwflags);
461 RtlFreeHeap(GetProcessHeap(), 0, pDevModeW);
462 }
463 else
464 rc = DISP_CHANGE_SUCCESSFUL;
465 }
466 else
467 rc = NtUserChangeDisplaySettings(pDeviceName, NULL, hwnd, dwflags);
468
469 if (lpszDeviceName != NULL)
470 RtlFreeUnicodeString(&DeviceName);
471
472 return rc;
473 }
474
475
476 /*
477 * @implemented
478 */
479 LONG
480 WINAPI
481 ChangeDisplaySettingsA(
482 LPDEVMODEA lpDevMode,
483 DWORD dwflags)
484 {
485 if(lpDevMode)
486 lpDevMode->dmDriverExtra = 0;
487 return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 );
488 }
489
490
491 /*
492 * @implemented
493 */
494 LONG
495 WINAPI
496 ChangeDisplaySettingsExW(
497 LPCWSTR lpszDeviceName,
498 LPDEVMODEW lpDevMode,
499 HWND hwnd,
500 DWORD dwflags,
501 LPVOID lParam)
502 {
503 LONG rc;
504 UNICODE_STRING DeviceName;
505 PUNICODE_STRING pDeviceName = &DeviceName;
506
507 if (lpszDeviceName != NULL)
508 RtlInitUnicodeString(pDeviceName, lpszDeviceName);
509 else
510 pDeviceName = NULL;
511
512 rc = NtUserChangeDisplaySettings(pDeviceName, lpDevMode, hwnd, dwflags);
513
514 return rc;
515 }
516
517
518 /*
519 * @implemented
520 */
521 LONG
522 WINAPI
523 ChangeDisplaySettingsW(
524 LPDEVMODEW lpDevMode,
525 DWORD dwflags)
526 {
527 if(lpDevMode)
528 lpDevMode->dmDriverExtra = 0;
529 return ChangeDisplaySettingsExW(NULL, lpDevMode, NULL, dwflags, 0);
530 }