mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-22 22:28:02 +01:00
This patch removes wmaker from PowerTop's shame list, where it appeared with ~3-4 wakeups/second. It adds the linux kernel's dnotify mechanism (adapted from the example in Documentation/dnotify.txt in the kernel source), to detect when a configuration file in ~/GNUStep/Defaults has changed to load it again on-the-fly. For me it usually means that modifications to ~/GNUStep/Defaults/WMRootMenu via the 'genmenu' script are automatically detected and loaded. The use of dnotify makes the ancient behaviour of polling unecessary and cuts down the wakeups count. Other 'apparently' useless timers are also deleted and it's been almost one year now that I use this patched exclusively without problems, so I am pretty sure that it doesn't hurt to remove them. The end result of all this is that wmaker generates 0 (zero) wakeups when idle in a Linux system. Signed-off-by: Carlos R. Mafra <crmafra@ift.unesp.br>
895 lines
22 KiB
C
895 lines
22 KiB
C
/*
|
|
* Window Maker window manager
|
|
*
|
|
* Copyright (c) 1997-2003 Alfredo K. Kojima
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
* USA.
|
|
*/
|
|
|
|
#define _GNU_SOURCE /* needed to get the defines in glibc 2.2 */
|
|
#include <fcntl.h> /* this has the needed values defined */
|
|
#include <signal.h>
|
|
|
|
#include "wconfig.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
|
|
|
|
/* Xlocale.h and locale.h are the same if X_LOCALE is undefind in wconfig.h,
|
|
* and if X_LOCALE is defined, X's locale emulating functions will be used.
|
|
* See Xlocale.h for more information.
|
|
*/
|
|
#include <X11/Xlocale.h>
|
|
|
|
#define MAINFILE
|
|
|
|
#include "WindowMaker.h"
|
|
#include "window.h"
|
|
#include "funcs.h"
|
|
#include "menu.h"
|
|
#include "keybind.h"
|
|
#include "xmodifier.h"
|
|
#include "defaults.h"
|
|
#include "session.h"
|
|
#include "dialog.h"
|
|
|
|
#include <WINGs/WUtil.h>
|
|
|
|
/****** Global Variables ******/
|
|
|
|
/* general info */
|
|
|
|
Display *dpy;
|
|
|
|
char *ProgName;
|
|
|
|
unsigned int ValidModMask = 0xff;
|
|
volatile int filesChanged;
|
|
|
|
/* locale to use. NULL==POSIX or C */
|
|
char *Locale=NULL;
|
|
|
|
int wScreenCount=0;
|
|
|
|
WPreferences wPreferences;
|
|
|
|
|
|
WMPropList *wDomainName;
|
|
WMPropList *wAttributeDomainName;
|
|
|
|
WShortKey wKeyBindings[WKBD_LAST];
|
|
|
|
/* defaults domains */
|
|
WDDomain *WDWindowMaker = NULL;
|
|
WDDomain *WDWindowAttributes = NULL;
|
|
WDDomain *WDRootMenu = NULL;
|
|
|
|
/* XContexts */
|
|
XContext wWinContext;
|
|
XContext wAppWinContext;
|
|
XContext wStackContext;
|
|
XContext wVEdgeContext;
|
|
|
|
/* Atoms */
|
|
Atom _XA_WM_STATE;
|
|
Atom _XA_WM_CHANGE_STATE;
|
|
Atom _XA_WM_PROTOCOLS;
|
|
Atom _XA_WM_TAKE_FOCUS;
|
|
Atom _XA_WM_DELETE_WINDOW;
|
|
Atom _XA_WM_SAVE_YOURSELF;
|
|
Atom _XA_WM_CLIENT_LEADER;
|
|
Atom _XA_WM_COLORMAP_WINDOWS;
|
|
Atom _XA_WM_COLORMAP_NOTIFY;
|
|
|
|
Atom _XA_GNUSTEP_WM_ATTR;
|
|
Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
|
|
Atom _XA_GNUSTEP_WM_RESIZEBAR;
|
|
Atom _XA_GNUSTEP_TITLEBAR_STATE;
|
|
|
|
Atom _XA_WINDOWMAKER_MENU;
|
|
Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
|
|
Atom _XA_WINDOWMAKER_STATE;
|
|
|
|
Atom _XA_WINDOWMAKER_WM_FUNCTION;
|
|
Atom _XA_WINDOWMAKER_NOTICEBOARD;
|
|
Atom _XA_WINDOWMAKER_COMMAND;
|
|
|
|
Atom _XA_WINDOWMAKER_ICON_SIZE;
|
|
Atom _XA_WINDOWMAKER_ICON_TILE;
|
|
|
|
|
|
/* cursors */
|
|
Cursor wCursor[WCUR_LAST];
|
|
|
|
/* last event timestamp for XSetInputFocus */
|
|
Time LastTimestamp = CurrentTime;
|
|
/* timestamp on the last time we did XSetInputFocus() */
|
|
Time LastFocusChange = CurrentTime;
|
|
|
|
#ifdef SHAPE
|
|
Bool wShapeSupported;
|
|
int wShapeEventBase;
|
|
#endif
|
|
|
|
#ifdef KEEP_XKB_LOCK_STATUS
|
|
Bool wXkbSupported;
|
|
int wXkbEventBase;
|
|
#endif
|
|
|
|
/* special flags */
|
|
char WProgramSigState = 0;
|
|
char WProgramState = WSTATE_NORMAL;
|
|
char WDelayedActionSet = 0;
|
|
|
|
|
|
/* temporary stuff */
|
|
int wVisualID = -1;
|
|
|
|
|
|
/* notifications */
|
|
const char *WMNManaged = "WMNManaged";
|
|
const char *WMNUnmanaged = "WMNUnmanaged";
|
|
const char *WMNChangedWorkspace = "WMNChangedWorkspace";
|
|
const char *WMNChangedState = "WMNChangedState";
|
|
const char *WMNChangedFocus = "WMNChangedFocus";
|
|
const char *WMNChangedStacking = "WMNChangedStacking";
|
|
const char *WMNChangedName = "WMNChangedName";
|
|
|
|
const char *WMNWorkspaceCreated = "WMNWorkspaceCreated";
|
|
const char *WMNWorkspaceDestroyed = "WMNWorkspaceDestroyed";
|
|
const char *WMNWorkspaceChanged = "WMNWorkspaceChanged";
|
|
const char *WMNWorkspaceNameChanged = "WMNWorkspaceNameChanged";
|
|
|
|
const char *WMNResetStacking = "WMNResetStacking";
|
|
|
|
/******** End Global Variables *****/
|
|
|
|
static char *DisplayName = NULL;
|
|
|
|
static char **Arguments;
|
|
|
|
static int ArgCount;
|
|
|
|
extern void EventLoop();
|
|
extern void StartUp();
|
|
extern int MonitorLoop(int argc, char **argv);
|
|
|
|
static Bool multiHead = True;
|
|
|
|
/* stdi/o for log shell */
|
|
static int LogStdIn = -1, LogStdOut = -1, LogStdErr = -1;
|
|
|
|
|
|
static int real_main(int argc, char **argv);
|
|
|
|
void
|
|
Exit(int status)
|
|
{
|
|
#ifdef XSMP_ENABLED
|
|
wSessionDisconnectManager();
|
|
#endif
|
|
if (dpy)
|
|
XCloseDisplay(dpy);
|
|
|
|
exit(status);
|
|
}
|
|
|
|
|
|
void
|
|
Restart(char *manager, Bool abortOnFailure)
|
|
{
|
|
char *prog=NULL;
|
|
char *argv[MAX_RESTART_ARGS];
|
|
int i;
|
|
|
|
if (manager && manager[0]!=0) {
|
|
prog = argv[0] = strtok(manager, " ");
|
|
for (i=1; i<MAX_RESTART_ARGS; i++) {
|
|
argv[i]=strtok(NULL, " ");
|
|
if (argv[i]==NULL) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (dpy) {
|
|
#ifdef XSMP_ENABLED
|
|
wSessionDisconnectManager();
|
|
#endif
|
|
XCloseDisplay(dpy);
|
|
dpy = NULL;
|
|
}
|
|
if (!prog) {
|
|
execvp(Arguments[0], Arguments);
|
|
wfatal(_("failed to restart Window Maker."));
|
|
} else {
|
|
execvp(prog, argv);
|
|
wsyserror(_("could not exec %s"), prog);
|
|
}
|
|
if (abortOnFailure)
|
|
exit(7);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SetupEnvironment(WScreen *scr)
|
|
{
|
|
char *tmp, *ptr;
|
|
char buf[16];
|
|
|
|
if (multiHead) {
|
|
int len = strlen(DisplayName)+64;
|
|
tmp = wmalloc(len);
|
|
snprintf(tmp, len, "DISPLAY=%s", XDisplayName(DisplayName));
|
|
ptr = strchr(strchr(tmp, ':'), '.');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
snprintf(buf, sizeof(buf), ".%i", scr->screen);
|
|
strcat(tmp, buf);
|
|
putenv(tmp);
|
|
}
|
|
tmp = wmalloc(60);
|
|
snprintf(tmp, 60, "WRASTER_COLOR_RESOLUTION%i=%i", scr->screen,
|
|
scr->rcontext->attribs->colors_per_channel);
|
|
putenv(tmp);
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
WScreen *scr;
|
|
char *command;
|
|
} _tuple;
|
|
|
|
|
|
static void
|
|
shellCommandHandler(pid_t pid, unsigned char status, _tuple *data)
|
|
{
|
|
if (status == 127) {
|
|
char *buffer;
|
|
|
|
buffer = wstrconcat(_("Could not execute command: "), data->command);
|
|
|
|
wMessageDialog(data->scr, _("Error"), buffer, _("OK"), NULL, NULL);
|
|
wfree(buffer);
|
|
} else if (status != 127) {
|
|
/*
|
|
printf("%s: %i\n", data->command, status);
|
|
*/
|
|
}
|
|
|
|
wfree(data->command);
|
|
wfree(data);
|
|
}
|
|
|
|
|
|
void
|
|
ExecuteShellCommand(WScreen *scr, char *command)
|
|
{
|
|
static char *shell = NULL;
|
|
pid_t pid;
|
|
|
|
/*
|
|
* This have a problem: if the shell is tcsh (not sure about others)
|
|
* and ~/.tcshrc have /bin/stty erase ^H somewhere on it, the shell
|
|
* will block and the command will not be executed.
|
|
if (!shell) {
|
|
shell = getenv("SHELL");
|
|
if (!shell)
|
|
shell = "/bin/sh";
|
|
}
|
|
*/
|
|
shell = "/bin/sh";
|
|
|
|
pid = fork();
|
|
|
|
if (pid==0) {
|
|
|
|
SetupEnvironment(scr);
|
|
|
|
#ifdef HAVE_SETSID
|
|
setsid();
|
|
#endif
|
|
execl(shell, shell, "-c", command, NULL);
|
|
wsyserror("could not execute %s -c %s", shell, command);
|
|
Exit(-1);
|
|
} else if (pid < 0) {
|
|
wsyserror("cannot fork a new process");
|
|
} else {
|
|
_tuple *data = wmalloc(sizeof(_tuple));
|
|
|
|
data->scr = scr;
|
|
data->command = wstrdup(command);
|
|
|
|
wAddDeathHandler(pid, (WDeathHandler*)shellCommandHandler, data);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*---------------------------------------------------------------------------
|
|
* StartLogShell
|
|
* Start a shell that will receive all stdin and stdout from processes
|
|
* forked by wmaker.
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
StartLogShell(WScreen *scr)
|
|
{
|
|
int in_fd[2];
|
|
int out_fd[2];
|
|
int err_fd[2];
|
|
pid_t pid;
|
|
|
|
SetupEnvironment(scr);
|
|
|
|
if (pipe(in_fd) < 0) {
|
|
wsyserror("could not create pipe for log shell\n");
|
|
return;
|
|
}
|
|
if (pipe(out_fd) < 0) {
|
|
wsyserror("could not create pipe for log shell\n");
|
|
close(in_fd[0]);
|
|
close(in_fd[1]);
|
|
return;
|
|
}
|
|
if (pipe(err_fd) < 0) {
|
|
wsyserror("could not create pipe for log shell\n");
|
|
close(out_fd[0]);
|
|
close(out_fd[1]);
|
|
close(in_fd[0]);
|
|
close(in_fd[1]);
|
|
return;
|
|
}
|
|
|
|
pid = fork();
|
|
if (pid < 0) {
|
|
wsyserror("could not fork a new process for log shell\n");
|
|
return;
|
|
} else if (pid == 0) {
|
|
close(in_fd[0]);
|
|
close(out_fd[1]);
|
|
close(err_fd[1]);
|
|
|
|
close(0);
|
|
close(1);
|
|
close(2);
|
|
|
|
if (dup2(in_fd[1], 0) < 0) {
|
|
wsyserror("could not redirect stdin for log shell\n");
|
|
exit(1);
|
|
}
|
|
if (dup2(out_fd[1], 1) < 0) {
|
|
wsyserror("could not redirect stdout for log shell\n");
|
|
exit(1);
|
|
}
|
|
if (dup2(err_fd[1], 2) < 0) {
|
|
wsyserror("could not redirect stderr for log shell\n");
|
|
exit(1);
|
|
}
|
|
|
|
close(in_fd[1]);
|
|
close(out_fd[1]);
|
|
close(err_fd[1]);
|
|
|
|
execl("/bin/sh", "/bin/sh", "-c", wPreferences.logger_shell, NULL);
|
|
wsyserror("could not execute %s\n", wPreferences.logger_shell);
|
|
exit(1);
|
|
} else {
|
|
close(in_fd[1]);
|
|
close(out_fd[0]);
|
|
close(err_fd[0]);
|
|
|
|
LogStdIn = in_fd[1];
|
|
LogStdOut = out_fd[0];
|
|
LogStdErr = err_fd[0];
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*---------------------------------------------------------------------
|
|
* wAbort--
|
|
* Do a major cleanup and exit the program
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
void
|
|
wAbort(Bool dumpCore)
|
|
{
|
|
int i;
|
|
WScreen *scr;
|
|
|
|
for (i=0; i<wScreenCount; i++) {
|
|
scr = wScreenWithNumber(i);
|
|
if (scr)
|
|
RestoreDesktop(scr);
|
|
}
|
|
printf(_("%s aborted.\n"), ProgName);
|
|
if (dumpCore)
|
|
abort();
|
|
else
|
|
exit(1);
|
|
}
|
|
|
|
|
|
void
|
|
print_help()
|
|
{
|
|
printf(_("Usage: %s [options]\n"), ProgName);
|
|
puts(_("The Window Maker window manager for the X window system"));
|
|
puts("");
|
|
puts(_(" -display host:dpy display to use"));
|
|
#ifdef USECPP
|
|
puts(_(" --no-cpp disable preprocessing of configuration files"));
|
|
#endif
|
|
puts(_(" --no-dock do not open the application Dock"));
|
|
puts(_(" --no-clip do not open the workspace Clip"));
|
|
puts(_(" --no-autolaunch do not autolaunch applications"));
|
|
puts(_(" --dont-restore do not restore saved session"));
|
|
|
|
puts(_(" --locale locale locale to use"));
|
|
|
|
puts(_(" --create-stdcmap create the standard colormap hint in PseudoColor visuals"));
|
|
puts(_(" --visual-id visualid visual id of visual to use"));
|
|
puts(_(" --static do not update or save configurations"));
|
|
#ifdef DEBUG
|
|
puts(_(" --synchronous turn on synchronous display mode"));
|
|
#endif
|
|
puts(_(" --version print version and exit"));
|
|
puts(_(" --help show this message"));
|
|
}
|
|
|
|
|
|
|
|
void
|
|
check_defaults()
|
|
{
|
|
char *path;
|
|
|
|
path = wdefaultspathfordomain("WindowMaker");
|
|
|
|
if (access(path, R_OK)!=0) {
|
|
#if 0
|
|
wfatal(_("could not find user GNUstep directory (%s).\n"
|
|
"Make sure you have installed Window Maker correctly and run wmaker.inst"),
|
|
path);
|
|
exit(1);
|
|
#else
|
|
wwarning(_("could not find user GNUstep directory (%s)."), path);
|
|
|
|
if (system("wmaker.inst --batch") != 0) {
|
|
wwarning(_("There was an error while creating GNUstep directory, please "
|
|
"make sure you have installed Window Maker correctly and run wmaker.inst"));
|
|
} else {
|
|
wwarning(_("%s directory created with default configuration."), path);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
wfree(path);
|
|
}
|
|
|
|
|
|
/*
|
|
* This is the handler used to notify if configuration
|
|
* files have changed, using linux kernel'l dnotify
|
|
* mechanism (from Documentation/dnotify.txt)
|
|
*/
|
|
void handler(int sig, siginfo_t *si, void *data)
|
|
{
|
|
filesChanged = si->si_fd;
|
|
}
|
|
|
|
static void
|
|
execInitScript()
|
|
{
|
|
char *file, *path, *paths;
|
|
struct sigaction act;
|
|
volatile int fd;
|
|
|
|
path = wstrconcat(wusergnusteppath(), "/Defaults");
|
|
|
|
act.sa_sigaction = handler;
|
|
sigemptyset(&act.sa_mask);
|
|
act.sa_flags = SA_SIGINFO;
|
|
sigaction(SIGRTMIN + 1, &act, NULL);
|
|
|
|
fd = open(path, O_RDONLY);
|
|
fcntl(fd, F_SETSIG, SIGRTMIN + 1);
|
|
fcntl(fd, F_NOTIFY, DN_MODIFY|DN_MULTISHOT);
|
|
wfree(path);
|
|
|
|
paths = wstrconcat(wusergnusteppath(), "/Library/WindowMaker");
|
|
paths = wstrappend(paths, ":"DEF_CONFIG_PATHS);
|
|
|
|
file = wfindfile(paths, DEF_INIT_SCRIPT);
|
|
wfree(paths);
|
|
|
|
if (file) {
|
|
if (system(file) != 0) {
|
|
wsyserror(_("%s:could not execute initialization script"), file);
|
|
}
|
|
#if 0
|
|
if (fork()==0) {
|
|
execl("/bin/sh", "/bin/sh", "-c", file, NULL);
|
|
wsyserror(_("%s:could not execute initialization script"), file);
|
|
exit(1);
|
|
}
|
|
#endif
|
|
wfree(file);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ExecExitScript()
|
|
{
|
|
char *file, *paths;
|
|
|
|
paths = wstrconcat(wusergnusteppath(), "/Library/WindowMaker");
|
|
paths = wstrappend(paths, ":"DEF_CONFIG_PATHS);
|
|
|
|
file = wfindfile(paths, DEF_EXIT_SCRIPT);
|
|
wfree(paths);
|
|
|
|
if (file) {
|
|
if (system(file) != 0) {
|
|
wsyserror(_("%s:could not execute exit script"), file);
|
|
}
|
|
#if 0
|
|
if (fork()==0) {
|
|
execl("/bin/sh", "/bin/sh", "-c", file, NULL);
|
|
wsyserror(_("%s:could not execute exit script"), file);
|
|
exit(1);
|
|
}
|
|
#endif
|
|
wfree(file);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
char*
|
|
getFullPath(char *path)
|
|
{
|
|
char buffer[1024];
|
|
char *tmp;
|
|
char *basep = (char*)buffer;
|
|
|
|
if (*path != '/' && getcwd(buffer, 1023)) {
|
|
|
|
for (;;) {
|
|
if (strncmp(path, "../", 3)==0) {
|
|
path += 3;
|
|
basep = strchr(basep, '/');
|
|
if (!basep || *path==0)
|
|
break;
|
|
}
|
|
}
|
|
if (*path == '/' || strncmp(path, "./",2)==0) {
|
|
tmp =
|
|
}
|
|
|
|
/*
|
|
* path
|
|
* ./path
|
|
* ../path
|
|
* ../../path
|
|
*/
|
|
|
|
|
|
} else {
|
|
return wstrconcat(path);
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
#endif
|
|
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i_am_the_monitor, i, len;
|
|
char *str, *alt;
|
|
|
|
/* setup common stuff for the monitor and wmaker itself */
|
|
WMInitializeApplication("WindowMaker", &argc, argv);
|
|
|
|
memset(&wPreferences, 0, sizeof(WPreferences));
|
|
|
|
wPreferences.fallbackWMs = WMCreateArray(8);
|
|
alt = getenv("WINDOWMAKER_ALT_WM");
|
|
if (alt != NULL)
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup(alt));
|
|
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("blackbox"));
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("metacity"));
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("fvwm"));
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("twm"));
|
|
WMAddToArray(wPreferences.fallbackWMs, NULL);
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("rxvt"));
|
|
WMAddToArray(wPreferences.fallbackWMs, wstrdup("xterm"));
|
|
|
|
i_am_the_monitor= 1;
|
|
|
|
for (i= 1; i < argc; i++)
|
|
{
|
|
if (strncmp(argv[i], "--for-real", strlen("--for-real"))==0)
|
|
{
|
|
i_am_the_monitor= 0;
|
|
break;
|
|
}
|
|
else if (strcmp(argv[i], "-display")==0 || strcmp(argv[i], "--display")==0)
|
|
{
|
|
i++;
|
|
if (i>=argc) {
|
|
wwarning(_("too few arguments for %s"), argv[i-1]);
|
|
exit(0);
|
|
}
|
|
DisplayName = argv[i];
|
|
}
|
|
}
|
|
|
|
DisplayName = XDisplayName(DisplayName);
|
|
len = strlen(DisplayName)+64;
|
|
str = wmalloc(len);
|
|
snprintf(str, len, "DISPLAY=%s", DisplayName);
|
|
putenv(str);
|
|
|
|
if (i_am_the_monitor)
|
|
return MonitorLoop(argc, argv);
|
|
else
|
|
return real_main(argc, argv);
|
|
}
|
|
|
|
|
|
static int
|
|
real_main(int argc, char **argv)
|
|
{
|
|
int i, restart=0;
|
|
char *str;
|
|
int d, s;
|
|
int flag;
|
|
#ifdef DEBUG
|
|
Bool doSync = False;
|
|
#endif
|
|
setlocale(LC_ALL, "");
|
|
|
|
wsetabort(wAbort);
|
|
|
|
/* for telling WPrefs what's the name of the wmaker binary being ran */
|
|
|
|
str = wstrconcat("WMAKER_BIN_NAME=", argv[0]);
|
|
putenv(str);
|
|
|
|
flag= 0;
|
|
ArgCount = argc;
|
|
Arguments = wmalloc(sizeof(char*)*(ArgCount+1));
|
|
for (i= 0; i < argc; i++)
|
|
{
|
|
Arguments[i]= argv[i];
|
|
}
|
|
/* add the extra option to signal that we're just restarting wmaker */
|
|
Arguments[argc-1]= "--for-real=";
|
|
Arguments[argc]= NULL;
|
|
|
|
ProgName = strrchr(argv[0],'/');
|
|
if (!ProgName)
|
|
ProgName = argv[0];
|
|
else
|
|
ProgName++;
|
|
|
|
|
|
restart = 0;
|
|
|
|
if (argc>1) {
|
|
for (i=1; i<argc; i++) {
|
|
#ifdef USECPP
|
|
if (strcmp(argv[i], "-nocpp")==0
|
|
|| strcmp(argv[i], "--no-cpp")==0) {
|
|
wPreferences.flags.nocpp=1;
|
|
} else
|
|
#endif
|
|
if (strcmp(argv[i], "--for-real")==0) {
|
|
wPreferences.flags.restarting = 0;
|
|
} else if (strcmp(argv[i], "--for-real=")==0) {
|
|
wPreferences.flags.restarting = 1;
|
|
} else if (strcmp(argv[i], "--for-real-")==0) {
|
|
wPreferences.flags.restarting = 2;
|
|
} else if (strcmp(argv[i], "-no-autolaunch")==0
|
|
|| strcmp(argv[i], "--no-autolaunch")==0) {
|
|
wPreferences.flags.noautolaunch = 1;
|
|
} else if (strcmp(argv[i], "-dont-restore")==0
|
|
|| strcmp(argv[i], "--dont-restore")==0) {
|
|
wPreferences.flags.norestore = 1;
|
|
} else if (strcmp(argv[i], "-nodock")==0
|
|
|| strcmp(argv[i], "--no-dock")==0) {
|
|
wPreferences.flags.nodock=1;
|
|
} else if (strcmp(argv[i], "-noclip")==0
|
|
|| strcmp(argv[i], "--no-clip")==0) {
|
|
wPreferences.flags.noclip=1;
|
|
} else if (strcmp(argv[i], "-version")==0
|
|
|| strcmp(argv[i], "--version")==0) {
|
|
printf("Window Maker %s\n", VERSION);
|
|
exit(0);
|
|
} else if (strcmp(argv[i], "--global_defaults_path")==0) {
|
|
printf("%s/WindowMaker\n", SYSCONFDIR);
|
|
exit(0);
|
|
#ifdef DEBUG
|
|
} else if (strcmp(argv[i], "--synchronous")==0) {
|
|
doSync = 1;
|
|
#endif
|
|
} else if (strcmp(argv[i], "-locale")==0
|
|
|| strcmp(argv[i], "--locale")==0) {
|
|
i++;
|
|
if (i>=argc) {
|
|
wwarning(_("too few arguments for %s"), argv[i-1]);
|
|
exit(0);
|
|
}
|
|
Locale = argv[i];
|
|
} else if (strcmp(argv[i], "-display")==0
|
|
|| strcmp(argv[i], "--display")==0) {
|
|
i++;
|
|
if (i>=argc) {
|
|
wwarning(_("too few arguments for %s"), argv[i-1]);
|
|
exit(0);
|
|
}
|
|
DisplayName = argv[i];
|
|
} else if (strcmp(argv[i], "-visualid")==0
|
|
|| strcmp(argv[i], "--visual-id")==0) {
|
|
i++;
|
|
if (i>=argc) {
|
|
wwarning(_("too few arguments for %s"), argv[i-1]);
|
|
exit(0);
|
|
}
|
|
if (sscanf(argv[i], "%i", &wVisualID)!=1) {
|
|
wwarning(_("bad value for visualid: \"%s\""), argv[i]);
|
|
exit(0);
|
|
}
|
|
} else if (strcmp(argv[i], "-static")==0
|
|
|| strcmp(argv[i], "--static")==0) {
|
|
|
|
wPreferences.flags.noupdates = 1;
|
|
#ifdef XSMP_ENABLED
|
|
} else if (strcmp(argv[i], "-clientid")==0
|
|
|| strcmp(argv[i], "-restore")==0) {
|
|
i++;
|
|
if (i>=argc) {
|
|
wwarning(_("too few arguments for %s"), argv[i-1]);
|
|
exit(0);
|
|
}
|
|
#endif
|
|
} else if (strcmp(argv[i], "--help")==0) {
|
|
print_help();
|
|
exit(0);
|
|
} else {
|
|
printf(_("%s: invalid argument '%s'\n"), argv[0], argv[i]);
|
|
printf(_("Try '%s --help' for more information\n"), argv[0]);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!wPreferences.flags.noupdates) {
|
|
/* check existence of Defaults DB directory */
|
|
check_defaults();
|
|
}
|
|
|
|
|
|
if (Locale) {
|
|
/* return of wstrconcat should not be free-ed! read putenv man page */
|
|
putenv(wstrconcat("LANG=", Locale));
|
|
} else {
|
|
Locale = getenv("LC_ALL");
|
|
if (!Locale) {
|
|
Locale = getenv("LANG");
|
|
}
|
|
}
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
if (!Locale || strcmp(Locale, "C")==0 || strcmp(Locale, "POSIX")==0)
|
|
Locale = NULL;
|
|
#ifdef I18N
|
|
if (getenv("NLSPATH"))
|
|
bindtextdomain("WindowMaker", getenv("NLSPATH"));
|
|
else
|
|
bindtextdomain("WindowMaker", LOCALEDIR);
|
|
bind_textdomain_codeset("WindowMaker", "UTF-8");
|
|
textdomain("WindowMaker");
|
|
|
|
if (!XSupportsLocale()) {
|
|
wwarning(_("X server does not support locale"));
|
|
}
|
|
|
|
if (XSetLocaleModifiers("") == NULL) {
|
|
wwarning(_("cannot set locale modifiers"));
|
|
}
|
|
#endif
|
|
|
|
if (Locale) {
|
|
char *ptr;
|
|
|
|
Locale = wstrdup(Locale);
|
|
ptr = strchr(Locale, '.');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
}
|
|
|
|
/* open display */
|
|
dpy = XOpenDisplay(DisplayName);
|
|
if (dpy == NULL) {
|
|
wfatal(_("could not open display \"%s\""), XDisplayName(DisplayName));
|
|
exit(1);
|
|
}
|
|
|
|
if (fcntl(ConnectionNumber(dpy), F_SETFD, FD_CLOEXEC) < 0) {
|
|
wsyserror("error setting close-on-exec flag for X connection");
|
|
exit(1);
|
|
}
|
|
|
|
/* check if the user specified a complete display name (with screen).
|
|
* If so, only manage the specified screen */
|
|
if (DisplayName)
|
|
str = strchr(DisplayName, ':');
|
|
else
|
|
str = NULL;
|
|
|
|
if (str && sscanf(str, ":%i.%i", &d, &s)==2)
|
|
multiHead = False;
|
|
|
|
DisplayName = XDisplayName(DisplayName);
|
|
{
|
|
int len = strlen(DisplayName)+64;
|
|
str = wmalloc(len);
|
|
snprintf(str, len, "DISPLAY=%s", DisplayName);
|
|
}
|
|
putenv(str);
|
|
|
|
#ifdef DEBUG
|
|
if (doSync)
|
|
XSynchronize(dpy, True);
|
|
#endif
|
|
|
|
wXModifierInitialize();
|
|
|
|
#ifdef XSMP_ENABLED
|
|
wSessionConnectManager(argv, argc);
|
|
#endif
|
|
|
|
StartUp(!multiHead);
|
|
|
|
if (wScreenCount==1)
|
|
multiHead = False;
|
|
|
|
execInitScript();
|
|
|
|
EventLoop();
|
|
return -1;
|
|
}
|
|
|