wined3d: Set 3D device caps in adapter_gl_get_wined3d_caps().
[wine.git] / dlls / uxtheme / uxini.c
blob1581ff469a59f4329bd88dde2f32a346128072d8
1 /*
2 * Win32 5.1 uxtheme ini file processing
4 * Copyright (C) 2004 Kevin Koltzau
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.
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.
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
21 #include "config.h"
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnls.h"
29 #include "wine/debug.h"
30 #include "wine/heap.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
34 /***********************************************************************
35 * Defines and global variables
38 static const WCHAR szTextFileResource[] = {
39 'T','E','X','T','F','I','L','E','\0'
42 typedef struct _UXINI_FILE {
43 LPCWSTR lpIni;
44 LPCWSTR lpCurLoc;
45 LPCWSTR lpEnd;
46 } UXINI_FILE, *PUXINI_FILE;
48 /***********************************************************************/
50 /**********************************************************************
51 * UXINI_LoadINI
53 * Load a theme INI file out of resources from the specified
54 * theme
56 * PARAMS
57 * tf Theme to load INI file out of resources
58 * lpName Resource name of the INI file
60 * RETURNS
61 * INI file, or NULL if not found
63 PUXINI_FILE UXINI_LoadINI(HMODULE hTheme, LPCWSTR lpName) {
64 HRSRC hrsc;
65 LPCWSTR lpThemesIni = NULL;
66 PUXINI_FILE uf;
67 DWORD dwIniSize;
69 TRACE("Loading resource INI %s\n", debugstr_w(lpName));
71 if((hrsc = FindResourceW(hTheme, lpName, szTextFileResource))) {
72 if(!(lpThemesIni = LoadResource(hTheme, hrsc))) {
73 TRACE("%s resource not found\n", debugstr_w(lpName));
74 return NULL;
78 dwIniSize = SizeofResource(hTheme, hrsc) / sizeof(WCHAR);
79 uf = heap_alloc(sizeof(*uf));
80 uf->lpIni = lpThemesIni;
81 uf->lpCurLoc = lpThemesIni;
82 uf->lpEnd = lpThemesIni + dwIniSize;
83 return uf;
86 /**********************************************************************
87 * UXINI_CloseINI
89 * Close an open theme INI file
91 * PARAMS
92 * uf Theme INI file to close
94 void UXINI_CloseINI(PUXINI_FILE uf)
96 heap_free(uf);
99 /**********************************************************************
100 * UXINI_eof
102 * Determines if we are at the end of the INI file
104 * PARAMS
105 * uf Theme INI file to test
107 static inline BOOL UXINI_eof(PUXINI_FILE uf)
109 return uf->lpCurLoc >= uf->lpEnd;
112 /**********************************************************************
113 * UXINI_isspace
115 * Check if a character is a space character
117 * PARAMS
118 * c Character to test
120 static inline BOOL UXINI_isspace(WCHAR c)
122 if (isspace(c)) return TRUE;
123 if (c=='\r') return TRUE;
124 return FALSE;
127 /**********************************************************************
128 * UXINI_GetNextLine
130 * Get the next line in the INI file, non NULL terminated
131 * removes whitespace at beginning and end of line, and removes comments
133 * PARAMS
134 * uf INI file to retrieve next line
135 * dwLen Location to store pointer to line length
137 * RETURNS
138 * The section name, non NULL terminated
140 static LPCWSTR UXINI_GetNextLine(PUXINI_FILE uf, DWORD *dwLen)
142 LPCWSTR lpLineEnd;
143 LPCWSTR lpLineStart;
144 DWORD len;
145 do {
146 if(UXINI_eof(uf)) return NULL;
147 /* Skip whitespace and empty lines */
148 while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++;
149 lpLineStart = uf->lpCurLoc;
150 lpLineEnd = uf->lpCurLoc;
151 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = ++uf->lpCurLoc;
152 /* If comment was found, skip the rest of the line */
153 if(*uf->lpCurLoc == ';')
154 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++;
155 len = (lpLineEnd - lpLineStart);
156 if(*lpLineStart != ';' && len == 0)
157 return NULL;
158 } while(*lpLineStart == ';');
159 /* Remove whitespace from end of line */
160 while(UXINI_isspace(lpLineStart[len-1])) len--;
161 *dwLen = len;
163 return lpLineStart;
166 static inline void UXINI_UnGetToLine(PUXINI_FILE uf, LPCWSTR lpLine)
168 uf->lpCurLoc = lpLine;
171 /**********************************************************************
172 * UXINI_GetNextSection
174 * Locate the next section in the ini file, and return pointer to
175 * section name, non NULL terminated. Use dwLen to determine length
177 * PARAMS
178 * uf INI file to search, search starts at current location
179 * dwLen Location to store pointer to section name length
181 * RETURNS
182 * The section name, non NULL terminated
184 LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen)
186 LPCWSTR lpLine;
187 while((lpLine = UXINI_GetNextLine(uf, dwLen))) {
188 /* Assuming a ']' ending to the section name */
189 if(lpLine[0] == '[') {
190 lpLine++;
191 *dwLen -= 2;
192 break;
195 return lpLine;
198 /**********************************************************************
199 * UXINI_FindSection
201 * Locate a section with the specified name, search starts
202 * at current location in ini file
204 * PARAMS
205 * uf INI file to search, search starts at current location
206 * lpName Name of the section to locate
208 * RETURNS
209 * TRUE if section was found, FALSE otherwise
211 BOOL UXINI_FindSection(PUXINI_FILE uf, LPCWSTR lpName)
213 LPCWSTR lpSection;
214 DWORD dwLen;
215 while((lpSection = UXINI_GetNextSection(uf, &dwLen))) {
216 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpSection, dwLen, lpName, -1) == CSTR_EQUAL) {
217 return TRUE;
220 return FALSE;
223 /**********************************************************************
224 * UXINI_GetNextValue
226 * Locate the next value in the current section
228 * PARAMS
229 * uf INI file to search, search starts at current location
230 * dwNameLen Location to store pointer to value name length
231 * lpValue Location to store pointer to the value
232 * dwValueLen Location to store pointer to value length
234 * RETURNS
235 * The value name, non NULL terminated
237 LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, DWORD *dwValueLen)
239 LPCWSTR lpLine;
240 LPCWSTR lpLineEnd;
241 LPCWSTR name = NULL;
242 LPCWSTR value = NULL;
243 DWORD vallen = 0;
244 DWORD namelen = 0;
245 DWORD dwLen;
246 lpLine = UXINI_GetNextLine(uf, &dwLen);
247 if(!lpLine)
248 return NULL;
249 if(lpLine[0] == '[') {
250 UXINI_UnGetToLine(uf, lpLine);
251 return NULL;
253 lpLineEnd = lpLine + dwLen;
255 name = lpLine;
256 while(namelen < dwLen && *lpLine != '=') {
257 lpLine++;
258 namelen++;
260 if(*lpLine != '=') return NULL;
261 lpLine++;
263 /* Remove whitespace from end of name */
264 while(UXINI_isspace(name[namelen-1])) namelen--;
265 /* Remove whitespace from beginning of value */
266 while(UXINI_isspace(*lpLine) && lpLine < lpLineEnd) lpLine++;
267 value = lpLine;
268 vallen = dwLen-(value-name);
270 *dwNameLen = namelen;
271 *dwValueLen = vallen;
272 *lpValue = value;
274 return name;
277 /**********************************************************************
278 * UXINI_FindValue
280 * Locate a value by name
282 * PARAMS
283 * uf INI file to search, search starts at current location
284 * lpName Value name to locate
285 * lpValue Location to store pointer to the value
286 * dwValueLen Location to store pointer to value length
288 * RETURNS
289 * The value name, non NULL terminated
291 BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen)
293 LPCWSTR name;
294 DWORD namelen;
296 while((name = UXINI_GetNextValue(uf, &namelen, lpValue, dwValueLen))) {
297 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, name, namelen, lpName, -1) == CSTR_EQUAL) {
298 return TRUE;
301 return FALSE;