Hans Leidekker : winex11.drv: Retrieve X color profile in GetICMProfile.
Alexandre Julliard
julliard at winehq.org
Wed Mar 5 13:41:15 CST 2008
Module: wine
Branch: master
Commit: 22f146f01115a03a55fbe2e32f63f3be4d38da06
URL: http://source.winehq.org/git/wine.git/?a=commit;h=22f146f01115a03a55fbe2e32f63f3be4d38da06
Author: Hans Leidekker <hans at it.vu.nl>
Date: Wed Mar 5 15:57:39 2008 +0100
winex11.drv: Retrieve X color profile in GetICMProfile.
---
dlls/winex11.drv/graphics.c | 84 +++++++++++++++++++++++++++++++++++-----
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 1 +
3 files changed, 76 insertions(+), 10 deletions(-)
diff --git a/dlls/winex11.drv/graphics.c b/dlls/winex11.drv/graphics.c
index 5272681..e75b594 100644
--- a/dlls/winex11.drv/graphics.c
+++ b/dlls/winex11.drv/graphics.c
@@ -1381,6 +1381,39 @@ DWORD X11DRV_SetDCOrg( X11DRV_PDEVICE *physDev, INT x, INT y )
return ret;
}
+static unsigned char *get_icm_profile( unsigned long *size )
+{
+ Atom type;
+ int format;
+ unsigned long count, remaining;
+ unsigned char *profile, *ret = NULL;
+
+ wine_tsx11_lock();
+ XGetWindowProperty( gdi_display, DefaultRootWindow(gdi_display),
+ x11drv_atom(_ICC_PROFILE), 0, ~0UL, False, AnyPropertyType,
+ &type, &format, &count, &remaining, &profile );
+ if (format && count)
+ {
+ *size = count * (format / 8);
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, *size ))) memcpy( ret, profile, *size );
+ XFree( profile );
+ }
+ wine_tsx11_unlock();
+ return ret;
+}
+
+typedef struct
+{
+ unsigned int unknown[6];
+ unsigned int state[5];
+ unsigned int count[2];
+ unsigned char buffer[64];
+} sha_ctx;
+
+extern void WINAPI A_SHAInit( sha_ctx * );
+extern void WINAPI A_SHAUpdate( sha_ctx *, const unsigned char *, unsigned int );
+extern void WINAPI A_SHAFinal( sha_ctx *, unsigned char * );
+
/***********************************************************************
* GetICMProfile (X11DRV.@)
*/
@@ -1398,22 +1431,53 @@ BOOL X11DRV_GetICMProfile( X11DRV_PDEVICE *physDev, LPDWORD size, LPWSTR filenam
'V','e','r','s','i','o','n','\\','I','C','M','\\','m','n','t','r',0};
HKEY hkey;
- DWORD required;
- WCHAR profile[MAX_PATH], fullname[MAX_PATH];
+ DWORD required, len;
+ WCHAR profile[MAX_PATH], fullname[2*MAX_PATH + sizeof(path)/sizeof(WCHAR)];
+ unsigned char *buffer;
+ unsigned long buflen;
if (!size) return FALSE;
- strcpyW( profile, srgb );
- if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, mntr, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+ GetSystemDirectoryW( fullname, MAX_PATH );
+ strcatW( fullname, path );
+
+ len = sizeof(profile)/sizeof(WCHAR);
+ if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, mntr, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL ) &&
+ !RegEnumValueW( hkey, 0, profile, &len, NULL, NULL, NULL, NULL )) /* FIXME handle multiple values */
{
- DWORD len = sizeof(profile)/sizeof(WCHAR);
- /* FIXME handle multiple values */
- RegEnumValueW( hkey, 0, profile, &len, NULL, NULL, NULL, NULL );
+ strcatW( fullname, profile );
RegCloseKey( hkey );
}
- GetSystemDirectoryW( fullname, MAX_PATH );
- strcatW( fullname, path );
- strcatW( fullname, profile );
+ else if ((buffer = get_icm_profile( &buflen )))
+ {
+ static const WCHAR fmt[] = {'%','0','2','x',0};
+ static const WCHAR icm[] = {'.','i','c','m',0};
+
+ unsigned char sha1sum[20];
+ unsigned int i;
+ sha_ctx ctx;
+ HANDLE file;
+
+ A_SHAInit( &ctx );
+ A_SHAUpdate( &ctx, buffer, buflen );
+ A_SHAFinal( &ctx, sha1sum );
+
+ for (i = 0; i < sizeof(sha1sum); i++) sprintfW( &profile[i * 2], fmt, sha1sum[i] );
+ memcpy( &profile[i * 2], icm, sizeof(icm) );
+
+ strcatW( fullname, profile );
+ file = CreateFileW( fullname, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0 );
+ if (file != INVALID_HANDLE_VALUE)
+ {
+ DWORD written;
+
+ if (!WriteFile( file, buffer, buflen, &written, NULL ) || written != buflen)
+ ERR( "Unable to write color profile\n" );
+ CloseHandle( file );
+ }
+ HeapFree( GetProcessHeap(), 0, buffer );
+ }
+ else strcatW( fullname, srgb );
required = strlenW( fullname ) + 1;
if (*size < required)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 2ef2f1f..4111866 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -564,6 +564,7 @@ enum x11drv_atoms
XATOM_KWM_DOCKWINDOW,
XATOM_DndProtocol,
XATOM_DndSelection,
+ XATOM__ICC_PROFILE,
XATOM__MOTIF_WM_HINTS,
XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
XATOM__NET_SYSTEM_TRAY_OPCODE,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 50d4546..9162857 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -128,6 +128,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"KWM_DOCKWINDOW",
"DndProtocol",
"DndSelection",
+ "_ICC_PROFILE",
"_MOTIF_WM_HINTS",
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
"_NET_SYSTEM_TRAY_OPCODE",
More information about the wine-cvs
mailing list