Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winprefs.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 * Copyright (C) Colin Harrison 2005-2008
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Except as contained in this notice, the name of the XFree86 Project
25 * shall not be used in advertising or otherwise to promote the sale, use
26 * or other dealings in this Software without prior written authorization
27 * from the XFree86 Project.
28 *
29 * Authors: Earle F. Philhower, III
30 * Colin Harrison
31 */
32
33#ifdef HAVE_XWIN_CONFIG_H
34#include <xwin-config.h>
35#endif
36#include <stdio.h>
37#include <stdlib.h>
38#ifdef __CYGWIN__
39#include <sys/resource.h>
40#endif
41#include "win.h"
42
43#include <X11/Xwindows.h>
44#include <shellapi.h>
45
46#include "winprefs.h"
47#include "winmultiwindowclass.h"
48
49/* Where will the custom menu commands start counting from? */
50#define STARTMENUID WM_USER
51
52extern const char *winGetBaseDir(void);
53
54/* From winprefslex.l, the real parser */
55extern int parse_file(FILE * fp);
56
57/* Currently in use command ID, incremented each new menu item created */
58static int g_cmdid = STARTMENUID;
59
60/* Local function to handle comma-ified icon names */
61static HICON LoadImageComma(char *fname, int sx, int sy, int flags);
62
63/*
64 * Creates or appends a menu from a MENUPARSED structure
65 */
66static HMENU
67MakeMenu(char *name, HMENU editMenu, int editItem)
68{
69 int i;
70 int item;
71 MENUPARSED *m;
72 HMENU hmenu, hsub;
73
74 for (i = 0; i < pref.menuItems; i++) {
75 if (!strcmp(name, pref.menu[i].menuName))
76 break;
77 }
78
79 /* Didn't find a match, bummer */
80 if (i == pref.menuItems) {
81 ErrorF("MakeMenu: Can't find menu %s\n", name);
82 return NULL;
83 }
84
85 m = &(pref.menu[i]);
86
87 if (editMenu) {
88 hmenu = editMenu;
89 item = editItem;
90 }
91 else {
92 hmenu = CreatePopupMenu();
93 if (!hmenu) {
94 ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name);
95 return NULL;
96 }
97 item = 0;
98 }
99
100 /* Add the menu items */
101 for (i = 0; i < m->menuItems; i++) {
102 /* Only assign IDs one time... */
103 if (m->menuItem[i].commandID == 0)
104 m->menuItem[i].commandID = g_cmdid++;
105
106 switch (m->menuItem[i].cmd) {
107 case CMD_EXEC:
108 case CMD_ALWAYSONTOP:
109 case CMD_RELOAD:
110 InsertMenu(hmenu,
111 item,
112 MF_BYPOSITION | MF_ENABLED | MF_STRING,
113 m->menuItem[i].commandID, m->menuItem[i].text);
114 break;
115
116 case CMD_SEPARATOR:
117 InsertMenu(hmenu, item, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
118 break;
119
120 case CMD_MENU:
121 /* Recursive! */
122 hsub = MakeMenu(m->menuItem[i].param, 0, 0);
123 if (hsub)
124 InsertMenu(hmenu,
125 item,
126 MF_BYPOSITION | MF_POPUP | MF_ENABLED | MF_STRING,
127 (UINT_PTR) hsub, m->menuItem[i].text);
128 break;
129 }
130
131 /* If item==-1 (means to add at end of menu) don't increment) */
132 if (item >= 0)
133 item++;
134 }
135
136 return hmenu;
137}
138
139#ifdef XWIN_MULTIWINDOW
140/*
141 * Callback routine that is executed once per window class.
142 * Removes or creates custom window settings depending on LPARAM
143 */
144static wBOOL CALLBACK
145ReloadEnumWindowsProc(HWND hwnd, LPARAM lParam)
146{
147 HICON hicon;
148
149 if (!hwnd) {
150 ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n");
151 return FALSE;
152 }
153
154 /* It's our baby, either clean or dirty it */
155 if (lParam == FALSE) {
156 /* Reset the window's icon to undefined. */
157 hicon = (HICON) SendMessage(hwnd, WM_SETICON, ICON_BIG, 0);
158
159 /* If the old icon is generated on-the-fly, get rid of it, will regen */
160 winDestroyIcon(hicon);
161
162 /* Same for the small icon */
163 hicon = (HICON) SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0);
164 winDestroyIcon(hicon);
165
166 /* Remove any menu additions; bRevert=TRUE destroys any modified menus */
167 GetSystemMenu(hwnd, TRUE);
168
169 /* This window is now clean of our taint (but with undefined icons) */
170 }
171 else {
172 /* Send a message to WM thread telling it re-evaluate the icon for this window */
173 {
174 winWMMessageRec wmMsg;
175
176 WindowPtr pWin = GetProp(hwnd, WIN_WINDOW_PROP);
177
178 if (pWin) {
179 winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
180 winPrivScreenPtr s_pScreenPriv = pWinPriv->pScreenPriv;
181
182 wmMsg.msg = WM_WM_ICON_EVENT;
183 wmMsg.hwndWindow = hwnd;
184 wmMsg.iWindow = (Window) (INT_PTR) GetProp(hwnd, WIN_WID_PROP);
185
186 winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
187 }
188 }
189
190 /* Update the system menu for this window */
191 SetupSysMenu(hwnd);
192
193 /* That was easy... */
194 }
195
196 return TRUE;
197}
198#endif
199
200/*
201 * Removes any custom icons in classes, custom menus, etc.
202 * Frees all members in pref structure.
203 * Reloads the preferences file.
204 * Set custom icons and menus again.
205 */
206static void
207ReloadPrefs(void)
208{
209 int i;
210
211#ifdef XWIN_MULTIWINDOW
212 /* First, iterate over all windows, deleting their icons and custom menus.
213 * This is really only needed because winDestroyIcon() will try to
214 * destroy the old global icons, which will have changed.
215 * It is probably better to set a windows USER_DATA to flag locally defined
216 * icons, and use that to accurately know when to destroy old icons.
217 */
218 EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
219#endif
220
221 /* Now, free/clear all info from our prefs structure */
222 for (i = 0; i < pref.menuItems; i++)
223 free(pref.menu[i].menuItem);
224 free(pref.menu);
225 pref.menu = NULL;
226 pref.menuItems = 0;
227
228 pref.rootMenuName[0] = 0;
229
230 free(pref.sysMenu);
231 pref.sysMenuItems = 0;
232
233 pref.defaultSysMenuName[0] = 0;
234 pref.defaultSysMenuPos = 0;
235
236 pref.iconDirectory[0] = 0;
237 pref.defaultIconName[0] = 0;
238 pref.trayIconName[0] = 0;
239
240 for (i = 0; i < pref.iconItems; i++)
241 if (pref.icon[i].hicon)
242 DestroyIcon((HICON) pref.icon[i].hicon);
243 free(pref.icon);
244 pref.icon = NULL;
245 pref.iconItems = 0;
246
247 /* Free global default X icon */
248 if (g_hIconX)
249 DestroyIcon(g_hIconX);
250 if (g_hSmallIconX)
251 DestroyIcon(g_hSmallIconX);
252
253 /* Reset the custom command IDs */
254 g_cmdid = STARTMENUID;
255
256 /* Load the updated resource file */
257 LoadPreferences();
258
259 g_hIconX = NULL;
260 g_hSmallIconX = NULL;
261
262#ifdef XWIN_MULTIWINDOW
263 winInitGlobalIcons();
264#endif
265
266#ifdef XWIN_MULTIWINDOW
267 /* Rebuild the icons and menus */
268 EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
269#endif
270
271 /* Whew, done */
272}
273
274/*
275 * Check/uncheck the ALWAYSONTOP items in this menu
276 */
277void
278HandleCustomWM_INITMENU(HWND hwnd, HMENU hmenu)
279{
280 DWORD dwExStyle;
281 int i, j;
282
283 if (!hwnd || !hmenu)
284 return;
285
286 if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
287 dwExStyle = MF_BYCOMMAND | MF_CHECKED;
288 else
289 dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
290
291 for (i = 0; i < pref.menuItems; i++)
292 for (j = 0; j < pref.menu[i].menuItems; j++)
293 if (pref.menu[i].menuItem[j].cmd == CMD_ALWAYSONTOP)
294 CheckMenuItem(hmenu, pref.menu[i].menuItem[j].commandID,
295 dwExStyle);
296
297}
298
299/*
300 * Searches for the custom WM_COMMAND command ID and performs action.
301 * Return TRUE if command is proccessed, FALSE otherwise.
302 */
303Bool
304HandleCustomWM_COMMAND(HWND hwnd, int command)
305{
306 int i, j;
307 MENUPARSED *m;
308 DWORD dwExStyle;
309
310 if (!command)
311 return FALSE;
312
313 for (i = 0; i < pref.menuItems; i++) {
314 m = &(pref.menu[i]);
315 for (j = 0; j < m->menuItems; j++) {
316 if (command == m->menuItem[j].commandID) {
317 /* Match! */
318 switch (m->menuItem[j].cmd) {
319#ifdef __CYGWIN__
320 case CMD_EXEC:
321 if (fork() == 0) {
322 struct rlimit rl;
323 int fd;
324
325 /* Close any open descriptors except for STD* */
326 getrlimit(RLIMIT_NOFILE, &rl);
327 for (fd = STDERR_FILENO + 1; fd < rl.rlim_cur; fd++)
328 close(fd);
329
330 /* Disassociate any TTYs */
331 setsid();
332
333 execl("/bin/sh",
334 "/bin/sh", "-c", m->menuItem[j].param, NULL);
335 exit(0);
336 }
337 else
338 return TRUE;
339 break;
340#else
341 case CMD_EXEC:
342 {
343 /* Start process without console window */
344 STARTUPINFO start;
345 PROCESS_INFORMATION child;
346
347 memset(&start, 0, sizeof(start));
348 start.cb = sizeof(start);
349 start.dwFlags = STARTF_USESHOWWINDOW;
350 start.wShowWindow = SW_HIDE;
351
352 memset(&child, 0, sizeof(child));
353
354 if (CreateProcess
355 (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, NULL,
356 NULL, &start, &child)) {
357 CloseHandle(child.hThread);
358 CloseHandle(child.hProcess);
359 }
360 else
361 MessageBox(NULL, m->menuItem[j].param,
362 "Mingrc Exec Command Error!",
363 MB_OK | MB_ICONEXCLAMATION);
364 }
365 return TRUE;
366#endif
367 case CMD_ALWAYSONTOP:
368 if (!hwnd)
369 return FALSE;
370
371 /* Get extended window style */
372 dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
373
374 /* Handle topmost windows */
375 if (dwExStyle & WS_EX_TOPMOST)
376 SetWindowPos(hwnd,
377 HWND_NOTOPMOST,
378 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
379 else
380 SetWindowPos(hwnd,
381 HWND_TOPMOST,
382 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
383#if XWIN_MULTIWINDOW
384 /* Reflect the changed Z order */
385 winReorderWindowsMultiWindow();
386#endif
387 return TRUE;
388
389 case CMD_RELOAD:
390 ReloadPrefs();
391 return TRUE;
392
393 default:
394 return FALSE;
395 }
396 } /* match */
397 } /* for j */
398 } /* for i */
399
400 return FALSE;
401}
402
403#ifdef XWIN_MULTIWINDOW
404/*
405 * Add the default or a custom menu depending on the class match
406 */
407void
408SetupSysMenu(HWND hwnd)
409{
410 HMENU sys;
411 int i;
412 WindowPtr pWin;
413 char *res_name, *res_class;
414
415 if (!hwnd)
416 return;
417
418 pWin = GetProp(hwnd, WIN_WINDOW_PROP);
419
420 sys = GetSystemMenu(hwnd, FALSE);
421 if (!sys)
422 return;
423
424 if (pWin) {
425 /* First see if there's a class match... */
426 if (winMultiWindowGetClassHint(pWin, &res_name, &res_class)) {
427 for (i = 0; i < pref.sysMenuItems; i++) {
428 if (!strcmp(pref.sysMenu[i].match, res_name) ||
429 !strcmp(pref.sysMenu[i].match, res_class)) {
430 free(res_name);
431 free(res_class);
432
433 MakeMenu(pref.sysMenu[i].menuName, sys,
434 pref.sysMenu[i].menuPos == AT_START ? 0 : -1);
435 return;
436 }
437 }
438
439 /* No match, just free alloc'd strings */
440 free(res_name);
441 free(res_class);
442 } /* Found wm_class */
443 } /* if pwin */
444
445 /* Fallback to system default */
446 if (pref.defaultSysMenuName[0]) {
447 if (pref.defaultSysMenuPos == AT_START)
448 MakeMenu(pref.defaultSysMenuName, sys, 0);
449 else
450 MakeMenu(pref.defaultSysMenuName, sys, -1);
451 }
452}
453#endif
454
455/*
456 * Possibly add a menu to the toolbar icon
457 */
458void
459SetupRootMenu(HMENU root)
460{
461 if (!root)
462 return;
463
464 if (pref.rootMenuName[0]) {
465 MakeMenu(pref.rootMenuName, root, 0);
466 }
467}
468
469/*
470 * Check for and return an overridden default ICON specified in the prefs
471 */
472HICON
473winOverrideDefaultIcon(int size)
474{
475 HICON hicon;
476
477 if (pref.defaultIconName[0]) {
478 hicon = LoadImageComma(pref.defaultIconName, size, size, 0);
479 if (hicon == NULL)
480 ErrorF("winOverrideDefaultIcon: LoadImageComma(%s) failed\n",
481 pref.defaultIconName);
482
483 return hicon;
484 }
485
486 return 0;
487}
488
489/*
490 * Return the HICON to use in the taskbar notification area
491 */
492HICON
493winTaskbarIcon(void)
494{
495 HICON hicon;
496
497 hicon = 0;
498 /* First try and load an overridden, if success then return it */
499 if (pref.trayIconName[0]) {
500 hicon = LoadImageComma(pref.trayIconName,
501 GetSystemMetrics(SM_CXSMICON),
502 GetSystemMetrics(SM_CYSMICON), 0);
503 }
504
505 /* Otherwise return the default */
506 if (!hicon)
507 hicon = (HICON) LoadImage(g_hInstance,
508 MAKEINTRESOURCE(IDI_XWIN),
509 IMAGE_ICON,
510 GetSystemMetrics(SM_CXSMICON),
511 GetSystemMetrics(SM_CYSMICON), 0);
512
513 return hicon;
514}
515
516/*
517 * Parse a filename to extract an icon:
518 * If fname is exactly ",nnn" then extract icon from our resource
519 * else if it is "file,nnn" then extract icon nnn from that file
520 * else try to load it as an .ico file and if that fails return NULL
521 */
522static HICON
523LoadImageComma(char *fname, int sx, int sy, int flags)
524{
525 HICON hicon;
526 int i;
527 char file[PATH_MAX + NAME_MAX + 2];
528
529 /* Some input error checking */
530 if (!fname || !fname[0])
531 return NULL;
532
533 i = 0;
534 hicon = NULL;
535
536 if (fname[0] == ',') {
537 /* It's the XWIN.EXE resource they want */
538 i = atoi(fname + 1);
539 hicon = LoadImage(g_hInstance,
540 MAKEINTRESOURCE(i), IMAGE_ICON, sx, sy, flags);
541 }
542 else {
543 file[0] = 0;
544 /* Prepend path if not given a "X:\" filename */
545 if (!(fname[0] && fname[1] == ':' && fname[2] == '\\')) {
546 strcpy(file, pref.iconDirectory);
547 if (pref.iconDirectory[0])
548 if (fname[strlen(fname) - 1] != '\\')
549 strcat(file, "\\");
550 }
551 strcat(file, fname);
552
553 if (strrchr(file, ',')) {
554 /* Specified as <fname>,<index> */
555
556 *(strrchr(file, ',')) = 0; /* End string at comma */
557 i = atoi(strrchr(fname, ',') + 1);
558 hicon = ExtractIcon(g_hInstance, file, i);
559 }
560 else {
561 /* Just an .ico file... */
562
563 hicon = (HICON) LoadImage(NULL,
564 file,
565 IMAGE_ICON,
566 sx, sy, LR_LOADFROMFILE | flags);
567 }
568 }
569 return hicon;
570}
571
572/*
573 * Check for a match of the window class to one specified in the
574 * ICONS{} section in the prefs file, and load the icon from a file
575 */
576HICON
577winOverrideIcon(char *res_name, char *res_class, char *wmName)
578{
579 int i;
580 HICON hicon;
581
582 for (i = 0; i < pref.iconItems; i++) {
583 if ((res_name && !strcmp(pref.icon[i].match, res_name)) ||
584 (res_class && !strcmp(pref.icon[i].match, res_class)) ||
585 (wmName && strstr(wmName, pref.icon[i].match))) {
586 if (pref.icon[i].hicon)
587 return pref.icon[i].hicon;
588
589 hicon = LoadImageComma(pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE);
590 if (hicon == NULL)
591 ErrorF("winOverrideIcon: LoadImageComma(%s) failed\n",
592 pref.icon[i].iconFile);
593
594 pref.icon[i].hicon = hicon;
595 return hicon;
596 }
597 }
598
599 /* Didn't find the icon, fail gracefully */
600 return 0;
601}
602
603/*
604 * Should we free this icon or leave it in memory (is it part of our
605 * ICONS{} overrides)?
606 */
607int
608winIconIsOverride(HICON hicon)
609{
610 int i;
611
612 if (!hicon)
613 return 0;
614
615 for (i = 0; i < pref.iconItems; i++)
616 if ((HICON) pref.icon[i].hicon == hicon)
617 return 1;
618
619 return 0;
620}
621
622/*
623 * Open and parse the XWinrc config file @path.
624 * If @path is NULL, use the built-in default.
625 */
626static int
627winPrefsLoadPreferences(char *path)
628{
629 FILE *prefFile = NULL;
630
631 if (path)
632 prefFile = fopen(path, "r");
633#ifdef __CYGWIN__
634 else {
635 char defaultPrefs[] =
636 "MENU rmenu {\n"
637 " \"How to customize this menu\" EXEC \"xterm +tb -e man XWinrc\"\n"
638 " \"Launch xterm\" EXEC xterm\n"
639 " \"Load .XWinrc\" RELOAD\n"
640 " SEPARATOR\n" "}\n" "\n" "ROOTMENU rmenu\n";
641
642 path = "built-in default";
643 prefFile = fmemopen(defaultPrefs, strlen(defaultPrefs), "r");
644 }
645#endif
646
647 if (!prefFile) {
648 ErrorF("LoadPreferences: %s not found\n", path);
649 return FALSE;
650 }
651
652 ErrorF("LoadPreferences: Loading %s\n", path);
653
654 if ((parse_file(prefFile)) != 0) {
655 ErrorF("LoadPreferences: %s is badly formed!\n", path);
656 fclose(prefFile);
657 return FALSE;
658 }
659
660 fclose(prefFile);
661 return TRUE;
662}
663
664/*
665 * Try and open ~/.XWinrc and system.XWinrc
666 * Load it into prefs structure for use by other functions
667 */
668void
669LoadPreferences(void)
670{
671 char *home;
672 char fname[PATH_MAX + NAME_MAX + 2];
673 char szDisplay[512];
674 char *szEnvDisplay;
675 int i, j;
676 char param[PARAM_MAX + 1];
677 char *srcParam, *dstParam;
678 int parsed = FALSE;
679
680 /* First, clear all preference settings */
681 memset(&pref, 0, sizeof(pref));
682
683 /* Now try and find a ~/.xwinrc file */
684 home = getenv("HOME");
685 if (home) {
686 strcpy(fname, home);
687 if (fname[strlen(fname) - 1] != '/')
688 strcat(fname, "/");
689 strcat(fname, ".XWinrc");
690 parsed = winPrefsLoadPreferences(fname);
691 }
692
693 /* No home file found, check system default */
694 if (!parsed) {
695 char buffer[MAX_PATH];
696
697#ifdef RELOCATE_PROJECTROOT
698 snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir());
699#else
700 strncpy(buffer, SYSCONFDIR "/X11/system.XWinrc", sizeof(buffer));
701#endif
702 buffer[sizeof(buffer) - 1] = 0;
703 parsed = winPrefsLoadPreferences(buffer);
704 }
705
706 /* Neither user nor system configuration found, or were badly formed */
707 if (!parsed) {
708 ErrorF
709 ("LoadPreferences: See \"man XWinrc\" to customize the XWin menu.\n");
710 parsed = winPrefsLoadPreferences(NULL);
711 }
712
713 /* Setup a DISPLAY environment variable, need to allocate on heap */
714 /* because putenv doesn't copy the argument... */
715 snprintf(szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
716 szEnvDisplay = (char *) (malloc(strlen(szDisplay) + 1));
717 if (szEnvDisplay) {
718 strcpy(szEnvDisplay, szDisplay);
719 putenv(szEnvDisplay);
720 }
721
722 /* Replace any "%display%" in menu commands with display string */
723 snprintf(szDisplay, 512, "127.0.0.1:%s.0", display);
724 for (i = 0; i < pref.menuItems; i++) {
725 for (j = 0; j < pref.menu[i].menuItems; j++) {
726 if (pref.menu[i].menuItem[j].cmd == CMD_EXEC) {
727 srcParam = pref.menu[i].menuItem[j].param;
728 dstParam = param;
729 while (*srcParam) {
730 if (!strncmp(srcParam, "%display%", 9)) {
731 memcpy(dstParam, szDisplay, strlen(szDisplay));
732 dstParam += strlen(szDisplay);
733 srcParam += 9;
734 }
735 else {
736 *dstParam = *srcParam;
737 dstParam++;
738 srcParam++;
739 }
740 }
741 *dstParam = 0;
742 strcpy(pref.menu[i].menuItem[j].param, param);
743 } /* cmd==cmd_exec */
744 } /* for all menuitems */
745 } /* for all menus */
746
747}
748
749/*
750 * Check for a match of the window class to one specified in the
751 * STYLES{} section in the prefs file, and return the style type
752 */
753unsigned long
754winOverrideStyle(char *res_name, char *res_class, char *wmName)
755{
756 int i;
757
758 for (i = 0; i < pref.styleItems; i++) {
759 if ((res_name && !strcmp(pref.style[i].match, res_name)) ||
760 (res_class && !strcmp(pref.style[i].match, res_class)) ||
761 (wmName && strstr(wmName, pref.style[i].match))) {
762 if (pref.style[i].type)
763 return pref.style[i].type;
764 }
765 }
766
767 /* Didn't find the style, fail gracefully */
768 return STYLE_NONE;
769}