mirror of https://github.com/morgant/mlvwm.git
700 lines
21 KiB
C
700 lines
21 KiB
C
/****************************************************************************/
|
|
/* This module is based on fvwm, but has been siginificantly modified */
|
|
/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */
|
|
/****************************************************************************/
|
|
/****************************************************************************
|
|
* This module is based on Twm, but has been siginificantly modified
|
|
* by Rob Nation (nation@rocket.sanders.lockheed.com)
|
|
****************************************************************************/
|
|
/*****************************************************************************/
|
|
/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
|
|
/** Salt Lake City, Utah **/
|
|
/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/
|
|
/** Cambridge, Massachusetts **/
|
|
/** **/
|
|
/** All Rights Reserved **/
|
|
/** **/
|
|
/** Permission to use, copy, modify, and distribute this software and **/
|
|
/** its documentation for any purpose and without fee is hereby **/
|
|
/** granted, provided that the above copyright notice appear in all **/
|
|
/** copies and that both that copyright notice and this permis- **/
|
|
/** sion notice appear in supporting documentation, and that the **/
|
|
/** names of Evans & Sutherland and M.I.T. not be used in advertising **/
|
|
/** in publicity pertaining to distribution of the software without **/
|
|
/** specific, written prior permission. **/
|
|
/** **/
|
|
/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/
|
|
/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/
|
|
/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/
|
|
/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/
|
|
/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
|
|
/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
|
|
/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
|
|
/** OR PERFORMANCE OF THIS SOFTWARE. **/
|
|
/*****************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "mlvwm.h"
|
|
#include "screen.h"
|
|
#include "event.h"
|
|
#include "add_window.h"
|
|
#include "config.h"
|
|
#include "functions.h"
|
|
#include "misc.h"
|
|
|
|
#include <X11/Xproto.h>
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Xresource.h>
|
|
#include <X11/extensions/shape.h>
|
|
#include <X11/xpm.h>
|
|
#ifdef USE_LOCALE
|
|
#include <X11/Xlocale.h>
|
|
#endif
|
|
|
|
static unsigned char start_mesh[] = { 0x03, 0x03, 0x0c, 0x0c};
|
|
|
|
ScreenInfo Scr;
|
|
Display *dpy;
|
|
int xfd;
|
|
XContext MlvwmContext;
|
|
XContext MenuContext;
|
|
XClassHint NoClass;
|
|
|
|
static char **g_argv;
|
|
int ShapeEventBase, ShapeErrorBase;
|
|
|
|
void CreateCursors( void )
|
|
{
|
|
Scr.MlvwmCursors[DEFAULT] = XCreateFontCursor( dpy, XC_left_ptr );
|
|
Scr.MlvwmCursors[SYS] = XCreateFontCursor( dpy, XC_X_cursor );
|
|
Scr.MlvwmCursors[TITLE_CURSOR] = XCreateFontCursor( dpy, XC_hand2 );
|
|
Scr.MlvwmCursors[RESIZE] =
|
|
XCreateFontCursor( dpy, XC_bottom_right_corner );
|
|
Scr.MlvwmCursors[MOVE] = XCreateFontCursor( dpy, XC_fleur );
|
|
Scr.MlvwmCursors[MENU] = XCreateFontCursor( dpy, XC_sb_left_arrow );
|
|
Scr.MlvwmCursors[WAIT] = XCreateFontCursor( dpy, XC_watch );
|
|
Scr.MlvwmCursors[SELECT] = XCreateFontCursor( dpy, XC_dot );
|
|
Scr.MlvwmCursors[DESTROY] = XCreateFontCursor( dpy, XC_pirate );
|
|
Scr.MlvwmCursors[SBARH_CURSOR] =
|
|
XCreateFontCursor( dpy, XC_sb_h_double_arrow );
|
|
Scr.MlvwmCursors[SBARV_CURSOR] =
|
|
XCreateFontCursor( dpy, XC_sb_v_double_arrow );
|
|
Scr.MlvwmCursors[MINMAX_CURSOR] = XCreateFontCursor( dpy, XC_sizing );
|
|
Scr.MlvwmCursors[SHADER_UP_CURSOR] =
|
|
XCreateFontCursor( dpy, XC_based_arrow_up );
|
|
Scr.MlvwmCursors[SHADER_DOWN_CURSOR] =
|
|
XCreateFontCursor( dpy, XC_based_arrow_down );
|
|
}
|
|
|
|
void LoadDefaultFonts( void )
|
|
{
|
|
#ifdef USE_LOCALE
|
|
char **miss, *def;
|
|
int n_miss, lp;
|
|
|
|
Scr.MenuBarFs = XCreateFontSet( dpy, DEFAULTFS, &miss, &n_miss, &def );
|
|
if( n_miss>0 ){
|
|
for( lp=0; lp<n_miss; lp++ )
|
|
DrawErrMsgOnMenu( "Can't load default font ", miss[lp] );
|
|
XFreeStringList( miss );
|
|
}
|
|
Scr.MenuFs = XCreateFontSet( dpy, DEFAULTFS, &miss, &n_miss, &def );
|
|
if( n_miss>0 ){
|
|
for( lp=0; lp<n_miss; lp++ )
|
|
DrawErrMsgOnMenu( "Can't load default font ", miss[lp] );
|
|
XFreeStringList( miss );
|
|
}
|
|
Scr.WindowFs = XCreateFontSet( dpy, DEFAULTFS, &miss, &n_miss, &def );
|
|
if( n_miss>0 ){
|
|
for( lp=0; lp<n_miss; lp++ )
|
|
DrawErrMsgOnMenu( "Can't load default font ", miss[lp] );
|
|
XFreeStringList( miss );
|
|
}
|
|
Scr.BalloonFs = XCreateFontSet( dpy, DEFAULTFS, &miss, &n_miss, &def );
|
|
if( n_miss>0 ){
|
|
for( lp=0; lp<n_miss; lp++ )
|
|
DrawErrMsgOnMenu( "Can't load default font ", miss[lp] );
|
|
XFreeStringList( miss );
|
|
}
|
|
#else
|
|
if(( Scr.MenuBarFont = XLoadQueryFont( dpy, DEFAULTFONT )) == NULL )
|
|
DrawErrMsgOnMenu( "Can't load default font ", "MenuBar" );
|
|
if(( Scr.MenuFont = XLoadQueryFont( dpy, DEFAULTFONT )) == NULL )
|
|
DrawErrMsgOnMenu( "Can't load default font ", "Menu" );
|
|
if(( Scr.WindowFont = XLoadQueryFont( dpy, DEFAULTFONT )) == NULL )
|
|
DrawErrMsgOnMenu( "Can't load default font ", "Window" );
|
|
if(( Scr.BalloonFont = XLoadQueryFont( dpy, DEFAULTFONT )) == NULL )
|
|
DrawErrMsgOnMenu( "Can't load default font ", "Balloon" );
|
|
#endif
|
|
}
|
|
|
|
void FreeFont( void )
|
|
{
|
|
#ifdef USE_LOCALE
|
|
XFreeFontSet( dpy, Scr.MenuBarFs );
|
|
XFreeFontSet( dpy, Scr.MenuFs );
|
|
XFreeFontSet( dpy, Scr.WindowFs );
|
|
#else
|
|
XFreeFont( dpy, Scr.MenuBarFont );
|
|
XFreeFont( dpy, Scr.MenuFont );
|
|
XFreeFont( dpy, Scr.WindowFont );
|
|
#endif
|
|
}
|
|
|
|
void InitScrParams( void )
|
|
{
|
|
unsigned char mask[] = {0x01, 0x02};
|
|
|
|
Scr.d_depth = DefaultDepth( dpy, Scr.screen );
|
|
Scr.n_desktop = 1;
|
|
Scr.Restarting = False;
|
|
{
|
|
Atom atype;
|
|
int aformat;
|
|
unsigned long nitems, bytes_remain;
|
|
unsigned char *prop;
|
|
|
|
Scr.currentdesk = 0;
|
|
if ((XGetWindowProperty(dpy, Scr.Root, _XA_WM_DESKTOP,
|
|
0L, 1L, True, _XA_WM_DESKTOP, &atype, &aformat,
|
|
&nitems, &bytes_remain, &prop))==Success){
|
|
if(prop != NULL){
|
|
Scr.Restarting = True;
|
|
Scr.currentdesk = *(unsigned long *)prop;
|
|
}
|
|
}
|
|
}
|
|
Scr.MlvwmRoot.w = Scr.Root;
|
|
Scr.MlvwmRoot.prev = NULL;
|
|
Scr.MlvwmRoot.next = NULL;
|
|
Scr.LastActive = calloc( 1, sizeof(MlvwmWindow));
|
|
Scr.MyDisplayWidth = DisplayWidth( dpy, Scr.screen );
|
|
Scr.MyDisplayHeight = DisplayHeight( dpy, Scr.screen );
|
|
Scr.MenuLabelRoot = NULL;
|
|
Scr.MenuRoot = NULL;
|
|
Scr.ActiveMenu = NULL;
|
|
Scr.IconMenu.m_item = NULL;
|
|
Scr.ActiveWin = NULL;
|
|
Scr.root_pushes = 0;
|
|
Scr.pushed_window = &Scr.MlvwmRoot;
|
|
Scr.style_list = NULL;
|
|
Scr.ShortCutRoot = NULL;
|
|
Scr.double_click_time = 300;
|
|
if( Scr.flags&SYSTEM8 )
|
|
Scr.bar_width = 16;
|
|
else
|
|
Scr.bar_width = 19;
|
|
Scr.flush_time = 100000;
|
|
Scr.flush_times = 2;
|
|
Scr.zoom_wait = 10000;
|
|
Scr.IconPath = NULL;
|
|
Scr.BalloonOffStr = NULL;
|
|
Scr.BalloonOnStr = NULL;
|
|
Scr.mask = XCreatePixmapFromBitmapData( dpy, Scr.Root, mask, 2, 2,
|
|
WhitePixel( dpy, Scr.screen ),
|
|
BlackPixel( dpy, Scr.screen ),
|
|
Scr.d_depth );
|
|
Scr.StartFunc = NULL;
|
|
Scr.flags |= STARTING;
|
|
}
|
|
|
|
void InitGCs( void )
|
|
{
|
|
XGCValues gcv;
|
|
unsigned long gcm;
|
|
|
|
gcm = GCFunction|GCForeground|GCSubwindowMode|GCLineWidth|GCLineStyle;
|
|
gcv.function = GXxor;
|
|
gcv.subwindow_mode = IncludeInferiors;
|
|
gcv.line_width = 1;
|
|
|
|
if( Scr.d_depth>1 )
|
|
gcv.foreground = GetColor( "#777777" );
|
|
else
|
|
gcv.foreground = WhitePixel( dpy, Scr.screen );
|
|
gcv.line_style = FillSolid;
|
|
|
|
Scr.RobberGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
gcm = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCTile;
|
|
gcv.function = GXcopy;
|
|
gcv.plane_mask = AllPlanes;
|
|
gcv.line_width = 0;
|
|
gcv.fill_style = FillSolid;
|
|
gcv.tile = Scr.mask;
|
|
|
|
gcv.foreground = BlackPixel( dpy, Scr.screen );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.BlackGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
gcv.foreground = WhitePixel( dpy, Scr.screen );
|
|
gcv.background = BlackPixel( dpy, Scr.screen );
|
|
Scr.WhiteGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#444444" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.Gray1GC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#777777" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.Gray2GC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#bbbbbb" );
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#aaaaaa" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.Gray3GC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#e0e0e0" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.Gray4GC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#3333ff" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.MenuSelectBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#dddddd" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.MenuBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
|
|
if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#ccccff" );
|
|
gcv.background = WhitePixel( dpy, Scr.screen );
|
|
Scr.ScrollBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv );
|
|
}
|
|
|
|
void InitVariables( void )
|
|
{
|
|
MlvwmContext = XUniqueContext();
|
|
|
|
InitScrParams();
|
|
InitGCs();
|
|
|
|
NoClass.res_name = NoName;
|
|
NoClass.res_class = NoName;
|
|
|
|
AddMenuItem( &(Scr.IconMenu), "Hide Active", "HideActive",
|
|
NULL, NULL, NULL, STRGRAY );
|
|
AddMenuItem( &(Scr.IconMenu), "Hide Others", "HideOthers",
|
|
NULL, NULL, NULL, STRGRAY );
|
|
AddMenuItem( &(Scr.IconMenu), "Show All", "ShowAll",
|
|
NULL, NULL, NULL, STRGRAY );
|
|
AddMenuItem( &(Scr.IconMenu), "", "Nop", NULL, NULL, NULL, STRGRAY );
|
|
}
|
|
|
|
Atom _XA_MIT_PRIORITY_COLORS;
|
|
Atom _XA_WM_CHANGE_STATE;
|
|
Atom _XA_WM_STATE;
|
|
Atom _XA_WM_COLORMAP_WINDOWS;
|
|
Atom _XA_WM_PROTOCOLS;
|
|
Atom _XA_WM_TAKE_FOCUS;
|
|
Atom _XA_WM_DELETE_WINDOW;
|
|
Atom _XA_WM_DESKTOP;
|
|
|
|
void InternUsefulAtoms (void)
|
|
{
|
|
/*
|
|
* Create priority colors if necessary.
|
|
*/
|
|
_XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False);
|
|
_XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False);
|
|
_XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False);
|
|
_XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False);
|
|
_XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
|
|
_XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False);
|
|
_XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
|
|
_XA_WM_DESKTOP = XInternAtom (dpy, "WM_DESKTOP", False);
|
|
|
|
return;
|
|
}
|
|
|
|
int MappedNotOverride( Window w )
|
|
{
|
|
XWindowAttributes wa;
|
|
|
|
XGetWindowAttributes(dpy, w, &wa);
|
|
return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True));
|
|
}
|
|
|
|
void RepaintAllWindows( Window w )
|
|
{
|
|
Window parent, *children;
|
|
XWindowAttributes attributes;
|
|
unsigned nchildren, lp;
|
|
MlvwmWindow *t;
|
|
|
|
XQueryTree( dpy, Scr.Root, &Scr.Root, &parent, &children, &nchildren );
|
|
for( lp=0; nchildren > lp; lp++ ){
|
|
if( children[lp]==w || children[lp]==Scr.MenuBar ) continue;
|
|
XGetWindowAttributes( dpy, children[lp], &attributes );
|
|
if( IsUnmapped ==attributes.map_state ) continue;
|
|
if( children[lp] && MappedNotOverride(children[lp]) ){
|
|
HandleMapRequest( children[lp] );
|
|
if( XFindContext( dpy, children[lp],
|
|
MlvwmContext, (caddr_t *)&t)!=XCNOENT)
|
|
DrawStringMenuBar( t->name );
|
|
}
|
|
XLowerWindow( dpy, children[lp] );
|
|
}
|
|
XFree( children );
|
|
}
|
|
|
|
void Reborder( Bool restart )
|
|
{
|
|
MlvwmWindow *tmp;
|
|
|
|
XGrabServer (dpy);
|
|
InstallWindowColormaps( &Scr.MlvwmRoot ); /* force reinstall */
|
|
for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL;
|
|
tmp = (MlvwmWindow *)tmp->next){
|
|
XUnmapWindow(dpy,tmp->frame);
|
|
RestoreWithdrawnLocation( tmp, restart );
|
|
}
|
|
XUngrabServer (dpy);
|
|
XSetInputFocus (dpy, PointerRoot, RevertToPointerRoot,CurrentTime);
|
|
}
|
|
|
|
void SaveDesktopState( void )
|
|
{
|
|
MlvwmWindow *t;
|
|
unsigned long data[1];
|
|
|
|
for (t = Scr.MlvwmRoot.next; t != NULL; t = t->next){
|
|
data[0] = (unsigned long) t->Desk;
|
|
XChangeProperty (dpy, t->w, _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32,
|
|
PropModeReplace, (unsigned char *) data, 1);
|
|
}
|
|
|
|
data[0] = (unsigned long) Scr.currentdesk;
|
|
XChangeProperty (dpy, Scr.Root, _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32,
|
|
PropModeReplace, (unsigned char *) data, 1);
|
|
|
|
XSync(dpy, 0);
|
|
}
|
|
|
|
void Done( int restart, char *command )
|
|
{
|
|
char *my_argv[10];
|
|
int i,done;
|
|
|
|
strcpy( Scr.ErrorFunc, "Start Done" );
|
|
|
|
FreeMenu();
|
|
strcpy( Scr.ErrorFunc, "FreeMenu Done" );
|
|
|
|
FreeShortCut();
|
|
strcpy( Scr.ErrorFunc, "FreeShortCut Done" );
|
|
|
|
FreeStyles();
|
|
strcpy( Scr.ErrorFunc, "FreeStyles Done" );
|
|
|
|
FreeFont();
|
|
strcpy( Scr.ErrorFunc, "FreeFont Done" );
|
|
|
|
if( Scr.LastActive ) free( Scr.LastActive );
|
|
if( Scr.Balloon!=None ) XDestroyWindow( dpy, Scr.Balloon );
|
|
|
|
Reborder( restart==0?False:True );
|
|
strcpy( Scr.ErrorFunc, "Reborder Done" );
|
|
|
|
if(restart){
|
|
i=0;
|
|
done = 0;
|
|
while((g_argv[i] != NULL)&&(i<8)){
|
|
if(strcmp(g_argv[i],"-s")==0)
|
|
done = 1;
|
|
my_argv[i] = g_argv[i];
|
|
i++;
|
|
}
|
|
if(!done)
|
|
my_argv[i++] = "-s";
|
|
while(i<10)
|
|
my_argv[i++] = NULL;
|
|
SaveDesktopState();
|
|
XSelectInput(dpy, Scr.Root, 0 );
|
|
XSync(dpy, 0);
|
|
XCloseDisplay(dpy);
|
|
|
|
sleep( 1 );
|
|
ReapChildren();
|
|
|
|
if( command != NULL )
|
|
execvp(command,g_argv);
|
|
else
|
|
execvp( *g_argv,g_argv);
|
|
|
|
fprintf( stderr, "Call of '%s' failed!!!!", command);
|
|
execvp( *g_argv, g_argv);
|
|
fprintf( stderr, "Call of '%s' failed!!!!", g_argv[0]);
|
|
}
|
|
else{
|
|
XCloseDisplay( dpy );
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
void SigDone(int nonsense)
|
|
{
|
|
fprintf( stderr, "Catch Signal in [%s]\n", Scr.ErrorFunc );
|
|
Done(0, NULL);
|
|
return;
|
|
}
|
|
|
|
void setsighandle( int sig )
|
|
{
|
|
if( signal( sig, SIG_IGN ) != SIG_IGN )
|
|
signal( sig, SigDone );
|
|
}
|
|
|
|
void usage( void )
|
|
{
|
|
fprintf( stderr, "Mlvwm Ver %s\n\n", VERSION );
|
|
fprintf( stderr, "mlvwm [-d display] [-f config_file]");
|
|
fprintf( stderr, " [-debug]\n" );
|
|
}
|
|
|
|
XErrorHandler CatchRedirectError(Display *err_dpy, XErrorEvent *event)
|
|
{
|
|
fprintf( stderr, "MLVWM : another WM may be running.\n" );
|
|
exit(1);
|
|
}
|
|
|
|
XErrorHandler MlvwmErrorHandler(Display *err_dpy, XErrorEvent *event)
|
|
{
|
|
char err_msg[80];
|
|
|
|
/* some errors are acceptable, mostly they're caused by
|
|
* trying to update a lost window */
|
|
if((event->error_code == BadWindow) ||
|
|
(event->request_code == X_GetGeometry) ||
|
|
(event->error_code==BadDrawable) ||
|
|
(event->request_code==X_SetInputFocus) ||
|
|
(event->request_code == X_InstallColormap))
|
|
return 0 ;
|
|
|
|
XGetErrorText( err_dpy, event->error_code, err_msg, 80 );
|
|
fprintf( stderr, "MLVWM : X Protocol error\n" );
|
|
fprintf( stderr, " Error detected : %s\n", err_msg );
|
|
fprintf( stderr, " Protocol Request : %d\n", event->request_code );
|
|
fprintf( stderr, " Error : %d\n", event->error_code);
|
|
fprintf( stderr, " Resource ID : 0x%x\n",
|
|
(unsigned int)event->resourceid );
|
|
fprintf( stderr,"\n");
|
|
return 0;
|
|
}
|
|
|
|
Window CreateStartWindow( void )
|
|
{
|
|
Pixmap p_map;
|
|
unsigned long valuemask;
|
|
Window StartWin;
|
|
XSetWindowAttributes attributes;
|
|
|
|
if( Scr.flags & DEBUGOUT )
|
|
fprintf( stderr, "Display Startup Screen !\n" );
|
|
p_map = XCreatePixmapFromBitmapData( dpy, Scr.Root, start_mesh, 4, 4,
|
|
WhitePixel( dpy, Scr.screen ),
|
|
BlackPixel( dpy, Scr.screen ), Scr.d_depth );
|
|
if( Scr.flags & DEBUGOUT )
|
|
fprintf( stderr, "Pixmap Create !\n" );
|
|
valuemask = CWBackPixmap | CWBackingStore | CWCursor;
|
|
attributes.background_pixmap = p_map;
|
|
attributes.cursor = Scr.MlvwmCursors[WAIT];
|
|
attributes.backing_store = NotUseful;
|
|
StartWin = XCreateWindow (dpy, Scr.Root, 0, 0,
|
|
(unsigned int) Scr.MyDisplayWidth,
|
|
(unsigned int) Scr.MyDisplayHeight,
|
|
(unsigned int) 0,
|
|
CopyFromParent, (unsigned int) CopyFromParent,
|
|
(Visual *) CopyFromParent, valuemask,
|
|
&attributes);
|
|
XMapRaised (dpy, StartWin);
|
|
XFreePixmap( dpy, p_map );
|
|
XFlush (dpy);
|
|
|
|
return StartWin;
|
|
}
|
|
|
|
void SegFault( int nosense )
|
|
{
|
|
fprintf( stderr,"Segmentation Fault\n" );
|
|
fprintf( stderr,"\tin %s\n", Scr.ErrorFunc );
|
|
exit( -1 );
|
|
}
|
|
|
|
void DoStartFunc( void )
|
|
{
|
|
ShortCut *now, *prev;
|
|
|
|
now = Scr.StartFunc;
|
|
while( now ){
|
|
ExecuteFunction( now->action );
|
|
prev = now;
|
|
now = now->next;
|
|
free( prev->action );
|
|
free( prev );
|
|
}
|
|
}
|
|
|
|
void main( int argc, char *argv[] )
|
|
{
|
|
char *display_name=NULL;
|
|
char *display_string;
|
|
char *config_file=NULL;
|
|
char message[255];
|
|
char num[10];
|
|
Window StartWin;
|
|
XSetWindowAttributes attributes;
|
|
int len, lp;
|
|
Bool single = False;
|
|
|
|
Scr.flags = 0;
|
|
for( lp=1; lp<argc; lp++ ){
|
|
if( !strncmp( argv[lp], "-d", 2 ) && strlen(argv[lp])==2 ){
|
|
if( ++lp>=argc ) usage();
|
|
else display_name = argv[lp];
|
|
continue;
|
|
}
|
|
if( !strncmp( argv[lp], "-f", 2 ) ){
|
|
if( ++lp>=argc ) usage();
|
|
else config_file = argv[lp];
|
|
continue;
|
|
}
|
|
if( !strncmp( argv[lp], "-s", 2 ) ){
|
|
single = True;
|
|
continue;
|
|
}
|
|
if( !strncmp( argv[lp], "-debug", 6 )){
|
|
Scr.flags |= DEBUGOUT;
|
|
continue;
|
|
}
|
|
usage();
|
|
}
|
|
if( Scr.flags & DEBUGOUT )
|
|
fprintf( stderr, "Welcome to MLVWM World !\n" );
|
|
#ifdef USE_LOCALE
|
|
if( setlocale( LC_CTYPE, "" )==NULL ){
|
|
fprintf( stderr, "Can't figure out your locale.\n" );
|
|
fprintf( stderr, "Check $LANG.\n" );
|
|
}
|
|
if( XSupportsLocale() == False ){
|
|
fprintf( stderr, "Can't support your local.\n" );
|
|
fprintf( stderr, "Use \"C\" locale.\n" );
|
|
setlocale( LC_CTYPE, "C" );
|
|
}
|
|
#endif
|
|
if( !(dpy = XOpenDisplay( display_name )) ){
|
|
fprintf( stderr, "can't open display %s\n",XDisplayName(display_name));
|
|
exit( 1 );
|
|
}
|
|
xfd = XConnectionNumber(dpy);
|
|
|
|
if( fcntl( xfd, F_SETFD, 1 ) == -1){
|
|
fprintf( stderr, "Close-on-exec failed\n" );
|
|
exit (1);
|
|
}
|
|
|
|
Scr.screen = DefaultScreen( dpy );
|
|
|
|
g_argv = argv;
|
|
|
|
setsighandle( SIGINT );
|
|
setsighandle( SIGHUP );
|
|
setsighandle( SIGQUIT );
|
|
setsighandle( SIGTERM );
|
|
signal( SIGSEGV, SegFault );
|
|
Scr.NumberOfScreens = ScreenCount(dpy);
|
|
|
|
if(!single){
|
|
for(lp=0;lp<Scr.NumberOfScreens;lp++){
|
|
if(lp!= Scr.screen){
|
|
sprintf(message,"%s -d %s",argv[0],XDisplayString(dpy));
|
|
len = strlen(message);
|
|
message[len-1] = '\0';
|
|
sprintf(num,"%d",lp);
|
|
strcat(message,num);
|
|
strcat(message," -s ");
|
|
if( Scr.flags & DEBUGOUT)
|
|
strcat(message," -debug");
|
|
if( config_file!=NULL ){
|
|
strcat(message," -f ");
|
|
strcat(message,config_file);
|
|
}
|
|
strcat(message," &\n");
|
|
system(message);
|
|
}
|
|
}
|
|
}
|
|
len = strlen( XDisplayString( dpy ) );
|
|
display_string = calloc( len+10, sizeof( char ) );
|
|
sprintf( display_string, "DISPLAY=%s", XDisplayString( dpy ) );
|
|
putenv( display_string );
|
|
|
|
XShapeQueryExtension( dpy, &ShapeEventBase, &ShapeErrorBase );
|
|
InternUsefulAtoms();
|
|
|
|
Scr.Root = RootWindow( dpy, Scr.screen );
|
|
if( Scr.Root == None ){
|
|
fprintf( stderr, "Root window don't exist\n" );
|
|
exit( 1 );
|
|
}
|
|
XChangeProperty (dpy, Scr.Root, _XA_MIT_PRIORITY_COLORS,
|
|
XA_CARDINAL, 32, PropModeReplace, NULL, 0);
|
|
XSetErrorHandler((XErrorHandler)CatchRedirectError);
|
|
XSelectInput( dpy, Scr.Root,
|
|
PropertyChangeMask |
|
|
SubstructureRedirectMask | KeyPressMask |
|
|
SubstructureNotifyMask |
|
|
ButtonPressMask | ButtonReleaseMask );
|
|
XSync( dpy, 0 );
|
|
|
|
XSetErrorHandler((XErrorHandler)MlvwmErrorHandler);
|
|
|
|
CreateCursors();
|
|
InitVariables();
|
|
XGrabServer( dpy );
|
|
|
|
attributes.event_mask = KeyPressMask|FocusChangeMask;
|
|
attributes.override_redirect = True;
|
|
Scr.NoFocusWin=XCreateWindow(dpy,Scr.Root,-10, -10, 10, 10, 0, 0,
|
|
InputOnly,CopyFromParent,
|
|
CWEventMask|CWOverrideRedirect,
|
|
&attributes);
|
|
XMapWindow(dpy, Scr.NoFocusWin);
|
|
XSetInputFocus (dpy, Scr.NoFocusWin, RevertToParent, CurrentTime);
|
|
|
|
StartWin = CreateStartWindow();
|
|
CreateMenuBar();
|
|
LoadDefaultFonts();
|
|
|
|
if( Scr.flags & DEBUGOUT )
|
|
DrawStringMenuBar( "Read Config File !" );
|
|
ReadConfigFile( config_file? config_file : CONFIGNAME );
|
|
if( Scr.flags & DEBUGOUT ){
|
|
DrawStringMenuBar( "Read Config File Success !" );
|
|
XSynchronize(dpy,1);
|
|
}
|
|
XUngrabServer( dpy );
|
|
if( !Scr.MenuLabelRoot ) CreateSimpleMenu();
|
|
else CreateMenuItems();
|
|
for( Scr.iconAnchor = Scr.IconMenu.m_item;
|
|
Scr.iconAnchor->next->next != NULL;
|
|
Scr.iconAnchor = Scr.iconAnchor->next );
|
|
RepaintAllWindows( StartWin );
|
|
if( Scr.StartFunc ) DoStartFunc();
|
|
|
|
XDestroyWindow (dpy, StartWin);
|
|
|
|
sprintf( message, "Desk %d", Scr.currentdesk );
|
|
DrawStringMenuBar( "" );
|
|
ChangeDesk( message );
|
|
Scr.flags &= ~STARTING;
|
|
MapMenuBar( Scr.ActiveWin );
|
|
|
|
while( True ) WaitEvents();
|
|
}
|