1 /* 2 * MSCMS - Color Management System for Wine 3 * 4 * Copyright 2004, 2005, 2008 Hans Leidekker 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "config.h" 22 #include "wine/debug.h" 23 24 #include <stdarg.h> 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "wingdi.h" 29 #include "winuser.h" 30 #include "icm.h" 31 32 #include "mscms_priv.h" 33 34 #ifdef HAVE_LCMS2 35 36 static CRITICAL_SECTION mscms_handle_cs; 37 static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug = 38 { 39 0, 0, &mscms_handle_cs, 40 { &mscms_handle_cs_debug.ProcessLocksList, 41 &mscms_handle_cs_debug.ProcessLocksList }, 42 0, 0, { (DWORD_PTR)(__FILE__ ": mscms_handle_cs") } 43 }; 44 static CRITICAL_SECTION mscms_handle_cs = { &mscms_handle_cs_debug, -1, 0, 0, 0, 0 }; 45 46 static struct profile *profiletable; 47 static struct transform *transformtable; 48 49 static unsigned int num_profile_handles; 50 static unsigned int num_transform_handles; 51 52 WINE_DEFAULT_DEBUG_CHANNEL(mscms); 53 54 void free_handle_tables( void ) 55 { 56 HeapFree( GetProcessHeap(), 0, profiletable ); 57 profiletable = NULL; 58 num_profile_handles = 0; 59 60 HeapFree( GetProcessHeap(), 0, transformtable ); 61 transformtable = NULL; 62 num_transform_handles = 0; 63 64 DeleteCriticalSection( &mscms_handle_cs ); 65 } 66 67 struct profile *grab_profile( HPROFILE handle ) 68 { 69 DWORD_PTR index; 70 71 EnterCriticalSection( &mscms_handle_cs ); 72 73 index = (DWORD_PTR)handle - 1; 74 if (index > num_profile_handles) 75 { 76 LeaveCriticalSection( &mscms_handle_cs ); 77 return NULL; 78 } 79 return &profiletable[index]; 80 } 81 82 void release_profile( struct profile *profile ) 83 { 84 LeaveCriticalSection( &mscms_handle_cs ); 85 } 86 87 struct transform *grab_transform( HTRANSFORM handle ) 88 { 89 DWORD_PTR index; 90 91 EnterCriticalSection( &mscms_handle_cs ); 92 93 index = (DWORD_PTR)handle - 1; 94 if (index > num_transform_handles) 95 { 96 LeaveCriticalSection( &mscms_handle_cs ); 97 return NULL; 98 } 99 return &transformtable[index]; 100 } 101 102 void release_transform( struct transform *transform ) 103 { 104 LeaveCriticalSection( &mscms_handle_cs ); 105 } 106 107 static HPROFILE alloc_profile_handle( void ) 108 { 109 DWORD_PTR index; 110 struct profile *p; 111 unsigned int count = 128; 112 113 for (index = 0; index < num_profile_handles; index++) 114 { 115 if (!profiletable[index].data) return (HPROFILE)(index + 1); 116 } 117 if (!profiletable) 118 { 119 p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct profile) ); 120 } 121 else 122 { 123 count = num_profile_handles * 2; 124 p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, profiletable, count * sizeof(struct profile) ); 125 } 126 if (!p) return NULL; 127 128 profiletable = p; 129 num_profile_handles = count; 130 131 return (HPROFILE)(index + 1); 132 } 133 134 HPROFILE create_profile( struct profile *profile ) 135 { 136 HPROFILE handle; 137 138 EnterCriticalSection( &mscms_handle_cs ); 139 140 if ((handle = alloc_profile_handle())) 141 { 142 DWORD_PTR index = (DWORD_PTR)handle - 1; 143 profiletable[index] = *profile; 144 } 145 LeaveCriticalSection( &mscms_handle_cs ); 146 return handle; 147 } 148 149 BOOL close_profile( HPROFILE handle ) 150 { 151 DWORD_PTR index; 152 struct profile *profile; 153 154 EnterCriticalSection( &mscms_handle_cs ); 155 156 index = (DWORD_PTR)handle - 1; 157 if (index > num_profile_handles) 158 { 159 LeaveCriticalSection( &mscms_handle_cs ); 160 return FALSE; 161 } 162 profile = &profiletable[index]; 163 164 if (profile->file != INVALID_HANDLE_VALUE) 165 { 166 if (profile->access & PROFILE_READWRITE) 167 { 168 DWORD written; 169 170 if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) || 171 !WriteFile( profile->file, profile->data, profile->size, &written, NULL ) || 172 written != profile->size) 173 { 174 ERR( "Unable to write color profile\n" ); 175 } 176 } 177 CloseHandle( profile->file ); 178 } 179 cmsCloseProfile( profile->cmsprofile ); 180 HeapFree( GetProcessHeap(), 0, profile->data ); 181 182 memset( profile, 0, sizeof(struct profile) ); 183 184 LeaveCriticalSection( &mscms_handle_cs ); 185 return TRUE; 186 } 187 188 static HTRANSFORM alloc_transform_handle( void ) 189 { 190 DWORD_PTR index; 191 struct transform *p; 192 unsigned int count = 128; 193 194 for (index = 0; index < num_transform_handles; index++) 195 { 196 if (!transformtable[index].cmstransform) return (HTRANSFORM)(index + 1); 197 } 198 if (!transformtable) 199 { 200 p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct transform) ); 201 } 202 else 203 { 204 count = num_transform_handles * 2; 205 p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, transformtable, count * sizeof(struct transform) ); 206 } 207 if (!p) return NULL; 208 209 transformtable = p; 210 num_transform_handles = count; 211 212 return (HTRANSFORM)(index + 1); 213 } 214 215 HTRANSFORM create_transform( struct transform *transform ) 216 { 217 HTRANSFORM handle; 218 219 EnterCriticalSection( &mscms_handle_cs ); 220 221 if ((handle = alloc_transform_handle())) 222 { 223 DWORD_PTR index = (DWORD_PTR)handle - 1; 224 transformtable[index] = *transform; 225 } 226 LeaveCriticalSection( &mscms_handle_cs ); 227 return handle; 228 } 229 230 BOOL close_transform( HTRANSFORM handle ) 231 { 232 DWORD_PTR index; 233 struct transform *transform; 234 235 EnterCriticalSection( &mscms_handle_cs ); 236 237 index = (DWORD_PTR)handle - 1; 238 if (index > num_transform_handles) 239 { 240 LeaveCriticalSection( &mscms_handle_cs ); 241 return FALSE; 242 } 243 transform = &transformtable[index]; 244 245 cmsDeleteTransform( transform->cmstransform ); 246 memset( transform, 0, sizeof(struct transform) ); 247 248 LeaveCriticalSection( &mscms_handle_cs ); 249 return TRUE; 250 } 251 252 #endif /* HAVE_LCMS2 */ 253