|  | /* | 
|  | * Image Color Management | 
|  | * | 
|  | * Copyright 2004 Marcus Meissner | 
|  | * Copyright 2008 Hans Leidekker | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
|  | */ | 
|  |  | 
|  | #include "config.h" | 
|  |  | 
|  | #include <stdarg.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include "windef.h" | 
|  | #include "winbase.h" | 
|  | #include "wingdi.h" | 
|  | #include "winnls.h" | 
|  | #include "winreg.h" | 
|  |  | 
|  | #include "gdi_private.h" | 
|  |  | 
|  | #include "wine/debug.h" | 
|  | #include "wine/unicode.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(icm); | 
|  |  | 
|  |  | 
|  | struct enum_profiles | 
|  | { | 
|  | ICMENUMPROCA funcA; | 
|  | LPARAM data; | 
|  | }; | 
|  |  | 
|  | static INT CALLBACK enum_profiles_callbackA( LPWSTR filename, LPARAM lparam ) | 
|  | { | 
|  | int len, ret = -1; | 
|  | struct enum_profiles *ep = (struct enum_profiles *)lparam; | 
|  | char *filenameA; | 
|  |  | 
|  | len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL ); | 
|  | filenameA = HeapAlloc( GetProcessHeap(), 0, len ); | 
|  | if (filenameA) | 
|  | { | 
|  | WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL ); | 
|  | ret = ep->funcA( filenameA, ep->data ); | 
|  | HeapFree( GetProcessHeap(), 0, filenameA ); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           EnumICMProfilesA    (GDI32.@) | 
|  | */ | 
|  | INT WINAPI EnumICMProfilesA(HDC hdc, ICMENUMPROCA func, LPARAM lparam) | 
|  | { | 
|  | struct enum_profiles ep; | 
|  |  | 
|  | if (!func) return -1; | 
|  | ep.funcA = func; | 
|  | ep.data  = lparam; | 
|  | return EnumICMProfilesW( hdc, enum_profiles_callbackA, (LPARAM)&ep ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           EnumICMProfilesW    (GDI32.@) | 
|  | */ | 
|  | INT WINAPI EnumICMProfilesW(HDC hdc, ICMENUMPROCW func, LPARAM lparam) | 
|  | { | 
|  | DC *dc; | 
|  | INT ret = -1; | 
|  |  | 
|  | TRACE("%p, %p, 0x%08lx\n", hdc, func, lparam); | 
|  |  | 
|  | if (!func) return -1; | 
|  | if ((dc = get_dc_ptr(hdc))) | 
|  | { | 
|  | PHYSDEV physdev = GET_DC_PHYSDEV( dc, pEnumICMProfiles ); | 
|  | ret = physdev->funcs->pEnumICMProfiles( physdev, func, lparam ); | 
|  | release_dc_ptr(dc); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           GetICMProfileA   (GDI32.@) | 
|  | * | 
|  | * Returns the filename of the specified device context's color | 
|  | * management profile, even if color management is not enabled | 
|  | * for that DC. | 
|  | * | 
|  | * RETURNS | 
|  | *    TRUE if filename is copied successfully. | 
|  | *    FALSE if the buffer length pointed to by size is too small. | 
|  | * | 
|  | * FIXME | 
|  | *    How does Windows assign these? Some registry key? | 
|  | */ | 
|  | BOOL WINAPI GetICMProfileA(HDC hdc, LPDWORD size, LPSTR filename) | 
|  | { | 
|  | WCHAR filenameW[MAX_PATH]; | 
|  | DWORD buflen = MAX_PATH; | 
|  | BOOL ret = FALSE; | 
|  |  | 
|  | TRACE("%p, %p, %p\n", hdc, size, filename); | 
|  |  | 
|  | if (!hdc || !size || !filename) return FALSE; | 
|  |  | 
|  | if (GetICMProfileW(hdc, &buflen, filenameW)) | 
|  | { | 
|  | int len = WideCharToMultiByte(CP_ACP, 0, filenameW, -1, NULL, 0, NULL, NULL); | 
|  | if (*size >= len) | 
|  | { | 
|  | WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, *size, NULL, NULL); | 
|  | ret = TRUE; | 
|  | } | 
|  | else SetLastError(ERROR_INSUFFICIENT_BUFFER); | 
|  | *size = len; | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           GetICMProfileW     (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI GetICMProfileW(HDC hdc, LPDWORD size, LPWSTR filename) | 
|  | { | 
|  | BOOL ret = FALSE; | 
|  | DC *dc = get_dc_ptr(hdc); | 
|  |  | 
|  | TRACE("%p, %p, %p\n", hdc, size, filename); | 
|  |  | 
|  | if (dc) | 
|  | { | 
|  | PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetICMProfile ); | 
|  | ret = physdev->funcs->pGetICMProfile( physdev, size, filename ); | 
|  | release_dc_ptr(dc); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           GetLogColorSpaceA     (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI GetLogColorSpaceA(HCOLORSPACE colorspace, LPLOGCOLORSPACEA buffer, DWORD size) | 
|  | { | 
|  | FIXME("%p %p 0x%08x stub\n", colorspace, buffer, size); | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           GetLogColorSpaceW      (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI GetLogColorSpaceW(HCOLORSPACE colorspace, LPLOGCOLORSPACEW buffer, DWORD size) | 
|  | { | 
|  | FIXME("%p %p 0x%08x stub\n", colorspace, buffer, size); | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           SetICMProfileA         (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI SetICMProfileA(HDC hdc, LPSTR filename) | 
|  | { | 
|  | FIXME("%p %s stub\n", hdc, debugstr_a(filename)); | 
|  |  | 
|  | if (!filename) | 
|  | { | 
|  | SetLastError( ERROR_INVALID_PARAMETER ); | 
|  | return FALSE; | 
|  | } | 
|  | if (!hdc) | 
|  | { | 
|  | SetLastError( ERROR_INVALID_HANDLE ); | 
|  | return FALSE; | 
|  | } | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           SetICMProfileW         (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI SetICMProfileW(HDC hdc, LPWSTR filename) | 
|  | { | 
|  | FIXME("%p %s stub\n", hdc, debugstr_w(filename)); | 
|  |  | 
|  | if (!filename) | 
|  | { | 
|  | SetLastError( ERROR_INVALID_PARAMETER ); | 
|  | return FALSE; | 
|  | } | 
|  | if (!hdc) | 
|  | { | 
|  | SetLastError( ERROR_INVALID_HANDLE ); | 
|  | return FALSE; | 
|  | } | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           UpdateICMRegKeyA       (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI UpdateICMRegKeyA(DWORD reserved, LPSTR cmid, LPSTR filename, UINT command) | 
|  | { | 
|  | FIXME("0x%08x, %s, %s, 0x%08x stub\n", reserved, debugstr_a(cmid), debugstr_a(filename), command); | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | /********************************************************************** | 
|  | *           UpdateICMRegKeyW       (GDI32.@) | 
|  | */ | 
|  | BOOL WINAPI UpdateICMRegKeyW(DWORD reserved, LPWSTR cmid, LPWSTR filename, UINT command) | 
|  | { | 
|  | FIXME("0x%08x, %s, %s, 0x%08x stub\n", reserved, debugstr_w(cmid), debugstr_w(filename), command); | 
|  | return TRUE; | 
|  | } |