/**************************************************************************** * This module is mostly all new * by Rob Nation * Copyright 1993 Robert Nation. No restrictions are placed on this code, * as long as the copyright notice is preserved ****************************************************************************/ /*************************************************************************** * * Configure.c: reads the .fvwmrc or system.fvwmrc file, interprets it, * and sets up menus, bindings, colors, and fonts as specified * ***************************************************************************/ #include "../configure.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef M4 #include #endif #include "fvwm.h" #include "menus.h" #include "misc.h" #include "parse.h" #include "screen.h" #include "../version.h" char *IconPath = FVWM_ICONDIR; #ifdef XPM char *PixmapPath=FVWM_ICONDIR; #endif char *ModulePath = FVWMDIR; char *white = "white"; char *black = "black"; char *grey = "SlateGrey"; char *Menuback; char *Menufore; char *Menustipple; char *Stdback; char *Stdfore; char *Stickyback; char *Stickyfore; char *Hiback; char *Hifore; #ifndef NO_PAGER char *Pagerback; char *Pagerfore; #endif void GetColors(void); Pixel GetColor(char *); MenuRoot *NewMenuRoot(char *name); char *stripcpy(char *); char *stripcpy2(char *,int, Bool); char *stripcpy3(char *, Bool); #ifndef NO_PAGER void initialize_pager(int x, int y); #endif void bad_binding(int num); void nofont(char *name); void nocolor(char *note, char *name); int contexts; int mods,func,func_val_1,func_val_2; #ifndef NO_PAGER int pager_x=10000,pager_y=10000; #endif unsigned PopupCount = 0; MenuRoot *PopupTable[MAXPOPUPS]; int dummy; char *config_file = ".fvwmrc"; extern XContext MenuContext; /* context for fvwm menus */ extern Bool DoHandlePageing; /* value for the rubberband XORing */ unsigned long XORvalue; int have_the_colors = 0; /* * Order is important here! if one keyword is the same as the first part of * another keyword, the shorter one must come first! */ struct config main_config[] = { {"OpaqueResize", SetFlag, (char **)OpaqueResize,(int *)0}, {"StubbornIcons", SetFlag, (char **)StubbornIcons,(int *)0}, {"StubbornPlacement", SetFlag, (char **)StubbornPlacement,(int *)0}, {"StubbornIconPlacement", SetFlag, (char **)StubbornIconPlacement, (int *)0}, {"Font", assign_string, &Scr.StdFont.name, (int *)0}, {"WindowFont", assign_string, &Scr.WindowFont.name, (int *)0}, {"MenuForeColor", assign_string, &Menufore, (int *)0}, {"MenuBackColor", assign_string, &Menuback, (int *)0}, {"MenuStippleColor", assign_string, &Menustipple, (int *)0}, {"StdForeColor", assign_string, &Stdfore, (int *)0}, {"StdBackColor", assign_string, &Stdback, (int *)0}, #ifdef XPM {"PixmapPath", assign_string, &PixmapPath, (int *)0}, #endif {"StickyForeColor", assign_string, &Stickyfore, (int *)0}, {"StickyBackColor", assign_string, &Stickyback, (int *)0}, {"HiForeColor", assign_string, &Hifore, (int *)0}, {"HiBackColor", assign_string, &Hiback, (int *)0}, {"IconPath", assign_string, &IconPath, (int *)0}, {"IconBox", SetBox, (char **)0, (int *)0}, {"StickyIcons", SetFlag, (char **)StickyIcons, (int *)0}, {"IconFont", assign_string, &Scr.IconFont.name, (int *)0}, #ifndef PRUNE {"Icon", SetOneStyle, (char **)&Scr.TheList,(int *)ICON_FLAG}, {"NoIconTitle", SetOneStyle, (char **)&Scr.TheList, (int *)NOICON_TITLE_FLAG}, #endif {"MWMBorders", SetFlag, (char **)MWMBorders, (int *)0}, {"MWMMenus", SetFlag, (char **)MWMMenus, (int *)0}, {"MWMButtons", SetFlag, (char **)MWMButtons, (int *)0}, {"MWMDecorHints", SetFlag, (char **)MWMDecorHints, (int *)0}, {"MWMFunctionHints", SetFlag, (char **)MWMFunctionHints, (int *)0}, {"MWMHintOverride", SetFlag, (char **)MWMHintOverride, (int *)0}, {"Lenience", SetFlag, (char **)Lenience, (int *)0}, {"NoPPosition", SetFlag, (char **)NoPPosition, (int *)0}, {"CirculateSkipIcons",SetFlag, (char **)CirculateSkipIcons, (int *)0}, #ifndef PRUNE {"NoTitle", SetOneStyle, (char **)&Scr.TheList, (int *)NOTITLE_FLAG}, {"NoBorder", SetOneStyle, (char **)&Scr.TheList, (int *)NOBORDER_FLAG}, {"Sticky", SetOneStyle, (char **)&Scr.TheList, (int *)STICKY_FLAG}, {"StaysOnTop", SetOneStyle, (char **)&Scr.TheList, (int *)STAYSONTOP_FLAG}, {"StartsOnDesk", SetOneStyle, (char **)&Scr.TheList, (int *)STAYSONDESK_FLAG}, {"CirculateSkip", SetOneStyle, (char **)&Scr.TheList, (int *)CIRCULATESKIP_FLAG}, {"WindowListSkip", SetOneStyle, (char **)&Scr.TheList, (int *)LISTSKIP_FLAG}, #endif {"Style", ParseStyle, (char **)0, (int *)0}, {"EdgeScroll", SetInts, (char **)&Scr.EdgeScrollX, &Scr.EdgeScrollY}, {"ButtonStyle", ButtonStyle, (char **)0, (int *)0}, {"RandomPlacement", SetFlag, (char **)RandomPlacement, (int *)0}, {"SmartPlacement", SetFlag, (char **)SMART_PLACEMENT, (int *)0}, #ifndef PRUNE {"SuppressIcons", SetFlag, (char **)SuppressIcons, (int *)0}, #endif {"DontMoveOff", SetFlag, (char **)DontMoveOff, (int *)0}, {"DecorateTransients",SetFlag, (char **)DecorateTransients, (int *)0}, {"CenterOnCirculate", SetFlag, (char **)CenterOnCirculate, (int *)0}, {"AutoRaise", SetInts, (char **)&Scr.AutoRaiseDelay,&dummy}, #ifndef NO_PAGER {"PagerBackColor", assign_string, &Pagerback, (int *)0}, {"PagerForeColor", assign_string, &Pagerfore, (int *)0}, {"PagerFont", assign_string, &Scr.PagerFont.name, (int *)0}, {"Pager", SetInts, (char **)&pager_x, &pager_y}, #endif {"DeskTopScale", SetInts, (char **)&Scr.VScale, &dummy}, {"DeskTopSize", SetInts, (char **)&Scr.VxMax, &Scr.VyMax}, {"ClickTime", SetInts, (char **)&Scr.ClickTime, &dummy}, {"OpaqueMove", SetInts, (char **)&Scr.OpaqueSize, &dummy}, #ifndef PRUNE {"BoundaryWidth", SetInts, (char **)&Scr.BoundaryWidth,&dummy}, {"NoBoundaryWidth", SetInts, (char **)&Scr.NoBoundaryWidth,&dummy}, #endif {"XorValue", SetInts, (char **)&XORvalue, &dummy}, {"Mouse", ParseMouseEntry,(char **)1, (int *)0}, {"Popup", ParsePopupEntry,(char **)1, (int *)0}, {"Function", ParsePopupEntry,(char **)1, (int *)0}, {"Key", ParseKeyEntry, (char **)1, (int *)0}, {"ClickToFocus", SetFlag, (char **)ClickToFocus,(int *)0}, {"SloppyFocus", SetFlag, (char **)SloppyFocus,(int *)0}, {"Cursor", SetCursor, (char **)0, (int *)0}, {"PagingDefault", SetInts, (char **)&DoHandlePageing, &dummy}, {"EdgeResistance", SetInts, (char **)&Scr.ScrollResistance, &Scr.MoveResistance}, {"BackingStore", SetFlag, (char **)BackingStore, (int *)0}, {"AppsBackingStore", SetFlag, (char **)AppsBackingStore, (int *)0}, {"SaveUnders", SetFlag, (char **)SaveUnders, (int *)0}, {"ModulePath", assign_string, &ModulePath, (int *)0}, #ifndef PRUNE {"Module", executeModule, (char **)0, (int *)0}, #endif {"", 0, (char **)0, (int *)0} }; struct config func_config[] = { {"Nop", set_func,(char **)F_NOP}, {"Title", set_func,(char **)F_TITLE}, {"Beep", set_func,(char **)F_BEEP}, {"Quit", set_func,(char **)F_QUIT}, {"Refresh", set_func,(char **)F_REFRESH}, {"Move", set_func,(char **)F_MOVE}, {"Iconify", set_func,(char **)F_ICONIFY}, {"Maximize", set_func,(char **)F_MAXIMIZE}, {"Resize", set_func,(char **)F_RESIZE}, {"RaiseLower", set_func,(char **)F_RAISELOWER}, {"Raise", set_func,(char **)F_RAISE}, {"Lower", set_func,(char **)F_LOWER}, {"Delete", set_func,(char **)F_DELETE}, {"Close", set_func,(char **)F_CLOSE}, {"Destroy", set_func,(char **)F_DESTROY}, {"PopUp", set_func,(char **)F_POPUP}, {"Function", set_func,(char **)F_FUNCTION}, {"CursorMove", set_func,(char **)F_MOVECURSOR}, {"Stick", set_func,(char **)F_STICK}, {"CirculateUp", set_func,(char **)F_CIRCULATE_UP}, {"CirculateDown",set_func,(char **)F_CIRCULATE_DOWN}, {"Wait", set_func,(char **)F_WAIT}, {"Warp", set_func,(char **)F_WARP}, {"Desk", set_func,(char **)F_DESK}, {"WindowsDesk", set_func,(char **)F_CHANGE_WINDOWS_DESK}, {"Focus", set_func,(char **)F_FOCUS}, {"Module", set_func,(char **)F_MODULE}, {"Quickie", set_func,(char **)F_QUICKIE}, {"Send_WindowList",set_func, (char **)F_SEND_WINDOW_LIST}, #ifndef NON_VIRTUAL {"Scroll", set_func,(char **)F_SCROLL}, {"GotoPage", set_func,(char **)F_GOTO_PAGE}, {"TogglePage", set_func,(char **)F_TOGGLE_PAGE}, #endif {"Exec", set_func,(char **)F_EXEC}, {"Restart", set_func,(char **)F_RESTART}, #ifndef NO_WINDOWLIST {"WindowList", set_func,(char **)F_WINDOWLIST}, #endif {"", 0,(char **)0} }; struct charstring { char key; int value; }; /* The keys musat be in lower case! */ struct charstring win_contexts[]= { {'w',C_WINDOW}, {'t',C_TITLE}, {'i',C_ICON}, {'r',C_ROOT}, {'f',C_FRAME}, {'s',C_SIDEBAR}, {'1',C_L1}, {'2',C_R1}, {'3',C_L2}, {'4',C_R2}, {'5',C_L3}, {'6',C_R3}, {'7',C_L4}, {'8',C_R4}, {'9',C_L5}, {'0',C_R5}, {'a',C_WINDOW|C_TITLE|C_ICON|C_ROOT|C_FRAME|C_SIDEBAR| C_L1|C_L2|C_L3|C_L4|C_L5|C_R1|C_R2|C_R3|C_R4|C_R5}, {0,0} }; /* The keys musat be in lower case! */ struct charstring key_modifiers[]= { {'s',ShiftMask}, {'c',ControlMask}, {'m',Mod1Mask}, {'1',Mod1Mask}, {'2',Mod2Mask}, {'3',Mod3Mask}, {'4',Mod4Mask}, {'5',Mod5Mask}, {'a',AnyModifier}, {'n',0}, {0,0} }; void find_context(char *, int *, struct charstring *); char *orig_tline; FILE *config_fd = (FILE *)0; /* we'll let modules get the fvwm_file that configuration was based on * for consistency */ char *fvwm_file; #ifdef M4 static char *m4_defs(Display*, const char*, char*, char*); #endif /***************************************************************************** * * This routine is responsible for reading and parsing the config file * ****************************************************************************/ void MakeMenus(const char *display_name, char *m4_options) { char *system_file = FVWMRC; char *home_file; char line[256],*tline; char *Home; /* the HOME environment variable */ int HomeLen; /* length of Home */ #ifdef M4 extern int m4_enable; #endif XORvalue = (((unsigned long) 1) << Scr.d_depth) - 1; Menuback = white; Menufore = black; Menustipple = grey; Stdback = white; Stdfore = black; Stickyback = NULL; Stickyfore = NULL; Hiback = white; Hifore = black; #ifndef NO_PAGER Pagerback = white; Pagerfore = black; #endif /* initialize some lists */ Scr.MouseButtonRoot = NULL; Scr.FuncKeyRoot.next = NULL; Scr.TheList = NULL; Scr.DefaultIcon = NULL; /* find the home directory to look in */ Home = getenv("HOME"); if (Home == NULL) Home = "./"; HomeLen = strlen(Home); if(config_file[0] == '/') { home_file = safemalloc(strlen(config_file)+1); strcpy(home_file,config_file); } else if(strncmp(config_file,"~/",2)==0) { home_file = safemalloc(HomeLen + strlen(&config_file[2])+3); strcpy(home_file,Home); strcat(home_file,"/"); strcat(home_file,&config_file[2]); } else { home_file = safemalloc(HomeLen+strlen(config_file)+3); strcpy(home_file,Home); strcat(home_file,"/"); strcat(home_file,config_file); } fvwm_file = home_file; config_fd = fopen(home_file,"r"); if(config_fd == (FILE *)NULL) { fvwm_file = system_file; config_fd = fopen(system_file,"r"); } if(config_fd == (FILE *)NULL) { fvwm_err("can't open %s or %s",system_file,home_file,NULL); exit(1); } if(fvwm_file != home_file) free(home_file); #ifdef M4 if (m4_enable) { extern void atexit_cleanup(void); /* * Process the config file through m4 and save the * results in a temp file. */ fvwm_file = m4_defs(dpy, display_name, m4_options, fvwm_file); fclose(config_fd); atexit(atexit_cleanup); /* we want to blow away /tmp file on quit */ config_fd = fopen(fvwm_file, "r"); if (config_fd == (FILE *) 0) { perror("Cannot open m4-processed config file\n"); exit(1); } } #endif /* M4 */ tline = fgets(line,(sizeof line)-1,config_fd); orig_tline = tline; while(tline != (char *)0) { while(isspace(*tline))tline++; if((strlen(&tline[0])>1)&&(tline[0]!='#')&&(tline[0]!='*')) match_string(main_config,tline,"error in config:",config_fd); tline = fgets(line,(sizeof line)-1,config_fd); orig_tline = tline; } fclose(config_fd); config_fd = (FILE *)NULL; /* If no edge scroll line is provided in the setup file, use * a default */ if(Scr.EdgeScrollX == -100000) Scr.EdgeScrollX = 25; if(Scr.EdgeScrollY == -100000) Scr.EdgeScrollY = Scr.EdgeScrollX; /* if edgescroll >1000 and < 100000m * wrap at edges of desktop (a "spherical" desktop) */ if (Scr.EdgeScrollX >= 1000) { Scr.EdgeScrollX /= 1000; Scr.flags |= EdgeWrapX; } if (Scr.EdgeScrollY >= 1000) { Scr.EdgeScrollY /= 1000; Scr.flags |= EdgeWrapY; } Scr.EdgeScrollX=Scr.EdgeScrollX*Scr.MyDisplayWidth/100; Scr.EdgeScrollY=Scr.EdgeScrollY*Scr.MyDisplayHeight/100; Scr.VxMax = Scr.VxMax*Scr.MyDisplayWidth - Scr.MyDisplayWidth; Scr.VyMax = Scr.VyMax*Scr.MyDisplayHeight - Scr.MyDisplayHeight; if(Scr.VxMax <0) Scr.VxMax = 0; if(Scr.VyMax <0) Scr.VyMax = 0; if (Scr.VxMax == 0) Scr.flags &= ~EdgeWrapX; if (Scr.VyMax == 0) Scr.flags &= ~EdgeWrapY; GetColors(); #ifndef NO_PAGER if(pager_x < 10000)initialize_pager(pager_x,pager_y); #endif return; } /***************************************************************************** * * Copies a text string from the config file to a specified location * ****************************************************************************/ void assign_string(char *text, FILE *fd, char **arg, int *junk) { *arg = stripcpy(text); } /***************************************************************************** * * Changes a button decoration style * ****************************************************************************/ void ButtonStyle(char *text, FILE *fd, char **arg,int *junk) { int button,w,h,n,num; char * letter=text; int offset,i; int num_coords; int *x_coords; int *y_coords; int *line_style; while(isspace(*letter))letter++; if (*letter == ':') /* signal for new data format */ { /* get button number */ num = sscanf(++letter,"%d%n",&button,&offset); if((num != 1)||(button>10)||(button<0)) { fvwm_err("Bad button style (1) in line %s",orig_tline,NULL,NULL); return; } if(button==10)button=0; /* get number of points */ text=offset+letter; num = sscanf(text,"%d%n",&num_coords,&offset); if((num != 1)||(num_coords>20)||(num_coords<2)) { fvwm_err("Bad button style (2) in line %s",orig_tline,NULL,NULL); return; } /* which arrays to use? */ n=button/2; if((n*2) == button) { /* right */ n = n - 1; if(n<0)n=4; Scr.right_num_coords[n] = num_coords; x_coords = Scr.right_x_coords[n]; y_coords = Scr.right_y_coords[n]; line_style = Scr.right_line_style[n]; } else { /* left */ Scr.left_num_coords[n] = num_coords; x_coords = Scr.left_x_coords[n]; y_coords = Scr.left_y_coords[n]; line_style = Scr.left_line_style[n]; } /* get the points */ for(i=0;i10)||(button<0))) { if(button==10)button=0; Scr.use_new_style[button] = False; } num = sscanf(text," %d %dx%d",&button, &w, &h); if((num != 3)||(button>10)||(button<0)) { fvwm_err("Bad button style in line %s",orig_tline,NULL,NULL); return; } /* allow button 10 as well as button 0 as definition for 10 */ if(button==10)button=0; n=button/2; if((n*2) == button) { n = n - 1; if(n<0)n=4; Scr.right_button_styles[0][n] = w; Scr.right_button_styles[1][n] = h; } else { Scr.left_button_styles[0][n] = w; Scr.left_button_styles[1][n] = h; } } /***************************************************************************** * * Changes a cursor def. * ****************************************************************************/ void SetCursor(char *text, FILE *fd, char **arg,int *junk) { int num,cursor_num,cursor_style; num = sscanf(text,"%d %d",&cursor_num, &cursor_style); if((num != 2)||(cursor_num >= MAX_CURSORS)||(cursor_num<0)) { fvwm_err("Bad cursor in line %s",orig_tline,NULL,NULL); return; } Scr.FvwmCursors[cursor_num] = XCreateFontCursor(dpy,cursor_style); } /***************************************************************************** * * Sets a boolean flag to true * ****************************************************************************/ void SetFlag(char *text, FILE *fd, char **arg,int *junk) { Scr.flags |= (unsigned long)arg; } /***************************************************************************** * * Reads in one or two integer values * ****************************************************************************/ void SetInts(char *text, FILE *fd, char **arg1, int *arg2) { sscanf(text,"%d%*c%d",(int *)arg1,(int *)arg2); } /***************************************************************************** * * Reads Dimensions for an icon box from the config file * ****************************************************************************/ void SetBox(char *text, FILE *fd, char **arg,int *junk) { int num; if(Scr.NumBoxes < MAX_BOXES) { /* Standard X11 geometry string */ num = sscanf(text,"%d%d%d%d",&Scr.IconBoxes[Scr.NumBoxes][0], &Scr.IconBoxes[Scr.NumBoxes][1], &Scr.IconBoxes[Scr.NumBoxes][2], &Scr.IconBoxes[Scr.NumBoxes][3]); /* check for negative locations */ if(Scr.IconBoxes[Scr.NumBoxes][0] < 0) Scr.IconBoxes[Scr.NumBoxes][0] += Scr.MyDisplayWidth; if(Scr.IconBoxes[Scr.NumBoxes][1] < 0) Scr.IconBoxes[Scr.NumBoxes][1] += Scr.MyDisplayHeight; if(Scr.IconBoxes[Scr.NumBoxes][2] < 0) Scr.IconBoxes[Scr.NumBoxes][2] += Scr.MyDisplayWidth; if(Scr.IconBoxes[Scr.NumBoxes][3] < 0) Scr.IconBoxes[Scr.NumBoxes][3] += Scr.MyDisplayHeight; if(num == 4) Scr.NumBoxes++; } } /**************************************************************************** * * This routine computes the shadow color from the background color * ****************************************************************************/ Pixel GetShadow(Pixel background) { XColor bg_color; XWindowAttributes attributes; unsigned int r,g,b; XGetWindowAttributes(dpy,Scr.Root,&attributes); bg_color.pixel = background; XQueryColor(dpy,attributes.colormap,&bg_color); r = bg_color.red % 0xffff; g = bg_color.green % 0xffff; b = bg_color.blue % 0xffff; r = r >>1; g = g >>1; b = b >>1; bg_color.red = r; bg_color.green = g; bg_color.blue = b; if(!XAllocColor(dpy,attributes.colormap,&bg_color)) { nocolor("alloc shadow",""); bg_color.pixel = background; } return bg_color.pixel; } /**************************************************************************** * * This routine computes the hilight color from the background color * ****************************************************************************/ Pixel GetHilite(Pixel background) { XColor bg_color, white_p; XWindowAttributes attributes; XGetWindowAttributes(dpy,Scr.Root,&attributes); bg_color.pixel = background; XQueryColor(dpy,attributes.colormap,&bg_color); white_p.pixel = GetColor(white); XQueryColor(dpy,attributes.colormap,&white_p); #ifndef min #define min(a,b) (((a)<(b)) ? (a) : (b)) #define max(a,b) (((a)>(b)) ? (a) : (b)) #endif bg_color.red = max((white_p.red/5), bg_color.red); bg_color.green = max((white_p.green/5), bg_color.green); bg_color.blue = max((white_p.blue/5), bg_color.blue); bg_color.red = min(white_p.red, (bg_color.red*140)/100); bg_color.green = min(white_p.green, (bg_color.green*140)/100); bg_color.blue = min(white_p.blue, (bg_color.blue*140)/100); #undef min #ifdef max #undef max #endif if(!XAllocColor(dpy,attributes.colormap,&bg_color)) { nocolor("alloc hilight",""); bg_color.pixel = background; } return bg_color.pixel; } /**************************************************************************** * * This routine loads all needed colors, and fonts, * and creates the GC's * ***************************************************************************/ #ifndef NO_PAGER Pixel PagerBackColor; Pixel PagerForeColor; #endif void GetColors(void) { extern MyFont *IconFont; if(have_the_colors) return; if(Stickyback == NULL) Stickyback = Stdback; if(Stickyfore == NULL) Stickyfore = Stdfore; have_the_colors = 1; /* setup default colors */ if(Scr.d_depth < 2) { /* black and white - override user choices */ Scr.MenuColors.back = GetColor(white); Scr.MenuColors.fore = GetColor(black); Scr.MenuStippleColors.back = GetColor(white); Scr.MenuStippleColors.fore = GetColor(black); Scr.MenuRelief.back = GetColor(black); Scr.MenuRelief.fore = GetColor(white); Scr.StdColors.back = GetColor(white); Scr.StdColors.fore = GetColor(black); Scr.StickyColors.back = GetColor(white); Scr.StickyColors.fore = GetColor(black); Scr.HiColors.back = GetColor(white); Scr.HiColors.fore = GetColor(black); Scr.StdRelief.back = GetColor(black); Scr.StdRelief.fore = GetColor(white); Scr.StickyRelief.back = GetColor(black); Scr.StickyRelief.fore = GetColor(white); Scr.HiRelief.back = GetColor(black); Scr.HiRelief.fore = GetColor(white); #ifndef NO_PAGER PagerBackColor = GetColor(white); PagerForeColor = GetColor(black); #endif } else { /* color - accept user choices */ Scr.MenuColors.back = GetColor(Menuback); Scr.MenuColors.fore = GetColor(Menufore); Scr.MenuStippleColors.back = GetColor(Menuback); Scr.MenuStippleColors.fore = GetColor(Menustipple); Scr.MenuRelief.back = GetShadow(Scr.MenuColors.back); Scr.MenuRelief.fore = GetHilite(Scr.MenuColors.back); Scr.StdColors.back = GetColor(Stdback); Scr.StdColors.fore = GetColor(Stdfore); Scr.StickyColors.back = GetColor(Stickyback); Scr.StickyColors.fore = GetColor(Stickyfore); Scr.HiColors.back = GetColor(Hiback); Scr.HiColors.fore = GetColor(Hifore); Scr.StdRelief.back = GetShadow(Scr.StdColors.back); Scr.StdRelief.fore = GetHilite(Scr.StdColors.back); Scr.StickyRelief.back = GetShadow(Scr.StickyColors.back); Scr.StickyRelief.fore = GetHilite(Scr.StickyColors.back); Scr.HiRelief.back = GetShadow(Scr.HiColors.back); Scr.HiRelief.fore = GetHilite(Scr.HiColors.back); #ifndef NO_PAGER PagerBackColor = GetColor(Pagerback); PagerForeColor = GetColor(Pagerfore); #endif } /* load the font */ if ((Scr.StdFont.font = XLoadQueryFont(dpy, Scr.StdFont.name)) == NULL) { nofont(Scr.StdFont.name); if ((Scr.StdFont.font = XLoadQueryFont(dpy, "fixed")) == NULL) exit(1); } Scr.StdFont.height = Scr.StdFont.font->ascent + Scr.StdFont.font->descent; Scr.StdFont.y = Scr.StdFont.font->ascent; Scr.EntryHeight = Scr.StdFont.height + HEIGHT_EXTRA; /* load the window-title font */ if ((Scr.WindowFont.font = XLoadQueryFont(dpy, Scr.WindowFont.name)) == NULL) { nofont(Scr.WindowFont.name); if ((Scr.WindowFont.font = XLoadQueryFont(dpy, "fixed")) == NULL) exit(1); } Scr.WindowFont.height= Scr.WindowFont.font->ascent+Scr.WindowFont.font->descent; Scr.WindowFont.y = Scr.WindowFont.font->ascent; /* load the pager-label font */ #ifndef NO_PAGER if(Scr.PagerFont.name != NULL) { if ((Scr.PagerFont.font = XLoadQueryFont(dpy, Scr.PagerFont.name))!=NULL) { Scr.PagerFont.height= Scr.PagerFont.font->ascent+Scr.PagerFont.font->descent; Scr.PagerFont.y = Scr.PagerFont.font->ascent; } else nofont(Scr.PagerFont.name); } #endif IconFont = &Scr.StdFont; if(Scr.IconFont.name != NULL) { if ((Scr.IconFont.font = XLoadQueryFont(dpy, Scr.IconFont.name))!=NULL) { Scr.IconFont.height= Scr.IconFont.font->ascent+Scr.IconFont.font->descent; Scr.IconFont.y = Scr.IconFont.font->ascent; IconFont = &Scr.IconFont; } else nofont(Scr.IconFont.name); } /* create graphics contexts */ CreateGCs(); XSync(dpy,0); return; } /**************************************************************************** * * Prints an error message for font loading * ****************************************************************************/ void nofont(char *name) { fvwm_err("can't get font %s", name,NULL,NULL); } /**************************************************************************** * * Processes a menu body definition * ****************************************************************************/ MenuRoot *ParseMenuBody(char *name,FILE *fd) { MenuRoot *mr; char newline[256]; register char *pline; char unit_1,unit_2; int n; pline = fgets(newline,(sizeof newline)-1,fd); orig_tline = pline; if (pline == NULL) return 0; mr = NewMenuRoot(name); GetColors(); while(isspace(*pline))pline++; while((pline != (char *)0) &&(mystrncasecmp("End",pline,3)!=0)) { if((*pline!='#')&&(*pline != 0)&&(*pline!='*')) { char *ptr2 = 0; match_string(func_config,pline, "bad menu body function:",fd); if((func == F_EXEC)||(func == F_POPUP)||(func == F_RESTART) ||(func == F_FUNCTION)||(func == F_MODULE)) ptr2=stripcpy3(pline,True); else ptr2=stripcpy3(pline,False); func_val_1 = 0; func_val_2 = 0; unit_1 = 's'; unit_2 = 's'; if(ptr2 != NULL) { n = sscanf(ptr2,"%d %d",&func_val_1,&func_val_2); if( n < 2) n = sscanf(ptr2,"%d%c %d%c",&func_val_1,&unit_1,&func_val_2,&unit_2); } AddToMenu(mr, stripcpy2(pline,1,True), stripcpy2(pline,2,True), ptr2, func,func_val_1,func_val_2, unit_1, unit_2); } pline = fgets(newline,(sizeof newline)-1,fd); if(pline == (char *)0)return NULL; orig_tline = pline; while(isspace(*pline))pline++; } MakeMenu(mr); return mr; } /**************************************************************************** * * Parses a popup definition * ****************************************************************************/ void ParsePopupEntry(char *tline,FILE *fd, char **junk,int *junk2) { MenuRoot *mr=0; mr = ParseMenuBody(stripcpy2(tline,0,True),fd); if (PopupCount < MAXPOPUPS) { PopupTable[PopupCount] = mr; PopupCount++; if(strcmp(mr->name,"InitFunction")==0) { Scr.InitFunction = mr; } else if(strcmp(mr->name,"RestartFunction")==0) { Scr.RestartFunction = mr; } } else { fprintf(stderr,"Popup/Function %s ignored, you have more than %u\n", mr->name,MAXPOPUPS); free(mr); } } /**************************************************************************** * * Parses a mouse binding * ****************************************************************************/ void ParseMouseEntry(char *tline,FILE *fd, char **junk,int *junk2) { char context[256],modifiers[256],function[256],*ptr; MenuRoot *mr=0; MenuItem *mi=0; MouseButton *temp; int button,i,j; int n; char unit_1, unit_2; unit_1 = 's'; unit_2 = 's'; func_val_1 = 0; func_val_2 = 0; n = sscanf(tline,"%d %s %s %s %d %d",&button,context,modifiers,function, &func_val_1,&func_val_2); if(n < 6) n = sscanf(tline,"%d %s %s %s %d%c %d%c",&button,context,modifiers,function, &func_val_1,&unit_1,&func_val_2,&unit_2); find_context(context,&contexts,win_contexts); if((contexts != C_ALL) && (contexts & C_LALL)) { /* check for nr_left_buttons */ i=0; j=(contexts &C_LALL)/C_L1; while(j>0) { i++; j=j>>1; } if(Scr.nr_left_buttons 0) { i++; j=j>>1; } if(Scr.nr_right_buttons name,ptr) == 0) { mr = PopupTable[i]; break; } if (!mr) { no_popup(ptr); func = F_NOP; } if(ptr != NULL) free(ptr); } else if((func == F_EXEC)||(func == F_RESTART)|| (func == F_CIRCULATE_UP)||(func == F_CIRCULATE_DOWN)|| (func == F_WARP)||(func == F_MODULE)) { mi = (MenuItem *)safemalloc(sizeof(MenuItem)); mi->next = (MenuItem *)NULL; mi->prev = (MenuItem *)NULL; mi->item_num = 0; if((func == F_EXEC)||(func == F_RESTART)||(func== F_MODULE)) { mi->item = stripcpy2(tline,0,True); mi->action = stripcpy3(tline,True); } else { mi->item = stripcpy2(tline,0,False); mi->action = stripcpy3(tline,False); } mi->state = 0; mi->func = func; mi->strlen = strlen(mi->item); mi->val1 = 0; mi->val2 = 0; mi->val1_unit = 1; mi->val2_unit = 1; } temp = Scr.MouseButtonRoot; Scr.MouseButtonRoot = (MouseButton *)safemalloc(sizeof(MouseButton)); Scr.MouseButtonRoot->func = func; Scr.MouseButtonRoot->menu = mr; Scr.MouseButtonRoot->item = mi; Scr.MouseButtonRoot->Button = button; Scr.MouseButtonRoot->Context = contexts; Scr.MouseButtonRoot->Modifier = mods; Scr.MouseButtonRoot->NextButton = temp; Scr.MouseButtonRoot->val1 = func_val_1; Scr.MouseButtonRoot->val2 = func_val_2; if((unit_1 == 'p')||(unit_1 == 'P')) Scr.MouseButtonRoot->val1_unit = 100; else Scr.MouseButtonRoot->val1_unit = Scr.MyDisplayWidth; if((unit_2 == 'p')||(unit_2 == 'P')) Scr.MouseButtonRoot->val2_unit = 100; else Scr.MouseButtonRoot->val2_unit = Scr.MyDisplayHeight; return; } void no_popup(char *ptr) { if((ptr)&&(orig_tline)) fprintf(stderr,"Popup '%s' not defined in line %s",ptr,orig_tline); } /**************************************************************************** * * Processes a line with a key binding * ****************************************************************************/ void ParseKeyEntry(char *tline, FILE *fd,char **junk,int *junk2) { char context[256],modifiers[256],function[256],*ptr; char name[256]; MenuRoot *mr = 0; char unit_1, unit_2; int n; ptr = NULL; func_val_1 = 0; func_val_2 = 0; unit_1 = 's'; unit_2 = 's'; n = sscanf(tline,"%s %s %s %s %d %d",name,context,modifiers,function, &func_val_1,&func_val_2); if(n < 6) n = sscanf(tline,"%s %s %s %s %d%c %d%c",name,context,modifiers,function, &func_val_1,&unit_1,&func_val_2,&unit_2); find_context(context,&contexts,win_contexts); find_context(modifiers,&mods,key_modifiers); match_string(func_config,function,"bad key function:",fd); /* Make CirculateUp and CirculateDown take args. by Y.NOMURA */ if ((func == F_CIRCULATE_UP) || (func == F_CIRCULATE_DOWN)|| (func == F_WARP)) ptr = stripcpy3(tline,False); /* End of addition */ if((func == F_EXEC)||(func == F_RESTART)||(func == F_MODULE)) { ptr = stripcpy3(tline,True); } else if((func == F_POPUP)||(func == F_FUNCTION)) { unsigned i; ptr = stripcpy2(tline,0,True); if(ptr != NULL) { for (i = 0; i < PopupCount; i++) if (mystrcasecmp(PopupTable[i]->name,ptr) == 0) { mr = PopupTable[i]; break; } } if (!mr) { no_popup(ptr); func = F_NOP; } } AddFuncKey(name,contexts,mods,func,ptr,func_val_1,func_val_2,mr, unit_1,unit_2); } /**************************************************************************** * * Sets menu/keybinding/mousebinding function to specified value * ****************************************************************************/ void set_func(char *text, FILE *fd, char **value,int *junk) { func = (unsigned long)value; } /**************************************************************************** * * Turns a string context of context or modifier values into an array of * true/false values (bits) * ****************************************************************************/ void find_context(char *string, int *output, struct charstring *table) { int i=0,j=0; Bool matched; char tmp1; *output=0; i=0; while(i0)) { if(mystrncasecmp(text,table[j].keyword,strlen(table[j].keyword))==0) { matched=TRUE; /* found key word */ table[j].action(&text[strlen(table[j].keyword)], fd,table[j].arg,table[j].arg2); } else j++; } if(!matched) { fvwm_err("%s %s in line %s",error_msg,text,orig_tline); } } /**************************************************************************** * * Generates the window for a menu * ****************************************************************************/ void MakeMenu(MenuRoot *mr) { MenuItem *cur; unsigned long valuemask; XSetWindowAttributes attributes; int y; /* lets first size the window accordingly */ mr->width += 10; if(mr->width2 > 0) mr->width += 5; /* allow two pixels for top border */ for (y=2, cur = mr->first; cur != NULL; cur = cur->next) { cur->y_offset = y; cur->x = 5; if(cur->func==F_TITLE) { /* Title */ if(cur->strlen2 == 0) cur->x = (mr->width - XTextWidth(Scr.StdFont.font, cur->item, cur->strlen))>>1; if(Scr.flags & MWMMenus) cur->y_height = Scr.EntryHeight + HEIGHT_EXTRA_TITLE; else { if((cur == mr->first)||(cur->next == NULL)) cur->y_height=Scr.EntryHeight-HEIGHT_EXTRA+1+ (HEIGHT_EXTRA_TITLE>>1); else cur->y_height = Scr.EntryHeight -HEIGHT_EXTRA +1+ HEIGHT_EXTRA_TITLE; } } else if(cur->func==F_NOP && *cur->item==0) /* Separator */ cur->y_height = HEIGHT_SEPARATOR; else /* Normal text entry */ cur->y_height = Scr.EntryHeight; y += cur->y_height; if(mr->width2 == 0) { cur->x2 = cur->x; } else { cur->x2 = mr->width -5; } } mr->in_use = 0; mr->height = y+2; #ifndef NO_SAVEUNDERS valuemask = (CWBackPixel | CWEventMask | CWCursor | CWSaveUnder); #else valuemask = (CWBackPixel | CWEventMask | CWCursor); #endif attributes.background_pixel = Scr.MenuColors.back; attributes.event_mask = (ExposureMask | EnterWindowMask); attributes.cursor = Scr.FvwmCursors[MENU]; #ifndef NO_SAVEUNDERS attributes.save_under = TRUE; #endif mr->width = mr->width + mr->width2; mr->w = XCreateWindow (dpy, Scr.Root, 0, 0, (unsigned int) (mr->width), (unsigned int) mr->height, (unsigned int) 0, CopyFromParent, (unsigned int) InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XSaveContext(dpy,mr->w,MenuContext,(caddr_t)mr); return; } /*********************************************************************** * Procedure: * scanForHotkeys - Look for hotkey markers in a MenuItem * (pete@tecc.co.uk) * * Inputs: * it - MenuItem to scan * which - +1 to look in it->item1 and -1 to look in it->item2. * ***********************************************************************/ void scanForHotkeys(MenuItem *it, int which) { char *start, *txt; start = (which > 0) ? it->item : it->item2; /* Get start of string */ for (txt = start; *txt != '\0'; txt++) { /* Scan whole string */ if (*txt == '&') { /* A hotkey marker? */ if (txt[1] == '&') { /* Just an escaped & */ char *tmp; /* Copy the string down over it */ for (tmp = txt; *tmp != '\0'; tmp++) tmp[0] = tmp[1]; continue; /* ...And skip to the key char */ } /* It's a hot key marker - work out the offset value */ it->hotkey = (1 + (txt - start)) * which; for (; *txt != '\0'; txt++) txt[0] = txt[1]; /* Copy down.. */ return; /* Only one hotkey per item... */ } } it->hotkey = 0; /* No hotkey found. Set offset to zero */ } /*********************************************************************** * * Procedure: * AddToMenu - add an item to a root menu * * Returned Value: * (MenuItem *) * * Inputs: * menu - pointer to the root menu to add the item * item - the text to appear in the menu * action - the string to possibly execute * func - the numeric function * ***********************************************************************/ void AddToMenu(MenuRoot *menu, char *item, char *item2, char *action,int func, long func_val_1,long func_val_2, char unit_1, char unit_2) { MenuItem *tmp; int width; if(item == NULL) return; tmp = (MenuItem *)safemalloc(sizeof(MenuItem)); if (menu->first == NULL) { menu->first = tmp; tmp->prev = NULL; } else { menu->last->next = tmp; tmp->prev = menu->last; } menu->last = tmp; tmp->item = item; if (item != (char *)0) { scanForHotkeys(tmp, 1); /* pete@tecc.co.uk */ tmp->strlen = strlen(item); } else tmp->strlen = 0; tmp->item2 = item2; if (item2 != (char *)0) { if (tmp->hotkey == 0) scanForHotkeys(tmp, -1); /* pete@tecc.co.uk */ tmp->strlen2 = strlen(item2); } else tmp->strlen2 = 0; tmp->menu = 0; if((func == F_POPUP)||(func == F_FUNCTION)) { unsigned i; if(action != (char *)0) { for (i = 0; i < PopupCount; i++) if (mystrcasecmp(PopupTable[i]->name,action) == 0) { tmp->menu = PopupTable[i]; break; } } if(tmp->menu == (MenuRoot *)0) { no_popup(action); func = F_NOP; } } tmp->action = action; tmp->next = NULL; tmp->state = 0; tmp->func = func; tmp->val1 = func_val_1; tmp->val2 = func_val_2; if((unit_1 == 'p')||(unit_1 == 'P')) tmp->val1_unit = 100; else tmp->val1_unit = Scr.MyDisplayWidth; if((unit_2 == 'p')||(unit_2 == 'P')) tmp->val2_unit = 100; else tmp->val2_unit = Scr.MyDisplayHeight; width = XTextWidth(Scr.StdFont.font, item, tmp->strlen); if(tmp->func == F_POPUP) width += 15; if (width <= 0) width = 1; if (width > menu->width) menu->width = width; width = XTextWidth(Scr.StdFont.font, item2, tmp->strlen2); if (width < 0) width = 0; if (width > menu->width2) menu->width2 = width; if((width==0)&&(tmp->strlen2>0)) menu->width2 = 1; tmp->item_num = menu->items++; } /*********************************************************************** * * Procedure: * NewMenuRoot - create a new menu root * * Returned Value: * (MenuRoot *) * * Inputs: * name - the name of the menu root * ***********************************************************************/ MenuRoot *NewMenuRoot(char *name) { MenuRoot *tmp; tmp = (MenuRoot *) safemalloc(sizeof(MenuRoot)); tmp->name = name; tmp->first = NULL; tmp->last = NULL; tmp->items = 0; tmp->width = 0; tmp->width2 = 0; tmp->w = None; return (tmp); } /*********************************************************************** * * Procedure: * AddFuncKey - add a function key to the list * * Inputs: * name - the name of the key * cont - the context to look for the key press in * mods - modifier keys that need to be pressed * func - the function to perform * action - the action string associated with the function (if any) * ***********************************************************************/ void AddFuncKey (char *name, int cont, int mods, int func, char *action, int val1, int val2,MenuRoot *mr, char unit_1, char unit_2) { FuncKey *tmp; KeySym keysym; KeyCode keycode; int i, min, max; /* * Don't let a 0 keycode go through, since that means AnyKey to the * XGrabKey call in GrabKeys(). */ if ((keysym = XStringToKeysym(name)) == NoSymbol || (keycode = XKeysymToKeycode(dpy, keysym)) == 0) return; XDisplayKeycodes(dpy, &min, &max); for (i=min; i<=max; i++) if (XKeycodeToKeysym(dpy, i, 0) == keysym) { tmp = (FuncKey *) safemalloc(sizeof(FuncKey)); tmp->next = Scr.FuncKeyRoot.next; Scr.FuncKeyRoot.next = tmp; tmp->name = name; tmp->keycode = i; tmp->cont = cont; tmp->mods = mods; tmp->func = func; tmp->action = action; tmp->val1 = val1; tmp->val2 = val2; if((unit_1 == 'p')||(unit_1 == 'P')) tmp->val1_unit = 100; else tmp->val1_unit = Scr.MyDisplayWidth; if((unit_2 == 'p')||(unit_2 == 'P')) tmp->val2_unit = 100; else tmp->val2_unit = Scr.MyDisplayHeight; tmp->menu = mr; } return; } /**************************************************************************** * * Loads a single color * ****************************************************************************/ Pixel GetColor(char *name) { XColor color; XWindowAttributes attributes; XGetWindowAttributes(dpy,Scr.Root,&attributes); color.pixel = 0; if (!XParseColor (dpy, attributes.colormap, name, &color)) { nocolor("parse",name); } else if(!XAllocColor (dpy, attributes.colormap, &color)) { nocolor("alloc",name); } return color.pixel; } void nocolor(char *note, char *name) { fvwm_err("can't %s color %s", note,name,NULL); } /**************************************************************************** * * Copies a string into a new, malloc'ed string * Strips leading spaces and trailing spaces and new lines * ****************************************************************************/ char *stripcpy(char *source) { char *tmp,*ptr; int len; while(isspace(*source)) source++; len = strlen(source); tmp = source + len -1; while(((isspace(*tmp))||(*tmp == '\n'))&&(tmp >=source)) { tmp--; len--; } ptr = safemalloc(len+1); strncpy(ptr,source,len); ptr[len]=0; return ptr; } /**************************************************************************** * * Copies a string into a new, malloc'ed string * Strips all data before the first quote and after the second * ****************************************************************************/ char *stripcpy2(char *source, int tab_sensitive, Bool error) { char *ptr; int count; while((*source != '"')&&(*source != 0)) source++; if(*source == 0) { if(error) bad_binding(2); return 0; } source++; ptr = source; count = 0; if(!tab_sensitive) while((*ptr!='"')&&(*ptr != 0)) { ptr++; count++; } else if(tab_sensitive==1) while((*ptr!='"')&&(*ptr != 0)&&(*ptr!='\t')) { ptr++; count++; } else if(tab_sensitive==2) { while((*ptr!='"')&&(*ptr != 0)&&(*ptr!='\t')) { source++; ptr++; } if((*ptr!='"')&&(*ptr != 0)) { ptr++; source++; } while((*ptr!='"')&&(*ptr != 0)) { ptr++; count++; } } ptr = safemalloc(count+1); strncpy(ptr,source,count); ptr[count]=0; return ptr; } /**************************************************************************** * * Copies a string into a new, malloc'ed string * Strips all data before the second quote. and strips trailing spaces and * new lines * ****************************************************************************/ char *stripcpy3(char *source,Bool Warn) { while((*source != '"')&&(*source != 0)) source++; if(*source != 0) source++; while((*source != '"')&&(*source != 0)) source++; if(*source == 0) { if(Warn)bad_binding(3); return 0; } source++; return stripcpy(source); } void bad_binding(int num) { fvwm_err("bad binding in line %s",orig_tline,NULL,NULL); return; } /*********************************************************************** * * Procedure: * CreateGCs - open fonts and create all the needed GC's. I only * want to do this once, hence the first_time flag. * ***********************************************************************/ void CreateGCs(void) { XGCValues gcv; unsigned long gcm; /* create GC's */ gcm = GCFunction|GCLineWidth|GCForeground|GCSubwindowMode; gcv.function = GXxor; gcv.line_width = 0; gcv.foreground = XORvalue; gcv.subwindow_mode = IncludeInferiors; Scr.DrawGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcm = GCFunction|GCPlaneMask|GCGraphicsExposures|GCLineWidth|GCForeground| GCBackground|GCFont; gcv.line_width = 0; gcv.function = GXcopy; gcv.plane_mask = AllPlanes; gcv.foreground = Scr.StdColors.fore; gcv.background = Scr.StdColors.back; gcv.font = Scr.StdFont.font->fid; /* * Prevent GraphicsExpose and NoExpose events. We'd only get NoExpose * events anyway; they cause BadWindow errors from XGetWindowAttributes * call in FindScreenInfo (events.c) (since drawable is a pixmap). */ gcv.graphics_exposures = False; Scr.NormalGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); /* GC for pager labels */ Scr.FontGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.fill_style = FillStippled; gcv.stipple = Scr.gray_bitmap; gcm = GCFunction|GCPlaneMask|GCGraphicsExposures|GCLineWidth|GCForeground| GCBackground|GCFont|GCStipple|GCFillStyle; Scr.StippleGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcm = GCFunction|GCPlaneMask|GCGraphicsExposures|GCLineWidth|GCForeground| GCBackground|GCFont; gcv.foreground = Scr.HiRelief.fore; gcv.background = Scr.HiRelief.back; gcv.fill_style = FillSolid; Scr.HiReliefGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.HiRelief.back; gcv.background = Scr.HiRelief.fore; Scr.HiShadowGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.MenuColors.fore; gcv.background = Scr.MenuColors.back; Scr.MenuGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); if(Scr.d_depth < 2) { gcv.fill_style = FillStippled; gcv.stipple = Scr.gray_bitmap; gcm=GCFunction|GCPlaneMask|GCGraphicsExposures|GCLineWidth|GCForeground| GCBackground|GCFont|GCStipple|GCFillStyle; Scr.MenuStippleGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcm=GCFunction|GCPlaneMask|GCGraphicsExposures|GCLineWidth|GCForeground| GCBackground|GCFont; gcv.fill_style = FillSolid; } else { gcv.foreground = Scr.MenuStippleColors.fore; gcv.background = Scr.MenuStippleColors.back; Scr.MenuStippleGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); } gcv.foreground = Scr.MenuRelief.fore; gcv.background = Scr.MenuRelief.back; Scr.MenuReliefGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.MenuRelief.back; gcv.background = Scr.MenuRelief.fore; Scr.MenuShadowGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.StdRelief.fore; gcv.background = Scr.StdRelief.back; Scr.StdReliefGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); Scr.ScratchGC1 = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.StdRelief.back; gcv.background = Scr.StdRelief.fore; Scr.StdShadowGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); Scr.ScratchGC2 = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.StickyRelief.fore; gcv.background = Scr.StickyRelief.back; Scr.StickyReliefGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); gcv.foreground = Scr.StickyRelief.back; gcv.background = Scr.StickyRelief.fore; Scr.StickyShadowGC = XCreateGC(dpy, Scr.Root, gcm, &gcv); } /*********************************************************************** * * Procedure: * SetOneStyle - add a window name to the no title list * * Inputs: * name - a pointer to the name of the window * ***********************************************************************/ #ifndef PRUNE void SetOneStyle(char *text, FILE *fd, char **list, int *junk) { char *name; unsigned long new_flags; char *icon_name = NULL; int desknumber = 0; new_flags = (unsigned long)junk; /* first, see if an entry for this name exists */ if((new_flags & ICON_FLAG) || (new_flags & STAYSONDESK_FLAG)) name = stripcpy2(text,FALSE,TRUE); else name = stripcpy(text); /* in case there was no argument! */ if(name == NULL) return; /* capture default icons */ if(strlen(name) == 0) { if(new_flags & ICON_FLAG) Scr.DefaultIcon = stripcpy3(text,TRUE); free(name); return; } if(new_flags & ICON_FLAG) { icon_name = stripcpy3(text,TRUE); } else if (new_flags & STAYSONDESK_FLAG) { char *p = stripcpy3(text,TRUE); desknumber = atoi (p); free (p); } AddToList(name,icon_name,new_flags,0,desknumber,0,0,NULL,NULL,0,0); } #endif #ifdef M4 /* For m4... */ #include #include #include #include #include /* Code taken and munged from xrdb.c */ #define MAXHOSTNAME 255 #define Resolution(pixels, mm) ((((pixels) * 100000 / (mm)) + 50) / 100) /* EXTRA should be the length of the strings "define(" + ", ``" + "'')dnl\n". */ #define EXTRA 50 extern int m4_prefix; extern char m4_prog[]; extern int m4_default_quotes; extern char m4_startquote[]; extern char m4_endquote[]; static char *MkDef(char *name, char *def) { static char *cp = NULL; static int maxsize = 0; int n; /* The char * storage only lasts for 1 call... */ /* Get space to hold everything, if needed */ n = EXTRA + strlen(name) + strlen(def); if (n > maxsize) { maxsize = n; if (cp == NULL) { cp = malloc(n); } else { cp = realloc(cp, n); } } if (cp == NULL) { perror("MkDef can't allocate enough space for a macro definition"); exit(0377); } /* Create the macro definition, using the appropriate prefix, if any */ if (m4_prefix) { strcpy(cp, "m4_define("); } else strcpy(cp, "define("); strcat(cp, name); /* Tack on "," and 2 sets of starting quotes */ strcat(cp, ","); strcat(cp, m4_startquote); strcat(cp, m4_startquote); /* The definition itself */ strcat(cp, def); /* Add 2 sets of closing quotes */ strcat(cp, m4_endquote); strcat(cp, m4_endquote); /* End the definition, appropriately */ strcat(cp, ")"); if (m4_prefix) { strcat(cp, "m4_"); } strcat(cp, "dnl\n"); return(cp); } static char *MkNum(char *name,int def) { char num[20]; sprintf(num, "%d", def); return(MkDef(name, num)); } static char *m4_defs(Display *display, const char *host, char *m4_options, char *config_file) { Screen *screen; Visual *visual; char client[MAXHOSTNAME], server[MAXHOSTNAME], *colon; char ostype[BUFSIZ]; char options[BUFSIZ]; static char tmp_name[BUFSIZ]; struct hostent *hostname; char *vc; /* Visual Class */ FILE *tmpf; struct passwd *pwent; int fd; /* Generate a temporary filename. Honor the TMPDIR environment variable, if set. Hope nobody deletes this file! */ if ((vc=getenv("TMPDIR"))) { strcpy(tmp_name, vc); } else { strcpy(tmp_name, "/tmp"); } strcat(tmp_name, "/fvwmrcXXXXXX"); vc = mktemp(tmp_name); if (vc == NULL) { perror("mktemp failed in m4_defs"); exit(0377); } if ((fd = open(tmp_name, O_WRONLY|O_EXCL|O_CREAT, 0600)) < 0) { perror("exclusive open for tmp_name failed in m4_defs"); exit(0377); } close(fd); /* * Create the appropriate command line to run m4, and * open a pipe to the command. */ sprintf(options, "%s %s %s > %s\n", m4_prog, ((m4_prefix == 0) ? "" : "--prefix-builtins"), m4_options, tmp_name); tmpf = popen(options, "w"); if (tmpf == NULL) { perror("Cannot open pipe to m4"); exit(0377); } mygethostname(client,MAXHOSTNAME); mygetostype (ostype, sizeof ostype); /* Change the quoting characters, if specified */ if (!m4_default_quotes) { fprintf(tmpf, "changequote(%s, %s)dnl\n", m4_startquote, m4_endquote); } hostname = gethostbyname(client); strcpy(server, XDisplayName(host)); colon = strchr(server, ':'); if (colon != NULL) *colon = '\0'; if ((server[0] == '\0') || (!strcmp(server, "unix"))) strcpy(server, client); /* must be connected to :0 or unix:0 */ /* TWM_TYPE is fvwm, for completeness */ fputs(MkDef("TWM_TYPE", "fvwm"), tmpf); /* The machine running the X server */ fputs(MkDef("SERVERHOST", server), tmpf); /* The machine running the window manager process */ fputs(MkDef("CLIENTHOST", client), tmpf); if (hostname) fputs(MkDef("HOSTNAME", (char *)hostname->h_name), tmpf); else fputs(MkDef("HOSTNAME", (char *)client), tmpf); fputs(MkDef("OSTYPE", ostype), tmpf); pwent=getpwuid(geteuid()); fputs(MkDef("USER", pwent->pw_name), tmpf); fputs(MkDef("HOME", getenv("HOME")), tmpf); fputs(MkNum("VERSION", ProtocolVersion(display)), tmpf); fputs(MkNum("REVISION", ProtocolRevision(display)), tmpf); fputs(MkDef("VENDOR", ServerVendor(display)), tmpf); fputs(MkNum("RELEASE", VendorRelease(display)), tmpf); screen = ScreenOfDisplay(display, Scr.screen); visual = DefaultVisualOfScreen(screen); fputs(MkNum("WIDTH", Scr.MyDisplayWidth), tmpf); fputs(MkNum("HEIGHT", Scr.MyDisplayHeight), tmpf); fputs(MkNum("X_RESOLUTION",Resolution(screen->width,screen->mwidth)),tmpf); fputs(MkNum("Y_RESOLUTION",Resolution(screen->height,screen->mheight)),tmpf); fputs(MkNum("PLANES",DisplayPlanes(display, Scr.screen)), tmpf); fputs(MkNum("BITS_PER_RGB", visual->bits_per_rgb), tmpf); switch(visual->class) { case(StaticGray): vc = "StaticGray"; break; case(GrayScale): vc = "GrayScale"; break; case(StaticColor): vc = "StaticColor"; break; case(PseudoColor): vc = "PseudoColor"; break; case(TrueColor): vc = "TrueColor"; break; case(DirectColor): vc = "DirectColor"; break; default: vc = "NonStandard"; break; } fputs(MkDef("CLASS", vc), tmpf); if (visual->class != StaticGray && visual->class != GrayScale) fputs(MkDef("COLOR", "Yes"), tmpf); else fputs(MkDef("COLOR", "No"), tmpf); fputs(MkDef("FVWM_VERSION", VERSION), tmpf); /* Add options together */ *options = '\0'; #ifdef SHAPE strcat(options, "SHAPE "); #endif #ifdef XPM strcat(options, "XPM "); #endif strcat(options, "M4 "); #ifdef NO_PAGER strcat(options, "NO_PAGER "); #endif #ifdef NON_VIRTUAL strcat(options, "NON_VIRTUAL "); #endif #ifdef NO_SAVEUNDERS strcat(options, "NO_SAVEUNDERS "); #endif #ifdef NO_WINDOWLIST strcat(options, "NO_WINDOWLIST "); #endif #ifdef PRUNE strcat(options, "PRUNE "); #endif fputs(MkDef("OPTIONS", options), tmpf); fputs(MkDef("FVWMDIR", FVWMDIR), tmpf); /* * At this point, we've sent the definitions to m4. Just include * the fvwmrc file now. */ fprintf(tmpf, "%sinclude(%s%s%s)\n", (m4_prefix) ? "m4_": "", m4_startquote, config_file, m4_endquote); pclose(tmpf); return(tmp_name); } #endif /* M4 */