/* * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/dde.c * PURPOSE: DDE * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) */ /* INCLUDES ******************************************************************/ #include #include WINE_DEFAULT_DEBUG_CHANNEL(user32); #define SIZEOF_DEVMODEA_300 124 #define SIZEOF_DEVMODEA_400 148 #define SIZEOF_DEVMODEA_500 156 #define SIZEOF_DEVMODEW_300 188 #define SIZEOF_DEVMODEW_400 212 #define SIZEOF_DEVMODEW_500 220 /* FUNCTIONS *****************************************************************/ /* * @implemented */ BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEA lpDisplayDevice, DWORD dwFlags) { BOOL rc; UNICODE_STRING Device; DISPLAY_DEVICEW DisplayDeviceW; if (!RtlCreateUnicodeStringFromAsciiz(&Device, (PCSZ)lpDevice)) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW)); DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW); rc = NtUserEnumDisplayDevices(&Device, iDevNum, &DisplayDeviceW, dwFlags); if (rc) { /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */ lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1, lpDisplayDevice->DeviceName, sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1, lpDisplayDevice->DeviceString, sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1, lpDisplayDevice->DeviceID, sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1, lpDisplayDevice->DeviceKey, sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), NULL, NULL); } RtlFreeUnicodeString(&Device); return rc; } /* * @implemented */ BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags) { UNICODE_STRING Device; BOOL rc; RtlInitUnicodeString(&Device, lpDevice); rc = NtUserEnumDisplayDevices( &Device, iDevNum, lpDisplayDevice, dwFlags); return rc; } /* * @implemented */ BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPCRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData) { INT iCount, i; HMONITOR *hMonitorList; LPRECT pRectList; HANDLE hHeap; BOOL ret = FALSE; /* get list of monitors/rects */ iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); if (iCount < 0) { /* FIXME: SetLastError() */ return FALSE; } if (iCount == 0) { return TRUE; } hHeap = GetProcessHeap(); hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount); if (hMonitorList == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); if (pRectList == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); if (iCount <= 0) { /* FIXME: SetLastError() */ goto cleanup; } /* enumerate list */ for (i = 0; i < iCount; i++) { HMONITOR hMonitor = hMonitorList[i]; LPRECT pMonitorRect = pRectList + i; HDC hMonitorDC = NULL; if (hdc != NULL) { /* make monitor DC */ hMonitorDC = hdc; } if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) goto cleanup; /* return FALSE */ } ret = TRUE; cleanup: if(hMonitorList) HeapFree(hHeap, 0, hMonitorList); if(pRectList) HeapFree(hHeap, 0, pRectList); return ret; } /* * @implemented */ BOOL WINAPI EnumDisplaySettingsExA( LPCSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEA lpDevMode, DWORD dwFlags) { NTSTATUS Status; UNICODE_STRING usDeviceName, *pusDeviceName = NULL; DEVMODEW DevModeW; if (lpszDeviceName) { if (!RtlCreateUnicodeStringFromAsciiz(&usDeviceName, (PCSZ)lpszDeviceName)) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } pusDeviceName = &usDeviceName; } memset(&DevModeW,0, sizeof(DEVMODEW)); DevModeW.dmSize = sizeof(DEVMODEW); Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, &DevModeW, dwFlags); if (pusDeviceName) { RtlFreeUnicodeString (&usDeviceName); } if (!NT_SUCCESS(Status)) { return FALSE; } #define COPYS(f,len) WideCharToMultiByte( CP_THREAD_ACP, 0, DevModeW.f, len, (LPSTR)lpDevMode->f, len, NULL, NULL ) #define COPYN(f) lpDevMode->f = DevModeW.f COPYS(dmDeviceName, CCHDEVICENAME ); COPYN(dmSpecVersion); COPYN(dmDriverVersion); switch (lpDevMode->dmSize) { case SIZEOF_DEVMODEA_300: case SIZEOF_DEVMODEA_400: case SIZEOF_DEVMODEA_500: break; default: lpDevMode->dmSize = SIZEOF_DEVMODEA_300; break; } COPYN(dmDriverExtra); COPYN(dmFields); COPYN(dmPosition.x); COPYN(dmPosition.y); COPYN(dmScale); COPYN(dmCopies); COPYN(dmDefaultSource); COPYN(dmPrintQuality); COPYN(dmColor); COPYN(dmDuplex); COPYN(dmYResolution); COPYN(dmTTOption); COPYN(dmCollate); COPYS(dmFormName,CCHFORMNAME); COPYN(dmLogPixels); COPYN(dmBitsPerPel); COPYN(dmPelsWidth); COPYN(dmPelsHeight); COPYN(dmDisplayFlags); // aka dmNup COPYN(dmDisplayFrequency); if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_300) return TRUE; // we're done with 0x300 fields COPYN(dmICMMethod); COPYN(dmICMIntent); COPYN(dmMediaType); COPYN(dmDitherType); COPYN(dmReserved1); COPYN(dmReserved2); if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_400) return TRUE; // we're done with 0x400 fields COPYN(dmPanningWidth); COPYN(dmPanningHeight); return TRUE; } /* * @implemented */ BOOL WINAPI EnumDisplaySettingsA( LPCSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEA lpDevMode) { return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } /* * @implemented */ BOOL WINAPI EnumDisplaySettingsExW( LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode, DWORD dwFlags) { NTSTATUS Status; UNICODE_STRING usDeviceName, *pusDeviceName = NULL; if (lpszDeviceName) { RtlInitUnicodeString(&usDeviceName, lpszDeviceName); pusDeviceName = &usDeviceName; } Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpDevMode, dwFlags); return NT_SUCCESS(Status); } /* * @implemented */ BOOL WINAPI EnumDisplaySettingsW( LPCWSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEW lpDevMode) { return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } /* * @implemented */ BOOL WINAPI GetMonitorInfoA( HMONITOR hMonitor, LPMONITORINFO lpmi) { if (lpmi->cbSize == sizeof (MONITORINFO)) { return NtUserGetMonitorInfo(hMonitor, lpmi); } else if (lpmi->cbSize != sizeof (MONITORINFOEXA)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } else { MONITORINFOEXW miExW; INT res; miExW.cbSize = sizeof (MONITORINFOEXW); if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW)) { return FALSE; } memcpy(lpmi, &miExW, sizeof (MONITORINFO)); res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1, ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME, NULL, NULL); if (res == 0) { WARN("WideCharToMultiByte() failed!\n"); return FALSE; } } return TRUE; } /* * @implemented */ BOOL WINAPI GetMonitorInfoW( HMONITOR hMonitor, LPMONITORINFO lpmi) { return NtUserGetMonitorInfo(hMonitor, lpmi); } /* * @implemented */ HMONITOR WINAPI MonitorFromPoint( IN POINT ptPoint, IN DWORD dwFlags ) { return NtUserMonitorFromPoint(ptPoint, dwFlags); } /* * @implemented */ HMONITOR WINAPI MonitorFromRect( IN LPCRECT lpcRect, IN DWORD dwFlags ) { return NtUserMonitorFromRect(lpcRect, dwFlags); } /* * @implemented */ HMONITOR WINAPI MonitorFromWindow( IN HWND hWnd, IN DWORD dwFlags ) { return NtUserMonitorFromWindow(hWnd, dwFlags); } /* * @implemented */ LONG WINAPI ChangeDisplaySettingsExA( LPCSTR lpszDeviceName, LPDEVMODEA lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) { LONG rc; UNICODE_STRING DeviceName; PUNICODE_STRING pDeviceName = &DeviceName; if (lpszDeviceName != NULL) { if (!RtlCreateUnicodeStringFromAsciiz(pDeviceName, (PCSZ)lpszDeviceName)) { SetLastError(ERROR_OUTOFMEMORY); return DISP_CHANGE_BADPARAM; /* FIXME what to return? */ } } else pDeviceName = NULL; if (lpDevMode != NULL) { LPDEVMODEW pDevModeW; pDevModeW = GdiConvertToDevmodeW(lpDevMode); if(pDevModeW) { rc = NtUserChangeDisplaySettings(pDeviceName, pDevModeW, hwnd, dwflags, lParam); RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); } else rc = DISP_CHANGE_SUCCESSFUL; } else rc = NtUserChangeDisplaySettings(pDeviceName, NULL, hwnd, dwflags, lParam); if (lpszDeviceName != NULL) RtlFreeUnicodeString(&DeviceName); return rc; } /* * @implemented */ LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA lpDevMode, DWORD dwflags) { if(lpDevMode) lpDevMode->dmDriverExtra = 0; return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 ); } /* * @implemented */ LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR lpszDeviceName, LPDEVMODEW lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam) { LONG rc; UNICODE_STRING DeviceName; PUNICODE_STRING pDeviceName = &DeviceName; if (lpszDeviceName != NULL) RtlInitUnicodeString(pDeviceName, lpszDeviceName); else pDeviceName = NULL; rc = NtUserChangeDisplaySettings(pDeviceName, lpDevMode, hwnd, dwflags, lParam); return rc; } /* * @implemented */ LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW lpDevMode, DWORD dwflags) { if(lpDevMode) lpDevMode->dmDriverExtra = 0; return ChangeDisplaySettingsExW(NULL, lpDevMode, NULL, dwflags, 0); }