662 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			662 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining
 | 
						|
 * a copy of this software and associated documentation files (the
 | 
						|
 * "Software"), to deal in the Software without restriction, including
 | 
						|
 * without limitation the rights to use, copy, modify, merge, publish,
 | 
						|
 * distribute, sublicense, and/or sell copies of the Software, and to
 | 
						|
 * permit persons to whom the Software is furnished to do so, subject to
 | 
						|
 * the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice shall be
 | 
						|
 * included in all copies or substantial portions of the Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
						|
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
						|
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
						|
 * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
 | 
						|
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | 
						|
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
						|
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 *
 | 
						|
 * Except as contained in this notice, the name of the XFree86 Project
 | 
						|
 * shall not be used in advertising or otherwise to promote the sale, use
 | 
						|
 * or other dealings in this Software without prior written authorization
 | 
						|
 * from the XFree86 Project.
 | 
						|
 *
 | 
						|
 * Authors:     Earle F. Philhower, III
 | 
						|
 */
 | 
						|
/* $XFree86: xc/programs/Xserver/hw/xwin/winprefs.c,v 1.1 2003/10/02 13:30:11 eich Exp $ */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <sys/resource.h>
 | 
						|
#include "win.h"
 | 
						|
 | 
						|
/* Fixups to prevent collisions between Windows and X headers */
 | 
						|
#define ATOM DWORD
 | 
						|
#include <windows.h>
 | 
						|
 | 
						|
#include "winprefs.h"
 | 
						|
#include "winmultiwindowclass.h"
 | 
						|
 | 
						|
/* Where will the custom menu commands start counting from? */
 | 
						|
#define STARTMENUID WM_USER
 | 
						|
 | 
						|
/* From winmultiwindowflex.l, the real parser */
 | 
						|
extern void parse_file (FILE *fp);
 | 
						|
 | 
						|
/* From winmultiwindowyacc.y, the pref structure loaded by the parser */
 | 
						|
extern WINMULTIWINDOWPREFS pref;
 | 
						|
 | 
						|
/* The global X default icon */
 | 
						|
extern HICON		g_hiconX;
 | 
						|
 | 
						|
/* Currently in use command ID, incremented each new menu item created */
 | 
						|
static int g_cmdid = STARTMENUID;
 | 
						|
 | 
						|
 | 
						|
/* Defined in DIX */
 | 
						|
extern char *display;
 | 
						|
 | 
						|
/*
 | 
						|
 * Creates or appends a menu from a MENUPARSED structure
 | 
						|
 */
 | 
						|
static HMENU
 | 
						|
MakeMenu (char *name,
 | 
						|
	  HMENU editMenu,
 | 
						|
	  int editItem)
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  int item;
 | 
						|
  MENUPARSED *m;
 | 
						|
  HMENU hmenu;
 | 
						|
 | 
						|
  for (i=0; i<pref.menuItems; i++)
 | 
						|
    {
 | 
						|
      if (!strcmp(name, pref.menu[i].menuName))
 | 
						|
	break;
 | 
						|
    }
 | 
						|
  
 | 
						|
  /* Didn't find a match, bummer */
 | 
						|
  if (i==pref.menuItems)
 | 
						|
    {
 | 
						|
      ErrorF("MakeMenu: Can't find menu %s\n", name);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  
 | 
						|
  m = &(pref.menu[i]);
 | 
						|
 | 
						|
  if (editMenu)
 | 
						|
    {
 | 
						|
      hmenu = editMenu;
 | 
						|
      item = editItem;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      hmenu = CreatePopupMenu();
 | 
						|
      item = 0;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Add the menu items */
 | 
						|
  for (i=0; i<m->menuItems; i++)
 | 
						|
    {
 | 
						|
      /* Only assign IDs one time... */
 | 
						|
      if ( m->menuItem[i].commandID == 0 )
 | 
						|
	m->menuItem[i].commandID = g_cmdid++;
 | 
						|
 | 
						|
      switch (m->menuItem[i].cmd)
 | 
						|
	{
 | 
						|
	case CMD_EXEC:
 | 
						|
	case CMD_ALWAYSONTOP:
 | 
						|
	case CMD_RELOAD:
 | 
						|
	  InsertMenu (hmenu,
 | 
						|
		      item,
 | 
						|
		      MF_BYPOSITION|MF_ENABLED|MF_STRING,
 | 
						|
		      m->menuItem[i].commandID,
 | 
						|
		      m->menuItem[i].text);
 | 
						|
	  break;
 | 
						|
	  
 | 
						|
	case CMD_SEPARATOR:
 | 
						|
	  InsertMenu (hmenu,
 | 
						|
		      item,
 | 
						|
		      MF_BYPOSITION|MF_SEPARATOR,
 | 
						|
		      0,
 | 
						|
		      NULL);
 | 
						|
	  break;
 | 
						|
	  
 | 
						|
	case CMD_MENU:
 | 
						|
	  /* Recursive! */
 | 
						|
	  InsertMenu (hmenu,
 | 
						|
		      item,
 | 
						|
		      MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,
 | 
						|
		      (UINT_PTR)MakeMenu (m->menuItem[i].param, 0, 0),
 | 
						|
		      m->menuItem[i].text);
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
 | 
						|
      /* If item==-1 (means to add at end of menu) don't increment) */
 | 
						|
      if (item>=0)
 | 
						|
	item++;
 | 
						|
    }
 | 
						|
 | 
						|
  return hmenu;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Callback routine that is executed once per window class.
 | 
						|
 * Removes or creates custom window settings depending on LPARAM
 | 
						|
 */
 | 
						|
static BOOL CALLBACK
 | 
						|
ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
 | 
						|
{
 | 
						|
  char    szClassName[1024];
 | 
						|
  HICON   hicon;
 | 
						|
 | 
						|
  if (!GetClassName (hwnd, szClassName, 1024))
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
  if (strncmp (szClassName, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X)))
 | 
						|
    /* Not one of our windows... */
 | 
						|
    return TRUE;
 | 
						|
  
 | 
						|
  /* It's our baby, either clean or dirty it */
 | 
						|
  if (lParam==FALSE) 
 | 
						|
    {
 | 
						|
      hicon = (HICON)GetClassLong(hwnd, GCL_HICON);
 | 
						|
 | 
						|
      /* Unselect any icon in the class structure */
 | 
						|
      SetClassLong (hwnd, GCL_HICON, (LONG)LoadIcon (NULL, IDI_APPLICATION));
 | 
						|
 | 
						|
      /* If it's generated on-the-fly, get rid of it, will regen */
 | 
						|
      if (!winIconIsOverride((unsigned long)hicon) && hicon!=g_hiconX)
 | 
						|
	DestroyIcon (hicon);
 | 
						|
      
 | 
						|
      /* Remove any menu additions, use bRevert flag */
 | 
						|
      GetSystemMenu (hwnd, TRUE);
 | 
						|
      
 | 
						|
      /* This window is now clean of our taint */
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      /* Make the icon default, dynamic, of from xwinrc */
 | 
						|
      SetClassLong (hwnd, GCL_HICON, (LONG)g_hiconX);
 | 
						|
      winUpdateIcon ((Window)GetProp (hwnd, WIN_WID_PROP));
 | 
						|
      /* Update the system menu for this window */
 | 
						|
      SetupSysMenu ((unsigned long)hwnd);
 | 
						|
 | 
						|
      /* That was easy... */
 | 
						|
    }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Removes any custom icons in classes, custom menus, etc.
 | 
						|
 * Frees all members in pref structure.
 | 
						|
 * Reloads the preferences file.
 | 
						|
 * Set custom icons and menus again.
 | 
						|
 */
 | 
						|
static void
 | 
						|
ReloadPrefs ()
 | 
						|
{
 | 
						|
  int i;
 | 
						|
 | 
						|
  /* First, iterate over all windows replacing their icon with system */
 | 
						|
  /* default one and deleting any custom system menus                 */
 | 
						|
  EnumWindows (ReloadEnumWindowsProc, FALSE);
 | 
						|
  
 | 
						|
  /* Now, free/clear all info from our prefs structure */
 | 
						|
  for (i=0; i<pref.menuItems; i++)
 | 
						|
    free (pref.menu[i].menuItem);
 | 
						|
  free (pref.menu);
 | 
						|
  pref.menu = NULL;
 | 
						|
  pref.menuItems = 0;
 | 
						|
 | 
						|
  pref.rootMenuName[0] = 0;
 | 
						|
 | 
						|
  free (pref.sysMenu);
 | 
						|
  pref.sysMenuItems = 0;
 | 
						|
 | 
						|
  pref.defaultSysMenuName[0] = 0;
 | 
						|
  pref.defaultSysMenuPos = 0;
 | 
						|
 | 
						|
  pref.iconDirectory[0] = 0;
 | 
						|
  pref.defaultIconName[0] = 0;
 | 
						|
 | 
						|
  for (i=0; i<pref.iconItems; i++)
 | 
						|
    if (pref.icon[i].hicon)
 | 
						|
      DestroyIcon ((HICON)pref.icon[i].hicon);
 | 
						|
  free (pref.icon);
 | 
						|
  pref.icon = NULL;
 | 
						|
  pref.iconItems = 0;
 | 
						|
  
 | 
						|
  /* Free global default X icon */
 | 
						|
  DestroyIcon (g_hiconX);
 | 
						|
 | 
						|
  /* Reset the custom command IDs */
 | 
						|
  g_cmdid = STARTMENUID;
 | 
						|
 | 
						|
  /* Load the updated resource file */
 | 
						|
  LoadPreferences();
 | 
						|
 | 
						|
  /* Define global icon, load it */
 | 
						|
  g_hiconX = (HICON)winOverrideDefaultIcon();
 | 
						|
  if (!g_hiconX)
 | 
						|
    g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
 | 
						|
  
 | 
						|
  /* Rebuild the icons and menus */
 | 
						|
  EnumWindows (ReloadEnumWindowsProc, TRUE);
 | 
						|
 | 
						|
  /* Whew, done */
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Check/uncheck the ALWAYSONTOP items in this menu
 | 
						|
 */
 | 
						|
void
 | 
						|
HandleCustomWM_INITMENU(unsigned long hwndIn,
 | 
						|
			unsigned long hmenuIn)
 | 
						|
{
 | 
						|
  HWND    hwnd;
 | 
						|
  HMENU   hmenu;
 | 
						|
  DWORD   dwExStyle;
 | 
						|
  int     i, j;
 | 
						|
 | 
						|
  hwnd = (HWND)hwndIn;
 | 
						|
  hmenu = (HMENU)hmenuIn;
 | 
						|
  if (!hwnd || !hmenu) 
 | 
						|
    return;
 | 
						|
  
 | 
						|
  if (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
 | 
						|
    dwExStyle = MF_BYCOMMAND | MF_CHECKED;
 | 
						|
  else
 | 
						|
    dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
 | 
						|
 | 
						|
  for (i=0; i<pref.menuItems; i++)
 | 
						|
    for (j=0; j<pref.menu[i].menuItems; j++)
 | 
						|
      if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP)
 | 
						|
	CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle );
 | 
						|
  
 | 
						|
}
 | 
						|
    
 | 
						|
/*
 | 
						|
 * Searches for the custom WM_COMMAND command ID and performs action
 | 
						|
 */
 | 
						|
int
 | 
						|
HandleCustomWM_COMMAND (unsigned long hwndIn,
 | 
						|
			int           command)
 | 
						|
{
 | 
						|
  HWND hwnd;
 | 
						|
  int i, j;
 | 
						|
  MENUPARSED *m;
 | 
						|
  DWORD			dwExStyle;
 | 
						|
 | 
						|
  hwnd = (HWND)hwndIn;
 | 
						|
 | 
						|
  if (!command)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  for (i=0; i<pref.menuItems; i++)
 | 
						|
    {
 | 
						|
      m = &(pref.menu[i]);
 | 
						|
      for (j=0; j<m->menuItems; j++)
 | 
						|
	{
 | 
						|
	  if (command==m->menuItem[j].commandID)
 | 
						|
	    {
 | 
						|
	      /* Match! */
 | 
						|
	      switch(m->menuItem[j].cmd)
 | 
						|
		{
 | 
						|
		case CMD_EXEC:
 | 
						|
		  if (fork()==0)
 | 
						|
		    {
 | 
						|
		      struct rlimit rl;
 | 
						|
		      unsigned long i;
 | 
						|
 | 
						|
		      /* Close any open descriptors except for STD* */
 | 
						|
		      getrlimit (RLIMIT_NOFILE, &rl);
 | 
						|
		      for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
 | 
						|
			close(i);
 | 
						|
 | 
						|
		      /* Disassociate any TTYs */
 | 
						|
		      setsid();
 | 
						|
 | 
						|
		      execl ("/bin/sh",
 | 
						|
			     "/bin/sh",
 | 
						|
			     "-c",
 | 
						|
			     m->menuItem[j].param,
 | 
						|
			     NULL);
 | 
						|
		      exit (0);
 | 
						|
		    }
 | 
						|
		  else
 | 
						|
		    return 0;
 | 
						|
		  break;
 | 
						|
		  
 | 
						|
		case CMD_ALWAYSONTOP:
 | 
						|
		  if (!hwnd)
 | 
						|
		    return 0;
 | 
						|
 | 
						|
		  /* Get extended window style */
 | 
						|
		  dwExStyle = GetWindowLong (hwnd, GWL_EXSTYLE);
 | 
						|
		  
 | 
						|
		  /* Handle topmost windows */
 | 
						|
		  if (dwExStyle & WS_EX_TOPMOST)
 | 
						|
		    SetWindowPos (hwnd,
 | 
						|
				  HWND_NOTOPMOST,
 | 
						|
				  0, 0,
 | 
						|
				  0, 0,
 | 
						|
				  SWP_NOSIZE | SWP_NOMOVE);
 | 
						|
		  else
 | 
						|
		    SetWindowPos (hwnd,
 | 
						|
				  HWND_TOPMOST,
 | 
						|
				  0, 0,
 | 
						|
				  0, 0,
 | 
						|
				  SWP_NOSIZE | SWP_NOMOVE);
 | 
						|
		  return 0;
 | 
						|
		  
 | 
						|
		case CMD_RELOAD:
 | 
						|
		  ReloadPrefs();
 | 
						|
		  return 0;
 | 
						|
 | 
						|
		default:
 | 
						|
		  return 0;
 | 
						|
	      }
 | 
						|
	    } /* match */
 | 
						|
	} /* for j */
 | 
						|
    } /* for i */
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Add the default or a custom menu depending on the class match
 | 
						|
 */
 | 
						|
void
 | 
						|
SetupSysMenu (unsigned long hwndIn)
 | 
						|
{
 | 
						|
  HWND    hwnd;
 | 
						|
  HMENU	  sys;
 | 
						|
  int     i;
 | 
						|
  WindowPtr pWin;
 | 
						|
  char *res_name, *res_class;
 | 
						|
 | 
						|
  hwnd = (HWND)hwndIn;
 | 
						|
  if (!hwnd)
 | 
						|
    return;
 | 
						|
 | 
						|
  pWin = GetProp (hwnd, WIN_WINDOW_PROP);
 | 
						|
  
 | 
						|
  sys = GetSystemMenu (hwnd, FALSE);
 | 
						|
  if (!sys)
 | 
						|
    return;
 | 
						|
 | 
						|
  if (pWin)
 | 
						|
    {
 | 
						|
      /* First see if there's a class match... */
 | 
						|
      if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
 | 
						|
	{
 | 
						|
	  for (i=0; i<pref.sysMenuItems; i++)
 | 
						|
	    {
 | 
						|
	      if (!strcmp(pref.sysMenu[i].match, res_name) ||
 | 
						|
		  !strcmp(pref.sysMenu[i].match, res_class) ) 
 | 
						|
		{
 | 
						|
		  free(res_name);
 | 
						|
		  free(res_class);
 | 
						|
  
 | 
						|
		  MakeMenu (pref.sysMenu[i].menuName, sys,
 | 
						|
			    pref.sysMenu[i].menuPos==AT_START?0:-1);
 | 
						|
		  return;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	  
 | 
						|
	  /* No match, just free alloc'd strings */
 | 
						|
	  free(res_name);
 | 
						|
	  free(res_class);
 | 
						|
	} /* Found wm_class */
 | 
						|
    } /* if pwin */
 | 
						|
 | 
						|
  /* Fallback to system default */
 | 
						|
  if (pref.defaultSysMenuName[0])
 | 
						|
    {
 | 
						|
      if (pref.defaultSysMenuPos==AT_START)
 | 
						|
	MakeMenu (pref.defaultSysMenuName, sys, 0);
 | 
						|
      else
 | 
						|
	MakeMenu (pref.defaultSysMenuName, sys, -1);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Possibly add a menu to the toolbar icon
 | 
						|
 */
 | 
						|
void
 | 
						|
SetupRootMenu (unsigned long hmenuRoot)
 | 
						|
{
 | 
						|
  HMENU root;
 | 
						|
 | 
						|
  root = (HMENU)hmenuRoot;
 | 
						|
  if (!root)
 | 
						|
    return;
 | 
						|
 | 
						|
  if (pref.rootMenuName[0])
 | 
						|
    {
 | 
						|
      MakeMenu(pref.rootMenuName, root, 0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Check for and return an overridden default ICON specified in the prefs
 | 
						|
 */
 | 
						|
unsigned long
 | 
						|
winOverrideDefaultIcon()
 | 
						|
{
 | 
						|
  HICON hicon;
 | 
						|
  char fname[PATH_MAX+NAME_MAX+2];
 | 
						|
  
 | 
						|
  if (pref.defaultIconName[0])
 | 
						|
    {
 | 
						|
      /* Make sure we have a dir with trailing backslash */
 | 
						|
      /* Note we are using _Windows_ paths here, not cygwin */
 | 
						|
      strcpy (fname, pref.iconDirectory);
 | 
						|
      if (pref.iconDirectory[0])
 | 
						|
	if (fname[strlen(fname)-1]!='\\')
 | 
						|
	  strcat (fname, "\\");
 | 
						|
      strcat (fname, pref.defaultIconName);
 | 
						|
 | 
						|
      hicon = (HICON)LoadImage(NULL,
 | 
						|
			       fname,
 | 
						|
			       IMAGE_ICON,
 | 
						|
			       0, 0,
 | 
						|
			       LR_DEFAULTSIZE|LR_LOADFROMFILE);
 | 
						|
      if (hicon==NULL)
 | 
						|
	ErrorF ("winOverrideDefaultIcon: LoadIcon(%s) failed\n", fname);
 | 
						|
 | 
						|
      return (unsigned long)hicon;
 | 
						|
    }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Check for a match of the window class to one specified in the
 | 
						|
 * ICONS{} section in the prefs file, and load the icon from a file
 | 
						|
 */
 | 
						|
unsigned long
 | 
						|
winOverrideIcon (unsigned long longWin)
 | 
						|
{
 | 
						|
  WindowPtr pWin = (WindowPtr) longWin;
 | 
						|
  char *res_name, *res_class;
 | 
						|
  int i;
 | 
						|
  HICON hicon;
 | 
						|
  char fname[PATH_MAX+NAME_MAX+2];
 | 
						|
  char *wmName;
 | 
						|
 | 
						|
  if (pWin==NULL)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  /* If we can't find the class, we can't override from default! */
 | 
						|
  if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
 | 
						|
    return 0;
 | 
						|
 | 
						|
  winMultiWindowGetWMName (pWin, &wmName);
 | 
						|
  
 | 
						|
  for (i=0; i<pref.iconItems; i++) {
 | 
						|
    if (!strcmp(pref.icon[i].match, res_name) ||
 | 
						|
	!strcmp(pref.icon[i].match, res_class) ||
 | 
						|
	(wmName && strstr(wmName, pref.icon[i].match))) 
 | 
						|
      {
 | 
						|
	free (res_name);
 | 
						|
	free (res_class);
 | 
						|
	if (wmName)
 | 
						|
	  free (wmName);
 | 
						|
 | 
						|
	if (pref.icon[i].hicon)
 | 
						|
	  return pref.icon[i].hicon;
 | 
						|
 | 
						|
	/* Make sure we have a dir with trailing backslash */
 | 
						|
	/* Note we are using _Windows_ paths here, not cygwin */
 | 
						|
	strcpy (fname, pref.iconDirectory);
 | 
						|
	if (pref.iconDirectory[0])
 | 
						|
	  if (fname[strlen(fname)-1]!='\\')
 | 
						|
	    strcat (fname, "\\");
 | 
						|
	strcat (fname, pref.icon[i].iconFile);
 | 
						|
 | 
						|
	hicon = (HICON)LoadImage(NULL,
 | 
						|
				 fname,
 | 
						|
				 IMAGE_ICON,
 | 
						|
				 0, 0,
 | 
						|
				 LR_DEFAULTSIZE|LR_LOADFROMFILE);
 | 
						|
	if (hicon==NULL)
 | 
						|
	  ErrorF ("winOverrideIcon: LoadIcon(%s) failed\n", fname);
 | 
						|
 | 
						|
	pref.icon[i].hicon = (unsigned long)hicon;
 | 
						|
	return (unsigned long)hicon;
 | 
						|
      }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /* Didn't find the icon, fail gracefully */
 | 
						|
  free (res_name);
 | 
						|
  free (res_class);
 | 
						|
  if (wmName)
 | 
						|
    free (wmName);
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Should we free this icon or leave it in memory (is it part of our
 | 
						|
 * ICONS{} overrides)?
 | 
						|
 */
 | 
						|
int
 | 
						|
winIconIsOverride(unsigned hiconIn)
 | 
						|
{
 | 
						|
  HICON hicon;
 | 
						|
  int i;
 | 
						|
 | 
						|
  hicon = (HICON)hiconIn;
 | 
						|
 | 
						|
  if (!hicon)
 | 
						|
    return 0;
 | 
						|
  
 | 
						|
  for (i=0; i<pref.iconItems; i++)
 | 
						|
    if ((HICON)pref.icon[i].hicon == hicon)
 | 
						|
      return 1;
 | 
						|
  
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Try and open ~/.XWinrc and /usr/X11R6/lib/X11/system.XWinrc
 | 
						|
 * Load it into prefs structure for use by other functions
 | 
						|
 */
 | 
						|
void
 | 
						|
LoadPreferences ()
 | 
						|
{
 | 
						|
  char *home;
 | 
						|
  char fname[PATH_MAX+NAME_MAX+2];
 | 
						|
  FILE *prefFile;
 | 
						|
  char szDisplay[512];
 | 
						|
  char *szEnvDisplay;
 | 
						|
  int i, j;
 | 
						|
  char param[PARAM_MAX+1];
 | 
						|
  char *srcParam, *dstParam;
 | 
						|
 | 
						|
  /* First, clear all preference settings */
 | 
						|
  memset (&pref, 0, sizeof(pref));
 | 
						|
  prefFile = NULL;
 | 
						|
 | 
						|
  /* Now try and find a ~/.xwinrc file */
 | 
						|
  home = getenv ("HOME");
 | 
						|
  if (home)
 | 
						|
    {
 | 
						|
      strcpy (fname, home);
 | 
						|
      if (fname[strlen(fname)-1]!='/')
 | 
						|
	strcat (fname, "/");
 | 
						|
      strcat (fname, ".XWinrc");
 | 
						|
      
 | 
						|
      prefFile = fopen (fname, "r");
 | 
						|
    }
 | 
						|
 | 
						|
  /* No home file found, check system default */
 | 
						|
  if (!prefFile)
 | 
						|
    prefFile = fopen (PROJECTROOT"/lib/X11/system.XWinrc", "r");
 | 
						|
 | 
						|
  /* If we could open it, then read the settings and close it */
 | 
						|
  if (prefFile)
 | 
						|
    {
 | 
						|
      parse_file (prefFile);
 | 
						|
      fclose (prefFile);
 | 
						|
    }
 | 
						|
 | 
						|
  /* Setup a DISPLAY environment variable, need to allocate on heap */
 | 
						|
  /* because putenv doesn't copy the argument... */
 | 
						|
  snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
 | 
						|
  szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1));
 | 
						|
  if (szEnvDisplay)
 | 
						|
    {
 | 
						|
      strcpy (szEnvDisplay, szDisplay);
 | 
						|
      putenv (szEnvDisplay);
 | 
						|
    }
 | 
						|
 | 
						|
  /* Replace any "%display%" in menu commands with display string */
 | 
						|
  snprintf (szDisplay, 512, "127.0.0.1:%s.0", display);
 | 
						|
  for (i=0; i<pref.menuItems; i++)
 | 
						|
    {
 | 
						|
      for (j=0; j<pref.menu[i].menuItems; j++)
 | 
						|
	{
 | 
						|
	  if (pref.menu[i].menuItem[j].cmd==CMD_EXEC)
 | 
						|
	    {
 | 
						|
	      srcParam = pref.menu[i].menuItem[j].param;
 | 
						|
	      dstParam = param;
 | 
						|
	      while (*srcParam) {
 | 
						|
		if (!strncmp(srcParam, "%display%", 9))
 | 
						|
		  {
 | 
						|
		    memcpy (dstParam, szDisplay, strlen(szDisplay));
 | 
						|
		    dstParam += strlen(szDisplay);
 | 
						|
		    srcParam += 9;
 | 
						|
		  }
 | 
						|
		else
 | 
						|
		  {
 | 
						|
		    *dstParam = *srcParam;
 | 
						|
		    dstParam++;
 | 
						|
		    srcParam++;
 | 
						|
		  }
 | 
						|
	      }
 | 
						|
	      *dstParam = 0;
 | 
						|
	      strcpy (pref.menu[i].menuItem[j].param, param);
 | 
						|
	    } /* cmd==cmd_exec */
 | 
						|
	} /* for all menuitems */
 | 
						|
    } /* for all menus */
 | 
						|
 | 
						|
}
 | 
						|
 |