hw/xwin: Add -icon option to set the screen window icon in windowed mode

Add an -icon option to set the screen window icon in windowed mode

Allow cygwin paths in an icon-specification

Update man pages and system.XWinrc appropriately

Also, log an error if the icon specified for TRAYICON cannot be loaded

Also, fix a bug in appending a '\' to IconDirectory only if it doesn't
already end with one, which was fortunately benign.

Note: LoadImageComma would be simpler if we just stated that XWinrc
paths are Cygwin paths on Cygwin, Windows paths on MinGW, but that could
break existing .XWinrc files

Note: Given that we can specify paths in an icon-specifier, I'm not sure
what IconDirectory wins us.

v2:
Fix formatting problems in man page additions

v3:
Fix some more s/_/@/g in man pages
This commit is contained in:
Jon Turney 2016-02-19 21:53:00 +00:00
parent ac5d3a200a
commit bcf2dd0cd2
9 changed files with 124 additions and 55 deletions

View File

@ -757,6 +757,8 @@ winUseMsg(void)
ErrorF("-[no]hostintitle\n" ErrorF("-[no]hostintitle\n"
"\tIn multiwindow mode, add remote host names to window titles.\n"); "\tIn multiwindow mode, add remote host names to window titles.\n");
ErrorF("-icon icon_specifier\n" "\tSet screen window icon in windowed mode.\n");
ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n"); ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
#ifdef XWIN_XF86CONFIG #ifdef XWIN_XF86CONFIG

View File

@ -108,6 +108,10 @@ The X server window takes the full screen, covering completely the
\fIWindows\fP desktop. \fIWindows\fP desktop.
Currently \fB\-fullscreen\fP may only be applied to one X screen. Currently \fB\-fullscreen\fP may only be applied to one X screen.
.TP 8 .TP 8
.B "\-icon" \fIicon-specifier\fP
Override the window icon for the screen window from the default.
The \fIicon-specifier\fP is as defined in \fIXWinrc(@filemansuffix@)\fP.
.TP 8
.B \-nodecoration .B \-nodecoration
Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, Do not give the Cygwin/X window a \fIWindows\fP window border, title bar,
etc. etc.

View File

@ -134,31 +134,34 @@ such items should be included at the start or at the end of the menu.
.SH Icon Instructions .SH Icon Instructions
When specifying an \fIicon-file\fP in the following commands several different formats are allowed: When specifying an \fIicon-specifier\fP in the following commands several different formats are allowed:
.PP
.IP \fI"NAME.ICO"\fP 16
filename of an .ico format file
.br .br
\fB"NAME.ICO"\fP\fI of an .ico format file\fP (e.g. "cygwin.ico", "apple.ico", "C:\\icons\\cheese.ico", "/usr/share/icons/moon.ico")
.IP \fI"NAME.DLL,nnn"\fP 16
filename of a DLL with an index into it's ICON resources
.br .br
\t \t ("cygwin.ico", "apple.ico") (e.g. "c:\\windows\\system32\\shell32.dll,4", the default folder icon,
"/usr/bin/cygicons-0.dll,10", the hippo icon)
.IP \fI",nnn"\fP 16
index into the XWin executable's internal ICON resources
.br .br
\fB"NAME.DLL,nn"\fP\fI of a .DLL and icon index\fP (e.g. ",101" is the 1st icon in \fIXWin\fP)
.br
\t \t ("c:\\windows\\system32\\shell32.dll,4" is the default folder icon)
.br
\fB",nnn"\fP\fI index into XWin.EXE internal ICON resources\fP
.br
\t \t (",101" is the 1st icon inside \fIXWin.EXE\fP)
.TP 8 .TP 8
.B ICONDIRECTORY \fIWindows-path-to-icon-directory\fP .B ICONDIRECTORY \fIWindows-path-to-icon-directory\fP
Defines the default directory to search for \ficon-file\fP files. Defines the default directory for the file when an \fIicon-specifier\fP doesn't
contain an absolute path.
It should be a \fIWindows\fP style path (e.g. C:\\cygwin\\usr\\local\\icons). It should be a \fIWindows\fP style path (e.g. C:\\cygwin\\usr\\local\\icons).
.TP 8 .TP 8
.B DEFAULTICON \fIicon-file\fP .B DEFAULTICON \fIicon-specifier\fP
Defines a replacement for the standard X icon for applications without Defines a replacement for the standard X icon for applications without
specified icons. specified icons.
.TP 8 .TP 8
.B ICONS { .B ICONS {
.br .br
\fIclass-or-name-of-window\fP \fIicon-file\fP \fIclass-or-name-of-window\fP \fIicon-specifier\fP
.br .br
\fI...\fP \fI...\fP
.br .br

View File

@ -8,10 +8,6 @@
# Comments begin with "#" or "//" and go to the end-of-line # Comments begin with "#" or "//" and go to the end-of-line
# Paths to commands are **cygwin** based (i.e. /usr/local/bin/xcalc)
# Paths to icons are **WINDOWS** based (i.e. c:\windows\icons)
# Menus are defined as... # Menus are defined as...
# MENU <name> { # MENU <name> {
# <Menu Text> EXEC <command> # <Menu Text> EXEC <command>
@ -55,15 +51,15 @@
# To define where ICO files live (** Windows path**) # To define where ICO files live (** Windows path**)
# ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons> # ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons>
# NOTE: If you specify a fully qualified path to an ICON below # NOTE: If you specify an absolute path in Windows or Cygwin format to an ICON below
# (i.e. "c:\xxx" or "d:\xxxx") # (i.e. "c:\icons\xxx.ico" or "/usr/share/icons/xxx.ico")
# this ICONDIRECTORY will not be prepended # this ICONDIRECTORY will not be prepended
# To change the taskbar icon use... # To change the taskbar icon use...
# TRAYICON <name-of-windows-ico-file-in-icondirectory> # TRAYICON <icon-specifier>
# To define a replacement for the standard X icon for apps w/o specified icons # To define a replacement for the standard X icon for apps w/o specified icons
# DEFAULTICON <name-of-windows-ico-file-in-icondirectory> # DEFAULTICON <icon-specifier>
# To define substitute icons on a per-window basis use... # To define substitute icons on a per-window basis use...
# ICONS { # ICONS {

View File

@ -404,6 +404,10 @@ typedef struct {
/* Did the user explicitly set this screen? */ /* Did the user explicitly set this screen? */
Bool fExplicitScreen; Bool fExplicitScreen;
/* Icons for screen window */
HICON hIcon;
HICON hIconSm;
} winScreenInfo, *winScreenInfoPtr; } winScreenInfo, *winScreenInfoPtr;
/* /*

View File

@ -72,18 +72,12 @@ winCreateBoundingWindowFullScreen(ScreenPtr pScreen)
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
wc.hInstance = g_hInstance; wc.hInstance = g_hInstance;
wc.hIcon = wc.hIcon = pScreenInfo->hIcon;
(HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CYICON), 0);
wc.hCursor = 0; wc.hCursor = 0;
wc.hbrBackground = 0; wc.hbrBackground = 0;
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = WINDOW_CLASS; wc.lpszClassName = WINDOW_CLASS;
wc.hIconSm = wc.hIconSm = pScreenInfo->hIconSm;
(HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
RegisterClassEx(&wc); RegisterClassEx(&wc);
/* Set display and screen-specific tooltip text */ /* Set display and screen-specific tooltip text */
@ -179,18 +173,12 @@ winCreateBoundingWindowWindowed(ScreenPtr pScreen)
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
wc.hInstance = g_hInstance; wc.hInstance = g_hInstance;
wc.hIcon = wc.hIcon = pScreenInfo->hIcon;
(HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CYICON), 0);
wc.hCursor = 0; wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = WINDOW_CLASS; wc.lpszClassName = WINDOW_CLASS;
wc.hIconSm = wc.hIconSm = pScreenInfo->hIconSm;
(HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
RegisterClassEx(&wc); RegisterClassEx(&wc);
/* Get size of work area */ /* Get size of work area */

View File

@ -37,6 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#ifdef __CYGWIN__ #ifdef __CYGWIN__
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/cygwin.h>
#endif #endif
#include "win.h" #include "win.h"
@ -59,9 +60,6 @@ extern int parse_file(FILE * fp);
/* Currently in use command ID, incremented each new menu item created */ /* Currently in use command ID, incremented each new menu item created */
static int g_cmdid = STARTMENUID; static int g_cmdid = STARTMENUID;
/* Local function to handle comma-ified icon names */
static HICON LoadImageComma(char *fname, int sx, int sy, int flags);
/* /*
* Creates or appends a menu from a MENUPARSED structure * Creates or appends a menu from a MENUPARSED structure
*/ */
@ -474,7 +472,7 @@ winOverrideDefaultIcon(int size)
HICON hicon; HICON hicon;
if (pref.defaultIconName[0]) { if (pref.defaultIconName[0]) {
hicon = LoadImageComma(pref.defaultIconName, size, size, 0); hicon = LoadImageComma(pref.defaultIconName, pref.iconDirectory, size, size, 0);
if (hicon == NULL) if (hicon == NULL)
ErrorF("winOverrideDefaultIcon: LoadImageComma(%s) failed\n", ErrorF("winOverrideDefaultIcon: LoadImageComma(%s) failed\n",
pref.defaultIconName); pref.defaultIconName);
@ -496,9 +494,12 @@ winTaskbarIcon(void)
hicon = 0; hicon = 0;
/* First try and load an overridden, if success then return it */ /* First try and load an overridden, if success then return it */
if (pref.trayIconName[0]) { if (pref.trayIconName[0]) {
hicon = LoadImageComma(pref.trayIconName, hicon = LoadImageComma(pref.trayIconName, pref.iconDirectory,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON), 0); GetSystemMetrics(SM_CYSMICON), 0);
if (hicon == NULL)
ErrorF("winTaskbarIcon: LoadImageComma(%s) failed\n",
pref.trayIconName);
} }
/* Otherwise return the default */ /* Otherwise return the default */
@ -513,17 +514,18 @@ winTaskbarIcon(void)
} }
/* /*
* Handle comma-ified icon names
*
* Parse a filename to extract an icon: * Parse a filename to extract an icon:
* If fname is exactly ",nnn" then extract icon from our resource * If fname is exactly ",nnn" then extract icon from our resource
* else if it is "file,nnn" then extract icon nnn from that file * else if it is "file,nnn" then extract icon nnn from that file
* else try to load it as an .ico file and if that fails return NULL * else try to load it as an .ico file and if that fails return NULL
*/ */
static HICON HICON
LoadImageComma(char *fname, int sx, int sy, int flags) LoadImageComma(char *fname, char *iconDirectory, int sx, int sy, int flags)
{ {
HICON hicon; HICON hicon;
int i; int i;
char file[PATH_MAX + NAME_MAX + 2];
/* Some input error checking */ /* Some input error checking */
if (!fname || !fname[0]) if (!fname || !fname[0])
@ -539,31 +541,67 @@ LoadImageComma(char *fname, int sx, int sy, int flags)
MAKEINTRESOURCE(i), IMAGE_ICON, sx, sy, flags); MAKEINTRESOURCE(i), IMAGE_ICON, sx, sy, flags);
} }
else { else {
char *file = malloc(PATH_MAX + NAME_MAX + 2);
Bool convert = FALSE;
if (!file)
return NULL;
file[0] = 0; file[0] = 0;
/* Prepend path if not given a "X:\" filename */
/* If fname starts 'X:\', it's an absolute Windows path, do nothing */
if (!(fname[0] && fname[1] == ':' && fname[2] == '\\')) { if (!(fname[0] && fname[1] == ':' && fname[2] == '\\')) {
strcpy(file, pref.iconDirectory); #ifdef __CYGWIN__
if (pref.iconDirectory[0]) /* If fname starts with '/', it's an absolute cygwin path, we'll
if (fname[strlen(fname) - 1] != '\\') need to convert it */
strcat(file, "\\"); if (fname[0] == '/') {
convert = TRUE;
}
else
#endif
if (iconDirectory) {
/* Otherwise, prepend the default icon directory, which
currently must be in absolute Windows path form */
strcpy(file, iconDirectory);
if (iconDirectory[0])
if (iconDirectory[strlen(iconDirectory) - 1] != '\\')
strcat(file, "\\");
}
} }
strcat(file, fname); strcat(file, fname);
/* Trim off any ',index' */
if (strrchr(file, ',')) { if (strrchr(file, ',')) {
/* Specified as <fname>,<index> */
*(strrchr(file, ',')) = 0; /* End string at comma */ *(strrchr(file, ',')) = 0; /* End string at comma */
i = atoi(strrchr(fname, ',') + 1); i = atoi(strrchr(fname, ',') + 1);
}
else {
i = -1;
}
#ifdef __CYGWIN__
/* Convert from Cygwin path to Windows path */
if (convert) {
char *converted_file = cygwin_create_path(CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, file);
if (converted_file) {
free(file);
file = converted_file;
}
}
#endif
if (i >= 0) {
/* Specified as <fname>,<index> */
hicon = ExtractIcon(g_hInstance, file, i); hicon = ExtractIcon(g_hInstance, file, i);
} }
else { else {
/* Just an .ico file... */ /* Specified as just an .ico file */
hicon = (HICON) LoadImage(NULL, hicon = (HICON) LoadImage(NULL,
file, file,
IMAGE_ICON, IMAGE_ICON,
sx, sy, LR_LOADFROMFILE | flags); sx, sy, LR_LOADFROMFILE | flags);
} }
free(file);
} }
return hicon; return hicon;
} }
@ -585,7 +623,7 @@ winOverrideIcon(char *res_name, char *res_class, char *wmName)
if (pref.icon[i].hicon) if (pref.icon[i].hicon)
return pref.icon[i].hicon; return pref.icon[i].hicon;
hicon = LoadImageComma(pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE); hicon = LoadImageComma(pref.icon[i].iconFile, pref.iconDirectory, 0, 0, LR_DEFAULTSIZE);
if (hicon == NULL) if (hicon == NULL)
ErrorF("winOverrideIcon: LoadImageComma(%s) failed\n", ErrorF("winOverrideIcon: LoadImageComma(%s) failed\n",
pref.icon[i].iconFile); pref.icon[i].iconFile);

View File

@ -175,4 +175,7 @@ unsigned long
HICON winTaskbarIcon(void); HICON winTaskbarIcon(void);
HICON winOverrideDefaultIcon(int size); HICON winOverrideDefaultIcon(int size);
HICON LoadImageComma(char *fname, char *iconDirectory, int sx, int sy, int flags);
#endif #endif

View File

@ -40,6 +40,7 @@ from The Open Group.
#include "winconfig.h" #include "winconfig.h"
#include "winmsg.h" #include "winmsg.h"
#include "winmonitors.h" #include "winmonitors.h"
#include "winprefs.h"
#include "winclipboard/winclipboard.h" #include "winclipboard/winclipboard.h"
@ -139,6 +140,13 @@ winInitializeScreenDefaults(void)
defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
defaultScreenInfo.fIgnoreInput = FALSE; defaultScreenInfo.fIgnoreInput = FALSE;
defaultScreenInfo.fExplicitScreen = FALSE; defaultScreenInfo.fExplicitScreen = FALSE;
defaultScreenInfo.hIcon = (HICON)
LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
defaultScreenInfo.hIconSm = (HICON)
LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTSIZE);
/* Note that the default screen has been initialized */ /* Note that the default screen has been initialized */
fInitializedScreenDefaults = TRUE; fInitializedScreenDefaults = TRUE;
@ -1066,6 +1074,29 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 1; return 1;
} }
if (IS_OPTION("-icon")) {
char *iconspec;
CHECK_ARGS(1);
iconspec = argv[++i];
screenInfoPtr->hIcon = LoadImageComma(iconspec, NULL,
GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CYICON),
0);
screenInfoPtr->hIconSm = LoadImageComma(iconspec, NULL,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTSIZE);
if ((screenInfoPtr->hIcon == NULL) ||
(screenInfoPtr->hIconSm == NULL)) {
ErrorF("ddxProcessArgument - icon - Invalid icon specification %s\n",
iconspec);
exit(1);
}
/* Indicate that we have processed the argument */
return 2;
}
return 0; return 0;
} }