FVWM: I've added miniicons to fvwm. Here's the patch

From: Brady Montz <bradym_at_cs.arizona.edu>
Date: 22 Sep 1996 11:37:47 -0700

Got tired of people (including me) talking about it, so I spent yesterday
adding miniicons into fvwm. I don't expect this stuff to be put into the 2.1
release (nor do I think it's necessarily wise to do so). I basically followed
what fvwm95 did, with the following changes:

1. Instead of calling these things title icons, they're mini icons, since they
   can be used in other places than the title bar.

2. You use the ButtonStyle's to say where it goes, exactly like how
   PixmapButtons does it.

I changed the builtin WindowList to use the icons, and added some stuff to
FvwmIconMan to use the miniicon to denote an iconified window instead of the
raised square thing. The FvwmIconMan code is rather rough proof-of-concept
type code (you can't turn off displaying icons mainly), but it seems to work.
Also, the version of FvwmIconMan that I hacked is the one that's due to come
out in the next release of fvwm, and is significantly different than the one
in 2.0.43. Read the CHANGES file and the manpage for info (nothing on
miniicons is mentioned though).

I didn't do anything to FvwmWinList, since somebody else indicated that they
were willing to do that.

Here's the relevant lines from my .fvwm2rc file:

Style "*" MiniIcon mini-bx2.xpm
Style "xterm" MiniIcon mini.xterm.xpm
Style "Emacs" MiniIcon mini-doc.xpm

ButtonStyle 1 MiniIcon

That's it. As with pixmapbuttons, you can use a buttonstyle of MiniIcon
to have a relief put around the pixmap, or you can use FullMiniIcon to have no
relief.

Also, there's no provision for a default MiniIcon, except for the "*" style.
If it can't find one, you get a blank spot.

I've protected all of the code that matters with #ifdef MINI_ICONS, so
(a) you need that set in your Fvwm.tmpl (the patch does that), and it pretty
clearly marks out where I've made changes. Finally, you need XPM.


-- 
 Brady Montz
 bradym_at_cs.arizona.edu
diff -rc fvwm-2.0.43/Fvwm.tmpl fvwm.patched/Fvwm.tmpl
*** fvwm-2.0.43/Fvwm.tmpl	Thu Jun 27 07:57:21 1996
--- fvwm.patched/Fvwm.tmpl	Sun Sep 22 11:06:08 1996
***************
*** 164,170 ****
   * 
   ***************************************************************************/
  
! OPTION_DEFINES = -DSHAPE -DPIXMAP_BUTTONS 
  
  
  
--- 164,170 ----
   * 
   ***************************************************************************/
  
! OPTION_DEFINES = -DSHAPE -DPIXMAP_BUTTONS -DMINI_ICONS
  
  
  
diff -rc fvwm-2.0.43/fvwm/add_window.c fvwm.patched/fvwm/add_window.c
*** fvwm-2.0.43/fvwm/add_window.c	Thu Apr 11 08:25:58 1996
--- fvwm.patched/fvwm/add_window.c	Sat Sep 21 22:03:29 1996
***************
*** 65,70 ****
--- 65,72 ----
      {"-xrm",		NULL,		XrmoptionResArg, (caddr_t) NULL},
  };
  
+ extern char *IconPath, *PixmapPath;
+ 
  /***********************************************************************
   *
   *  Procedure:
***************
*** 85,91 ****
    XSetWindowAttributes attributes;	/* attributes for create windows */
    int i,width,height;
    int a,b;
!   char *value;
    unsigned long tflag;
    int Desk, border_width, resize_width;
    extern Bool NeedToResizeToo;
--- 87,93 ----
    XSetWindowAttributes attributes;	/* attributes for create windows */
    int i,width,height;
    int a,b;
!   char *value, *mini_value;
    unsigned long tflag;
    int Desk, border_width, resize_width;
    extern Bool NeedToResizeToo;
***************
*** 109,114 ****
--- 111,120 ----
    tmp_win->w = w;
  
    tmp_win->cmap_windows = (Window *)NULL;
+ #ifdef MINI_ICONS
+   tmp_win->mini_pixmap_file = NULL;
+   tmp_win->mini_icon = NULL;
+ #endif
  
    if(!PPosOverride)
      if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY,
***************
*** 177,183 ****
    tmp_win->flags |= TITLE;
    tmp_win->title_height = Scr.TitleHeight + tmp_win->bw;
  
!   tflag = LookInList(Scr.TheList,tmp_win->name,&tmp_win->class, &value, &Desk,
  		     &border_width, &resize_width,
                       &forecolor,&backcolor,&tmp_win->buttons, 
  		     tmp_win->IconBox,&(tmp_win->BoxFillMethod));
--- 183,193 ----
    tmp_win->flags |= TITLE;
    tmp_win->title_height = Scr.TitleHeight + tmp_win->bw;
  
!   tflag = LookInList(Scr.TheList,tmp_win->name,&tmp_win->class, &value, 
! #ifdef MINI_ICONS
! 		     &mini_value, 
! #endif
! 		     &Desk,
  		     &border_width, &resize_width,
                       &forecolor,&backcolor,&tmp_win->buttons, 
  		     tmp_win->IconBox,&(tmp_win->BoxFillMethod));
***************
*** 206,211 ****
--- 216,230 ----
        tmp_win->icon_bitmap_file = Scr.DefaultIcon;
      }
  
+ #ifdef MINI_ICONS
+   if (tflag & MINIICON_FLAG) {
+     tmp_win->mini_pixmap_file = mini_value;
+   }
+   else {
+     tmp_win->mini_pixmap_file = NULL;
+   }
+ #endif
+ 
    GetWindowSizeHints (tmp_win);
  
    /* Tentative size estimate */
***************
*** 406,411 ****
--- 425,440 ----
  	  else
  	    tmp_win->right_w[i] = None;
  	}
+ #ifdef MINI_ICONS
+       if (tmp_win->mini_pixmap_file) {
+ 	tmp_win->mini_icon = CachePicture (dpy, Scr.Root, 
+ 					   IconPath, PixmapPath, 
+ 					   tmp_win->mini_pixmap_file);
+       }
+       else {
+ 	tmp_win->mini_icon = NULL;
+       }
+ #endif
      }
  
    if(tmp_win->flags & BORDER)
***************
*** 521,526 ****
--- 550,565 ----
  		(unsigned long)tmp_win,tmp_win->class.res_class);
    BroadcastName(M_RES_NAME,tmp_win->w,tmp_win->frame,
  		(unsigned long)tmp_win,tmp_win->class.res_name);
+ #ifdef MINI_ICONS
+   if (tmp_win->mini_icon != NULL)
+     Broadcast(M_MINI_ICON, 6,
+               tmp_win->w, /* Watch Out ! : I reduced the set of infos... */
+               tmp_win->mini_icon->picture,
+               tmp_win->mini_icon->mask,
+               tmp_win->mini_icon->width,
+               tmp_win->mini_icon->height,
+               tmp_win->mini_icon->depth, 0);
+ #endif
  
    FetchWmProtocols (tmp_win);
    FetchWmColormapWindows (tmp_win);
***************
*** 800,813 ****
   *
   ***********************************************************************/
  unsigned long LookInList(name_list *list, char *name, XClassHint *class, 
! 			 char **value, int *Desk, int *border_width,
  			 int *resize_width, char **forecolor, char **backcolor,
!                          unsigned long * buttons, int *IconBox, int *BoxFillMethod)
  {
    name_list *nptr;
    unsigned long retval = 0;
  
    *value = NULL;
    *forecolor = NULL;
    *backcolor = NULL;
    *Desk = 0;
--- 839,861 ----
   *
   ***********************************************************************/
  unsigned long LookInList(name_list *list, char *name, XClassHint *class, 
! 			 char **value, 
! #ifdef MINI_ICONS
! 			 char **mini_value, 
! #endif
! 			 int *Desk, 
! 			 int *border_width,
  			 int *resize_width, char **forecolor, char **backcolor,
!                          unsigned long * buttons, int *IconBox, 
! 			 int *BoxFillMethod)
  {
    name_list *nptr;
    unsigned long retval = 0;
  
    *value = NULL;
+ #ifdef MINI_ICONS
+   *mini_value = NULL;
+ #endif
    *forecolor = NULL;
    *backcolor = NULL;
    *Desk = 0;
***************
*** 829,834 ****
--- 877,885 ----
  	  if (matchWildcards(nptr->name,class->res_class) == TRUE)
  	    {
  	      if(nptr->value != NULL)*value = nptr->value;
+ #ifdef MINI_ICONS
+ 	      if(nptr->mini_value != NULL) *mini_value = nptr->mini_value;
+ #endif
  	      if(nptr->off_flags & STARTSONDESK_FLAG)
  		*Desk = nptr->Desk;
  	      if(nptr->off_flags & BW_FLAG)
***************
*** 858,863 ****
--- 909,917 ----
  	  if (matchWildcards(nptr->name,class->res_name) == TRUE)
  	    {
  	      if(nptr->value != NULL)*value = nptr->value;
+ #ifdef MINI_ICONS
+ 	      if(nptr->mini_value != NULL) *mini_value = nptr->mini_value;
+ #endif
  	      if(nptr->off_flags & STARTSONDESK_FLAG)
  		*Desk = nptr->Desk;
  	      if(nptr->off_flags & FORE_COLOR_FLAG)
***************
*** 887,892 ****
--- 941,949 ----
        if (matchWildcards(nptr->name,name) == TRUE)
  	{
  	  if(nptr->value != NULL)*value = nptr->value;
+ #ifdef MINI_ICONS
+ 	  if(nptr->mini_value != NULL) *mini_value = nptr->mini_value;
+ #endif
  	  if(nptr->off_flags & STARTSONDESK_FLAG)	   
  	    *Desk = nptr->Desk;
  	  if(nptr->off_flags & FORE_COLOR_FLAG)
diff -rc fvwm-2.0.43/fvwm/borders.c fvwm.patched/fvwm/borders.c
*** fvwm-2.0.43/fvwm/borders.c	Thu Apr 11 08:27:10 1996
--- fvwm.patched/fvwm/borders.c	Sat Sep 21 18:33:11 1996
***************
*** 196,201 ****
--- 196,238 ----
                            t->title_height);
  	    break;
  
+ #ifdef MINI_ICONS
+ 	  case MiniIconButton:
+ 	  case FullMiniIconButton:
+ 	    if (!t->mini_icon)
+ 	      break;
+ 	    pbf = *t->mini_icon;
+ 	    if (Scr.button_style[button] == FullMiniIconButton) 
+ 	    {
+ 	      /* button face max width/height */
+ 	      a = t->title_height;
+ 	      x=(a - pbf.width) / 2; if (x < 0) x = 0; 
+ 	      y=(a - pbf.height) / 2; if (y < 0) y = 0;
+ 	      if (pbf.width > a) pbf.width = a; 
+ 	      if (pbf.height > a) pbf.height = a;
+ 	      XClearArea(dpy, t->left_w[i], 0, 0, a + 2, a + 2, False);
+ 	    }
+ 	    else
+ 	    {
+ 	      /* button face max width/height */
+ 	      a = t->title_height - 2;
+ 	      x=(a - pbf.width) / 2 + 1; if (x < 1) x = 1; 
+ 	      y=(a - pbf.height) / 2 + 1; if (y < 1) y = 1;
+ 	      if (pbf.width >= a) pbf.width = a - 1; 
+ 	      if (pbf.height >= a) pbf.height = a - 1;
+ 	      XClearArea(dpy, t->left_w[i], 1, 1, a - 1, a - 1, False);
+ 	    }
+ 
+ 	    /* set transparency mask */
+ 	    XSetClipMask(dpy, Scr.ButtonMaskGC, pbf.mask);
+ 	    XSetClipOrigin(dpy, Scr.ButtonMaskGC, x, y);
+ 
+ 	    /* draw the new button face */
+ 	    XCopyArea(dpy, pbf.picture, t->left_w[i], Scr.ButtonMaskGC,
+ 		      0, 0, pbf.width, pbf.height, x, y);
+ 	    break;
+ #endif
+ 
  #ifdef XPM
  #ifdef PIXMAP_BUTTONS
  	  case PixmapButton:
diff -rc fvwm-2.0.43/fvwm/builtins.c fvwm.patched/fvwm/builtins.c
*** fvwm-2.0.43/fvwm/builtins.c	Thu Jun 27 07:34:19 1996
--- fvwm.patched/fvwm/builtins.c	Sat Sep 21 18:23:06 1996
***************
*** 599,606 ****
    if(tmp_win)
      RaiseWindow(tmp_win);
  
!   if (LookInList(Scr.TheList,tmp_win->name, &tmp_win->class, &junk, &junkD,
! 		 &junkD, &junkD, &junkC, &junkC, &junkN,
  		 BoxJunk,  &method)& STAYSONTOP_FLAG)
      tmp_win->flags |= ONTOP;
    KeepOnTop();
--- 599,609 ----
    if(tmp_win)
      RaiseWindow(tmp_win);
  
!   if (LookInList(Scr.TheList,tmp_win->name, &tmp_win->class, &junk, 
! #ifdef MINI_ICONS
! 		 &junk,
! #endif
! 		 &junkD, &junkD, &junkD, &junkC, &junkC, &junkN,
  		 BoxJunk,  &method)& STAYSONTOP_FLAG)
      tmp_win->flags |= ONTOP;
    KeepOnTop();
***************
*** 970,975 ****
--- 973,981 ----
    {
      RaiseWindow(tmp_win);
      if (LookInList(Scr.TheList,tmp_win->name, &tmp_win->class,&junk,
+ #ifdef MINI_ICONS
+ 		   &junk,
+ #endif
                     &junkD,&junkD, &junkD, &junkC,&junkC,&junkN,BoxJunk,
                     &method)&STAYSONTOP_FLAG)
        tmp_win->flags |= ONTOP;	    
***************
*** 1725,1730 ****
--- 1731,1754 ----
               "Pixmap button style requires Xpm support -- line: %s",action);
  #endif /* XPM */
    } 
+   else if (!mystrncasecmp (button_style, "MiniIcon", 8)) {
+ #ifdef MINI_ICONS
+     Scr.button_style[button] = MiniIconButton;
+ #else /* !defined (MINI_ICONS) */
+     fvwm_msg (ERR, "ButtonStyle",
+ 	      "MiniIcon button style not supported -- line: %s",
+ 	      action);
+ #endif /* MINI_ICONS */
+   }
+   else if (!mystrncasecmp (button_style, "FullMiniIcon", 8)) {
+ #ifdef MINI_ICONS
+     Scr.button_style[button] = FullMiniIconButton;
+ #else /* !defined (MINI_ICONS) */
+     fvwm_msg (ERR, "ButtonStyle",
+ 	      "FullMiniIcon button style not supported -- line: %s",
+ 	      action);
+ #endif /* MINI_ICONS */
+   }
    else 
    {
      fvwm_msg(ERR,"ButtonStyle",
diff -rc fvwm-2.0.43/fvwm/fvwm.h fvwm.patched/fvwm/fvwm.h
*** fvwm-2.0.43/fvwm/fvwm.h	Thu Apr 11 08:22:24 1996
--- fvwm.patched/fvwm/fvwm.h	Sat Sep 21 15:58:33 1996
***************
*** 118,123 ****
--- 118,126 ----
    Pixel back;
  } ColorPair;
  
+ #ifdef MINI_ICONS
+ #include "../libs/fvwmlib.h"
+ #endif
  
  /* for each window that is on the display, one of these structures
   * is allocated and linked into a list 
***************
*** 180,185 ****
--- 183,192 ----
      Window transientfor;
  
      unsigned long flags;
+ #ifdef MINI_ICONS
+     char *mini_pixmap_file;
+     Picture *mini_icon;
+ #endif
      char *icon_bitmap_file;
  
      int orig_x;                 /* unmaximized x coordinate */
diff -rc fvwm-2.0.43/fvwm/misc.h fvwm.patched/fvwm/misc.h
*** fvwm-2.0.43/fvwm/misc.h	Wed Jun 19 18:31:15 1996
--- fvwm.patched/fvwm/misc.h	Sat Sep 21 17:03:09 1996
***************
*** 20,25 ****
--- 20,28 ----
    struct name_list_struct *next;   /* pointer to the next name */
    char *name;		  	   /* the name of the window */
    char *value;                     /* icon name */
+ #ifdef MINI_ICONS
+   char *mini_value;                /* mini icon name */
+ #endif
    int Desk;                        /* Desktop number */
    unsigned long on_flags; 
    unsigned long off_flags; 
***************
*** 96,101 ****
--- 99,108 ----
  #define NO_PPOSITION_FLAG    (1<<29)
  #define OL_DECOR_FLAG        (1<<30)
  
+ #ifdef MINI_ICONS
+ #define MINIICON_FLAG        (1<<31)
+ #endif
+ 
  /* some fancy font handling stuff */
  #define NewFontAndColor(newfont,color,backcolor) {\
     Globalgcv.font = newfont;\
***************
*** 121,127 ****
  extern char NoResource[];
  
  extern unsigned long LookInList(name_list *, char *, XClassHint *, 
! 				char **value, int *Desk, int *bw, int *nobw,
  				char **forecolor, char **backcolor, 
                                  unsigned long * buttons, int *IconBox, 
  				int *BoxFillMethod);
--- 128,139 ----
  extern char NoResource[];
  
  extern unsigned long LookInList(name_list *, char *, XClassHint *, 
! 				char **value, 
! #ifdef MINI_ICONS
! char **mini_value, 
! #endif
! 				int *Desk, 
! 				int *bw, int *nobw,
  				char **forecolor, char **backcolor, 
                                  unsigned long * buttons, int *IconBox, 
  				int *BoxFillMethod);
***************
*** 291,301 ****
--- 303,323 ----
  void ParseKeyEntry(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *tline,int* Module);
  void SetOneStyle(char *text,FILE *,char **,int *);
+ 
+ #ifdef MINI_ICONS
+ void AddToList(char *name, char *icon_name, char *miniicon_name, 
+ 	       unsigned long off_flags, 
+ 	       unsigned long on_flags, int desk,int bw, int nobw, 
+ 	       char *forecolor, char *backcolor,
+                unsigned long off_buttons, unsigned long on_buttons,
+ 	       int *IconBox, int BoxFillMethod);
+ #else
  void AddToList(char *name, char *icon_name, unsigned long off_flags, 
  	       unsigned long on_flags, int desk,int bw, int nobw, 
  	       char *forecolor, char *backcolor,
                 unsigned long off_buttons, unsigned long on_buttons,
  	       int *IconBox, int BoxFillMethod);
+ #endif
  
  void ParseStyle(char *text,FILE *,char **,int *);
  void assign_string(char *text, FILE *fd, char **arg,int *);
diff -rc fvwm-2.0.43/fvwm/module.c fvwm.patched/fvwm/module.c
*** fvwm-2.0.43/fvwm/module.c	Thu Jun  6 08:27:12 1996
--- fvwm.patched/fvwm/module.c	Sat Sep 21 22:03:38 1996
***************
*** 762,767 ****
--- 762,777 ----
  	  if((t->flags & ICONIFIED) && (t->flags & ICON_UNMAPPED))
  	    SendPacket(*Module,M_ICONIFY,7,t->w,t->frame,
  		       (unsigned long)t,0,0,0,0);
+ #ifdef MINI_ICONS
+ 	  if (t->mini_icon != NULL) 
+ 	    SendPacket(*Module, M_MINI_ICON, 6,
+                        t->w,
+                        t->mini_icon->picture,
+                        t->mini_icon->mask,
+                        t->mini_icon->width,
+                        t->mini_icon->height,
+                        t->mini_icon->depth, 0);
+ #endif
  	}
        if(Scr.Hilite == NULL)
  	{
diff -rc fvwm-2.0.43/fvwm/module.h fvwm.patched/fvwm/module.h
*** fvwm-2.0.43/fvwm/module.h	Mon May 27 17:12:33 1996
--- fvwm.patched/fvwm/module.h	Sat Sep 21 22:03:53 1996
***************
*** 39,44 ****
--- 39,45 ----
  #define M_ICON_FILE          (1<<20)
  #define M_DEFAULTICON        (1<<21)
  #define M_STRING             (1<<22)
+ #define M_MINI_ICON          (1<<23)
  #define MAX_MESSAGES         23
  #define MAX_MASK             ((1<<MAX_MESSAGES)-1)
  
diff -rc fvwm-2.0.43/fvwm/screen.h fvwm.patched/fvwm/screen.h
*** fvwm-2.0.43/fvwm/screen.h	Thu Apr  4 17:18:23 1996
--- fvwm.patched/fvwm/screen.h	Sat Sep 21 15:54:22 1996
***************
*** 90,95 ****
--- 90,99 ----
    PixmapButton,
    FullPixmapButton,
  #endif
+ #ifdef MINI_ICONS
+   MiniIconButton,
+   FullMiniIconButton,
+ #endif
  #endif
    SimpleButton
  } ButtonFaceStyle;
diff -rc fvwm-2.0.43/fvwm/style.c fvwm.patched/fvwm/style.c
*** fvwm-2.0.43/fvwm/style.c	Wed May  8 14:09:06 1996
--- fvwm.patched/fvwm/style.c	Sat Sep 21 16:17:55 1996
***************
*** 36,41 ****
--- 36,44 ----
    char *name, *line;
    char *restofline,*tmp;
    char *icon_name = NULL;
+ #ifdef MINI_ICONS
+   char *miniicon_name = NULL;
+ #endif
    char *forecolor = NULL;
    char *backcolor = NULL;
    unsigned long off_buttons=0;
***************
*** 348,353 ****
--- 351,378 ----
            restofline +=10;
            off_flags |= MWM_BUTTON_FLAG;
          }
+ #ifdef MINI_ICONS
+ 	else if (mystrncasecmp(restofline,"MINIICON", 8) == 0)
+ 	{
+ 	  restofline += 8;
+ 	  while (isspace (*restofline)) restofline++;
+ 	  tmp = restofline;
+ 	  len = 0;
+ 	  while((tmp != NULL)&&(*tmp != 0)&&(*tmp != ',')&&(*tmp != '\n'))
+           {
+             tmp++;
+             len++;
+           }
+           if(len > 0)
+           {
+             miniicon_name = safemalloc(len+1);
+             strncpy(miniicon_name,restofline,len);
+             miniicon_name[len] = 0;
+             off_flags |= MINIICON_FLAG;
+           }
+           restofline = tmp;
+ 	}
+ #endif
          else if(mystrncasecmp(restofline,"MWMBORDER",9)==0)
          {
            restofline +=9;
***************
*** 568,573 ****
--- 593,601 ----
                on_flags      = nptr->on_flags;
                off_flags     = nptr->off_flags;
                icon_name     = nptr->value;
+ #ifdef MINI_ICONS
+               miniicon_name = nptr->mini_value;
+ #endif
                desknumber    = nptr->Desk;
                bw            = nptr->border_width;
                nobw          = nptr->resize_width;
***************
*** 640,652 ****
--- 668,688 ----
      icon_name = NULL;
    }
  
+ #ifdef MINI_ICONS
+   AddToList(name,icon_name,miniicon_name,off_flags,on_flags,desknumber,bw,nobw,
+ 	    forecolor,backcolor,off_buttons,on_buttons,IconBox,BoxFillMethod);
+ #else
    AddToList(name,icon_name,off_flags,on_flags,desknumber,bw,nobw,
  	    forecolor,backcolor,off_buttons,on_buttons,IconBox,BoxFillMethod);
+ #endif
  }
  
  
  void AddToList(char *name,
                 char *icon_name,
+ #ifdef MINI_ICONS
+ 	       char *miniicon_name,
+ #endif
                 unsigned long off_flags, 
  	       unsigned long on_flags,
                 int desk,
***************
*** 685,690 ****
--- 721,729 ----
    nptr->on_flags = on_flags;
    nptr->off_flags = off_flags;
    nptr->value = icon_name;
+ #ifdef MINI_ICONS
+   nptr->mini_value = miniicon_name;
+ #endif
    nptr->Desk = desk;
    nptr->border_width = bw;
    nptr->resize_width = nobw;
diff -rc fvwm-2.0.43/fvwm/windows.c fvwm.patched/fvwm/windows.c
*** fvwm-2.0.43/fvwm/windows.c	Thu Jun 27 06:39:25 1996
--- fvwm.patched/fvwm/windows.c	Sat Sep 21 18:46:20 1996
***************
*** 131,136 ****
--- 131,145 ----
  	      strcat(t_hot,"\t");
  	      strcat(t_hot,tname);
  	      AddToMenu(mr, t_hot, tlabel);
+ 
+ 	      /* Add the title pixmap */
+ 	      if (t->mini_icon) {
+ 		mr->last->lpicture = t->mini_icon;
+ 		t->mini_icon->count++; /* increase the cache count!!
+ 					  otherwise the pixmap will be
+ 					  eventually removed from the 
+ 					  cache by DestroyMenu */
+ 	      }
  	      free(t_hot);
  	      free(tname);
  	    }
diff -rc fvwm-2.0.43/modules/FvwmIconMan/CHANGES fvwm.patched/modules/FvwmIconMan/CHANGES
*** fvwm-2.0.43/modules/FvwmIconMan/CHANGES	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/CHANGES	Sun Sep 22 11:33:29 1996
***************
*** 1,3 ****
--- 1,18 ----
+ 8/13/96         Version 0.7b:
+ 			fixed some bugs.
+ 			added better error messages.
+ 			grab pointer when in transient mode.
+ 
+ 8/11/96         Version 0.7:
+ 			removed showtitle option. 
+ 			added new option format, which allows for printf-like
+ 				formatting of the label for the window buttons.
+ 			added title and iconname options.
+ 			added ability to run transiently, like WinList.
+ 
+ 7/10/96		Version 0.6:
+ 			Bugfixes
+ 
  6/23/96		Version 0.5:
  			fvwm 2.0.43 changes: Focus, SendToModule
  			redid actions, with builtin functions
***************
*** 8,14 ****
  			FvwmIconMan put into fvwm 2.0 distribution.
  			support for fvwm 1 discontinued
  			one bug fix: wouldn't work without a numManagers
! 					line in .fvwm2rc
  
  2/06/96		Version 0.3:
  			added sort option
--- 23,29 ----
  			FvwmIconMan put into fvwm 2.0 distribution.
  			support for fvwm 1 discontinued
  			one bug fix: wouldn't work without a numManagers
! 				line in .fvwm2rc
  
  2/06/96		Version 0.3:
  			added sort option
diff -rc fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.c fvwm.patched/modules/FvwmIconMan/FvwmIconMan.c
*** fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.c	Sun Jun 23 13:21:15 1996
--- fvwm.patched/modules/FvwmIconMan/FvwmIconMan.c	Sun Sep 22 11:00:02 1996
***************
*** 9,15 ****
  
  static int fd_width;
  static FILE *console = NULL;
! static char *VERSION = "0.5";
  
  char *copy_string (char **target, char *src)
  {
--- 9,15 ----
  
  static int fd_width;
  static FILE *console = NULL;
! static char *VERSION = "0.7";
  
  char *copy_string (char **target, char *src)
  {
***************
*** 145,150 ****
--- 145,151 ----
  {
    fd_set readset;
    struct timeval tv;
+   int n;
  
    while(1) {
      FD_ZERO( &readset);
***************
*** 152,162 ****
      FD_SET (x_fd,&readset);
      tv.tv_sec=0;
      tv.tv_usec=0;
!     if (!select(fd_width,&readset,NULL,NULL,&tv)) {
        FD_ZERO (&readset);
        FD_SET (Fvwm_fd[1],&readset);
        FD_SET (x_fd, &readset);
!       select(fd_width,&readset,NULL,NULL,NULL);
      }
  
      if (FD_ISSET (x_fd, &readset) || XPending (theDisplay)) {
--- 153,168 ----
      FD_SET (x_fd,&readset);
      tv.tv_sec=0;
      tv.tv_usec=0;
!     if (!(n = select(fd_width,&readset,NULL,NULL,&tv))) {
!       XPending (theDisplay);
        FD_ZERO (&readset);
        FD_SET (Fvwm_fd[1],&readset);
        FD_SET (x_fd, &readset);
!       n = select(fd_width,&readset,NULL,NULL,NULL);
!     }
!     
!     if (n < 0) {
!       ConsoleMessage ("Internal error with select\n");
      }
  
      if (FD_ISSET (x_fd, &readset) || XPending (theDisplay)) {
***************
*** 185,190 ****
--- 191,198 ----
        VERSION);
      ShutMeDown (1);
    }
+   if (argc == 7 && !strcasecmp (argv[6], "Transient"))
+     globals.transient = 1;
  
    Fvwm_fd[0] = atoi(argv[1]);
    Fvwm_fd[1] = atoi(argv[2]);
***************
*** 202,211 ****
                   M_ADD_WINDOW | M_DESTROY_WINDOW | M_ICON_NAME |
                   M_DEICONIFY | M_ICONIFY | M_END_WINDOWLIST |
                   M_NEW_DESK | M_NEW_PAGE | M_FOCUS_CHANGE | M_WINDOW_NAME |
  		 M_STRING);
  
    SendInfo (Fvwm_fd, "Send_WindowList", 0);
-   
    main_loop();
  
    ConsoleMessage ("Shouldn't be here\n");
--- 210,222 ----
                   M_ADD_WINDOW | M_DESTROY_WINDOW | M_ICON_NAME |
                   M_DEICONIFY | M_ICONIFY | M_END_WINDOWLIST |
                   M_NEW_DESK | M_NEW_PAGE | M_FOCUS_CHANGE | M_WINDOW_NAME |
+ #ifdef MINI_ICONS
+ 		 M_MINI_ICON | M_STRING);
+ #else
  		 M_STRING);
+ #endif
  
    SendInfo (Fvwm_fd, "Send_WindowList", 0);
    main_loop();
  
    ConsoleMessage ("Shouldn't be here\n");
diff -rc fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.h fvwm.patched/modules/FvwmIconMan/FvwmIconMan.h
*** fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.h	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/FvwmIconMan.h	Sun Sep 22 11:00:02 1996
***************
*** 18,23 ****
--- 18,37 ----
  #include <X11/cursorfont.h>
  #include <X11/keysym.h>
  
+ #ifdef MALLOC_H
+ #include <malloc.h>
+ #endif
+ 
+ #ifndef FVWM_VERSION
+ #define FVWM_VERSION 2
+ #endif
+ 
+ #ifdef COMPILE_STANDALONE
+ #include "fvwmlib.h"
+ #else
+ #include "../../libs/fvwmlib.h"
+ #endif
+ 
  #if defined ___AIX || defined _AIX || defined __QNX__ || defined ___AIXV3 || defined AIXV3 || defined _SEQUENT_
  #include <sys/select.h>
  #endif
***************
*** 34,46 ****
  #define MIN(a,b) ((a) > (b) ? (b) : (a))
  #endif
  
- #ifndef FVWM_VERSION
- #define FVWM_VERSION 2
- #endif
  
- #ifdef MALLOC_H
- #include <malloc.h>
- #endif
  
  #if 1
  #define OUTPUT_FILE "/dev/console"
--- 48,54 ----
***************
*** 109,114 ****
--- 117,123 ----
  } Contexts;
  
  typedef enum {
+   NO_NAME       = 0,
    TITLE_NAME    = 1,
    ICON_NAME     = 2,
    RESOURCE_NAME = 4,
***************
*** 188,194 ****
      reliefContext[NUM_CONTEXTS];
    GC shadowContext[NUM_CONTEXTS], flatContext[NUM_CONTEXTS];
    XFontStruct *ButtonFont;
!   int fontheight, boxheight;
    int win_width, win_height;
    int win_x, win_y, win_title, win_border;
    WinList icon_list;
--- 197,206 ----
      reliefContext[NUM_CONTEXTS];
    GC shadowContext[NUM_CONTEXTS], flatContext[NUM_CONTEXTS];
    XFontStruct *ButtonFont;
! #ifdef MINI_ICONS
!   int draw_icons;
! #endif
!   int fontheight, boxheight, fontwidth;
    int win_width, win_height;
    int win_x, win_y, win_title, win_border;
    WinList icon_list;
***************
*** 199,206 ****
    char *backColorName[NUM_CONTEXTS];
    char *foreColorName[NUM_CONTEXTS];
    char *geometry;
!   Uchar use_titlename;
!   Schar current_box, focus_box;
    Uchar cursor_in_window;
    Uchar window_up, window_mapped;
    Schar grow_direction;
--- 211,220 ----
    char *backColorName[NUM_CONTEXTS];
    char *foreColorName[NUM_CONTEXTS];
    char *geometry;
!   char *titlename, *iconname;
!   char *formatstring;
!   NameType format_depend;
!   Schar select_box, focus_box;
    Uchar cursor_in_window;
    Uchar window_up, window_mapped;
    Schar grow_direction;
***************
*** 217,223 ****
    char *classname;
    char *titlename;
    char *iconname;
!   char **name;      /* either titlename or iconname */
    struct win_data *win_prev, *win_next, *icon_prev, *icon_next;
    WinManager *manager;
    Uchar iconified;
--- 231,240 ----
    char *classname;
    char *titlename;
    char *iconname;
! #ifdef MINI_ICONS
!   Picture pic;
! #endif
!   char *display_string; /* what gets shown in the manager window */
    struct win_data *win_prev, *win_next, *icon_prev, *icon_next;
    WinManager *manager;
    Uchar iconified;
***************
*** 236,242 ****
--- 253,261 ----
    Ulong screenx, screeny; /* screen dimensions */
    WinManager *managers;
    int num_managers;
+   int transient;
    WinData *focus_win;
+   WinData *select_win;
  } GlobalData;
  
  typedef struct {
***************
*** 273,278 ****
--- 292,298 ----
  extern WinData *new_windata (void);
  extern void free_windata (WinData *p);
  extern int check_win_complete (WinData *p);
+ extern void set_displaystring (WinData *win);
  extern int set_win_manager (WinData *win, Uchar mask);
  extern void init_winlists (void);
  extern void insert_win_iconlist (WinData *win);
***************
*** 298,312 ****
  extern void draw_window (WinManager *man);
  extern WinManager *find_windows_manager (Window win);
  extern void map_new_manger (WinManager *man);
! extern void move_highlight (WinManager *man, int to);
  extern int move_win_iconlist (WinData *win);
  
- extern char *safemalloc(int length);
- extern void SendText(int *fd,char *message,unsigned long window);
- extern void SetMessageMask(int *fd, unsigned long mask);
- extern void SendInfo(int *fd,char *message,unsigned long window);
- extern int ReadFvwmPacket(int fd, unsigned long *header, unsigned long **body);
- extern int matchWildcards(char *pattern, char *string);
- #if FVWM_VERSION == 2
- extern void *GetConfigLine(int *fd, char **tline);
- #endif
--- 318,323 ----
  extern void draw_window (WinManager *man);
  extern WinManager *find_windows_manager (Window win);
  extern void map_new_manger (WinManager *man);
! extern void move_highlight (WinManager *man, int box);
  extern int move_win_iconlist (WinData *win);
  
diff -rc fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.man fvwm.patched/modules/FvwmIconMan/FvwmIconMan.man
*** fvwm-2.0.43/modules/FvwmIconMan/FvwmIconMan.man	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/FvwmIconMan.man	Sun Sep 22 11:33:29 1996
***************
*** 1,6 ****
  .\" t
! .\" _at_(#)FvwmIconMan.1	6/23/96
! .TH FvwmIconMan 0.5 "Jun 23 1996"
  .UC
  .SH NAME
  FvwmIconMan \- an Fvwm Icon Manager
--- 1,6 ----
  .\" t
! .\" _at_(#)FvwmIconMan.1	8/11/96
! .TH FvwmIconMan 0.7 "Aug 11 1996"
  .UC
  .SH NAME
  FvwmIconMan \- an Fvwm Icon Manager
***************
*** 43,48 ****
--- 43,91 ----
  invoke it later. FvwmIconMan should be placed in the ModulePath (defined in
  the .fvwmrc file) in order for fvwm to find it.
  
+ If you wish to run FvwmIconMan in a transient mode, such as with the built
+ in window list, then pass Transient as an argument. The invocation 
+ "Module FvwmIconMan Transient" will do nicely. In this mode, FvwmIconMan
+ will pop up one manager window directly under the cursor. When the mouse
+ button is released, it will execute the appropriate action, and then exit.
+ Things are somewhat complicated by the fact that you can specify that 
+ FvwmIconMan create multiple manager windows, behavior which is unsuitable
+ when running transiently. So, when running transiently, FvwmIconMan will
+ only create one manager window. Use the manager id 'transient' to specify
+ options for this manager window.
+ 
+ .SH CONFIGURATION OPTIONS REFERENCE CHART
+ FvwmIconMan has acquired quite a few options. I assume others share my
+ dislike of paging though a long manpage, so here is a terse reference
+ chart describing the available options. They are described in more detail
+ in the next section.
+ 
+ .ft C                   \" Courier
+ .nf
+ Name            Description                Default
+ .ft P
+ 
+ nummanagers     number of managers         1
+ resolution      global, desk, or page      global  
+ font                                       8x13
+ format          describes button label     "%c: %i"
+ geometry                                   100x100
+ title           manager title              FvwmIconMan
+ iconname        manger icon name           FvwmIconMan
+ foreground      default text color         white
+ background      default background         gray
+ plainbutton     style for normal buttons   up,white,gray
+ selectbutton    style for selected buttons flat,white,gray 
+ focusbutton     style for focused buttons  up,black,white
+ focusandselectbutton                       flat,black,white
+ action          binds command to event     Mouse 0 N sendcommand select select Iconify
+ show            list of windows to show
+ dontshow        list of windows to ignore  
+ followfocus     show which win has focus   false
+ sort            keep managers sorted       true
+ 
+ .fi
+ 
  .SH CONFIGURATION OPTIONS
  With the exception of the nummanagers option, all of the options may be
  defined on a per-manager basis. So, for example, the user may have his emacs
***************
*** 54,67 ****
  for all managers.
  .IP "*FvwmIconMan*managerid*optionname optionvalue"
  To specify that the option \fIoptionname\fP takes the value \fIoptionvalue\fP
! for manager \fImanagerid\fP.
  
  The following options may be specified:
  
  .IP "*FvwmIconMan*nummanagers \fInum\fP"
  \fInum\fP is a positive integer specifying the total number of icon managers.
  Since FvwmIconMan would like to know how many managers there are before
! handling any manager specific options, this should come first. Default is 1.
  
  .IP "*FvwmIconMan*[id*]resolution \fIresolution\fP"
  Specifies when the manager will display an entry for a certain
--- 97,114 ----
  for all managers.
  .IP "*FvwmIconMan*managerid*optionname optionvalue"
  To specify that the option \fIoptionname\fP takes the value \fIoptionvalue\fP
! for manager \fImanagerid\fP. \fIMangerid\fP may either be a positive integer,
! or the string "transient". An integral id refers to managers which FvwmIconMan
! creates when running normally, and an id of "transient" refers to the single
! manager which FvwmIconMan creates when running transiently.
  
  The following options may be specified:
  
  .IP "*FvwmIconMan*nummanagers \fInum\fP"
  \fInum\fP is a positive integer specifying the total number of icon managers.
  Since FvwmIconMan would like to know how many managers there are before
! handling any manager specific options, this should come first. The default
! is 1.
  
  .IP "*FvwmIconMan*[id*]resolution \fIresolution\fP"
  Specifies when the manager will display an entry for a certain
***************
*** 69,88 ****
  or page. If global, then all windows of the appropriate type (see the show
  and dontshow options below) will be shown. If desk, then only those windows 
  on the current desk will be down. And if page, then only those windows on the 
! current page will be shown. Default is global.
! 
! .IP "*FvwmIconMan*[id*]showtitle \fIboolean\fP"
! If \fItrue\fP, then print the window title names in the
! manager, if \fIfalse\fP, then print the icon names. Default is false.
  
  .IP "*FvwmIconMan*[id*]font \fIfont\fP"
! Specifies the font to be used for labeling the buttons.
  
  .IP "*FvwmIconMan*[id*]geometry \fIgeometry\fP"
! Specified the geometry of the manager. If the geometry is specified with a 
  negative y coordinate, then the window manager will grow upwards. Otherwise,
  it will shrink downwards.
  
  .IP "*FvwmIconMan*[id*]foreground \fIforeground\fP"
  Specifies the default foreground color.
  
--- 116,148 ----
  or page. If global, then all windows of the appropriate type (see the show
  and dontshow options below) will be shown. If desk, then only those windows 
  on the current desk will be down. And if page, then only those windows on the 
! current page will be shown. The default is global.
  
  .IP "*FvwmIconMan*[id*]font \fIfont\fP"
! Specifies the font to be used for labeling the buttons. The default is 8x13.
! 
! .IP "*FvwmIconMan*[id*]format \fIformatstring\fP"
! A printf like format string which describes the string to be printed in the
! manager window for each managed window. Possible flags are: %t, %i, %c, and
! %r for the window's title, icon, class, or resource name, respectively. 
! The default is "%c: %i". \fBWarning\fP: m4 reserves the word \fIformat\fP, 
! so if you use m4, take appropriate action.
  
  .IP "*FvwmIconMan*[id*]geometry \fIgeometry\fP"
! Specifies the geometry of the manager. If the geometry is specified with a 
  negative y coordinate, then the window manager will grow upwards. Otherwise,
  it will shrink downwards.
  
+ .IP "*FvwmIconMan*[id*]title \fItitlestring\fP"
+ Specifies the window title string for that manager window. \fITitlestring\fP
+ may either be a single word, or a string enclosed in quotes. The default is
+ "FvwmIconMan".
+ 
+ .IP "*FvwmIconMan*[id*]iconname \fIiconstring\fP"
+ Specifies the window icon name for that manager window. \fIIconstring\fP
+ may either be a single word, or a string enclosed in quotes. The default is
+ "FvwmIconMan".
+ 
  .IP "*FvwmIconMan*[id*]foreground \fIforeground\fP"
  Specifies the default foreground color.
  
***************
*** 147,153 ****
  .SH ACTIONS
  Actions are commands which may be bound to an event of the type: a keypress,
  a mouse click, or the mouse entering a window manager button - denoted by
! the action types \fIKey\fP, \fIMouse\fP, and \fISelect\fP.
  
  The syntax for actions are:
  
--- 207,222 ----
  .SH ACTIONS
  Actions are commands which may be bound to an event of the type: a keypress,
  a mouse click, or the mouse entering a window manager button - denoted by
! the action types \fIKey\fP, \fIMouse\fP, and \fISelect\fP. 
! 
! Normally, actions bound to a mouse click are executed when the button is
! pressed. In transient mode, the action is executed when the button is
! released, since it is assumed that FvwmIconMan was bound to some mouse
! event. A tip/warning: FvwmIconMan still keeps track of the mouse button
! and any modifier keys in this case, so if you bind FvwmIconMan to say,
! meta-button3, then it would be wise to ensure that the action you want
! to execute will be executed when the meta-button3 event occurs (which would
! be the button release, assuming you kept your finger on the meta key).
  
  The syntax for actions are:
  
***************
*** 169,181 ****
  \fIManager\fP, \fIWindow\fP, and \fIButton\fP types all look exactly the same
  in the .fvwmrc file, but are interpreted either as specifing a manager, a
  window, or a window manager button corresponding to a window. They can either
! be an integer (which is intepreted module N where N is the number of managers
! or buttons - so 0 is the first and -1 is the last), or a simple additive 
! expression of the form "\fIbutton\fP [+-] \fIinteger\fP" where \fIbutton\fP
! can be \fIselect\fP or \fIfocus\fP to specify the manager or button which 
! is currently selected or focused. If \fIselect\fP or \fIfocus\fP is used in 
! a command, then whenever it is executed it will do nothing if there is in
! fact no selected (or focused) window. FvwmIconMan uses the same rules to 
  tokenize as fvwm, so you must seperate all tokens with whitespace.
  
  The following functions are currently defined:
--- 238,250 ----
  \fIManager\fP, \fIWindow\fP, and \fIButton\fP types all look exactly the same
  in the .fvwmrc file, but are interpreted either as specifing a manager, a
  window, or a window manager button corresponding to a window. They can either
! be an integer (which is intepreted module N where N is the number of nonempty
! managers or buttons - so 0 is the first and -1 is the last), or a simple
! additive expression of the form "\fIbutton\fP [+-] \fIinteger\fP" where
! \fIbutton\fP can be \fIselect\fP or \fIfocus\fP to specify the manager or
! button which is currently selected or focused. If \fIselect\fP or \fIfocus\fP
! is used in a command, then whenever it is executed it will do nothing if there
! is in fact no selected (or focused) window. FvwmIconMan uses the same rules to
  tokenize as fvwm, so you must seperate all tokens with whitespace.
  
  The following functions are currently defined:
***************
*** 280,288 ****
  *FvwmIconMan*action      Mouse  3 N sendcommand select select "Module FvwmIdent FvwmIdent"
  *FvwmIconMan*action      Select     sendcommand select select Focus
  *FvwmIconMan*action      Key    q N quit
- *FvwmIconMan*showtitle   false
  *FvwmIconMan*followfocus true
  *FvwmIconMan*sort        true
  *FvwmIconMan*plainbutton          up white steelblue
  *FvwmIconMan*selectbutton         down white steelblue
  *FvwmIconMan*focusbutton          up white brown
--- 349,357 ----
  *FvwmIconMan*action      Mouse  3 N sendcommand select select "Module FvwmIdent FvwmIdent"
  *FvwmIconMan*action      Select     sendcommand select select Focus
  *FvwmIconMan*action      Key    q N quit
  *FvwmIconMan*followfocus true
  *FvwmIconMan*sort        true
+ *FvwmIconMan*format      "%i"
  *FvwmIconMan*plainbutton          up white steelblue
  *FvwmIconMan*selectbutton         down white steelblue
  *FvwmIconMan*focusbutton          up white brown
***************
*** 290,298 ****
--- 359,376 ----
  
  *FvwmIconMan*1*geometry   194x100-204-90
  *FvwmIconMan*1*show       resource=emacs resource=gemacs
+ *FvwmIconMan*1*title      "Emacs windows"
+ *FvwmIconMan*1*iconname   "FvwmIconMan: Emacs"
+ 
  
  *FvwmIconMan*2*geometry   194x100-0-90
  *FvwmIconMan*2*dontshow   icon=Untitled
+ *FvwmIconMan*2*title      "All windows"
+ *FvwmIconMan*2*iconname   "FvwmIconMan: all"
+ 
+ *FvwmIconMan*transient*geometry 194x100
+ *FvwmIconMan*transient*dontshow icon=Untitled
+ *FvwmIconMan*transient*action   Mouse 0 A sendcommand select select Iconify
  
  .sp
  .fi
diff -rc fvwm-2.0.43/modules/FvwmIconMan/README fvwm.patched/modules/FvwmIconMan/README
*** fvwm-2.0.43/modules/FvwmIconMan/README	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/README	Sun Sep 22 11:33:29 1996
***************
*** 1,25 ****
! This is version 0.5 of FvwmIconMan, an icon manager modeled roughly on 
! TWM's icon manager.
  
! It has been tested under linux, solaris, OSF/1 3.0, and hp-ux 9.01. The latest
! changes I made haven't been tested under sunos4, as I no longer have access to 
! a sunos4 machine, but I believe they should work.
  
! The included man page gives some examples of how to configure FvwmIconMan, and
! a description of what it is, so I won't repeat it here.
! 
! If something needs to be tweaked to make this more portable, then feel free
! to inform me, and I would greatly appreciate any suggestions towards
! improvement.
  
  I realize that the syntax for setting options is different from that used by
  other modules.
  
! I have discontinued support for fvwm 1. If you need to compile it for
! that version of fvwm, send me mail, and I'll tell you how. The version of
  FvwmIconMan included in the fvwm 2.0 distribution WILL NOT run under fvwm 1.
  
! The latest up to date version can be found in ftp://mahler.cs.arizona.edu/pub,
! if it's not in the fvwm distribution.
  
  bradym_at_cs.arizona.edu 
--- 1,24 ----
! Aug 13, 1996
! ------------
  
! This is my second try for version 0.7 of FvwmIconMan, an icon manager modeled
! roughly on TWM's icon manager. The file CHANGES lists what's new with this
! version, and the included man page gives some examples of how to configure
! FvwmIconMan, and a description of what it is, so I won't repeat it here.
  
! If something needs to be tweaked to make this more portable, then feel free to
! inform me, and I would greatly appreciate any suggestions towards improvement.
  
  I realize that the syntax for setting options is different from that used by
  other modules.
  
! I have discontinued support for fvwm 1. If you need to compile it for that
! version of fvwm, send me mail, and I'll tell you how. The version of
  FvwmIconMan included in the fvwm 2.0 distribution WILL NOT run under fvwm 1.
  
! The latest up to date version will be in the latest fvwm distribution, with
! the exception of beta and emergency bugfix releases. You can find those
! in ftp://mahler.cs.arizona.edu/pub/FvwmIconMan, but note that mahler may
! be retired soon. 
  
  bradym_at_cs.arizona.edu 
diff -rc fvwm-2.0.43/modules/FvwmIconMan/functions.c fvwm.patched/modules/FvwmIconMan/functions.c
*** fvwm-2.0.43/modules/FvwmIconMan/functions.c	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/functions.c	Sun Sep 22 11:00:02 1996
***************
*** 3,32 ****
  
  extern WinData *find_win (WinManager *man, int box);
  
- 
  static int find_selected_manager (void)
  {
!   int i, index = -1;
! 
!   for (i = 0; i < globals.num_managers; i++) {
!     if (globals.managers[i].current_box >= 0) {
!       index = i;
!       break;
!     }
    }
  
!   if (i == globals.num_managers) {
!     ConsoleDebug ("No selected manager\n");
    }
    
!   return index;
  }
  
  /* Returns NULL if none found */
  static WinManager *get_manager (BuiltinArg *arg)
  {
    ButtonType base;
!   int offset, index;
    
    if (arg->type != ManagerArg) {
      ConsoleMessage ("Internal error in get_manager: 1\n");
--- 3,39 ----
  
  extern WinData *find_win (WinManager *man, int box);
  
  static int find_selected_manager (void)
  {
!   WinManager *man;
!   
!   if (globals.select_win) {
!     man = globals.select_win->manager;
!     return man->index;
    }
+   
+   ConsoleDebug ("No selected manager\n");
+   return -1;
+ }
  
! static int find_focus_manager (void)
! {
!   WinManager *man;
!   
!   if (globals.focus_win) {
!     man = globals.focus_win->manager;
!     return man->index;
    }
    
!   ConsoleDebug ("No focus manager\n");
!   return -1;
  }
  
  /* Returns NULL if none found */
  static WinManager *get_manager (BuiltinArg *arg)
  {
    ButtonType base;
!   int offset, index, i;
    
    if (arg->type != ManagerArg) {
      ConsoleMessage ("Internal error in get_manager: 1\n");
***************
*** 46,62 ****
      break;
  
    case FocusButton:
!     index = globals.focus_win->manager->index;
      break;
  
    case AbsoluteButton:
      index = 0;
      break;
    }
  
!   index = (index + offset) % globals.num_managers;
!   if (index < 0) 
!     index += globals.num_managers;
  
    return &globals.managers[index];
  }
--- 53,99 ----
      break;
  
    case FocusButton:
!     index = find_focus_manager();;
      break;
  
    case AbsoluteButton:
      index = 0;
      break;
+ 
+   default:
+     ConsoleMessage ("Internal error in get_manager\n");
+     break;
    }
  
!   if (index == -1 || globals.managers[index].icon_list.n == 0) {
!     ConsoleDebug ("get_manager: manager not found\n");
!     return NULL;
!   }
! 
!   /* Now we find the manager modulo the VISIBLE managers */
!   /* If someone tries this with an obscenely huge offset, tough luck */
!   /* We know that if we've made it this far, there must be a visible
!      manager */
! 
!   i = 0;
!   if (offset > 0) {
!     while (i != offset) {
!       index++;
!       if (index == globals.num_managers)
! 	index = 0;
!       if (globals.managers[index].icon_list.n > 0)
! 	i++;
!     }
!   }
!   else if (offset < 0) {
!     while (i != offset) {
!       index--;
!       if (index == -1) 
! 	index = globals.num_managers - 1;
!       if (globals.managers[index].icon_list.n > 0) 
! 	i--;
!     }
!   }
  
    return &globals.managers[index];
  }
***************
*** 81,88 ****
      return -1;
  
    case SelectButton:
!     if (man->current_box >= 0) {
!       index = man->current_box;
      }
      else {
        ConsoleDebug ("No selected window\n");
--- 118,125 ----
      return -1;
  
    case SelectButton:
!     if (man->select_box >= 0) {
!       index = man->select_box;
      }
      else {
        ConsoleDebug ("No selected window\n");
***************
*** 105,111 ****
      break;
    }
  
!   index = (index + offset) % man->icon_list.n;
    if (index < 0)
      index += man->icon_list.n;
  
--- 142,154 ----
      break;
    }
  
!   if (man->icon_list.n == 0) {
!     ConsoleMessage ("Internal error in get_button\n");
!     index = 0;
!   }
!   else {
!     index = (index + offset) % man->icon_list.n;
!   }
    if (index < 0)
      index += man->icon_list.n;
  
***************
*** 143,150 ****
  
  int builtin_selectbutton (int numargs, BuiltinArg *args)
  {
!   int button, index;
!   WinManager *oldman, *man;
  
    ConsoleDebug ("selectbutton: ");
    print_args (numargs, args);
--- 186,193 ----
  
  int builtin_selectbutton (int numargs, BuiltinArg *args)
  {
!   int button;
!   WinManager *man;
  
    ConsoleDebug ("selectbutton: ");
    print_args (numargs, args);
***************
*** 157,170 ****
    if (button == -1)
      return 0;
  
-   index = find_selected_manager();
-   if (index >= 0) {
-     oldman = &globals.managers[index];
-     if (oldman != man)
-       move_highlight (oldman, -1);
-   }
    move_highlight (man, button);
!   
    return 1;
  }
  
--- 200,207 ----
    if (button == -1)
      return 0;
  
    move_highlight (man, button);
! 
    return 1;
  }
  
diff -rc fvwm-2.0.43/modules/FvwmIconMan/fvwm.c fvwm.patched/modules/FvwmIconMan/fvwm.c
*** fvwm-2.0.43/modules/FvwmIconMan/fvwm.c	Sun Jun 23 13:21:15 1996
--- fvwm.patched/modules/FvwmIconMan/fvwm.c	Sun Sep 22 11:00:03 1996
***************
*** 62,67 ****
--- 62,73 ----
    } name;
  } m_name_data;
  
+ #ifdef MINI_ICONS
+ typedef struct {
+   Ulong app_id, picture, mask, width, height, depth;
+ } m_mini_icon_data;
+ #endif
+ 
  typedef struct {
    Ulong start, type, len, time /* in fvwm 2 only */;
  } FvwmPacketHeader;
***************
*** 74,79 ****
--- 80,88 ----
    m_minimal_data       minimal_data;
    m_icon_data          icon_data;
    m_name_data          name_data;
+ #ifdef MINI_ICONS
+   m_mini_icon_data     mini_icon_data;
+ #endif
  } FvwmPacketBody;
  
  int window_up = 0;
***************
*** 368,373 ****
--- 377,383 ----
    copy_string (&win->resname, (char *)name);
    oldman = win->manager;
    new = set_win_manager (win, ALL_NAME);
+   set_displaystring (win);
    if (new) {
      if (oldman && win->in_iconlist) {
        delete_win_iconlist  (win, oldman);
***************
*** 398,403 ****
--- 408,414 ----
    copy_string (&win->classname, (char *)name);
    oldman = win->manager;
    new = set_win_manager (win, ALL_NAME);
+   set_displaystring (win);
    if (new) {
      if (oldman && win->in_iconlist) {
        delete_win_iconlist  (win, oldman);
***************
*** 433,440 ****
--- 444,453 ----
    }
  
    copy_string (&win->iconname, (char *)name);
+   ConsoleDebug ("new icon name: %s\n", win->iconname);
    oldman = win->manager;
    new = set_win_manager (win, ALL_NAME);
+   set_displaystring (win);
    check_win_complete (win);
    if (new) {
      if (oldman && win->in_iconlist) {
***************
*** 448,454 ****
    }
    else {
      if (win->in_iconlist && 
! 	!win->manager->use_titlename && win->manager->sort) {
        moved = move_win_iconlist (win);
      }
      if (moved) 
--- 461,467 ----
    }
    else {
      if (win->in_iconlist && 
! 	(win->manager->format_depend & ICON_NAME) && win->manager->sort) {
        moved = move_win_iconlist (win);
      }
      if (moved) 
***************
*** 485,490 ****
--- 498,504 ----
  
    oldman = win->manager;
    new = set_win_manager (win, ALL_NAME);
+   set_displaystring (win);
    check_win_complete (win);
    if (new) {
      if (oldman && win->in_iconlist) {
***************
*** 498,504 ****
    }
    else {
      if (win->in_iconlist && 
! 	win->manager->use_titlename && win->manager->sort) {
        moved = move_win_iconlist (win);
      }
      if (moved) 
--- 512,518 ----
    }
    else {
      if (win->in_iconlist && 
! 	(win->manager->format_depend & TITLE_NAME) && win->manager->sort) {
        moved = move_win_iconlist (win);
      }
      if (moved) 
***************
*** 558,563 ****
--- 572,606 ----
    free_windata (win);
  }
  
+ #ifdef MINI_ICONS
+ static void mini_icon (FvwmPacketBody *body)
+ {
+   Ulong app_id = body->mini_icon_data.app_id;
+   WinData *win;
+   int box;
+   
+   win = id_to_win (app_id);
+   win->pic.picture = body->mini_icon_data.picture;
+   win->pic.mask = body->mini_icon_data.mask;
+   win->pic.width = body->mini_icon_data.width;
+   win->pic.height = body->mini_icon_data.height;
+   win->pic.depth = body->mini_icon_data.depth;
+ 
+   ConsoleDebug ("mini_icon: 0x%x 0x%x %dx%dx%d\n", win->pic.picture,
+ 		win->pic.mask, win->pic.width, win->pic.height,
+ 		win->pic.depth);
+ 
+   if (win->complete && win->in_iconlist && win->manager->draw_icons) {
+     box = win_to_box (win->manager, win);
+     if (box >= 0)
+       draw_button (win->manager, win, box);
+     else
+       ConsoleMessage ("Internal error in mini_icon\n"); 
+   }
+ 
+ }
+ #endif
+ 
  static void iconify (FvwmPacketBody *body, int dir)
  {
    Ulong app_id = body->minimal_data.app_id;
***************
*** 664,669 ****
--- 707,719 ----
      ConsoleDebug ("DEBUG::M_DESTROY_WINDOW\n");
      destroy_window (body);
      break;
+ 
+ #ifdef MINI_ICONS
+   case M_MINI_ICON:
+     ConsoleDebug ("DEBUG::M_MINI_ICON\n");
+     mini_icon (body);
+     break;
+ #endif
  
    case M_WINDOW_NAME:
      ConsoleDebug ("DEBUG::M_WINDOW_NAME\n");
diff -rc fvwm-2.0.43/modules/FvwmIconMan/globals.c fvwm.patched/modules/FvwmIconMan/globals.c
*** fvwm-2.0.43/modules/FvwmIconMan/globals.c	Sun Jun 23 13:21:15 1996
--- fvwm.patched/modules/FvwmIconMan/globals.c	Sun Sep 22 11:00:03 1996
***************
*** 16,26 ****
--- 16,38 ----
  char *Module = "*FvwmIconMan";
  int ModuleLen = 12;
  
+ /* This is solely so that we can turn a string constant into something
+    which can be freed */
+ 
+ static char *alloc_string (char *string)
+ {
+   int len = strlen (string);
+   char *ret = (char *)safemalloc ((len + 1) * sizeof (char));
+   strcpy (ret, string);
+   return ret;
+ }
+ 
  static void init_win_manager (int id)
  {
    int i;
  
    globals.managers[id].index = id;
+   globals.managers[id].draw_icons = 1;
    globals.managers[id].res = SHOW_PAGE;
    globals.managers[id].icon_list.n = 0;
    globals.managers[id].icon_list.head = NULL;  
***************
*** 28,33 ****
--- 40,50 ----
    globals.managers[id].window_up = 0;
    globals.managers[id].window_mapped = 0;
    globals.managers[id].fontname = NULL;
+   globals.managers[id].titlename = alloc_string ("FvwmIconMan");
+   globals.managers[id].iconname = alloc_string ("FvwmIconMan");
+   globals.managers[id].formatstring = alloc_string ("%c: %i");
+   globals.managers[id].format_depend = CLASS_NAME | ICON_NAME;
+ 
    for ( i = 0; i < NUM_CONTEXTS; i++ ) {
      globals.managers[id].backColorName[i] = NULL;
      globals.managers[id].foreColorName[i] = NULL;
***************
*** 39,45 ****
    globals.managers[id].dontshow.list = NULL;
    globals.managers[id].dontshow.mask = ALL_NAME;
    globals.managers[id].grow_direction = ForgetGravity;
-   globals.managers[id].use_titlename = 1;
    globals.managers[id].followFocus = 0;
    globals.managers[id].sort = 1;
    globals.managers[id].focus_box = -1;
--- 56,61 ----
***************
*** 110,113 ****
--- 126,131 ----
    globals.num_managers = 1;
    globals.managers = NULL;
    globals.focus_win = NULL;
+   globals.select_win = NULL;
+   globals.transient = 0;
  }
diff -rc fvwm-2.0.43/modules/FvwmIconMan/readconfig.c fvwm.patched/modules/FvwmIconMan/readconfig.c
*** fvwm-2.0.43/modules/FvwmIconMan/readconfig.c	Sun Jun 23 13:21:16 1996
--- fvwm.patched/modules/FvwmIconMan/readconfig.c	Sun Sep 22 11:00:03 1996
***************
*** 73,78 ****
--- 73,101 ----
  static FILE *config_fp = NULL;
  #endif
  
+ 
+ /* This is only used for printing out the .fvwmrc line if an error
+    occured */
+ 
+ #define PRINT_LINE_LENGTH 80
+ static char current_line[PRINT_LINE_LENGTH];
+ 
+ static void save_current_line (char *s)
+ {
+   char *p = current_line;
+ 
+   while (*s && p < current_line + PRINT_LINE_LENGTH - 1) {
+     if (*s == '\n') {
+       *p = '\0';
+       return;
+     }
+     else {
+       *p++ = *s++;
+     }
+   }
+   *p = '\0';
+ }
+ 
  void print_args (int numargs, BuiltinArg *args)
  {
  #ifdef PRINT_DEBUG
***************
*** 351,357 ****
  	}
        if(!matched)
  	{
! 	  ConsoleMessage ("bad context in line %s\n",tline);
  	}
        i++;
      }
--- 374,381 ----
  	}
        if(!matched)
  	{
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("Bad context: %s\n", string);
  	}
        i++;
      }
***************
*** 388,397 ****
      term->buttontype = NoButton;
      return NULL;
    }
!   if (!strcmp (token, "focus")) {
      term->buttontype = FocusButton;
    }
!   else if (!strcmp (token, "select")) {
      term->buttontype = SelectButton;
    }
    else if (extract_int (token, &n)) {
--- 412,421 ----
      term->buttontype = NoButton;
      return NULL;
    }
!   if (!strcasecmp (token, "focus")) {
      term->buttontype = FocusButton;
    }
!   else if (!strcasecmp (token, "select")) {
      term->buttontype = SelectButton;
    }
    else if (extract_int (token, &n)) {
***************
*** 494,500 ****
    }
    
    for (i = 0; i < num_builtins; i++) {
!     if (!strcmp (name, builtin_functions[i].name)) {
        Free (name);
        ftype->func = builtin_functions[i].func;
        ftype->numargs = builtin_functions[i].numargs;
--- 518,524 ----
    }
    
    for (i = 0; i < num_builtins; i++) {
!     if (!strcasecmp (name, builtin_functions[i].name)) {
        Free (name);
        ftype->func = builtin_functions[i].func;
        ftype->numargs = builtin_functions[i].numargs;
***************
*** 547,591 ****
    return NULL;
  }
  
- #if 0
- static Function *parse_function_list (char *line)
- {
-   Function *func, *list = NULL, *finallist = NULL, *p;
-   char *ptr = line, *token;
-   
-   while (1) {
-     ptr = parse_function (ptr, &func);
-     if (ptr == NULL) {
-       break;
-     }
-     func->next = list;
-     list = func;
-     ptr = GetNextToken (ptr, &token);
-     if (token == NULL)
-       break;
-     if (!strcmp (token, ",")) {
-       Free (token);
-       break;
-     }
-     else {
-       ConsoleMessage ("Malformed sequence of functions\n");
-     }
-     Free (token);
-   }
- 
-   /* reverse the list */
- 
-   while (list) {
-     p = list->next;
-     list->next = newlist;
-     newlist = list;
-     list = p;
-   }
- 
-   return newlist;
- }
- #endif
- 
  Binding *ParseMouseEntry (char *tline)
  {
    char modifiers[20],*ptr,*action,*token;
--- 571,576 ----
***************
*** 608,614 ****
      Free(token);
    }
    if((n1 != 1)||(n2 != 1))
!     ConsoleMessage ("Mouse binding: Syntax error in line %s", tline);
    
    find_context(modifiers,&mods,key_modifiers,tline);
    if((mods & AnyModifier)&&(mods&(~AnyModifier))) {
--- 593,599 ----
      Free(token);
    }
    if((n1 != 1)||(n2 != 1))
!     ConsoleMessage ("Mouse binding: Syntax error");
    
    find_context(modifiers,&mods,key_modifiers,tline);
    if((mods & AnyModifier)&&(mods&(~AnyModifier))) {
***************
*** 676,683 ****
     * XGrabKey call in GrabKeys().
     */
    if ((keysym = XStringToKeysym(key)) == NoSymbol || 
!       XKeysymToKeycode(theDisplay, keysym) == 0)
      return NULL;
    
   
    XDisplayKeycodes(theDisplay, &min, &max);
--- 661,670 ----
     * XGrabKey call in GrabKeys().
     */
    if ((keysym = XStringToKeysym(key)) == NoSymbol || 
!       XKeysymToKeycode(theDisplay, keysym) == 0) {
!     ConsoleMessage ("Can't find keysym: %s\n", key);
      return NULL;
+   }
    
   
    XDisplayKeycodes(theDisplay, &min, &max);
***************
*** 891,896 ****
--- 878,923 ----
      return copy_string (s1, s2);
  }
  
+ static NameType parse_format_dependencies (char *format)
+ {
+   NameType flags = NO_NAME;
+ 
+   ConsoleDebug ("Parsing format: %s\n", format);
+ 
+   while (*format) {
+     if (*format != '%') {
+       format++;
+     }
+     else {
+       format++;
+       if (*format == 'i')
+ 	flags |= ICON_NAME;
+       else if (*format == 't')
+ 	flags |= TITLE_NAME;
+       else if (*format == 'c')
+ 	flags |= CLASS_NAME;
+       else if (*format == 'r')
+ 	flags |= RESOURCE_NAME;
+       else if (*format != '%')
+ 	ConsoleMessage ("Bad format string: %s\n", format);
+     }
+   }
+ #ifdef PRINT_DEBUG
+   ConsoleDebug ("Format depends on: ");
+   if (flags & ICON_NAME)
+     ConsoleDebug ("Icon ");
+   if (flags & TITLE_NAME)
+     ConsoleDebug ("Title ");
+   if (flags & CLASS_NAME)
+     ConsoleDebug ("Class ");
+   if (flags & RESOURCE_NAME)
+     ConsoleDebug ("Resource ");
+   ConsoleDebug ("\n");
+ #endif
+ 
+   return flags;
+ }
+ 
  #define SET_MANAGER(manager,field,value)                           \
     do {                                                            \
       int id = manager;                                             \
***************
*** 921,948 ****
  
    while ((p = read_next_cmd (READ_LINE))) {
      ConsoleDebug ("line: %s\n", p);
      option1 = read_next_cmd (READ_OPTION);
      if (option1 == NULL)
        continue;
  
      ConsoleDebug ("option1: %s\n", option1);
      if (!strcasecmp (option1, "nummanagers")) {
!       p = read_next_cmd (READ_ARG);
!       if (!option1) {
! 	ConsoleMessage ("Error in input file\n");
! 	continue;
!       }
!       if (extract_int (p, &n) == 0) {
! 	ConsoleMessage ("This is not a number: %s\n", p);
! 	continue;
!       }
!       if (n > 0) {
! 	allocate_managers (n);
! 	ConsoleDebug ("num managers: %d\n", n);
!       }
!       else {
! 	ConsoleMessage ("You can't have zero managers. I'll give you one.\n");
! 	allocate_managers (1);
        }
      }
      else {
--- 948,983 ----
  
    while ((p = read_next_cmd (READ_LINE))) {
      ConsoleDebug ("line: %s\n", p);
+     save_current_line (p);
+ 
      option1 = read_next_cmd (READ_OPTION);
      if (option1 == NULL)
        continue;
  
      ConsoleDebug ("option1: %s\n", option1);
      if (!strcasecmp (option1, "nummanagers")) {
!       /* If in transient mode, just use the default of 1 manager */
!       if (!globals.transient) {
! 	p = read_next_cmd (READ_ARG);
! 	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  continue;
! 	}
! 	if (extract_int (p, &n) == 0) {
! 	  ConsoleMessage ("This is not a number: %s\n", p);
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  continue;
! 	}
! 	if (n > 0) {
! 	  allocate_managers (n);
! 	  ConsoleDebug ("num managers: %d\n", n);
! 	}
! 	else {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("You can't have zero managers. "
! 			  "I'll give you one.\n");
! 	  allocate_managers (1);
! 	}
        }
      }
      else {
***************
*** 956,969 ****
        manager = 0;
  
        if (option1[0] >= '0' && option1[0] <= '9') {
  	if (extract_int (option1, &manager) == 0 || 
  	    manager <= 0 || manager > globals.num_managers) {
  	  ConsoleMessage ("This is not a valid manager: %s.\n", option1);
  	  manager = 0;
  	}
  	option1 = read_next_cmd (READ_OPTION);
  	if (!option1) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
        }
--- 991,1024 ----
        manager = 0;
  
        if (option1[0] >= '0' && option1[0] <= '9') {
+ 	if (globals.transient) {
+ 	  ConsoleDebug ("In transient mode. Ignoring this line\n");
+ 	  continue;
+ 	}
  	if (extract_int (option1, &manager) == 0 || 
  	    manager <= 0 || manager > globals.num_managers) {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  ConsoleMessage ("This is not a valid manager: %s.\n", option1);
  	  manager = 0;
  	}
  	option1 = read_next_cmd (READ_OPTION);
  	if (!option1) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  continue;
! 	}
!       }
!       else if (!strcasecmp (option1, "transient")) {
! 	if (globals.transient) {
! 	  ConsoleDebug ("Transient manager config line\n");
! 	  manager = 1;
! 	  option1 = read_next_cmd (READ_OPTION);
! 	  if (!option1) {
! 	    ConsoleMessage ("Bad line: %s\n", current_line);
! 	    continue;
! 	  }
! 	}
! 	else {
! 	  ConsoleDebug ("Not in transient mode. Ignoring this line\n");
  	  continue;
  	}
        }
***************
*** 975,981 ****
        if (!strcasecmp (option1, "resolution")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
  	ConsoleDebug ("resolution: %s\n", p);
--- 1030,1036 ----
        if (!strcasecmp (option1, "resolution")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	ConsoleDebug ("resolution: %s\n", p);
***************
*** 985,997 ****
  	  r = SHOW_DESKTOP;
  	else if (!strcasecmp (p, "page"))
  	  r = SHOW_PAGE;
  
  	SET_MANAGER (manager, res, r);
        }
        else if (!strcasecmp (option1, "font")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
  	ConsoleDebug ("font: %s\n", p);
--- 1040,1057 ----
  	  r = SHOW_DESKTOP;
  	else if (!strcasecmp (p, "page"))
  	  r = SHOW_PAGE;
+ 	else {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
+ 	  ConsoleMessage ("What kind of resolution is this?\n");
+ 	  continue;
+ 	}
  
  	SET_MANAGER (manager, res, r);
        }
        else if (!strcasecmp (option1, "font")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	ConsoleDebug ("font: %s\n", p);
***************
*** 1002,1018 ****
        else if (!strcasecmp (option1, "geometry")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
  
  	SET_MANAGER (manager, geometry, 
  		     copy_string (&globals.managers[id].geometry, p));
        }
        else if (!strcasecmp (option1, "dontshow")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input_file\n");
  	  continue;
  	}
  	do {
--- 1062,1121 ----
        else if (!strcasecmp (option1, "geometry")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  
  	SET_MANAGER (manager, geometry, 
  		     copy_string (&globals.managers[id].geometry, p));
        }
+       else if (!strcasecmp (option1, "title")) {
+ 	char *token;
+ 	p = read_next_cmd (READ_REST_OF_LINE);
+ 	if (!p) {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
+ 	  continue;
+ 	}
+ 	GetNextToken (p, &token);
+ 	
+ 	SET_MANAGER (manager, titlename,
+ 		     copy_string (&globals.managers[id].titlename, token));
+ 	Free (token);
+       }
+       else if (!strcasecmp (option1, "iconname")) {
+ 	char *token;
+ 	p = read_next_cmd (READ_REST_OF_LINE);
+ 	if (!p) {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
+ 	  continue;
+ 	}
+ 	GetNextToken (p, &token);
+ 	
+ 	SET_MANAGER (manager, iconname,
+ 		     copy_string (&globals.managers[id].iconname, token));
+ 	Free (token);
+       }
+       else if (!strcasecmp (option1, "format")) {
+ 	char *token;
+ 	NameType flags;
+ 
+ 	p = read_next_cmd (READ_REST_OF_LINE);
+ 	if (!p) {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
+ 	  continue;
+ 	}
+ 	GetNextToken (p, &token);
+ 	
+ 	SET_MANAGER (manager, formatstring,
+ 		     copy_string (&globals.managers[id].formatstring, token));
+ 	flags = parse_format_dependencies (token);
+ 	SET_MANAGER (manager, format_depend, flags);
+ 	Free (token);
+       }
        else if (!strcasecmp (option1, "dontshow")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	do {
***************
*** 1031,1037 ****
        else if (!strcasecmp (option1, "show")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input_file\n");
  	  continue;
  	}
  	do {
--- 1134,1140 ----
        else if (!strcasecmp (option1, "show")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	do {
***************
*** 1050,1056 ****
        else if (!strcasecmp (option1, "background")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
  	ConsoleDebug ("default background: %s\n", p);
--- 1153,1159 ----
        else if (!strcasecmp (option1, "background")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	ConsoleDebug ("default background: %s\n", p);
***************
*** 1063,1069 ****
        else if (!strcasecmp (option1, "foreground")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file\n");
  	  continue;
  	}
  	ConsoleDebug ("default foreground: %s\n", p);
--- 1166,1172 ----
        else if (!strcasecmp (option1, "foreground")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  	ConsoleDebug ("default foreground: %s\n", p);
***************
*** 1076,1082 ****
        else if (!strcasecmp (option1, "action")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file: need arguments to action\n");
  	  continue;
  	}
  
--- 1179,1185 ----
        else if (!strcasecmp (option1, "action")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  continue;
  	}
  
***************
*** 1090,1102 ****
  	  i = SELECT;
  	}
  	else {
! 	  ConsoleMessage ("Error in input file: this isn't a valid action name: %s\n", p);
  	  continue;
  	}
  
  	q = read_next_cmd (READ_REST_OF_LINE);
  	if (!q) {
! 	  ConsoleMessage ("Error in input file: need an action\n");
  	  continue;
  	}
  	
--- 1193,1207 ----
  	  i = SELECT;
  	}
  	else {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("This isn't a valid action name: %s\n", p);
  	  continue;
  	}
  
  	q = read_next_cmd (READ_REST_OF_LINE);
  	if (!q) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("Need an action\n");
  	  continue;
  	}
  	
***************
*** 1115,1121 ****
  	}
  
  	if (binding == NULL) {
! 	  ConsoleMessage ("Error in input file: bad action\n");
  	  continue;
  	}
  
--- 1220,1227 ----
  	}
  
  	if (binding == NULL) {
! 	  ConsoleMessage ("Offending line: %s\n", current_line);
! 	  ConsoleMessage ("Bad action\n");
  	  continue;
  	}
  
***************
*** 1129,1155 ****
  	  add_to_binding (&globals.managers[manager].bindings[i], binding);
  	}
  	else {
  	  ConsoleMessage ("There's no manager %d\n", manager);
  	}
        }
        else if (!strcasecmp (option1, "showtitle")) {
! 	p = read_next_cmd (READ_ARG);
! 	if (!p) {
! 	  ConsoleMessage ("Error in input file: need argument to showtitle\n");
! 	  continue;
! 	}
! 	if (!strcasecmp (p, "true")) {
! 	  i = 1;
! 	}
! 	else if (!strcasecmp (p, "false")) {
! 	  i = 0;
! 	}
! 	else {
! 	  ConsoleMessage ("Error in input file. What is this: %s?\n", p);
! 	  continue;
! 	}
! 	ConsoleDebug ("Setting showtitle to: %d\n", i);
! 	SET_MANAGER (manager, use_titlename, i);
        }
        else if (!strcasecmp (option1, "plainButton")  ||
                 !strcasecmp (option1, "selectButton")  ||
--- 1235,1248 ----
  	  add_to_binding (&globals.managers[manager].bindings[i], binding);
  	}
  	else {
+ 	  ConsoleMessage ("Bad line: %s\n", current_line);
  	  ConsoleMessage ("There's no manager %d\n", manager);
  	}
        }
        else if (!strcasecmp (option1, "showtitle")) {
! 	ConsoleMessage ("Bad line: %s\n", current_line);
! 	ConsoleMessage ("showtitle is no longer an option. Use format\n");
! 	continue;
        }
        else if (!strcasecmp (option1, "plainButton")  ||
                 !strcasecmp (option1, "selectButton")  ||
***************
*** 1161,1173 ****
              i = SELECT_CONTEXT;
           else if (!strcasecmp (option1, "focusandselectButton"))
  	   i = FOCUS_SELECT_CONTEXT;
! 	 else
              i = FOCUS_CONTEXT;
           p = read_next_cmd (READ_ARG);
           if (!p) {
!             ConsoleMessage ("Error in input file: need argument to %s\n",
! 			    option1);
!             continue;
           }
           else if (!strcasecmp (p, "flat")) {
              state = BUTTON_FLAT;
--- 1254,1267 ----
              i = SELECT_CONTEXT;
           else if (!strcasecmp (option1, "focusandselectButton"))
  	   i = FOCUS_SELECT_CONTEXT;
!          else
              i = FOCUS_CONTEXT;
+ 	   
           p = read_next_cmd (READ_ARG);
           if (!p) {
! 	   ConsoleMessage ("Bad line: %s\n", current_line);
! 	   ConsoleMessage ("Need argument to %s\n", option1);
! 	   continue;
           }
           else if (!strcasecmp (p, "flat")) {
              state = BUTTON_FLAT;
***************
*** 1179,1185 ****
              state = BUTTON_DOWN;
           }
           else {
!            ConsoleMessage ("Error in input file: this isn't a valid button state: %s\n", p);
             continue;
           }
  	 ConsoleDebug ("Setting buttonState[%s] to %s\n", 
--- 1273,1280 ----
              state = BUTTON_DOWN;
           }
           else {
! 	   ConsoleMessage ("Bad line: %s\n", current_line);
!            ConsoleMessage ("This isn't a valid button state: %s\n", p);
             continue;
           }
  	 ConsoleDebug ("Setting buttonState[%s] to %s\n", 
***************
*** 1209,1215 ****
        else if (!strcasecmp (option1, "followfocus")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file: need argument to followfocus\n");
  	  continue;
  	}
  	if (!strcasecmp (p, "true")) {
--- 1304,1311 ----
        else if (!strcasecmp (option1, "followfocus")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("Need argument to followfocus\n");
  	  continue;
  	}
  	if (!strcasecmp (p, "true")) {
***************
*** 1219,1225 ****
  	  i = 0;
  	}
  	else {
! 	  ConsoleMessage ("Error in input file. What is this: %s?\n", p);
  	  continue;
  	}
  	ConsoleDebug ("Setting followfocus to: %d\n", i);
--- 1315,1322 ----
  	  i = 0;
  	}
  	else {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("What is this: %s?\n", p);
  	  continue;
  	}
  	ConsoleDebug ("Setting followfocus to: %d\n", i);
***************
*** 1228,1234 ****
        else if (!strcasecmp (option1, "sort")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Error in input file: need argument to sort\n");
  	  continue;
  	}
  	if (!strcasecmp (p, "true")) {
--- 1325,1332 ----
        else if (!strcasecmp (option1, "sort")) {
  	p = read_next_cmd (READ_ARG);
  	if (!p) {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("Need argument to sort\n");
  	  continue;
  	}
  	if (!strcasecmp (p, "true")) {
***************
*** 1238,1250 ****
  	  i = 0;
  	}
  	else {
! 	  ConsoleMessage ("Error in input file. What is this: %s?\n", p);
  	  continue;
  	}
  	ConsoleDebug ("Setting sort to: %d\n", i);
  	SET_MANAGER (manager, sort, i);
        }
        else {
  	ConsoleMessage ("Unknown option: %s\n", p);
        }
      }
--- 1336,1350 ----
  	  i = 0;
  	}
  	else {
! 	  ConsoleMessage ("Bad line: %s\n", current_line);
! 	  ConsoleMessage ("What is this: %s?\n", p);
  	  continue;
  	}
  	ConsoleDebug ("Setting sort to: %d\n", i);
  	SET_MANAGER (manager, sort, i);
        }
        else {
+ 	ConsoleMessage ("Bad line: %s\n", current_line);
  	ConsoleMessage ("Unknown option: %s\n", p);
        }
      }
diff -rc fvwm-2.0.43/modules/FvwmIconMan/winlist.c fvwm.patched/modules/FvwmIconMan/winlist.c
*** fvwm-2.0.43/modules/FvwmIconMan/winlist.c	Sun Jun 23 13:21:15 1996
--- fvwm.patched/modules/FvwmIconMan/winlist.c	Sun Sep 22 11:00:03 1996
***************
*** 29,34 ****
--- 29,37 ----
      case CLASS_NAME:
        s = "class";
        break;
+       
+     default:
+       s = "unknown type";
      }
      ConsoleDebug ("\t%s = %s\n", s, p->string);
    }
***************
*** 45,57 ****
    pat = strchr (s, '=');
    if (pat) {
      *pat++ = '\0';
!     if (!strcmp (s, "icon"))
        type = ICON_NAME;
!     else if (!strcmp (s, "title"))
        type = TITLE_NAME;
!     else if (!strcmp (s, "resource"))
        type = RESOURCE_NAME;
!     else if (!strcmp (s, "class"))
        type = CLASS_NAME;
      else {
        ConsoleMessage ("Bad element in show/dontshow list: %s\n", s);
--- 48,60 ----
    pat = strchr (s, '=');
    if (pat) {
      *pat++ = '\0';
!     if (!strcasecmp (s, "icon"))
        type = ICON_NAME;
!     else if (!strcasecmp (s, "title"))
        type = TITLE_NAME;
!     else if (!strcasecmp (s, "resource"))
        type = RESOURCE_NAME;
!     else if (!strcasecmp (s, "class"))
        type = CLASS_NAME;
      else {
        ConsoleMessage ("Bad element in show/dontshow list: %s\n", s);
***************
*** 86,100 ****
  {
    int ans = 0;
    
!   if (tname && (type == ALL_NAME || type == TITLE_NAME))
      ans |= matchWildcards (pattern, tname);
!   if (iname && (type == ALL_NAME || type == ICON_NAME))
      ans |= matchWildcards (pattern, iname);
!   if (rname && (type == ALL_NAME || type == RESOURCE_NAME))
      ans |= matchWildcards (pattern, rname);
!   if (cname && (type == ALL_NAME || type == CLASS_NAME))
      ans |= matchWildcards (pattern, cname);
  
    return ans;
  }
  
--- 89,111 ----
  {
    int ans = 0;
    
!   ConsoleDebug ("matches_string: type: 0x%x pattern: %s\n", type, pattern);
!   ConsoleDebug ("\tstrings: %s:%s %s:%s\n", tname, iname, rname, cname);
! 
!   if (tname && (type == ALL_NAME || type == TITLE_NAME)) {
      ans |= matchWildcards (pattern, tname);
!   }
!   if (iname && (type == ALL_NAME || type == ICON_NAME)) {
      ans |= matchWildcards (pattern, iname);
!   }
!   if (rname && (type == ALL_NAME || type == RESOURCE_NAME)) {
      ans |= matchWildcards (pattern, rname);
!   }
!   if (cname && (type == ALL_NAME || type == CLASS_NAME)) {
      ans |= matchWildcards (pattern, cname);
+   }
  
+   ConsoleDebug ("\tmatches_string: %d\n", ans);
    return ans;
  }
  
***************
*** 193,199 ****
    new->classname = NULL;
    new->iconname = NULL;
    new->titlename = NULL;
!   new->name = NULL;
    new->manager = NULL;
    new->win_prev = new->win_next = NULL;
    new->icon_prev = new->icon_next = NULL;
--- 204,210 ----
    new->classname = NULL;
    new->iconname = NULL;
    new->titlename = NULL;
!   new->display_string = NULL;
    new->manager = NULL;
    new->win_prev = new->win_next = NULL;
    new->icon_prev = new->icon_next = NULL;
***************
*** 203,208 ****
--- 214,222 ----
    new->focus = 0;
    new->sticky = 0;
    new->winlistskip = 0;
+ #ifdef MINI_ICONS
+   new->pic.picture = 0;
+ #endif
    return new;
  }
  
***************
*** 214,222 ****
    Free (p);
  }
  
  int set_win_manager (WinData *win, Uchar name_mask)
  {
!   int i;
    char *tname = win->titlename;
    char *iname = win->iconname;
    char *rname = win->resname;
--- 228,319 ----
    Free (p);
  }
  
+ static char *make_display_string (WinData *win, char *format, int len)
+ {
+ #define MAX_DISPLAY_SIZE 1024
+ #define COPY(field)                                       \
+   temp_p = win->##field;                                  \
+   if (temp_p)                                             \
+     while (*temp_p && out_p - buf < len - 1) \
+       *out_p++ = *temp_p++;                               \
+   in_p++;
+ 
+   static char buf[MAX_DISPLAY_SIZE];
+   char *string, *in_p, *out_p, *temp_p;
+ 
+   in_p = format;
+   out_p = buf;
+ 
+   if (len > MAX_DISPLAY_SIZE || len <= 0)
+     len = MAX_DISPLAY_SIZE;
+   
+   while (*in_p && out_p - buf < len - 1) {
+     if (*in_p == '%') {
+       switch (*(++in_p)) {
+       case 'i':
+ 	COPY (iconname);
+ 	break;
+ 
+       case 't':
+ 	COPY (titlename);
+ 	break;
+ 
+       case 'r':
+ 	COPY (resname);
+ 	break;
+ 
+       case 'c':
+ 	COPY (classname);
+ 	break;
+ 
+       default:
+ 	*out_p++ = *in_p++;
+ 	break;
+       }
+     }
+     else {
+       *out_p++ = *in_p++;
+     }
+   }
+ 
+   *out_p++ = '\0';
+ 
+   string = buf;
+   return string;
+ 
+ #undef COPY
+ #undef MAX_DISPLAY_SIZE
+ }
+ 
+ void set_displaystring (WinData *win)
+ {
+   WinManager *man = win->manager;
+   int maxlen;
+ 
+   if (!man || ((man->format_depend & CLASS_NAME) && !win->classname)
+       || ((man->format_depend & ICON_NAME) && !win->iconname)
+       || ((man->format_depend & TITLE_NAME) && !win->titlename)
+       || ((man->format_depend & RESOURCE_NAME) && !win->resname)) {
+     return;
+   }
+ 
+   if (man->window_up) {
+     assert (man->win_width && man->fontwidth);
+     maxlen = man->win_width / man->fontwidth + 2 /* fudge factor */;
+   }
+   else {
+     maxlen = 0;
+   }
+   copy_string (&win->display_string, 
+ 	       make_display_string (win, man->formatstring, maxlen));
+ }
+ 
+ 
+ /* This ALWAYS gets called when one of the name strings changes */
+ 
  int set_win_manager (WinData *win, Uchar name_mask)
  {
!   int i, new_manager = 0;
    char *tname = win->titlename;
    char *iname = win->iconname;
    char *rname = win->resname;
***************
*** 224,248 ****
    WinManager *man;
  
    assert (tname || iname || rname || cname);
  
    for (i = 0, man = &globals.managers[0]; i < globals.num_managers;
         i++, man++) {
      if (iconmanager_show (man, tname, iname, rname, cname)) {
        if (man != win->manager) {
  	win->manager = man;
! 	if (win->manager->use_titlename)
! 	  win->name = &win->titlename;
! 	else
! 	  win->name = &win->iconname;
! 	return 1;
!       }
!       else {
! 	return 0;
        }
      }
    }
  
!   return 0;
  }
  
  int check_win_complete (WinData *p)
--- 321,346 ----
    WinManager *man;
  
    assert (tname || iname || rname || cname);
+   ConsoleDebug ("set_win_manager: %s %s %s %s\n", tname, iname, rname, cname);
  
    for (i = 0, man = &globals.managers[0]; i < globals.num_managers;
         i++, man++) {
      if (iconmanager_show (man, tname, iname, rname, cname)) {
        if (man != win->manager) {
  	win->manager = man;
! 	new_manager = 1;
        }
+       return new_manager;
      }
    }
  
!   /* No manager wants this window */
!   if (win->manager) {
!     win->manager = NULL;
!     return 1;
!   }
! 
!   return new_manager;
  }
  
  int check_win_complete (WinData *p)
***************
*** 255,260 ****
--- 353,359 ----
    ConsoleDebug ("\ticonname: %s\n", p->iconname);
    ConsoleDebug ("\tres: %s\n", p->resname);
    ConsoleDebug ("\tclass: %s\n", p->classname);
+   ConsoleDebug ("\tdisplaystring: %s\n", p->display_string);
    ConsoleDebug ("\t(x, y): (%d, %d)\n", p->x, p->y);
    ConsoleDebug ("\tapp_id: 0x%x %d\n", p->app_id, p->app_id_set);
    ConsoleDebug ("\tdesknum: %d\n", p->desknum);
***************
*** 324,335 ****
    ConsoleDebug ("in find_win_insert\n");
    
    assert (win->manager);
!   assert (win->name);
    list = &win->manager->icon_list;
  
    if (win->manager->sort) {
      for (p = list->head; 
! 	 p && strcmp (*win->name, *p->name) > 0; 
  	 p = p->icon_next) 
        ;
    }
--- 423,434 ----
    ConsoleDebug ("in find_win_insert\n");
    
    assert (win->manager);
!   assert (win->display_string);
    list = &win->manager->icon_list;
  
    if (win->manager->sort) {
      for (p = list->head; 
! 	 p && strcmp (win->display_string, p->display_string) > 0; 
  	 p = p->icon_next) 
        ;
    }
diff -rc fvwm-2.0.43/modules/FvwmIconMan/xmanager.c fvwm.patched/modules/FvwmIconMan/xmanager.c
*** fvwm-2.0.43/modules/FvwmIconMan/xmanager.c	Sun Jun 23 13:21:15 1996
--- fvwm.patched/modules/FvwmIconMan/xmanager.c	Sun Sep 22 11:00:03 1996
***************
*** 1,8 ****
  #include "FvwmIconMan.h"
  #include "readconfig.h"
  
  #define FONT_STRING "8x13"
- #define WIN_WIDTH   12
  #define DEFAULT_WIN_WIDTH  100
  #define DEFAULT_WIN_HEIGHT 100
  
--- 1,9 ----
  #include "FvwmIconMan.h"
  #include "readconfig.h"
  
+ #define GRAB_EVENTS (ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|EnterWindowMask|LeaveWindowMask)
+ 
  #define FONT_STRING "8x13"
  #define DEFAULT_WIN_WIDTH  100
  #define DEFAULT_WIN_HEIGHT 100
  
***************
*** 10,15 ****
--- 11,22 ----
  static Window theRoot;
  static int theDepth, theScreen;
  
+ static enum {
+   NOT_GRABBED = 0,
+   NEED_TO_GRAB = 1,
+   HAVE_GRABBED = 2
+ } grab_state = NOT_GRABBED;
+ 
  WinData *find_win (WinManager *man, int box);
  
  static void ClipRectangle (WinManager *man, int focus,
***************
*** 29,40 ****
  {
  }
  
  static void map_manager (WinManager *man)
  {
    if (man->window_mapped == 0 && man->win_height > 0) {
      XMapWindow (theDisplay, man->theWindow);
      man->window_mapped = 1;
! 	 XFlush (theDisplay);
    }
  }
  
--- 36,65 ----
  {
  }
  
+ static void grab_pointer (WinManager *man)
+ {
+   /* This should only be called after we get our EXPOSE event */
+   if (grab_state == NEED_TO_GRAB) {
+     if (XGrabPointer (theDisplay, man->theWindow, True, GRAB_EVENTS,
+ 		      GrabModeAsync, GrabModeAsync, None, 
+ 		      None, CurrentTime) != GrabSuccess) {
+       ConsoleMessage ("Couldn't grab pointer\n");
+       ShutMeDown (0);
+     }
+     grab_state = HAVE_GRABBED;
+   }
+ }
+ 
  static void map_manager (WinManager *man)
  {
    if (man->window_mapped == 0 && man->win_height > 0) {
      XMapWindow (theDisplay, man->theWindow);
      man->window_mapped = 1;
!     XFlush (theDisplay);
!     if (globals.transient) {
!       /* wait for an expose event to actually do the grab */
!       grab_state = NEED_TO_GRAB;
!     }
    }
  }
  
***************
*** 225,235 ****
    
  
    /* this routine should only be called from draw_button() */
! static void iconify_box (WinManager *man, int box, int iconified,
                           Contexts contextId)
  {
!   int x, y, h;
    int focus;
  
    focus = (box == man->focus_box);
    
--- 250,264 ----
    
  
    /* this routine should only be called from draw_button() */
! static void iconify_box (WinManager *man, WinData *win, int box, int iconified,
                           Contexts contextId)
  {
!   int x, y, w, h;
    int focus;
+ #ifdef MINI_ICONS
+   XGCValues gcv;
+   unsigned long gcm;
+ #endif
  
    focus = (box == man->focus_box);
    
***************
*** 241,247 ****
    h = man->boxheight - 8;
    
    if (theDepth > 2) {
!     draw_3d_icon (man, box, iconified, 1, contextId);
    }
    else {
      if (iconified == 0) {
--- 270,302 ----
    h = man->boxheight - 8;
    
    if (theDepth > 2) {
! #ifdef MINI_ICONS
!     if (man->draw_icons && win->pic.picture) {
!       if (iconified == 1) {
! 	x = 4;
! 	y = man->boxheight * box + 2;
! 	w = MIN (win->pic.width, man->boxheight);
! 	h = MIN (man->boxheight - 4, win->pic.height);
!       
! 	gcm = GCClipMask|GCClipXOrigin|GCClipYOrigin;
! 	gcv.clip_mask = win->pic.mask;
! 	gcv.clip_x_origin = x;
! 	gcv.clip_y_origin = y;
! 	XChangeGC (theDisplay, man->hiContext[contextId], gcm, &gcv);
!       
! 	XCopyArea(theDisplay, win->pic.picture, man->theWindow, 
! 		  man->hiContext[contextId], 0, 0, w, h, x, y);
! 	gcm = GCClipMask;
! 	gcv.clip_mask = None;
! 	XChangeGC(theDisplay, man->hiContext[contextId], gcm, &gcv);
!       }
!     } 
!     else {
! #endif
!       draw_3d_icon (man, box, iconified, 1, contextId);
! #ifdef MINI_ICONS
!     }
! #endif
    }
    else {
      if (iconified == 0) {
***************
*** 261,270 ****
    GC context1, context2;
    ButtonState state;
    int focus = (button == man->focus_box && man->followFocus);
!   int selected = (button == man->current_box);
    int draw_name;
    Contexts contextId;
!   int len, x, y, w, h;
    char *name;
  
    assert (man);
--- 316,325 ----
    GC context1, context2;
    ButtonState state;
    int focus = (button == man->focus_box && man->followFocus);
!   int selected = (button == man->select_box);
    int draw_name;
    Contexts contextId;
!   int len, x, y, w, h, text_pos;
    char *name;
  
    assert (man);
***************
*** 310,320 ****
--- 365,382 ----
        context1 = man->shadowContext[contextId];
        context2 = man->reliefContext[contextId];
        break;
+ 
+     default:
+       ConsoleMessage ("Internal error in draw_button\n");
+       break;
      }
      draw_3d_square (man, 0, button * man->boxheight, 
  		    man->win_width, man->boxheight, context1, context2 );
+ 
+     text_pos = 10 + (man->boxheight - 8);
    }
    else {
+     text_pos = 10 + (man->boxheight - 8);
      if (selected)
        XDrawRectangle (theDisplay, man->theWindow, man->hiContext[contextId], 
  		      2, button * man->boxheight + 1, 
***************
*** 323,331 ****
    }
  
    if (draw_name) {
!     name = *win->name;
      len = strlen (name);
!     x = 10 + (man->boxheight - 8);
      y = man->boxheight * button + 2;
      w = man->win_width - 4 - x;
      h = man->fontheight;
--- 385,394 ----
    }
  
    if (draw_name) {
!     name = win->display_string;
!     assert (name);
      len = strlen (name);
!     x = text_pos;
      y = man->boxheight * button + 2;
      w = man->win_width - 4 - x;
      h = man->fontheight;
***************
*** 333,365 ****
      ClipRectangle (man, focus, x, y, w, h);
      
      XDrawString (theDisplay, man->theWindow, man->hiContext[contextId], 
! 		 10 + (man->boxheight - 8), 
! 		 man->boxheight * (button + 1) - 4,
  		 name, len);
      
      XSetClipMask (theDisplay, man->hiContext[contextId], None);
    }
  
    if ( win ) 
!     iconify_box( man, button, win->iconified, contextId );
  }
  
- void move_highlight (WinManager *man, int to)
- {
-   int box;
  
!   ConsoleDebug ("move_highlight: current %d to %d\n", man->current_box, to);
  
!   if (man->current_box >= 0) { 
!     box = man->current_box;
!     man->current_box = -1;
!     draw_button( man, NULL, box );
!   }
  
!   man->current_box = to;
  
!   if (to >= 0)
!     draw_button( man, NULL, to );
  }
    
  
--- 396,450 ----
      ClipRectangle (man, focus, x, y, w, h);
      
      XDrawString (theDisplay, man->theWindow, man->hiContext[contextId], 
! 		 x, man->boxheight * (button + 1) - 4,
  		 name, len);
      
      XSetClipMask (theDisplay, man->hiContext[contextId], None);
    }
  
    if ( win ) 
!     iconify_box( man, win, button, win->iconified, contextId );
  }
  
  
! /* If man == NULL || box < 0, then there will be no selected button */
  
! void move_highlight (WinManager *man, int box)
! {
!   WinData *new_win;
!   WinManager *select_man;
!   int select_box;
  
!   ConsoleDebug ("move_highlight: 0x%x, %d\n", man, box);
  
!   if (man && box >= 0) {
!     new_win = find_win (man, box);
!     if (new_win == NULL) {
!       ConsoleMessage ("Internal error in move_highlight\n");
!       return;
!     }
!     if (new_win == globals.select_win) {
!       return;
!     }
!     if (globals.select_win) {
!       select_man = globals.select_win->manager;
!       select_box = select_man->select_box;
!       select_man->select_box = -1;
!       draw_button (select_man, NULL, select_box);
!     }
!     globals.select_win = new_win;
!     globals.select_win->manager->select_box = box;
!     draw_button (globals.select_win->manager, NULL, box);
!   }
!   else {
!     if (globals.select_win) {
!       select_man = globals.select_win->manager;
!       select_box = select_man->select_box;
!       select_man->select_box = -1;
!       globals.select_win = NULL;
!       draw_button (select_man, NULL, select_box);
!     }
!   }
  }
    
  
***************
*** 494,506 ****
    return NULL;
  }
  
  void xevent_loop (void)
  {
    XEvent theEvent;
-   WinData *win;
    int k, glob_x, glob_y, x, y, mask;
    unsigned int modifier;
!   Binding *key, *MouseEntry;
    static int flag = 0;
    WinManager *man;
    Window root, child;
--- 579,631 ----
    return NULL;
  }
  
+ static void handle_buttonevent (XEvent *theEvent, WinManager *man)
+ {
+   int k;
+   WinData *win;
+   unsigned int modifier;
+   Binding *MouseEntry;
+ 
+   k = which_box (man, theEvent->xbutton.x, theEvent->xbutton.y);
+   ConsoleDebug ("Got a Button event %d in box: %d\n", 
+ 		theEvent->xbutton.button, k);
+   if (k >= 0 && theEvent->xbutton.button >= 1 && 
+       theEvent->xbutton.button <= 3) {
+     win = find_win (man, k);
+     if (win != NULL) {
+       ConsoleDebug ("Found the window:\n");
+       ConsoleDebug ("\tid:        %d\n", win->app_id);
+       ConsoleDebug ("\tdesknum:   %d\n", win->desknum);
+       ConsoleDebug ("\tx, y:      %d %d\n", win->x, win->y);
+       ConsoleDebug ("\ticon:      %d\n", win->iconname);
+       ConsoleDebug ("\ticonified: %d\n", win->iconified);
+       ConsoleDebug ("\tcomplete:  %d\n", win->complete);
+ 
+       modifier = (theEvent->xbutton.state & MODS_USED);
+       /* need to search for an appropriate mouse binding */
+       for (MouseEntry = man->bindings[MOUSE]; MouseEntry != NULL;
+ 	   MouseEntry= MouseEntry->NextBinding) {
+ 	if(((MouseEntry->Button_Key == theEvent->xbutton.button)||
+ 	    (MouseEntry->Button_Key == 0))&&
+ 	   ((MouseEntry->Modifier == AnyModifier)||
+ 	    (MouseEntry->Modifier == (modifier& (~LockMask)))))
+ 	{
+ 	  Function *ftype = MouseEntry->Function;
+ 	  if (ftype && ftype->func) 
+ 	    run_function_list (ftype);
+ 	  break;
+ 	}
+       }
+     }
+   }
+ }
+ 
  void xevent_loop (void)
  {
    XEvent theEvent;
    int k, glob_x, glob_y, x, y, mask;
    unsigned int modifier;
!   Binding *key;
    static int flag = 0;
    WinManager *man;
    Window root, child;
***************
*** 511,526 ****
    }
    while (XPending (theDisplay)) {
      XNextEvent (theDisplay, &theEvent);
!     if (theEvent.type == MappingNotify)
        continue;
  
      man = find_windows_manager (theEvent.xany.window);
!     if (!man)
        continue;
  
      switch (theEvent.type) {
  #if 0
      case ReparentNotify:
        man->theParent = theEvent.xreparent.parent;
        XQueryTree (theDisplay, man->theParent, &junkroot, &man->theFrame, 
  		  &junkwinlist, &junknumchildren);
--- 636,657 ----
    }
    while (XPending (theDisplay)) {
      XNextEvent (theDisplay, &theEvent);
!     ConsoleDebug ("theEvent.type: %d\n", theEvent.type);
!     if (theEvent.type == MappingNotify) {
!       ConsoleDebug ("XEVENT: MappingNotify\n");
        continue;
+     }
  
      man = find_windows_manager (theEvent.xany.window);
!     if (!man) {
!       ConsoleDebug ("Event doesn't belong to a manager\n");
        continue;
+     }
  
      switch (theEvent.type) {
  #if 0
      case ReparentNotify:
+       ConsoleDebug ("XEVENT: ReparentNotify\n");
        man->theParent = theEvent.xreparent.parent;
        XQueryTree (theDisplay, man->theParent, &junkroot, &man->theFrame, 
  		  &junkwinlist, &junknumchildren);
***************
*** 537,542 ****
--- 668,674 ----
  #endif
  
      case KeyPress:
+       ConsoleDebug ("XEVENT: KeyPress\n");
        /* Here's a real hack - some systems have two keys with the
         * same keysym and different keycodes. This converts all
         * the cases to one keycode. */
***************
*** 562,607 ****
      break;
  
      case Expose:
!       if (theEvent.xexpose.count == 0)
  	draw_window (man);
        break;
  
      case ButtonPress:
!       k = which_box (man, theEvent.xbutton.x, theEvent.xbutton.y);
!       ConsoleDebug ("Got a Button press %d in box: %d\n", 
! 		    theEvent.xbutton.button, k);
!       if (k >= 0 && theEvent.xbutton.button >= 1 && 
! 	  theEvent.xbutton.button <= 3) {
! 	win = find_win (man, k);
! 	if (win != NULL) {
! 	  ConsoleDebug ("Found the window:\n");
! 	  ConsoleDebug ("\tid:        %d\n", win->app_id);
! 	  ConsoleDebug ("\tdesknum:   %d\n", win->desknum);
! 	  ConsoleDebug ("\tx, y:      %d %d\n", win->x, win->y);
! 	  ConsoleDebug ("\ticon:      %d\n", win->iconname);
! 	  ConsoleDebug ("\ticonified: %d\n", win->iconified);
! 	  ConsoleDebug ("\tcomplete:  %d\n", win->complete);
! 
! 	  modifier = (theEvent.xbutton.state & MODS_USED);
! 	  /* need to search for an appropriate mouse binding */
! 	  for (MouseEntry = man->bindings[MOUSE]; MouseEntry != NULL;
! 	       MouseEntry= MouseEntry->NextBinding) {
! 	    if(((MouseEntry->Button_Key == theEvent.xbutton.button)||
! 		(MouseEntry->Button_Key == 0))&&
! 	       ((MouseEntry->Modifier == AnyModifier)||
! 		(MouseEntry->Modifier == (modifier& (~LockMask)))))
! 	    {
! 	      Function *ftype = MouseEntry->Function;
! 	      if (ftype && ftype->func) 
! 		run_function_list (ftype);
! 	      break;
! 	    }
! 	  }
! 	}
        }
        break;
  
      case EnterNotify:
        man->cursor_in_window = 1;
        k = which_box (man, theEvent.xcrossing.x, theEvent.xcrossing.y);
        move_highlight (man, k);
--- 694,724 ----
      break;
  
      case Expose:
!       ConsoleDebug ("XEVENT: Expose\n");
!       if (theEvent.xexpose.count == 0) {
  	draw_window (man);
+ 	if (globals.transient) {
+ 	  grab_pointer (man);
+ 	}
+       }
        break;
  
      case ButtonPress:
!       ConsoleDebug ("XEVENT: ButtonPress\n");
!       if (!globals.transient)
! 	handle_buttonevent (&theEvent, man);
!       break;
! 
!     case ButtonRelease:
!       ConsoleDebug ("XEVENT: ButtonRelease\n");
!       if (globals.transient) {
! 	handle_buttonevent (&theEvent, man);
! 	ShutMeDown (0);
        }
        break;
  
      case EnterNotify:
+       ConsoleDebug ("XEVENT: EnterNotify\n");
        man->cursor_in_window = 1;
        k = which_box (man, theEvent.xcrossing.x, theEvent.xcrossing.y);
        move_highlight (man, k);
***************
*** 609,619 ****
        break;
  
      case LeaveNotify:
!       move_highlight (man, -1);
        break;
  
      case ConfigureNotify:
!       ConsoleDebug ("Configure Notify: %d %d %d %d\n",
  		    theEvent.xconfigure.x, theEvent.xconfigure.y,
  		    theEvent.xconfigure.width, theEvent.xconfigure.height);
        if (theEvent.xconfigure.send_event) {
--- 726,737 ----
        break;
  
      case LeaveNotify:
!       ConsoleDebug ("XEVENT: LeaveNotify\n");
!       move_highlight (NULL, -1);
        break;
  
      case ConfigureNotify:
!       ConsoleDebug ("XEVENT: Configure Notify: %d %d %d %d\n",
  		    theEvent.xconfigure.x, theEvent.xconfigure.y,
  		    theEvent.xconfigure.width, theEvent.xconfigure.height);
        if (theEvent.xconfigure.send_event) {
***************
*** 635,685 ****
  			 &x, &y, &mask)) {
  	k = which_box (man, x, y);
  	ConsoleDebug (">>>>> Query: %d %d = %d\n", x, y, k);
! 	if (k != man->current_box) {
  	  move_highlight (man, k);
  	  run_binding (man, SELECT);
  	}
        }
        else {
! 	if (man->current_box != -1)
! 	  move_highlight (man, -1);
        }
        break;
  
      case MotionNotify:
        k = which_box (man, theEvent.xmotion.x, theEvent.xmotion.y);
!       if (k != man->current_box) {
  	move_highlight (man, k);
  	run_binding (man, SELECT);
        }
        break;
      }
    }
    XFlush (theDisplay);
  }
  
! void set_window_properties (Window win, char *p, XSizeHints *sizehints)
  {
!   XTextProperty name;
    XClassHint class;
    XWMHints wmhints;
  
    wmhints.initial_state = NormalState;
    wmhints.flags = StateHint;
  
!   if (XStringListToTextProperty (&p, 1, &name) == 0) {
      ConsoleMessage ("%s: cannot allocate window name.\n",Module);
      return;
    }
  
    class.res_name = Module + 1;
    class.res_class = "FvwmModule";
    
  
!   XSetWMProperties (theDisplay, win, &name, &name, NULL, 0,
  		    sizehints, &wmhints, &class);
  
!   XFree (name.value);
  }
  
  static int load_default_context_fore (WinManager *man, int i)
--- 753,814 ----
  			 &x, &y, &mask)) {
  	k = which_box (man, x, y);
  	ConsoleDebug (">>>>> Query: %d %d = %d\n", x, y, k);
! 	if (k != man->select_box) {
  	  move_highlight (man, k);
  	  run_binding (man, SELECT);
  	}
        }
        else {
! 	if (man->select_box != -1)
! 	  move_highlight (NULL, -1);
        }
        break;
  
      case MotionNotify:
+    /* ConsoleDebug ("XEVENT: MotionNotify\n"); */
        k = which_box (man, theEvent.xmotion.x, theEvent.xmotion.y);
!       if (k != man->select_box) {
  	move_highlight (man, k);
  	run_binding (man, SELECT);
        }
        break;
+ 
+     default:
+       ConsoleDebug ("XEVENT: unknown\n");
      }
    }
    XFlush (theDisplay);
  }
  
! static void set_window_properties (Window win, char *name, char *icon, 
! 				   XSizeHints *sizehints)
  {
!   XTextProperty win_name;
!   XTextProperty win_icon;
    XClassHint class;
    XWMHints wmhints;
  
    wmhints.initial_state = NormalState;
    wmhints.flags = StateHint;
  
!   if (XStringListToTextProperty (&name, 1, &win_name) == 0) {
      ConsoleMessage ("%s: cannot allocate window name.\n",Module);
      return;
    }
+   if (XStringListToTextProperty (&icon, 1, &win_icon) == 0) {
+     ConsoleMessage ("%s: cannot allocate window icon.\n",Module);
+     return;
+   }
  
    class.res_name = Module + 1;
    class.res_class = "FvwmModule";
    
  
!   XSetWMProperties (theDisplay, win, &win_name, &win_icon, NULL, 0,
  		    sizehints, &wmhints, &class);
  
!   XFree (win_name.value);
!   XFree (win_icon.value);
  }
  
  static int load_default_context_fore (WinManager *man, int i)
***************
*** 731,737 ****
  
    man->win_height = DEFAULT_WIN_HEIGHT;
    man->win_width = DEFAULT_WIN_WIDTH;
!   man->current_box = -1;
    man->cursor_in_window = 0;
  
    if (man->fontname) {
--- 860,866 ----
  
    man->win_height = DEFAULT_WIN_HEIGHT;
    man->win_width = DEFAULT_WIN_WIDTH;
!   man->select_box = -1;
    man->cursor_in_window = 0;
  
    if (man->fontname) {
***************
*** 793,798 ****
--- 922,932 ----
      man->ButtonFont->descent;
    man->boxheight = man->fontheight + 4;
  
+   /* silly hack to guess the minimum char width of the font 
+      doesn't have to be perfect. */
+ 
+   man->fontwidth = XTextWidth (man->ButtonFont, ".", 1);
+ 
    man->win_height = man->boxheight * man->icon_list.n;
    if (man->win_height == 0) {
      man->win_height = 1;
***************
*** 832,893 ****
      ConsoleDebug ("gravity: %d %d\n", sizehints.win_gravity, gravity);
      sizehints.flags |= USPosition;
    }
! 
!   if (0 && man->geometry) {
!     val = XParseGeometry (man->geometry, &x, &y, &width, &height);
!     if (val & WidthValue) {
!       man->win_width = sizehints.width = width;
!     }
!     if (val & XValue) {
!       sizehints.x = x;
!       if (val & XNegative) {
! 	sizehints.x += globals.screenx - sizehints.width - 2;
!       }
!     }
!     if (val & YValue) {
!       sizehints.y = y;
!       if (val & YNegative) {
! 	sizehints.y += globals.screeny - sizehints.height - 2;
!       }
!     }
! 
!     if (val & XNegative) { 
!       if (val & YNegative) {
! 	sizehints.win_gravity = SouthEastGravity;
! 	man->grow_direction = SouthGravity;
!       }
!       else { 
! 	sizehints.win_gravity = NorthEastGravity;
!       }
!     }
!     else { 
!       if (val & YNegative) { 
! 	sizehints.win_gravity = SouthWestGravity;
! 	man->grow_direction = SouthGravity;
!       }
!       else { 
! 	sizehints.win_gravity = NorthWestGravity;
!       }
!     }
!     /*
! 
!     if ((val & YValue) && (val & YNegative)) {
!       man->grow_direction = SouthGravity;
!       if (val & XValue & XNegative) 
! 	sizehints.win_gravity = SouthEastGravity;
!       else 
! 	sizehints.win_gravity = SouthWestGravity;
!     } else {
!       man->grow_direction = NorthGravity;
!       if (val & XValue & XNegative) 
! 	sizehints.win_gravity = NorthWestGravity;
!       else 
! 	sizehints.win_gravity = NorthEastGravity;
!     }
!     */
! 
      sizehints.flags |= USPosition;
-     ConsoleDebug ("Got geometry: %d %d\n", sizehints.x, sizehints.y);
    }
  
    man->win_x = sizehints.x;
--- 966,979 ----
      ConsoleDebug ("gravity: %d %d\n", sizehints.win_gravity, gravity);
      sizehints.flags |= USPosition;
    }
!   if (globals.transient) {
!     Window dummyroot, dummychild;
!     int x, y, dummymask;
! 
!     XQueryPointer(theDisplay, theRoot, &dummyroot, &dummychild, &sizehints.x,
! 		  &sizehints.y, &x, &y, &dummymask);
!     sizehints.win_gravity = NorthWestGravity;
      sizehints.flags |= USPosition;
    }
  
    man->win_x = sizehints.x;
***************
*** 896,911 ****
    winattr.background_pixel = man->backcolor[PLAIN_CONTEXT];
    winattr.border_pixel = man->forecolor[PLAIN_CONTEXT];
    winattr.backing_store = WhenMapped;
!   winattr.event_mask = ExposureMask | ButtonPressMask | 
!     PointerMotionMask | EnterWindowMask | LeaveWindowMask |
!       KeyPressMask | StructureNotifyMask;
  
    man->theWindow = XCreateWindow (theDisplay, theRoot, sizehints.x,
  				  sizehints.y, man->win_width, man->win_height,
  				  1, CopyFromParent, InputOutput, 
  				  (Visual *)CopyFromParent, winattrmask,
  				  &winattr);
!   
    for (i = 0; i < NUM_CONTEXTS; i++) {
      man->backContext[i] =
        XCreateGC (theDisplay, man->theWindow, gcmask, &gcval);
--- 982,1001 ----
    winattr.background_pixel = man->backcolor[PLAIN_CONTEXT];
    winattr.border_pixel = man->forecolor[PLAIN_CONTEXT];
    winattr.backing_store = WhenMapped;
!   winattr.event_mask = ExposureMask | PointerMotionMask | EnterWindowMask | 
!     LeaveWindowMask | KeyPressMask | StructureNotifyMask;
! 
!   if (globals.transient)
!     winattr.event_mask |= ButtonReleaseMask;
!   else
!     winattr.event_mask |= ButtonPressMask;
  
    man->theWindow = XCreateWindow (theDisplay, theRoot, sizehints.x,
  				  sizehints.y, man->win_width, man->win_height,
  				  1, CopyFromParent, InputOutput, 
  				  (Visual *)CopyFromParent, winattrmask,
  				  &winattr);
! 
    for (i = 0; i < NUM_CONTEXTS; i++) {
      man->backContext[i] =
        XCreateGC (theDisplay, man->theWindow, gcmask, &gcval);
***************
*** 939,945 ****
      }
    }
      
!   set_window_properties (man->theWindow, Module + 1, &sizehints);
    man->window_up = 1;
    update_window_stuff (man);
  
--- 1029,1036 ----
      }
    }
      
!   set_window_properties (man->theWindow, man->titlename, 
! 			 man->iconname, &sizehints);
    man->window_up = 1;
    update_window_stuff (man);
  
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to majordomo_at_hpc.uh.edu.
To report problems, send mail to fvwm-owner_at_hpc.uh.edu.
Received on Sun Sep 22 1996 - 21:27:45 BST

This archive was generated by hypermail 2.3.0 : Mon Aug 29 2016 - 19:37:59 BST