summaryrefslogtreecommitdiff
path: root/Build/source/texk
diff options
context:
space:
mode:
authorPiotr Strzelczyk <piotr@eps.gda.pl>2011-06-07 22:42:20 +0000
committerPiotr Strzelczyk <piotr@eps.gda.pl>2011-06-07 22:42:20 +0000
commitb8dfbc9c6b54d6976e2d0ae38049c23c618afeed (patch)
tree86d6272c4b441476a273a12252228c4936fa0bb4 /Build/source/texk
parent22a39f77a28f39b600112e5c375ec9e50336d508 (diff)
configurable tl-tray-menu + example configuration file
git-svn-id: svn://tug.org/texlive/trunk@22856 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
-rw-r--r--Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c403
1 files changed, 235 insertions, 168 deletions
diff --git a/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c b/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c
index b848b223898..a9281fd2223 100644
--- a/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c
+++ b/Build/source/texk/texlive/w32_wrapper/tl-tray-menu.c
@@ -18,223 +18,290 @@ gcc -Os -s -mwindows -o tl-tray-menu.exe tl-tray-menu-rc.o tl-tray-menu.c
#include <stdlib.h>
#include <stdio.h>
-#define MAX_CMD 32768
+#define MAX_STR 32768
+
+static char strBuf[MAX_STR];
-static char msgbuf[4*MAX_PATH];
#define DIE(...) { \
- _snprintf( msgbuf, 4*MAX_PATH, __VA_ARGS__ ); \
- MessageBox( NULL, msgbuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
+ _snprintf( strBuf, 4*MAX_PATH, __VA_ARGS__ ); \
+ MessageBox( NULL, strBuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\
return 1; \
}
#define IDI_ICON 1 // resource number of icon
#define IDI_TRAY 100
#define WM_TRAYMSG 101
-#define MENU_TLMGR 0
-#define MENU_TEXDOC 1
-#define MENU_EDITOR 2
-#define MENU_COMSPEC 3
-#define MENU_CUSTOM 4
-#define MENU_EXIT 42
-HMENU hPopMenu;
-NOTIFYICONDATA nid;
+#define MAX_MENU_ENTRIES 31
+#define MENU_CONFIG ( MAX_MENU_ENTRIES + 1 )
+#define MENU_EXIT ( MAX_MENU_ENTRIES + 2 )
-char szAppName[] = "TrayMenu";
-char ExeList[5][MAX_PATH] = {
- "tlmgr-gui.exe",
- "texdoctk.exe",
- "texworks.exe",
- "cmd.exe",
- ""
-};
+// buffer holding menu labels and commands
+// (used only with config file)
+static char menuStrings[MAX_STR];
-int CustomHowMessageBox()
-{
-}
+// default menu labels
+char *menuLabels[MAX_MENU_ENTRIES] = {
+"&Package Manager",
+"&Documentation",
+"&Editor",
+"&Command Prompt",
+NULL };
+
+// default menu commands
+char *menuCommands[MAX_MENU_ENTRIES] = {
+"bin\\win32\\tlmgr-gui.exe",
+"bin\\win32\\texdoctk.exe",
+"bin\\win32\\texworks.exe",
+"tlpkg\\installer\\tl-cmd.bat",
+NULL };
+
+char configInfo[4*MAX_PATH] = "\
+The menu can be customized with a configuration file.\n\
+For an example and instructions see:\n";
+
+HMENU hPopMenu;
+NOTIFYICONDATA nid;
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch ( msg )
{
- case WM_CREATE:
- {
- hPopMenu = CreatePopupMenu();
- if ( ExeList[MENU_TLMGR][0] )
- AppendMenu( hPopMenu, MF_STRING, MENU_TLMGR, "&Package Manager (tlmgr)" );
- if ( ExeList[MENU_TEXDOC][0] )
- AppendMenu( hPopMenu, MF_STRING, MENU_TEXDOC, "&Documentation (texdoc)" );
- if ( ExeList[MENU_EDITOR][0] )
- AppendMenu( hPopMenu, MF_STRING, MENU_EDITOR, "&Editor (texworks)" );
- if ( ExeList[MENU_COMSPEC][0] )
- AppendMenu( hPopMenu, MF_STRING, MENU_COMSPEC, "&Command Prompt" );
- if ( ExeList[MENU_CUSTOM][0] )
- AppendMenu( hPopMenu, MF_STRING, MENU_CUSTOM, "Custom &Script" );
- else
- AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
- AppendMenu( hPopMenu, MF_STRING, MENU_EXIT, "E&xit" );
- }
- break;
-
- case WM_TRAYMSG:
- {
- switch ( lParam )
+ case WM_CREATE:
{
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
+ hPopMenu = CreatePopupMenu();
+ int i;
+ for ( i = 0; menuLabels[i]; i++ )
{
- POINT pnt;
- GetCursorPos( &pnt );
- SetForegroundWindow( hWnd ); // needed to get keyboard focus
- TrackPopupMenu( hPopMenu, TPM_LEFTALIGN, pnt.x, pnt.y, TPM_LEFTBUTTON, hWnd, NULL );
+ if ( menuCommands[i] )
+ AppendMenu( hPopMenu, MF_STRING, i, menuLabels[i] );
}
- break;
+ AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
+ AppendMenu( hPopMenu, MF_STRING, MENU_CONFIG, "More..." );
+ AppendMenu( hPopMenu, MF_STRING, MENU_EXIT, "E&xit" );
}
- }
- break;
-
- case WM_COMMAND:
- switch ( LOWORD( wParam ) )
+ break;
+
+ case WM_TRAYMSG:
{
- case MENU_TLMGR:
- case MENU_TEXDOC:
- case MENU_EDITOR:
- case MENU_COMSPEC:
- if ( _spawnlp( _P_NOWAIT, ExeList[LOWORD(wParam)], NULL ) < 0 )
- DIE( "Failed to start: %s", ExeList[LOWORD(wParam)] );
- break;
- case MENU_CUSTOM:
- if ( GetFileAttributes( ExeList[LOWORD(wParam)] ) != INVALID_FILE_ATTRIBUTES )
- {
- if ( _spawnlp( _P_NOWAIT, ExeList[LOWORD(wParam)], NULL ) < 0 )
- DIE( "Failed to start: %s", ExeList[LOWORD(wParam)] );
- }
- else
- MessageBox(
- NULL,
- "For a custom menu, create tl-tray-menu-custom.bat \nin the root of the installation.\nSee sample at tlpkg\\installer\\tl-tray-menu-custom.bat.",
- "Custom menu",
- MB_ICONINFORMATION
- );
- break;
-
- case MENU_EXIT:
- Shell_NotifyIcon( NIM_DELETE, &nid );
- ExitProcess(0);
- break;
+ switch ( lParam )
+ {
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ {
+ POINT pnt;
+ GetCursorPos( &pnt );
+ SetForegroundWindow( hWnd ); // needed to get keyboard focus
+ TrackPopupMenu( hPopMenu, TPM_LEFTALIGN, pnt.x, pnt.y, 0, hWnd, NULL );
+ }
+ break;
+ }
}
- break;
+ break;
+
+ case WM_COMMAND:
+ {
+ switch ( LOWORD( wParam ) )
+ {
+ case MENU_CONFIG:
+ MessageBox( NULL, configInfo, nid.szTip, MB_SETFOREGROUND );
+ break;
+
+ case MENU_EXIT:
+ Shell_NotifyIcon( NIM_DELETE, &nid );
+ ExitProcess(0);
+ break;
+
+ default:
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ //si.dwFlags = STARTF_USESHOWWINDOW;
+ //si.wShowWindow = SW_HIDE ;
+ ZeroMemory( &pi, sizeof(pi) );
+ if( !CreateProcess(
+ NULL, // module name (uses command line if NULL)
+ menuCommands[LOWORD(wParam)], // command line
+ NULL, // process security atrributes
+ NULL, // thread security atrributes
+ TRUE, // handle inheritance
+ 0, // creation flags, e.g. CREATE_NO_WINDOW, DETACHED_PROCESS
+ NULL, // pointer to environment block (uses parent if NULL)
+ NULL, // starting directory (uses parent if NULL)
+ &si, // STARTUPINFO structure
+ &pi ) // PROCESS_INFORMATION structure
+ ) DIE( "Failed to execute command:\n%s", menuCommands[LOWORD(wParam)] );
+ }
+ }
+ }
+ break;
+
+ default:
+ return DefWindowProc( hWnd, msg, wParam, lParam );
- default:
- return DefWindowProc( hWnd, msg, wParam, lParam );
}
return 0;
}
int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow )
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow )
{
+ // scratch variables
+
+ char *s;
+
// get file name of this executable
- static char selfdir[MAX_PATH];
- char *s;
- DWORD nchars = GetModuleFileName(NULL, selfdir, MAX_PATH);
- if ( !nchars || ( nchars == MAX_PATH ) ) DIE( "cannot get own path" );
- if ( s = strrchr( selfdir, '\\' ) ) *s = '\0'; // remove file name part
+ static char dirSelf[MAX_PATH];
+ DWORD nchars = GetModuleFileName(NULL, dirSelf, MAX_PATH);
+ if ( !nchars || ( nchars == MAX_PATH ) ) DIE( "Cannot get own path." );
+ if ( s = strrchr( dirSelf, '\\' ) ) *s = '\0'; // remove file name part
- // append bin/win32 to PATH
+ // set current directory
- static char buffer[MAX_CMD];
- strcpy( buffer, selfdir );
- strcat( buffer, "\\bin\\win32;" );
- strcat( buffer, getenv( "PATH" ) );
- SetEnvironmentVariable( "PATH", buffer );
+ if ( !SetCurrentDirectory( dirSelf ) )
+ DIE( "Failed to change current directory to:\n%s", dirSelf );
- // set up a list of executables
+ // prepend bin/win32 to PATH
- s = strchr( buffer, ';' ); *s = '\\'; s++;
- int i;
- for ( i = 0; i < 3; i++ )
- {
- *s = '\0';
- strcat( buffer, ExeList[i] );
- if ( GetFileAttributes( buffer ) != INVALID_FILE_ATTRIBUTES )
- strncpy( ExeList[i], buffer, MAX_PATH );
- else
- ExeList[i][0] = '\0';
- }
+ strcpy( strBuf, dirSelf );
+ strcat( strBuf, "\\bin\\win32;" );
+ strcat( strBuf, getenv( "PATH" ) );
+ SetEnvironmentVariable( "PATH", strBuf );
+
+ // configuration
+
+ static char fileConfig[MAX_PATH];
+ s = dirSelf + strlen(dirSelf) + 1;
+ strcpy( fileConfig, s );
+ if ( s = strrchr( fileConfig, '.' ) ) *s = '\0'; // remove file extension part
+ strcat( fileConfig, ".ini" );
+
+ strcat( configInfo, dirSelf );
+ strcat( configInfo, "\\tlpkg\\installer\\" );
+ strcat( configInfo, fileConfig );
- if ( s = getenv( "COMSPEC" ) ) strncpy( ExeList[3], s, MAX_PATH );
+ if ( GetFileAttributes( fileConfig ) == INVALID_FILE_ATTRIBUTES ) {
- strcpy( buffer, selfdir );
- strcat( buffer, "\\tl-tray-menu-custom.bat" );
- // if ( GetFileAttributes( buffer ) != INVALID_FILE_ATTRIBUTES )
- // At call time, we test for this file and display
- // a message box if it is missing.
- strncpy( ExeList[4], buffer, MAX_PATH );
+ // validate default configuration (menuCommands should be existing files)
- // create a hidden window for messaging
-
- MSG msg;
- WNDCLASS wc;
- HWND hWnd;
-
- ZeroMemory( &wc, sizeof wc );
- wc.hInstance = hInstance;
- wc.lpszClassName = szAppName;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.style = 0;
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
-
- if ( FALSE == RegisterClass( &wc ) ) DIE( "Failed to register window class" );
-
- hWnd = CreateWindow(
- szAppName,
- "",
- 0,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 0,
- 0,
- hInstance,
- 0);
-
- if ( hWnd == NULL ) DIE( "Failed to create window" );
-
- // tray icon stuff
+ int i;
+ for ( i = 0; menuLabels[i]; i++ )
+ if ( GetFileAttributes( menuCommands[i] ) == INVALID_FILE_ATTRIBUTES )
+ menuCommands[i] = NULL;
+
+ } else {
+
+ // read menu configuration from ini file
+
+ FILE *CONFIG = fopen( fileConfig, "rt" );
+ if ( CONFIG == NULL )
+ DIE( "Failed to open configuration file:\n%s\\%s", dirSelf, fileConfig );
+
+ char strSect[] = "[menu]";
+ int menuItem = -1;
+ int i = 0;
+ int lineNo;
+ for ( lineNo = 1 ; fgets( strBuf, MAX_STR, CONFIG )
+ && menuItem < MAX_MENU_ENTRIES ; lineNo++ )
+ {
+ if ( menuItem < 0 )
+ {
+ if ( *strBuf == '[' &&
+ strncmp( strBuf, strSect, strlen( strSect ) ) == 0 ) menuItem++;
+ continue;
+ }
+ if ( *strBuf == ';' ) continue; // skip comments
+ if ( *strBuf == '[' ) break; // next section
+ s = &menuStrings[i];
+ i += ExpandEnvironmentStrings( strBuf, s, MAX_STR - i );
+ if ( i >= MAX_STR )
+ DIE( "Exceeded 32KB limit for configuration." );
+ if ( i-2 && menuStrings[i-2] == '\n' ) { menuStrings[i-2] = '\0'; i--; }
+ menuLabels[menuItem] = s;
+ while ( *s && *s != '=' ) s++;
+ if ( *s == '\0' )
+ DIE( "Missing '=' on line %d in configuration file:\n%s\\%s",
+ lineNo, dirSelf, fileConfig );
+ *s++ = '\0'; // assign first, then increment
+ menuCommands[menuItem] = s;
+ menuItem++;
+ }
+ if ( menuItem < 0 )
+ DIE( "Missing [menu] section in configuration file:\n%s\\%s",
+ dirSelf, fileConfig );
+ menuLabels[menuItem] = NULL;
+ menuCommands[menuItem] = NULL;
+
+ fclose( CONFIG );
+
+ }
- nid.cbSize = sizeof nid;
- nid.hWnd = hWnd;
- nid.uID = IDI_TRAY;
- nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
- nid.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) );
- nid.uCallbackMessage = WM_TRAYMSG;
- strcpy( nid.szTip, "TeX Live Menu" );
+ // create a hidden window for messaging
+
+ MSG msg;
+ WNDCLASS wc;
+ HWND hWnd;
+ char szAppName[] = "TrayMenu";
+
+ ZeroMemory( &wc, sizeof wc );
+ wc.hInstance = hInstance;
+ wc.lpszClassName = szAppName;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.style = 0;
+ wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+ wc.hCursor = LoadCursor( NULL, IDC_ARROW );
+
+ if ( FALSE == RegisterClass( &wc ) ) DIE( "Failed to register window class" );
+
+ hWnd = CreateWindow(
+ szAppName,
+ "",
+ 0,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 0,
+ 0,
+ hInstance,
+ 0);
+
+ if ( hWnd == NULL ) DIE( "Failed to create window" );
+
+ // tray icon stuff
+
+ nid.cbSize = sizeof nid;
+ nid.hWnd = hWnd;
+ nid.uID = IDI_TRAY;
+ nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
+ nid.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) );
+ nid.uCallbackMessage = WM_TRAYMSG;
+ strcpy( nid.szTip, "TeX Live Menu" );
#if (_WIN32_IE >= 0X0500)
nid.uFlags |= NIF_INFO;
nid.dwInfoFlags = NIIF_INFO;
strcpy( nid.szInfo, "Click on the tray icon\nto activate the menu." );
strcpy( nid.szInfoTitle, nid.szTip );
#endif
- Shell_NotifyIcon( NIM_ADD, &nid );
+ Shell_NotifyIcon( NIM_ADD, &nid );
- // main message loop:
+ // main message loop:
- while ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
+ while ( GetMessage( &msg, NULL, 0, 0 ) > 0 )
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
- return msg.wParam;
+ return msg.wParam;
}