/* FvwmIconBox Module --- Copyright 1994, 1995 Nobutaka Suzuki. * * No guarantees or warantees or anything are provided or implied in * any way whatsoever. Use this program at your own risk. Permission * to use this program for any purpose is given, as long as the * copyright is kept intact. * * The functions based on part of GoodStuff, FvwmScroll, FvwmWinList * and Fvwm are noted by a small copyright atop that function. * Full original copyright is described in COPYRIGHT. */ #define TRUE 1 #define FALSE 0 #define NONE 0 #define VERTICAL 1 #define HORIZONTAL 2 #include "config.h" #ifdef HAVE_SYS_BSDTYPES_H #include /* Saul */ #endif #include #include #include #include #include #include #if HAVE_SYS_SELECT_H #include #endif #include #include #include #include "../../fvwm/module.h" #include #include #include #include #include #ifdef SHAPE #include #endif /* SHAPE */ /* just as same as wild.c */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #include "FvwmIconBox.h" char *MyName; XFontStruct *font; Display *dpy; /* which display are we talking to */ int x_fd,fd_width; Window Root; int screen; int d_depth; char *Back = "#5f9ea0"; char *Fore = "#82dfe3"; char *IconBack = "#cfcfcf"; char *IconFore = "black"; char *ActIconBack = "white"; char *ActIconFore = "black"; char *font_string = "fixed"; /* same strings as in misc.c */ char NoClass[] = "NoClass"; char NoResource[] = "NoResource"; Pixel fore_pix, hilite_pix, back_pix, shadow_pix; Pixel icon_fore_pix, icon_back_pix, icon_hilite_pix, icon_shadow_pix; Pixel act_icon_fore_pix, act_icon_back_pix, act_icon_hilite_pix, act_icon_shadow_pix; GC NormalGC,ShadowGC,ReliefGC,IconShadowGC,IconReliefGC; Window main_win; Window holder_win; Window icon_win; Window h_scroll_bar; Window v_scroll_bar; Window l_button, r_button, t_button, b_button; Window Pressed = None; long CurrentDesk; int Width, Height; int UWidth, UHeight; #define MW_EVENTS (KeyPressMask| ExposureMask | StructureNotifyMask|\ ButtonReleaseMask | ButtonPressMask ) #define SCROLL_EVENTS (ExposureMask | StructureNotifyMask|\ ButtonReleaseMask |ButtonPressMask | PointerMotionMask) #define BUTTON_EVENTS (ExposureMask | StructureNotifyMask|\ ButtonReleaseMask | ButtonPressMask |\ LeaveWindowMask | PointerMotionMask) unsigned long m_mask = M_CONFIGURE_WINDOW|M_ADD_WINDOW|M_DESTROY_WINDOW| M_END_WINDOWLIST| M_ICONIFY|M_DEICONIFY|M_ICON_NAME| M_RES_NAME|M_RES_CLASS|M_WINDOW_NAME|M_ICON_FILE| M_DEFAULTICON|M_CONFIG_INFO|M_END_CONFIG_INFO; struct icon_info *Hilite; int main_width, main_height; int num_icons = 0; int num_rows = 1; int num_columns = 6; int Lines = 6; int max_icon_width = 48,max_icon_height = 48; int ButtonWidth,ButtonHeight; int x= -100000,y= -100000,w= -1,h= -1,gravity = NorthWestGravity; int icon_win_x = 0, icon_win_y = 0, icon_win_width = 100, icon_win_height = 100; int interval = 8; int motion = NONE; int primary = LEFT, secondary = BOTTOM; int xneg = 0, yneg = 0; int ClickTime = 150; unsigned int bar_width = 9; int redraw_flag = 3; int icon_relief = 4; int margin1 = 8; int margin2 = 6; Pixmap IconwinPixmap = None; char *IconwinPixmapFile = NULL; int h_margin; int v_margin; int fd[2]; struct icon_info *Head = NULL; struct icon_info *Tail = NULL; struct iconfile *IconListHead = NULL; struct iconfile *IconListTail = NULL; struct iconfile *DefaultIcon = NULL; struct mousefunc *MouseActions = NULL; struct keyfunc *KeyActions = NULL; char *iconPath = NULL; char *pixmapPath = NULL; char *FvwmDefaultIcon = NULL; static Atom wm_del_win; Atom _XA_WM_PROTOCOLS; Atom _XA_WM_NAME; int ready = 0; unsigned long local_flags = 0; int sortby = UNSORT; int save_color_limit; /* color limit from config */ /************************************************************************ Main Based on main() from GoodStuff: Copyright 1993, Robert Nation. ************************************************************************/ int main(int argc, char **argv) { char *display_name = NULL; char *temp, *s; XIconSize* size; temp = argv[0]; s=strrchr(argv[0], '/'); if (s != NULL) temp = s + 1; MyName = safemalloc(strlen(temp)+1); strcpy(MyName, temp); signal (SIGPIPE, DeadPipe); if((argc != 6)&&(argc != 7)) { fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName, VERSION); exit(1); } fd[0] = atoi(argv[1]); fd[1] = atoi(argv[2]); if (!(dpy = XOpenDisplay(display_name))) { fprintf(stderr,"%s: can't open display %s", MyName, XDisplayName(display_name)); exit (1); } x_fd = XConnectionNumber(dpy); fd_width = GetFdWidth(); screen= DefaultScreen(dpy); Root = RootWindow(dpy, screen); if(Root == None) { fprintf(stderr,"%s: Screen %d is not valid ", MyName, screen); exit(1); } InitPictureCMap(dpy,Root); /* store the root cmap */ d_depth = DefaultDepth(dpy, screen); XSetErrorHandler((XErrorHandler)myErrorHandler); ParseOptions(); SetMessageMask(fd, m_mask); if ((local_flags & SETWMICONSIZE) && (size = XAllocIconSize()) != NULL){ size->max_width = size->min_width = max_icon_width + icon_relief; size->max_height = size->min_height = max_icon_height + icon_relief; size->width_inc = size->height_inc = 0; XSetIconSizes(dpy, Root, size, 1); XFree(size); } CreateWindow(); SendFvwmPipe(fd,"Send_WindowList",0); Loop(); return 0; } /************************************************************************ Loop Based on Loop() from GoodStuff: Copyright 1993, Robert Nation. ************************************************************************/ void Loop(void) { Window root; struct icon_info *tmp, *exhilite; int x,y,border_width,depth; int i, hr = icon_relief/2; XEvent Event; int tw,th; int diffx, diffy; int oldw, oldh; while(1) { if(My_XNextEvent(dpy,&Event)) { switch(Event.type) { case Expose: if(Event.xexpose.count == 0){ if (Event.xany.window == main_win){ RedrawWindow(); }else{ tmp = Head; while(tmp != NULL){ if (Event.xany.window == tmp->icon_pixmap_w){ RedrawIcon(tmp, 1); break; }else if(Event.xany.window == tmp->IconWin){ RedrawIcon(tmp, 2); break; } tmp = tmp->next; } } } break; case ConfigureNotify: XGetGeometry(dpy,main_win,&root,&x,&y, (unsigned int *)&tw,(unsigned int *)&th, (unsigned int *)&border_width, (unsigned int *)&depth); if (ready && (tw != main_width || th != main_height)){ main_width = tw; main_height= th; oldw = Width; oldh = Height; num_columns = (tw - h_margin - interval + 1) / UWidth; num_rows = (th - v_margin - interval + 1) / UHeight; Width = UWidth * num_columns + interval - 1; Height = UHeight * num_rows + interval -1; XMoveResizeWindow(dpy, holder_win, margin1+2, margin1+2, tw - h_margin, th - v_margin); if (!(local_flags & HIDE_H)) XResizeWindow(dpy, h_scroll_bar, Width - bar_width*2, bar_width); if (!(local_flags & HIDE_V)) XResizeWindow(dpy ,v_scroll_bar, bar_width, Height - bar_width*2); GetIconwinSize(&diffx, &diffy); if (primary == BOTTOM || secondary == BOTTOM) icon_win_y -= Height - oldh; if (primary == RIGHT || secondary == RIGHT) icon_win_x -= Width - oldw; if (icon_win_x < 0) icon_win_x = 0; if (icon_win_y < 0) icon_win_y = 0; if (icon_win_x + Width > icon_win_width) icon_win_x = icon_win_width - Width; if (icon_win_y + Height > icon_win_height) icon_win_y = icon_win_height - Height; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); AdjustIconWindows(); XClearWindow(dpy,main_win); RedrawWindow(); } break; case KeyPress: ExecuteKey(Event); break; case ButtonPress: if (!(local_flags & HIDE_H)){ if (Event.xbutton.window == h_scroll_bar) motion = HORIZONTAL; else if (Event.xbutton.window == l_button){ Pressed = l_button; RedrawLeftButton(ShadowGC, ReliefGC); } else if (Event.xbutton.window == r_button){ Pressed = r_button; RedrawRightButton(ShadowGC, ReliefGC); } } if (!(local_flags & HIDE_V)){ if (Event.xbutton.window == v_scroll_bar) motion = VERTICAL; else if (Event.xbutton.window == t_button){ Pressed = t_button; RedrawTopButton(ShadowGC, ReliefGC); } else if (Event.xbutton.window == b_button){ Pressed = b_button; RedrawBottomButton(ShadowGC, ReliefGC); } } if ((tmp = Search(Event.xbutton.window)) != NULL) ExecuteAction(Event.xbutton.x, Event.xbutton.y, tmp); break; case ButtonRelease: if (!(local_flags & HIDE_H)){ if (Event.xbutton.window == h_scroll_bar && motion == HORIZONTAL) HScroll(Event.xbutton.x * icon_win_width / Width); else if (Event.xbutton.window == l_button && Pressed == l_button){ Pressed = None; RedrawLeftButton(ReliefGC, ShadowGC); HScroll(icon_win_x - UWidth); } else if (Event.xbutton.window == r_button && Pressed == r_button){ Pressed = None; RedrawRightButton(ReliefGC, ShadowGC); HScroll(icon_win_x + UWidth); } } if (!(local_flags & HIDE_V)){ if (Event.xbutton.window == v_scroll_bar && motion == VERTICAL) VScroll(Event.xbutton.y * icon_win_height / Height); else if (Event.xbutton.window == t_button && Pressed == t_button){ Pressed = None; RedrawTopButton(ReliefGC, ShadowGC); VScroll(icon_win_y - UHeight); } else if (Event.xbutton.window == b_button && Pressed == b_button){ Pressed = None; RedrawBottomButton(ReliefGC, ShadowGC); VScroll(icon_win_y + UHeight); } } motion = NONE; break; case MotionNotify: if (motion == VERTICAL){ VScroll(Event.xbutton.y * icon_win_height / Height); }else if (motion == HORIZONTAL){ HScroll(Event.xbutton.x * icon_win_width / Width); } break; case EnterNotify: if ((tmp = Search(Event.xcrossing.window)) != NULL) if ((exhilite = Hilite) != tmp){ Hilite = tmp; if (exhilite != NULL) RedrawIcon(exhilite, redraw_flag); RedrawIcon(tmp, redraw_flag); } break; case LeaveNotify: if ((tmp = Search(Event.xcrossing.window)) != NULL && tmp == Hilite){ Hilite = NULL; RedrawIcon(tmp, redraw_flag); } if (!(local_flags & HIDE_H) && Event.xbutton.window == l_button && Pressed == l_button){ Pressed = None; RedrawLeftButton(ReliefGC, ShadowGC); } else if (!(local_flags & HIDE_H) && Event.xbutton.window == r_button && Pressed == r_button){ Pressed = None; RedrawRightButton(ReliefGC, ShadowGC); } else if (!(local_flags & HIDE_V) && Event.xbutton.window == t_button && Pressed == t_button){ Pressed = None; RedrawTopButton(ReliefGC, ShadowGC); } else if (!(local_flags & HIDE_V) && Event.xbutton.window == b_button && Pressed == b_button){ Pressed = None; RedrawBottomButton(ReliefGC, ShadowGC); } break; case ClientMessage: if ((Event.xclient.format==32) && (Event.xclient.data.l[0]==wm_del_win)) DeadPipe(1); break; case PropertyNotify: switch (Event.xproperty.atom){ case XA_WM_HINTS: if (Event.xproperty.state == PropertyDelete) break; tmp = Head; i=0; while(tmp != NULL){ if (Event.xproperty.window == tmp->id) break; tmp = tmp->next; ++i; } if (tmp == NULL || tmp->wmhints == NULL || !(tmp->extra_flags & DEFAULTICON)) break; if (tmp->wmhints) XFree (tmp->wmhints); tmp->wmhints = XGetWMHints(dpy, tmp->id); if (tmp->wmhints && (tmp->wmhints->flags & IconPixmapHint)){ #ifdef SHAPE /* turn off "old" shape mask */ if (tmp->icon_maskPixmap != None) XShapeCombineMask(dpy, tmp->icon_pixmap_w, ShapeBounding, 0, 0, None, ShapeSet); #endif if (tmp->iconPixmap != None) XFreePixmap(dpy, tmp->iconPixmap); GetIconBitmap(tmp); #ifdef SHAPE if (tmp->icon_maskPixmap != None) XShapeCombineMask(dpy, tmp->icon_pixmap_w, ShapeBounding, hr, hr, tmp->icon_maskPixmap, ShapeSet); #endif AdjustIconWindow(tmp, i); if (max_icon_height != 0) RedrawIcon(tmp, 1); } break; } break; default: break; } } } return; } void HScroll(int x) { int oldx = icon_win_x; if (x + Width > icon_win_width) x = icon_win_width - Width; if (x < 0) x = 0; if (oldx != x){ icon_win_x = x; XMoveWindow(dpy,icon_win, -icon_win_x, -icon_win_y); if (!(local_flags & HIDE_H)) RedrawHScrollbar(); } } void VScroll(int y) { int oldy = icon_win_y; if (y + Height > icon_win_height) y = icon_win_height - Height; if (y < 0) y = 0; if (oldy != y){ icon_win_y = y; XMoveWindow(dpy,icon_win, -icon_win_x, -icon_win_y); if (!(local_flags & HIDE_V)) RedrawVScrollbar(); } } struct icon_info *Search(Window w) { struct icon_info *tmp; tmp = Head; while (tmp != NULL){ if (tmp->IconWin == w || tmp->icon_pixmap_w == w) return tmp; tmp = tmp->next; } return NULL; } /************************************************************************ * * Draw the window * ***********************************************************************/ void RedrawWindow(void) { XEvent dummy; while (XCheckTypedWindowEvent (dpy, main_win, Expose, &dummy)); RelieveWindow(main_win, margin1, margin1, Width + 4, Height + 4, ShadowGC,ReliefGC); if (!(local_flags & HIDE_H)) RelieveWindow(main_win, margin1, margin1 + 4 + Height + margin2, Width + 4, bar_width+4, ShadowGC,ReliefGC); if (!(local_flags & HIDE_V)) RelieveWindow(main_win, margin1 + 4 + Width + margin2, margin1, bar_width+4, Height + 4, ShadowGC,ReliefGC); RelieveWindow(main_win, 0, 0, Width + h_margin, Height + v_margin, ReliefGC, ShadowGC); /* scroll bar */ if (!(local_flags & HIDE_H)) RedrawHScrollbar(); if (!(local_flags & HIDE_V)) RedrawVScrollbar(); /* buttons */ if (!(local_flags & HIDE_H)){ RedrawLeftButton(ReliefGC, ShadowGC); RedrawRightButton(ReliefGC, ShadowGC); } if (!(local_flags & HIDE_V)){ RedrawTopButton(ReliefGC, ShadowGC); RedrawBottomButton(ReliefGC, ShadowGC); } /* icons */ RedrawIcons(); } void RedrawIcons(void) { struct icon_info *tmp; tmp = Head; while(tmp != NULL){ if (desk_cond(tmp)) RedrawIcon(tmp, redraw_flag); tmp = tmp->next; } } void RedrawIcon(struct icon_info *item, int f) { unsigned long plane = 1; int hr, len; int diff, lm ,w, h, tw; char label[256]; hr = icon_relief/2; if (Hilite == item){ XSetForeground(dpy, NormalGC, act_icon_fore_pix); XSetBackground(dpy, NormalGC, act_icon_back_pix); XSetForeground(dpy, IconReliefGC, act_icon_hilite_pix); XSetForeground(dpy, IconShadowGC, act_icon_shadow_pix); if (max_icon_height != 0 && (item->flags & ICON_OURS)) XSetWindowBackground(dpy, item->icon_pixmap_w, act_icon_back_pix); XSetWindowBackground(dpy, item->IconWin, act_icon_back_pix); } /* icon pixmap */ if ((f & 1) && (item->flags & ICON_OURS)){ if (item->iconPixmap != None && item->icon_pixmap_w != None){ if (item->icon_depth != d_depth) XCopyPlane(dpy, item->iconPixmap, item->icon_pixmap_w, NormalGC, 0, 0, item->icon_w, item->icon_h, hr, hr, plane); else XCopyArea(dpy, item->iconPixmap, item->icon_pixmap_w, NormalGC, 0, 0, item->icon_w, item->icon_h, hr, hr); } if (!(item->flags & SHAPED_ICON)){ if (item->icon_w > 0 && item->icon_h > 0) RelieveWindow(item->icon_pixmap_w, 0, 0, item->icon_w +icon_relief, item->icon_h + icon_relief, IconReliefGC, IconShadowGC); else RelieveWindow(item->icon_pixmap_w, 0, 0, max_icon_width +icon_relief, max_icon_height + icon_relief, IconReliefGC, IconShadowGC); } } /* label */ if (f & 2){ w = max_icon_width + icon_relief; h = max_icon_height + icon_relief; if (item->flags & ICONIFIED){ sprintf(label, "(%s)", item->name); }else strcpy(label, item->name); len = strlen(label); tw = XTextWidth(font, label, len); diff = max_icon_width + icon_relief - tw; lm = diff/2; lm = lm > 4 ? lm : 4; if (Hilite == item){ XRaiseWindow(dpy, item->IconWin); XMoveResizeWindow(dpy, item->IconWin, item->x + min(0, (diff - 8))/2, item->y + h, max(tw + 8, w), 6 + font->ascent + font->descent); XClearWindow(dpy, item->IconWin); XDrawString(dpy, item->IconWin, NormalGC, lm, 3 + font->ascent, label, len); RelieveWindow(item->IconWin, 0, 0, max(tw + 8, w), 6 + font->ascent + font->descent, IconReliefGC, IconShadowGC); }else{ XMoveResizeWindow(dpy, item->IconWin, item->x, item->y + h, w, 6 + font->ascent + font->descent); XClearWindow(dpy, item->IconWin); XDrawString(dpy, item->IconWin, NormalGC, lm, 3 + font->ascent, label, len); RelieveWindow(item->IconWin, 0, 0, w, 6 + font->ascent + font->descent, IconReliefGC, IconShadowGC); } } if (Hilite == item){ XSetForeground(dpy, NormalGC, icon_fore_pix); XSetBackground(dpy, NormalGC, icon_back_pix); XSetForeground(dpy, IconReliefGC, icon_hilite_pix); XSetForeground(dpy, IconShadowGC, icon_shadow_pix); if (max_icon_height != 0 && (item->flags & ICON_OURS)) XSetWindowBackground(dpy, item->icon_pixmap_w, icon_back_pix); XSetWindowBackground(dpy, item->IconWin, icon_back_pix); } } /*********************************************************************** * RedrawHScrollbar * Based on part of Loop() of GrabWindow.c in FvwmScroll: * Copyright 1994, Robert Nation. ***********************************************************************/ void RedrawHScrollbar(void) { int x,width; x = (Width - bar_width*2) * icon_win_x / icon_win_width; width = (Width - bar_width*2) * Width / icon_win_width; XClearArea(dpy, h_scroll_bar, 0, 0, Width, bar_width,False); RelieveWindow(h_scroll_bar, x, 0, width, bar_width, ReliefGC, ShadowGC); } /*********************************************************************** * RedrawVScrollbar * Based on part of Loop() of GrabWindow.c in FvwmScroll: * Copyright 1994, Robert Nation. ***********************************************************************/ void RedrawVScrollbar(void) { int y, height; y = (Height - bar_width*2) * icon_win_y / icon_win_height; height = (Height - bar_width*2)* Height / icon_win_height; XClearArea(dpy, v_scroll_bar, 0, 0, bar_width, Height,False); RelieveWindow(v_scroll_bar, 0, y, bar_width, height, ReliefGC, ShadowGC); } void RedrawLeftButton(GC rgc, GC sgc) { XSegment seg[4]; int i=0; seg[i].x1 = 1; seg[i].y1 = bar_width/2; seg[i].x2 = bar_width - 2; seg[i++].y2 = 1; seg[i].x1 = 0; seg[i].y1 = bar_width/2; seg[i].x2 = bar_width - 1; seg[i++].y2 = 0; XDrawSegments(dpy, l_button, rgc, seg, i); i = 0; seg[i].x1 = 1; seg[i].y1 = bar_width/2; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2; seg[i].x1 = 0; seg[i].y1 = bar_width/2; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1; seg[i].x1 = bar_width - 2; seg[i].y1 = 1; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2; seg[i].x1 = bar_width - 1; seg[i].y1 = 0; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1; XDrawSegments(dpy, l_button, sgc, seg, i); } void RedrawRightButton(GC rgc, GC sgc) { XSegment seg[4]; int i=0; seg[i].x1 = 1; seg[i].y1 = 1; seg[i].x2 = 1; seg[i++].y2 = bar_width - 2; seg[i].x1 = 0; seg[i].y1 = 0; seg[i].x2 = 0; seg[i++].y2 = bar_width - 1; seg[i].x1 = 1; seg[i].y1 = 1; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width/2; seg[i].x1 = 0; seg[i].y1 = 0; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width/2; XDrawSegments(dpy, r_button, rgc, seg, i); i = 0; seg[i].x1 = 1; seg[i].y1 = bar_width - 2; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width/2; seg[i].x1 = 0; seg[i].y1 = bar_width - 1; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width/2; XDrawSegments(dpy, r_button, sgc, seg, i); } void RedrawTopButton(GC rgc, GC sgc) { XSegment seg[4]; int i=0; seg[i].x1 = bar_width/2; seg[i].y1 = 1; seg[i].x2 = 1; seg[i++].y2 = bar_width - 2; seg[i].x1 = bar_width/2; seg[i].y1 = 0; seg[i].x2 = 0; seg[i++].y2 = bar_width - 1; XDrawSegments(dpy, t_button, rgc, seg, i); i = 0; seg[i].x1 = bar_width/2; seg[i].y1 = 1; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2; seg[i].x1 = bar_width/2; seg[i].y1 = 0; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1; seg[i].x1 = 1; seg[i].y1 = bar_width - 2; seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2; seg[i].x1 = 0; seg[i].y1 = bar_width - 1; seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1; XDrawSegments(dpy, t_button, sgc, seg, i); } void RedrawBottomButton(GC rgc, GC sgc) { XSegment seg[4]; int i=0; seg[i].x1 = 1; seg[i].y1 = 1; seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 2; seg[i].x1 = 0; seg[i].y1 = 0; seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 1; seg[i].x1 = 1; seg[i].y1 = 1; seg[i].x2 = bar_width - 2; seg[i++].y2 = 1; seg[i].x1 = 0; seg[i].y1 = 0; seg[i].x2 = bar_width - 1; seg[i++].y2 = 0; XDrawSegments(dpy, b_button, rgc, seg, i); i = 0; seg[i].x1 = bar_width - 2; seg[i].y1 = 1; seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 2; seg[i].x1 = bar_width - 1; seg[i].y1 = 0; seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 1; XDrawSegments(dpy, b_button, sgc, seg, i); } /************************************************************************ RelieveWindow Original work from GoodStuff: Copyright 1993, Robert Nation. ************************************************************************/ void RelieveWindow(Window win,int x,int y,int w,int h, GC rgc,GC sgc) { XSegment seg[4]; int i; i=0; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = y; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = x; seg[i++].y2 = h+y-1; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = x+w-2; seg[i++].y2 = y+1; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = x+1; seg[i++].y2 = y+h-2; XDrawSegments(dpy, win, rgc, seg, i); i=0; seg[i].x1 = x; seg[i].y1 = y+h-1; seg[i].x2 = w+x-1; seg[i++].y2 = y+h-1; seg[i].x1 = x+w-1; seg[i].y1 = y; seg[i].x2 = x+w-1; seg[i++].y2 = y+h-1; if(d_depth<2) XDrawSegments(dpy, win, ShadowGC, seg, i); else XDrawSegments(dpy, win, sgc, seg, i); i=0; seg[i].x1 = x+1; seg[i].y1 = y+h-2; seg[i].x2 = x+w-2; seg[i++].y2 = y+h-2; seg[i].x1 = x+w-2; seg[i].y1 = y+1; seg[i].x2 = x+w-2; seg[i++].y2 = y+h-2; XDrawSegments(dpy, win, sgc, seg, i); } /************************************************************************ * CreateWindow --Sizes and creates the window * Based on CreateWindow() from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ void CreateWindow(void) { XGCValues gcv; unsigned long gcm; unsigned long mask; char *list[2]; XSetWindowAttributes attributes; XSizeHints mysizehints; XTextProperty name; XClassHint class_hints; h_margin = margin1*2 + bar_width + margin2 + 8; v_margin = margin1*2 + bar_width + margin2 + 8; wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); /* load the font */ if ((font = XLoadQueryFont(dpy, font_string)) == NULL) { if ((font = XLoadQueryFont(dpy, "fixed")) == NULL) { fprintf(stderr,"%s: No fonts available\n",MyName); exit(1); } }; if ((local_flags & HIDE_H)) v_margin -= bar_width + margin2 + 4; if ((local_flags & HIDE_V)) h_margin -= bar_width + margin2 + 4; UWidth = max_icon_width + icon_relief + interval; UHeight = font->ascent + font->descent + max_icon_height + icon_relief + 6 + interval; Width = UWidth * num_columns + interval -1; Height = UHeight * num_rows + interval -1; mysizehints.flags = PWinGravity| PResizeInc | PMinSize; /* subtract one for the right/bottom border */ mysizehints.min_width = UWidth + interval - 1 + h_margin; main_width = mysizehints.width = Width + h_margin; mysizehints.min_height = UHeight + interval - 1 + v_margin; main_height = mysizehints.height = Height + v_margin; mysizehints.width_inc = UWidth; mysizehints.height_inc = UHeight; if(x > -100000) { if (xneg) { mysizehints.x = DisplayWidth(dpy,screen) + x - mysizehints.width; gravity = NorthEastGravity; } else mysizehints.x = x; if (yneg) { mysizehints.y = DisplayHeight(dpy,screen) + y - mysizehints.height; gravity = SouthWestGravity; } else mysizehints.y = y; if((xneg) && (yneg)) gravity = SouthEastGravity; mysizehints.flags |= USPosition; } mysizehints.win_gravity = gravity; if(d_depth < 2) { back_pix = icon_back_pix = act_icon_fore_pix = GetColor("white"); fore_pix = icon_fore_pix = act_icon_back_pix = GetColor("black"); hilite_pix = icon_hilite_pix = act_icon_shadow_pix = icon_back_pix; shadow_pix = icon_shadow_pix = act_icon_hilite_pix = icon_fore_pix; } else { fore_pix = GetColor(Fore); back_pix = GetColor(Back); icon_back_pix = GetColor(IconBack); icon_fore_pix = GetColor(IconFore); icon_hilite_pix = GetHilite(icon_back_pix); icon_shadow_pix = GetShadow(icon_back_pix); act_icon_back_pix = GetColor(ActIconBack); act_icon_fore_pix = GetColor(ActIconFore); act_icon_hilite_pix = GetHilite(act_icon_back_pix); act_icon_shadow_pix = GetShadow(act_icon_back_pix); hilite_pix = GetHilite(back_pix); shadow_pix = GetShadow(back_pix); } main_win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y, mysizehints.width,mysizehints.height, 0,fore_pix,back_pix); XSetWMProtocols(dpy,main_win,&wm_del_win,1); XSelectInput(dpy,main_win,MW_EVENTS); /* set normal_hits, wm_hints, and, class_hints */ list[0]=MyName; list[1]=NULL; if (XStringListToTextProperty(list,1,&name) == 0) { fprintf(stderr,"%s: cannot allocate window name",MyName); return; } class_hints.res_name = MyName; class_hints.res_class = "FvwmIconBox"; XSetWMProperties(dpy,main_win,&name,&name, NULL,0,&mysizehints,NULL,&class_hints); XFree(name.value); mysizehints.width -= h_margin; mysizehints.height -= v_margin; holder_win = XCreateSimpleWindow(dpy,main_win,margin1+2, margin1+2, mysizehints.width, mysizehints.height, 0,fore_pix,back_pix); icon_win = XCreateSimpleWindow(dpy,holder_win,-icon_win_x,-icon_win_y, icon_win_width, icon_win_height, 0,fore_pix,back_pix); gcm = GCForeground|GCBackground; gcv.foreground = hilite_pix; gcv.background = back_pix; ReliefGC = XCreateGC(dpy, Root, gcm, &gcv); gcm = GCForeground|GCBackground; gcv.foreground = shadow_pix; gcv.background = back_pix; ShadowGC = XCreateGC(dpy, Root, gcm, &gcv); gcm = GCForeground|GCBackground; gcv.foreground = icon_hilite_pix; gcv.background = icon_back_pix; IconReliefGC = XCreateGC(dpy, Root, gcm, &gcv); gcm = GCForeground|GCBackground; gcv.foreground = icon_shadow_pix; gcv.background = icon_back_pix; IconShadowGC = XCreateGC(dpy, Root, gcm, &gcv); gcm = GCForeground|GCBackground|GCFont; gcv.foreground = fore_pix; gcv.background = back_pix; gcv.font = font->fid; NormalGC = XCreateGC(dpy, Root, gcm, &gcv); /* icon_win's background */ if (GetBackPixmap() == True){ XSetWindowBackgroundPixmap(dpy, icon_win, IconwinPixmap); /* special thanks to Dave Goldberg for his helpful information */ XFreePixmap(dpy, IconwinPixmap); } XSetForeground(dpy, NormalGC, icon_fore_pix); XSetBackground(dpy, NormalGC, icon_back_pix); /* scroll bars */ mask = CWWinGravity | CWBackPixel; attributes.background_pixel = back_pix; if (!(local_flags & HIDE_H)){ attributes.win_gravity = SouthWestGravity; h_scroll_bar = XCreateWindow(dpy ,main_win, margin1 + 2 + bar_width, margin1 + 6 + Height + margin2, Width - bar_width*2, bar_width, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); XSelectInput(dpy,h_scroll_bar,SCROLL_EVENTS); } if (!(local_flags & HIDE_V)){ attributes.win_gravity = NorthEastGravity; v_scroll_bar = XCreateWindow(dpy ,main_win, margin1 + 6 + Width + margin2, margin1 + 2 + bar_width, bar_width, Height - bar_width*2, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); XSelectInput(dpy,v_scroll_bar,SCROLL_EVENTS); } /* buttons */ if (!(local_flags & HIDE_H)){ attributes.win_gravity = SouthWestGravity; l_button = XCreateWindow(dpy, main_win, margin1 + 2, margin1 + 6 + Height + margin2, bar_width, bar_width, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); attributes.win_gravity = SouthEastGravity; r_button = XCreateWindow(dpy, main_win, margin1 + 2 + Width - bar_width, margin1 + 6 + Height + margin2, bar_width, bar_width, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); XSelectInput(dpy,l_button,BUTTON_EVENTS); XSelectInput(dpy,r_button,BUTTON_EVENTS); } if (!(local_flags & HIDE_V)){ attributes.win_gravity = NorthEastGravity; t_button = XCreateWindow(dpy, main_win, margin1 + 6 + Width + margin2, margin1 + 2, bar_width, bar_width, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); attributes.win_gravity = SouthEastGravity; b_button = XCreateWindow(dpy, main_win, margin1 + 6 + Width + margin2, margin1 + 2 + Height - bar_width, bar_width, bar_width, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &attributes); XSelectInput(dpy,t_button,BUTTON_EVENTS); XSelectInput(dpy,b_button,BUTTON_EVENTS); } } void GetIconwinSize(int *dx, int *dy) { *dx = icon_win_width; *dy = icon_win_height; if (primary == LEFT || primary == RIGHT){ icon_win_width = max(Width, UWidth * Lines + interval - 1); icon_win_height = max(Height, UHeight * (max(0, (num_icons-1))/Lines + 1) - 1 + interval); }else{ icon_win_width = max(Width, UWidth * (max(0,num_icons-1) / Lines + 1) + interval - 1); icon_win_height = max(Height, UHeight * Lines - 1 + interval); } *dx = icon_win_width - *dx; *dy = icon_win_height - *dy; } /************************************************************************ * nocolor * Original work from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ void nocolor(char *a, char *b) { fprintf(stderr,"%s: can't %s %s\n", MyName, a,b); } /************************************************************************ * GetColor * Original work from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ Pixel GetColor(char *name) { XColor color; XWindowAttributes attributes; XGetWindowAttributes(dpy,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; } /************************************************************************ SendFvwmPipe - Send a message back to fvwm Original work from FvwmWinList: Copyright 1994, Mike Finger. ************************************************************************/ void SendFvwmPipe(int *fd, char *message,unsigned long window) { int w; char *hold,*temp,*temp_msg; hold=message; while(1) { temp=strchr(hold,','); if (temp!=NULL) { temp_msg=malloc(temp-hold+1); strncpy(temp_msg,hold,(temp-hold)); temp_msg[(temp-hold)]='\0'; hold=temp+1; } else temp_msg=hold; if (!ExecIconBoxFunction(temp_msg)){ write(fd[0],&window, sizeof(unsigned long)); w=strlen(temp_msg); write(fd[0],&w,sizeof(int)); write(fd[0],temp_msg,w); /* keep going */ w=1; write(fd[0],&w,sizeof(int)); } if(temp_msg!=hold) free(temp_msg); else break; } } Bool ExecIconBoxFunction(char *msg) { if (strncasecmp(msg, "Next", 4) == 0){ Next(); return True; }else if (strncasecmp(msg, "Prev", 4) == 0){ Prev(); return True; }else if (strncasecmp(msg, "Left", 4) == 0){ HScroll(icon_win_x - UWidth); return True; }else if (strncasecmp(msg, "Right", 5) == 0){ HScroll(icon_win_x + UWidth); return True; }else if (strncasecmp(msg, "Up", 2) == 0){ VScroll(icon_win_y - UHeight); return True; }else if (strncasecmp(msg, "Down", 4) == 0){ VScroll(icon_win_y + UHeight); return True; } return False; } void Next(void) { struct icon_info *new, *old; int i; old = new = Hilite; if (new != NULL) new = new->next; if (new != NULL) Hilite = new; else new = Hilite = Head; if (new == NULL) return; if (old != NULL) RedrawIcon(old, redraw_flag); if (new != NULL) RedrawIcon(new, redraw_flag); i=0; if (new->x < icon_win_x){ while (new->x + UWidth * ++i < icon_win_x) ; HScroll(icon_win_x - UWidth*i); }else if (new->x > icon_win_x + Width){ while (new->x - UWidth * ++i > icon_win_x + Width) ; HScroll(icon_win_x + UWidth*i); } i=0; if (new->y < icon_win_y){ while (new->y + UHeight * ++i < icon_win_y) ; VScroll(icon_win_y - UHeight*i); }else if (new->y > icon_win_y + Height){ while (new->y - UHeight * ++i > icon_win_y + Height) ; VScroll(icon_win_y + UHeight*i); } } void Prev(void) { struct icon_info *new, *old; int i; old = new = Hilite; if (new != NULL) new = new->prev; if (new != NULL) Hilite = new; else new = Hilite = Tail; if (new == NULL) return; if (old != NULL) RedrawIcon(old, redraw_flag); if (new != NULL) RedrawIcon(new, redraw_flag); i=0; if (new->x < icon_win_x){ while (new->x + UWidth * ++i < icon_win_x) ; HScroll(icon_win_x - UWidth*i); }else if (new->x > icon_win_x + Width){ while (new->x - UWidth * ++i > icon_win_x + Width) ; HScroll(icon_win_x + UWidth*i); } i=0; if (new->y < icon_win_y){ while (new->y + UHeight * ++i < icon_win_y) ; VScroll(icon_win_y - UHeight*i); }else if (new->y > icon_win_y + Height){ while (new->y - UHeight * ++i > icon_win_y + Height) ; VScroll(icon_win_y + UHeight*i); } } /************************************************************************ * DeadPipe --Dead pipe handler * Based on DeadPipe() from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ void DeadPipe(int nonsense) { #if 0 /* can't do X or malloc stuff in a signal handler, so just exit */ struct icon_info *tmpi, *tmpi2; struct mousefunc *tmpm, *tmpm2; struct keyfunc *tmpk, *tmpk2; struct iconfile *tmpf, *tmpf2; if (FvwmDefaultIcon != NULL) free(FvwmDefaultIcon); tmpm = MouseActions; while(tmpm != NULL){ tmpm2 = tmpm; tmpm = tmpm->next; free(tmpm2->action); free(tmpm2); } tmpk = KeyActions; while(tmpk != NULL){ tmpk2 = tmpk; tmpk = tmpk->next; free(tmpk2->action); free(tmpk2->name); free(tmpk2); } tmpf = IconListHead; while(tmpf != NULL){ tmpf2 = tmpf; tmpf = tmpf->next; free(tmpf2->name); free(tmpf2->iconfile); free(tmpf2); } tmpi = Head; while(tmpi != NULL){ tmpi2 = tmpi; tmpi = tmpi->next; freeitem(tmpi2, 0); } if ((local_flags & SETWMICONSIZE)) XDeleteProperty(dpy, Root, XA_WM_ICON_SIZE); XSync(dpy,0); #endif /* 0 */ exit(0); } /************************************************************************ * ParseOptions * Based on ParseConfig() from FvwmWinList: * Copyright 1994, Mike Finger. ***********************************************************************/ void ParseOptions(void) { char *tline= NULL,*tmp; int Clength; Clength = strlen(MyName); GetConfigLine(fd,&tline); while(tline != NULL) { int g_x, g_y, flags; unsigned width,height; if(strlen(&tline[0])>1){ if (strncasecmp(tline,CatString3("*", MyName, "Geometry"),Clength+9)==0){ tmp = &tline[Clength+9]; while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0)) tmp++; tmp[strlen(tmp)-1] = 0; flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height); if (flags & WidthValue) num_columns = width; if (flags & HeightValue) num_rows = height; if (flags & XValue) x = g_x; if (flags & YValue) y = g_y; if (flags & XNegative) xneg = 1; if (flags & YNegative) yneg = 1; } else if (strncasecmp(tline,CatString3("*", MyName, "MaxIconSize"),Clength+12)==0){ tmp = &tline[Clength+12]; while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0)) tmp++; tmp[strlen(tmp)-1] = 0; flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height); if (flags & WidthValue) max_icon_width = width; if (flags & HeightValue) max_icon_height = height; if (height == 0){ icon_relief = 0; redraw_flag = 2; max_icon_width += 4; } }else if (strncasecmp(tline,CatString3("*",MyName,"Font"),Clength+5)==0) CopyString(&font_string,&tline[Clength+5]); else if (strncasecmp(tline,CatString3("*",MyName,"IconFore"),Clength+9)==0) CopyString(&IconFore,&tline[Clength+9]); else if (strncasecmp(tline,CatString3("*",MyName,"IconBack"),Clength+9)==0) CopyString(&IconBack,&tline[Clength+9]); else if (strncasecmp(tline,CatString3("*",MyName,"IconHiFore"),Clength+11)==0) CopyString(&ActIconFore,&tline[Clength+11]); else if (strncasecmp(tline,CatString3("*",MyName,"IconHiBack"),Clength+11)==0) CopyString(&ActIconBack,&tline[Clength+11]); else if (strncasecmp(tline,CatString3("*",MyName, "Fore"),Clength+5)==0) CopyString(&Fore,&tline[Clength+5]); else if (strncasecmp(tline,CatString3("*",MyName, "Back"),Clength+5)==0) CopyString(&Back,&tline[Clength+5]); else if (strncasecmp(tline,CatString3("*",MyName, "Pixmap"),Clength+7)==0) CopyString(&IconwinPixmapFile,&tline[Clength+7]); else if (strncasecmp(tline,CatString3("*",MyName, "Padding"),Clength+8)==0) interval = max(0,atoi(&tline[Clength+8])); else if (strncasecmp(tline,CatString3("*",MyName, "FrameWidth"),Clength+11)==0){ sscanf(&tline[Clength+11], "%d %d", &margin1, &margin2); margin1 = max(0, margin1); margin2 = max(0, margin2); }else if (strncasecmp(tline,CatString3("*",MyName, "Lines"),Clength+6)==0) Lines = max(1,atoi(&tline[Clength+6])); else if (strncasecmp(tline,CatString3("*",MyName, "SBWidth"),Clength+8)==0) bar_width = max(5,atoi(&tline[Clength+8])); else if (strncasecmp(tline,CatString3("*",MyName, "Placement"),Clength+10)==0) parseplacement(&tline[Clength+10]); else if (strncasecmp(tline,CatString3("*",MyName, "SetWMIconSize"),Clength+14)==0) local_flags |= SETWMICONSIZE; else if (strncasecmp(tline,CatString3("*",MyName, "HilightFocusWin"),Clength+16)==0) m_mask |= M_FOCUS_CHANGE; else if (strncasecmp(tline,CatString3("*",MyName, "Resolution"),Clength+11)==0){ tmp = &tline[Clength+11]; while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0)) tmp++; if (strncasecmp(tmp, "Desk", 4) == 0){ m_mask |= M_NEW_DESK; local_flags |= CURRENT_ONLY; } }else if (strncasecmp(tline,CatString3("*",MyName, "Mouse"),Clength+6)==0) parsemouse(&tline[Clength + 6]); else if (strncasecmp(tline,CatString3("*",MyName, "Key"),Clength+4)==0) parsekey(&tline[Clength + 4]); else if (strncasecmp(tline,CatString3("*",MyName, "SortIcons"),Clength+10)==0){ tmp = &tline[Clength+10]; while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0)) tmp++; if (strlen(tmp) == 0){ /* the case where no argument is given */ sortby = ICONNAME; return; } if (strncasecmp(tmp, "WindowName", 10) == 0) sortby = WINDOWNAME; else if (strncasecmp(tmp, "IconName", 8) == 0) sortby = ICONNAME; else if (strncasecmp(tmp, "ResClass", 8) == 0) sortby = RESCLASS; else if (strncasecmp(tmp, "ResName", 7) == 0) sortby = RESNAME; }else if (strncasecmp(tline,CatString3("*",MyName, "HideSC"),Clength+7)==0){ tmp = &tline[Clength+7]; while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0)) tmp++; if (strncasecmp(tmp, "Horizontal", 10) == 0) local_flags |= HIDE_H; else if (strncasecmp(tmp, "Vertical", 8) == 0) local_flags |= HIDE_V; }else if (strncasecmp(tline,CatString3("*",MyName, ""),Clength+1)==0) parseicon(&tline[Clength + 1]); else if (strncasecmp(tline,"IconPath",8)==0) CopyString(&iconPath,&tline[8]); else if (strncasecmp(tline,"PixmapPath",10)==0) CopyString(&pixmapPath,&tline[10]); else if (strncasecmp(tline,"ClickTime",9)==0) ClickTime = atoi(&tline[9]); else if (strncasecmp(tline,"ColorLimit",10)==0) { save_color_limit = atoi(&tline[10]); } } GetConfigLine(fd,&tline); } return; } void parseicon(char *tline) { int len; struct iconfile *tmp; char *ptr, *start, *end; tmp = (struct iconfile *)safemalloc(sizeof(struct iconfile)); /* windowname */ tmp->name = stripcpy2(tline); if(tmp->name == NULL){ free(tmp); return; } /* skip windowname, based on strpcpy3 of configure.c */ while((*tline != '"')&&(tline != NULL)) tline++; if(*tline != 0) tline++; while((*tline != '"')&&(tline != NULL)) tline++; if(*tline == 0){ free(tmp); return; } tline++; /* file */ /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; while(!isspace(*end)&&(*end != '\n')&&(*end != 0)) end++; len = end - start; ptr = safemalloc(len+1); strncpy(ptr, start, len); ptr[len] = 0; tmp->iconfile = ptr; if (strcmp(tmp->name, "*") == 0) DefaultIcon = tmp; tmp->next = NULL; if (IconListHead == NULL) IconListHead = IconListTail = tmp; else{ IconListTail->next = tmp; IconListTail = tmp; } } void parseplacement(char *tline) { char p[240], s[240]; sscanf(tline, "%s %s", p, s); if (strncasecmp(p, "Left", 4) == 0) primary = LEFT; else if (strncasecmp(p, "Right", 5) == 0) primary = RIGHT; else if (strncasecmp(p, "Top", 3) == 0) primary = TOP; else if (strncasecmp(p, "Bottom", 6) == 0) primary = BOTTOM; if (strncasecmp(s, "Left", 4) == 0) secondary = LEFT; else if (strncasecmp(s, "Right", 5) == 0) secondary = RIGHT; else if (strncasecmp(s, "Top", 3) == 0) secondary = TOP; else if (strncasecmp(s, "Bottom", 6) == 0) secondary = BOTTOM; } void parsemouse(char *tline) { struct mousefunc *f = NULL; int len; char *ptr,*start,*end,*tmp; f = (struct mousefunc *)safemalloc(sizeof(struct mousefunc)); f->next = NULL; f->mouse = 0; /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; while((!isspace(*end))&&(*end!='\n')&&(*end!=0)) end++; if (strncasecmp(start, "1", 1) == 0) f->mouse = Button1; else if (strncasecmp(start, "2", 1) == 0) f->mouse = Button2; else if (strncasecmp(start, "3", 1) == 0) f->mouse = Button3; /* click or doubleclick */ tline = end; /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; while((!isspace(*end))&&(*end!='\n')&&(*end!=0)) end++; if (strncasecmp(start, "Click", 5) == 0) f->type = CLICK; else if (strncasecmp(start, "DoubleClick", 11) == 0) f->type = DOUBLE_CLICK; /* actions */ tline = end; /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; tmp = tline; while((*tmp!='\n')&&(*tmp!=0)){ if (!isspace(*tmp)) end = tmp; tmp++; } end++; len = end - start; ptr = safemalloc(len+1); strncpy(ptr, start, len); ptr[len] = 0; f->action = ptr; f->next = MouseActions; MouseActions = f; } /*********************************************************************** parsekey Based on part of AddFunckey() of configure.c in Fvwm. Copyright 1988, Evans and Sutherland Computer Corporation, Copyright 1989, Massachusetts Institute of Technology, Copyright 1993, Robert Nation. ***********************************************************************/ void parsekey(char *tline) { struct keyfunc *k; int nlen, alen; char *nptr, *aptr, *start, *end, *tmp; int i, kmin, kmax; KeySym keysym; /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; while((!isspace(*end))&&(*end!='\n')&&(*end!=0)) end++; nlen = end - start; nptr = safemalloc(nlen+1); strncpy(nptr, start, nlen); nptr[nlen] = 0; /* actions */ tline = end; /* skip spaces */ while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0)) tline++; start = tline; end = tline; tmp = tline; while((*tmp!='\n')&&(*tmp!=0)){ if (!isspace(*tmp)) end = tmp; tmp++; } end++; alen = end - start; aptr = safemalloc(alen+1); strncpy(aptr, start, alen); aptr[alen] = 0; if ((keysym = XStringToKeysym(nptr)) == NoSymbol || XKeysymToKeycode(dpy, keysym) == 0){ free(nptr); free(aptr); return; } XDisplayKeycodes(dpy, &kmin, &kmax); for (i=kmin; i<=kmax; i++) if (XKeycodeToKeysym(dpy, i, 0) == keysym) { k = (struct keyfunc *)safemalloc(sizeof(struct keyfunc)); k->name = nptr; k->keycode = i; k->action = aptr; k->next = KeyActions; KeyActions = k; } } /*********************************************************************** * change_window_name * Original work from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ void change_window_name(char *str) { XTextProperty name; if (XStringListToTextProperty(&str,1,&name) == 0) { fprintf(stderr,"%s: cannot allocate window name",MyName); return; } XSetWMName(dpy,main_win,&name); XSetWMIconName(dpy,main_win,&name); XFree(name.value); } /*********************************************************************** * My_XNextEvent * Original work from GoodStuff: * Copyright 1993, Robert Nation. ***********************************************************************/ int My_XNextEvent(Display *dpy, XEvent *event) { fd_set in_fdset; unsigned long header[HEADER_SIZE]; static int miss_counter = 0; unsigned long *body; if(XPending(dpy)) { XNextEvent(dpy,event); return 1; } FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_SET(fd[1],&in_fdset); select(fd_width,SELECT_TYPE_ARG234 &in_fdset, 0, 0, NULL); if(FD_ISSET(x_fd, &in_fdset)) { if(XPending(dpy)) { XNextEvent(dpy,event); miss_counter = 0; return 1; } else miss_counter++; if(miss_counter > 100) DeadPipe(0); } if(FD_ISSET(fd[1], &in_fdset)) { if(ReadFvwmPacket(fd[1],header,&body) > 0) { process_message(header[1],body); free(body); } } return 0; } /************************************************************************** * process_message * Based on ProcessMassage() from FvwmWinList: * Copyright 1994, Mike Finger. *************************************************************************/ int diffx, diffy; void process_message(unsigned long type, unsigned long *body) { struct icon_info *tmp, *old; char *str; long olddesk; switch(type){ case M_CONFIGURE_WINDOW: if (ready){ if (!(local_flags & CURRENT_ONLY)) break; tmp = Head; while(tmp != NULL){ if (tmp->id == body[0]){ if ((tmp->desk != body[7]) && !(tmp->flags & STICKY)){ olddesk = tmp->desk; tmp->desk = body[7]; if (olddesk == CurrentDesk || tmp->desk == CurrentDesk){ if (tmp->desk == CurrentDesk && sortby != UNSORT) SortItem(NULL); num_icons = AdjustIconWindows(); GetIconwinSize(&diffx, &diffy); if (diffy && (primary == BOTTOM || secondary == BOTTOM)) icon_win_y += diffy; if (diffx && (primary == RIGHT || secondary == RIGHT)) icon_win_x += diffx; if (icon_win_y < 0) icon_win_y = 0; if (icon_win_x < 0) icon_win_x = 0; if (icon_win_x + Width > icon_win_width) icon_win_x = icon_win_width - Width; if (icon_win_y + Height > icon_win_height) icon_win_y = icon_win_height - Height; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); if (tmp->desk == CurrentDesk){ XMapWindow(dpy, tmp->IconWin); if (max_icon_height != 0) XMapWindow(dpy, tmp->icon_pixmap_w); }else{ XUnmapWindow(dpy, tmp->IconWin); if (max_icon_height != 0) XUnmapWindow(dpy, tmp->icon_pixmap_w); } if (!(local_flags & HIDE_H) && diffx) RedrawHScrollbar(); if (!(local_flags & HIDE_V) && diffy) RedrawVScrollbar(); } }else if ((body[8] & STICKY) && !(tmp->flags & STICKY)) /* stick */ tmp->flags |= STICKY; else if (!(body[8] & STICKY) && (tmp->flags & STICKY)){ /* unstick */ tmp->flags &= ~STICKY; tmp->desk = body[7]; } return; } tmp = tmp->next; } break; } case M_ADD_WINDOW: if (AddItem(body[0], body[7], body[8]) == True && ready){ GetIconwinSize(&diffx, &diffy); if (diffy && (primary == BOTTOM || secondary == BOTTOM)) icon_win_y += diffy; if (diffx && (primary == RIGHT || secondary == RIGHT)) icon_win_x += diffx; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); } break; case M_DESTROY_WINDOW: if (DeleteItem(body[0]) && ready){ GetIconwinSize(&diffx, &diffy); if (diffy && (primary == BOTTOM || secondary == BOTTOM)) icon_win_y += diffy; if (diffx && (primary == RIGHT || secondary == RIGHT)) icon_win_x += diffx; if (icon_win_y < 0) icon_win_y = 0; if (icon_win_x < 0) icon_win_x = 0; if (icon_win_x + Width > icon_win_width) icon_win_x = icon_win_width - Width; if (icon_win_y + Height > icon_win_height) icon_win_y = icon_win_height - Height; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); AdjustIconWindows(); if (!(local_flags & HIDE_H) && diffx) RedrawHScrollbar(); if (!(local_flags & HIDE_V) && diffy) RedrawVScrollbar(); } break; case M_ICON_FILE: case M_RES_CLASS: UpdateItem(type, body[0], (char *)&body[3]); break; case M_WINDOW_NAME: tmp = UpdateItem(type, body[0], (char *)&body[3]); if (!ready || tmp == NULL) break; if (sortby == WINDOWNAME && tmp->IconWin != None && desk_cond(tmp) && SortItem(tmp) == True) AdjustIconWindows(); break; case M_RES_NAME: if ((tmp = UpdateItem(type, body[0], (char *)&body[3])) == NULL) break; if (LookInList(tmp) && ready){ if (sortby != UNSORT) SortItem(tmp); CreateIconWindow(tmp); ConfigureIconWindow(tmp); AdjustIconWindows(); if (desk_cond(tmp)){ if (max_icon_height != 0) XMapWindow(dpy, tmp->icon_pixmap_w); XMapWindow(dpy, tmp->IconWin); if (!(local_flags & HIDE_H)) RedrawHScrollbar(); if (!(local_flags & HIDE_V)) RedrawVScrollbar(); } } break; case M_ICON_NAME: tmp = UpdateItem(type, body[0], (char *)&body[3]); if (!ready || tmp == NULL) break; if (sortby != UNSORT && tmp->IconWin != None && desk_cond(tmp) && SortItem(tmp) == True) AdjustIconWindows(); if (tmp->IconWin != None && desk_cond(tmp)) RedrawIcon(tmp, 2); break; case M_DEFAULTICON: str = (char *)safemalloc(strlen((char *)&body[3])+1); strcpy(str, (char *)&body[3]); FvwmDefaultIcon = str; break; case M_ICONIFY: case M_DEICONIFY: if (ready && (tmp = SetFlag(body[0], type)) != NULL) RedrawIcon(tmp, 2); break; case M_FOCUS_CHANGE: if (!ready) break; tmp = Head; while(tmp != NULL){ if (tmp->id == body[0]) break; tmp = tmp->next; } old = Hilite; Hilite = tmp; if (old != NULL) RedrawIcon(old, redraw_flag); if (tmp != NULL) RedrawIcon(tmp, redraw_flag); break; case M_NEW_DESK: if (CurrentDesk != body[0]){ CurrentDesk = body[0]; if (body[0] != 10000 && ready){ /* 10000 is a "magic" number used in FvwmPager */ if (sortby != UNSORT) SortItem(NULL); num_icons = AdjustIconWindows(); GetIconwinSize(&diffx, &diffy); icon_win_x = icon_win_y = 0; if (primary == BOTTOM || secondary == BOTTOM) icon_win_y = icon_win_height - Height; if (primary == RIGHT || secondary == RIGHT) icon_win_x = icon_win_width - Width; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); XUnmapSubwindows(dpy, icon_win); mapicons(); if (!(local_flags & HIDE_H)) RedrawHScrollbar(); if (!(local_flags & HIDE_V)) RedrawVScrollbar(); } } break; case M_END_WINDOWLIST: GetIconwinSize(&diffx, &diffy); tmp = Head; while(tmp != NULL){ CreateIconWindow(tmp); ConfigureIconWindow(tmp); tmp = tmp->next; } if (sortby != UNSORT) SortItem(NULL); if (primary == BOTTOM || secondary == BOTTOM) icon_win_y = icon_win_height - Height; if (primary == RIGHT || secondary == RIGHT) icon_win_x = icon_win_width - Width; XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y, icon_win_width, icon_win_height); AdjustIconWindows(); XMapWindow(dpy,main_win); XMapSubwindows(dpy, main_win); XMapWindow(dpy, icon_win); mapicons(); ready = 1; break; default: break; } } struct icon_info *SetFlag(unsigned long id, int t) { struct icon_info *tmp; tmp = Head; while(tmp != NULL){ if (tmp->id == id){ if (t == M_ICONIFY) tmp->flags |= ICONIFIED; else tmp->flags ^= ICONIFIED; return tmp; } tmp = tmp->next; } return NULL; } void mapicons(void) { struct icon_info *tmp; tmp = Head; while(tmp != NULL){ if (desk_cond(tmp)){ XMapWindow(dpy, tmp->IconWin); if (max_icon_height != 0) XMapWindow(dpy, tmp->icon_pixmap_w); } tmp = tmp->next; } } int AdjustIconWindows(void) { struct icon_info *tmp; int i = 0; tmp = Head; while(tmp != NULL){ if (desk_cond(tmp) && tmp->IconWin != None) AdjustIconWindow(tmp, i++); tmp = tmp->next; } return i; } int desk_cond(struct icon_info *item) { if (!(local_flags & CURRENT_ONLY) || (item->flags & STICKY) || (item->desk == CurrentDesk)) return 1; return 0; } /************************************************************************ * AddItem * Skeleton based on AddItem() from FvwmWinList: * Copyright 1994, Mike Finger. ***********************************************************************/ Bool AddItem(unsigned long id, long desk, unsigned long flags) { struct icon_info *new, *tmp; tmp = Head; if (id == main_win || (flags & TRANSIENT) || !(flags & SUPPRESSICON)) return False; while (tmp != NULL){ if (tmp->id == id || (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint) && tmp->wmhints->icon_window == id)) return False; tmp = tmp->next; } new = (struct icon_info *)safemalloc(sizeof(struct icon_info)); new->name = NULL; new->window_name = NULL; new->res_class = NULL; new->res_name = NULL; new->action = NULL; new->icon_file = NULL; new->icon_w = 0; new->icon_h = 0; new->IconWin = None; new->iconPixmap = None; new->icon_maskPixmap = None; new->icon_pixmap_w = None; new->icon_depth = 0; new->desk = desk; new->id = id; new->extra_flags = DEFAULTICON; new->flags = flags | ICON_OURS; new->wmhints = NULL; /* add new item to the head of the list new->prev = NULL; new->next = Head; if (Head != NULL) Head->prev = new; else Tail = new; Head = new; */ /* add new item to the tail of the list */ new->prev = Tail; new->next = NULL; if (Tail != NULL) Tail->next = new; else Head = new; Tail = new; if (desk_cond(new)) num_icons++; return True; } /************************************************************************ * Deletetem * Skeleton based on DeleteItem() from FvwmWinList: * Copyright 1994, Mike Finger. ***********************************************************************/ Bool DeleteItem(unsigned long id) { struct icon_info *tmp = Head; while(tmp != NULL){ if (tmp->id == id){ if (desk_cond(tmp)) num_icons--; if (Hilite == tmp) Hilite = NULL; if ((tmp->icon_pixmap_w != None) && (tmp->flags & ICON_OURS)) XDestroyWindow(dpy, tmp->icon_pixmap_w); if (tmp->IconWin != None) XDestroyWindow(dpy, tmp->IconWin); if (tmp == Head){ Head = tmp->next; if (Head != NULL) Head->prev = NULL; else Tail = NULL; }else { if (Tail == tmp) Tail = tmp->prev; tmp->prev->next = tmp->next; if (tmp->next != NULL) tmp->next->prev = tmp->prev; } freeitem(tmp, 1); return True; } tmp = tmp->next; } return False; } /************************************************************************ * UpdateItem * Skeleton based on UpdateItem() from FvwmWinList: * Copyright 1994, Mike Finger. ***********************************************************************/ struct icon_info *UpdateItem(unsigned long type, unsigned long id, char *item) { struct icon_info *tmp; char *str; XClassHint classhint; int ret; tmp = Head; while (tmp != NULL){ if (tmp->id == id){ str = (char *)safemalloc(strlen(item)+1); strcpy(str, item); switch (type){ case M_ICON_NAME: if (tmp->name != NULL) free(tmp->name); tmp->name = str; return tmp; case M_ICON_FILE: tmp->icon_file = str; tmp->extra_flags &= ~DEFAULTICON; return tmp; case M_WINDOW_NAME: if (tmp->window_name != NULL) free(tmp->window_name); tmp->window_name = str; return tmp; case M_RES_CLASS: tmp->res_class = str; ret = 0; if (sortby == RESCLASS && strcmp(NoClass, str) == 0 && !(ret = XGetClassHint(dpy, tmp->id, &classhint))){ tmp->extra_flags |= NOCLASS; } if (ret){ if (classhint.res_class != NULL) XFree(classhint.res_class); if (classhint.res_name != NULL) XFree(classhint.res_name); } return tmp; case M_RES_NAME: tmp->res_name = str; ret = 0; if (sortby == RESNAME && strcmp(NoResource, str) == 0 && !(ret = XGetClassHint(dpy, tmp->id, &classhint))) tmp->extra_flags |= NONAME; if (ret){ if (classhint.res_class != NULL) XFree(classhint.res_class); if (classhint.res_name != NULL) XFree(classhint.res_name); } return tmp; } } tmp = tmp->next; } return NULL; } Bool SortItem(struct icon_info *item) { struct icon_info *tmp1=Head, *a, *b, *tmp2; if (tmp1 == NULL) return False; if (item != NULL && ((itemcmp(item->prev, item) <= 0) && (itemcmp(item->next, item) >= 0))) return False; while (tmp1->next != NULL){ tmp2 = MinItem(tmp1); if (tmp1 == tmp2){ tmp1 = tmp1->next; continue; } if (tmp1 == Head) Head = tmp2; a = tmp1->prev; b = tmp1->next; if (tmp1->prev != NULL) tmp1->prev->next = tmp2; if (b != tmp2) tmp1->next->prev = tmp2; if (b != tmp2) tmp2->prev->next = tmp1; if (tmp2->next != NULL) tmp2->next->prev = tmp1; if (b == tmp2){ tmp1->prev = tmp2; tmp1->next = tmp2->next; tmp2->prev = a; tmp2->next = tmp1; }else{ tmp1->prev = tmp2->prev; tmp1->next = tmp2->next; tmp2->prev = a; tmp2->next = b; } tmp1 = b; } Tail = tmp1; return True; } struct icon_info *MinItem(struct icon_info *head) { struct icon_info *tmp, *i_min; if (head == NULL) return NULL; i_min = head; tmp = head->next; while (tmp != NULL){ if (itemcmp(i_min, tmp) > 0) i_min = tmp; tmp = tmp->next; } return i_min; } int itemcmp(struct icon_info *item1, struct icon_info *item2) { int ret1, ret2; if (item1 == NULL){ if (item2 == NULL) return 0; else return -1; } else if (item2 == NULL) return 1; /* skip items not on the current desk */ ret1 = desk_cond(item1); ret2 = desk_cond(item2); if (!ret1 || !ret2) return (ret1 - ret2); ret1 = 0; ret2 = strcmp(item1->name, item2->name); switch(sortby){ case WINDOWNAME: ret1 = strcmp(item1->window_name, item2->window_name); break; case RESCLASS: if ((item1->extra_flags & NOCLASS)){ if ((item2->extra_flags & NOCLASS)) ret1 = 0; else if (!(item2->extra_flags & NOCLASS)) ret1 = -1; }else if ((item2->extra_flags & NOCLASS)) ret1 = 1; else ret1 = strcmp(item1->res_class, item2->res_class); break; case RESNAME: if ((item1->extra_flags & NOCLASS)){ if ((item2->extra_flags & NOCLASS)) ret1 = 0; else if (!(item2->extra_flags & NOCLASS)) ret1 = -1; }else if ((item2->extra_flags & NOCLASS)) ret1 = 1; else ret1 = strcmp(item1->res_name, item2->res_name); break; default: break; } return (ret1 != 0 ? ret1 : ret2); } /* void ShowItem(struct icon_info *head) { struct icon_info *tmp; fprintf(stderr, "The contents of item are as follows:\n"); tmp = head; while (tmp != NULL){ fprintf(stderr, "id:%x name:%s resname:%s class%s iconfile:%s\n", tmp->id, tmp->name == NULL ? "NULL" : tmp->name, tmp->res_name, tmp->res_class, tmp->icon_file); tmp = tmp->next; } } void ShowAction(void) { struct mousefunc *tmp; tmp = MouseActions; while (tmp != NULL){ fprintf(stderr, "mouse:%d type %d action:%s\n", tmp->mouse, tmp->type, tmp->action); tmp = tmp->next; } } void ShowKAction(void) { struct keyfunc *tmp; tmp = KeyActions; while (tmp != NULL){ fprintf(stderr, "key:%s keycode:%d action:%s\n", tmp->name, tmp->keycode, tmp->action); tmp = tmp->next; } } */ void freeitem(struct icon_info *item, int d) { if (item == NULL) return; if (!(item->flags & ICON_OURS)){ if (max_icon_height != 0) XUnmapWindow(dpy, item->icon_pixmap_w); if (d == 0) XReparentWindow(dpy, item->icon_pixmap_w, Root, 0, 0); } if (item->name != NULL) free(item->name); if (item->window_name != NULL) free(item->window_name); if (item->res_name != NULL) free(item->res_name); if (item->res_class != NULL) free(item->res_class); if (item->wmhints != NULL) XFree(item->wmhints); if (item->iconPixmap != None) XFreePixmap(dpy, item->iconPixmap); if (item->icon_maskPixmap != None && (item->wmhints == NULL || !(item->wmhints->flags & (IconPixmapHint|IconWindowHint)))) XFreePixmap(dpy, item->icon_maskPixmap); free(item); } /************************************************************************ IsClick Based on functions.c from Fvwm: Copyright 1988, Evans and Sutherland Computer Corporation, Copyright 1989, Massachusetts Institute of Technology, Copyright 1993, Robert Nation. ***********************************************************************/ Bool IsClick(int x,int y,unsigned EndMask, XEvent *d) { int xcurrent,ycurrent,total = 0; xcurrent = x; ycurrent = y; while((total < ClickTime)&& (x - xcurrent < 5)&&(x - xcurrent > -5)&& (y - ycurrent < 5)&&(y - ycurrent > -5)) { usleep(10000); total+=10; if(XCheckMaskEvent (dpy,EndMask, d)) return True; if(XCheckMaskEvent (dpy,ButtonMotionMask|PointerMotionMask, d)) { xcurrent = d->xmotion.x_root; ycurrent = d->xmotion.y_root; } } return False; } /************************************************************************ * ExecuteAction * Based on part of ComplexFunction() of functions.c from fvwm: Copyright 1988, Evans and Sutherland Computer Corporation, Copyright 1989, Massachusetts Institute of Technology, Copyright 1993, Robert Nation. ***********************************************************************/ void ExecuteAction(int x, int y, struct icon_info *item) { int type = NO_CLICK; XEvent *ev; XEvent d; struct mousefunc *tmp; /* Wait and see if we have a click, or a move */ /* wait 100 msec, see if the used releases the button */ if(IsClick(x,y,ButtonReleaseMask,&d)) { type = CLICK; ev = &d; } /* If it was a click, wait to see if its a double click */ if((type == CLICK) && (IsClick(x,y,ButtonPressMask, &d))) { type = ONE_AND_A_HALF_CLICKS; ev = &d; } if((type == ONE_AND_A_HALF_CLICKS) && (IsClick(x,y,ButtonReleaseMask, &d))) { type = DOUBLE_CLICK; ev = &d; } tmp = MouseActions; while (tmp != NULL){ if (tmp->mouse == d.xbutton.button && tmp->type == type){ SendFvwmPipe(fd, tmp->action, item->id); return; } tmp = tmp->next; } } void ExecuteKey(XEvent event) { struct icon_info *item; struct keyfunc *tmp; if ((item = Hilite) == NULL) if ((item = Head) == NULL) return; tmp = KeyActions; event.xkey.keycode = XKeysymToKeycode(dpy,XKeycodeToKeysym(dpy,event.xkey.keycode,0)); while (tmp != NULL){ if (tmp->keycode == event.xkey.keycode){ SendFvwmPipe(fd, tmp->action, item->id); return; } tmp = tmp->next; } } /*********************************************************************** LookInList Based on part of LookInList() of add_window.c from fvwm: Copyright 1988, Evans and Sutherland Computer Corporation, Copyright 1989, Massachusetts Institute of Technology, Copyright 1993, Robert Nation. ***********************************************************************/ int LookInList(struct icon_info *item) { int isdefault=1; char *value=NULL; struct iconfile *nptr; if (IconListHead == NULL) { if ((item->extra_flags & DEFAULTICON) && (FvwmDefaultIcon != NULL)) item->icon_file = FvwmDefaultIcon; return 1; } for (nptr = IconListHead; nptr != NULL; nptr = nptr->next){ if (nptr == DefaultIcon) isdefault = 1; if (matchWildcards(nptr->name, item->res_class) == TRUE){ value = nptr->iconfile; if (nptr != DefaultIcon) isdefault = 0; } if (matchWildcards(nptr->name, item->res_name) == TRUE){ value = nptr->iconfile; if (nptr != DefaultIcon) isdefault = 0; } if (matchWildcards(nptr->name, item->window_name) == TRUE){ value = nptr->iconfile; if (nptr != DefaultIcon) isdefault = 0; } } if (!isdefault){ item->icon_file = value; item->extra_flags &= ~DEFAULTICON; }else if ((item->extra_flags & DEFAULTICON)){ if (DefaultIcon != NULL) item->icon_file = DefaultIcon->iconfile; else if (FvwmDefaultIcon != NULL) item->icon_file = FvwmDefaultIcon; } /* Icon is not shown if "-" is specified */ if (item->icon_file != NULL && (strcmp(item->icon_file, "-") == 0)){ DeleteItem(item->id); return 0; } return 1; } /*********************************************************************** strcpy Based on stripcpy2() of configure.c from Fvwm: Copyright 1988, Evans and Sutherland Computer Corporation, Copyright 1989, Massachusetts Institute of Technology, Copyright 1993, Robert Nation. ***********************************************************************/ char *stripcpy2(char *source) { char *ptr; int count = 0; while((*source != '"')&&(*source != 0)) source++; if(*source == 0) return 0; source++; ptr = source; while((*ptr!='"')&&(*ptr != 0)){ ptr++; count++; } ptr = safemalloc(count+1); strncpy(ptr,source,count); ptr[count]=0; return ptr; } /*********************************************************************** Error handler ***********************************************************************/ XErrorHandler myErrorHandler(Display *dpy, XErrorEvent *event) { char msg[256]; if (event->error_code == BadWindow) return 0; XGetErrorText(dpy, event->error_code, msg, 256); fprintf(stderr, "Error in %s: %s \n", MyName, msg); fprintf(stderr, "Major opcode of failed request: %d \n", event->request_code); fprintf(stderr, "Resource id of failed request: 0x%lx \n", event->resourceid); return 0; }