From: [email-masked] (Rob Whapham)
Date: Fri, 31 Jan 1997 12:18:54 -0500

----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 32

Attached is a patch for the FvwmPager module distributed with Fvwm95 v2.0.43a
(it may also work with the real Fvwm2, which is why I'm also sending this to
both mailing lists).  It adds the option to allow the pager to display a
window's title/mini icon instead of it's name (or instead of nothing).  To
enable it, use:

	*FvwmPagerMiniIcons

Note that if you also have SmallFont set, this will unset it (i.e., you can't
have both the mini icon and the title at the same time).  Also, no attempt is
made to scale the icons--they are centered in the window and clipped where
necessary.

Also in the patch is the ability to change the normal/highlight colors of
the windows.  Use:

	*FvwmPagerWindowColors normalFore normalBack hiFore hiBack

This is useful for picking colors that will make your icons stand out better
than the default window colors set up via the Fvwm DefaultColors resource.  It
also works when having the pager display the window titles.

By the way, all the changes in the patch are line additions, so if it doesn't
fit exactly with the real Fvwm2, it shouldn't be too hard to do the patch by
hand.

Questions/comments welcome.

--------------------
Rob Whapham
Software Developer
HubLink, Inc.
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: FvwmPager.diff
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 623

*** FvwmPager.orig.h	Thu Jan 30 13:52:25 1997
--- FvwmPager.h	Fri Jan 31 08:40:41 1997
***************
*** 55,60 ****
--- 55,65 ----
    Window icon_w;
    Window icon_pixmap_w;
    char *icon_name;
+   Picture mini_icon;
+   int pager_view_width;
+   int pager_view_height;
+   int icon_view_width;
+   int icon_view_height;
  
    Window PagerView;
    Window IconView;
***************
*** 82,87 ****
--- 87,93 ----
   * Subroutine Prototypes
   * 
   *************************************************************************/
+ char *GetNextToken(char *indata,char **token);
  void Loop(int *fd);
  void SendInfo(int *fd,char *message,unsigned long window);
  char *safemalloc(int length);
***************
*** 105,110 ****
--- 111,117 ----
  void list_icon_name(unsigned long *body);
  void list_class(unsigned long *body);
  void list_res_name(unsigned long *body);
+ void list_mini_icon(unsigned long *body);
  void list_end(void);
  int My_XNextEvent(Display *dpy, XEvent *event);
  
***************
*** 129,134 ****
--- 136,143 ----
  void MoveWindow(XEvent *Event);
  void LabelWindow(PagerWindow *t);
  void LabelIconWindow(PagerWindow *t);
+ void PictureWindow(PagerWindow *t);
+ void PictureIconWindow(PagerWindow *t);
  void ReConfigureIcons(void);
  void IconSwitchPage(XEvent *Event);
  void IconScroll(int x, int y);
*** FvwmPager.orig.c	Thu Jan 30 13:44:44 1997
--- FvwmPager.c	Fri Jan 31 09:09:56 1997
***************
*** 63,68 ****
--- 63,72 ----
  char *font_string = "fixed";
  char *smallFont = NULL;
  char *HilightC = "black";
+ char *WindowBack = NULL;
+ char *WindowFore = NULL;
+ char *WindowHiBack = NULL;
+ char *WindowHiFore = NULL;
  
  int window_w=0, window_h=0, window_x=0, window_y=0;
  int icon_x=-10000, icon_y=-10000, icon_w=0, icon_h=0;
***************
*** 70,78 ****
--- 74,89 ----
  int xneg = 0, yneg = 0;
  extern DeskInfo *Desks;
  int StartIconic = 0;
+ int	MiniIcons = 0;
  int Rows = -1, Columns = -1;
  int desk1=0, desk2 =0;
  int ndesks = 0;
+ 
+ Pixel win_back_pix = -1;
+ Pixel win_fore_pix = -1;
+ Pixel win_hi_back_pix = -1;
+ Pixel win_hi_fore_pix = -1;
+ 
  /***********************************************************************
   *
   *  Procedure:
***************
*** 174,179 ****
--- 185,191 ----
  		 M_ICON_NAME|
  		 M_CONFIG_INFO|
  		 M_END_CONFIG_INFO|
+ 		 M_MINI_ICON|
  		 M_END_WINDOWLIST);
  #ifdef DEBUG
    fprintf(stderr,"[main]: calling ParseOptions\n");
***************
*** 262,267 ****
--- 274,282 ----
      case M_ICON_NAME:
        list_icon_name(body);
        break;
+ 	case M_MINI_ICON:
+ 		list_mini_icon(body);
+ 		break;
      case M_END_WINDOWLIST:
        list_end();
        break;
***************
*** 313,325 ****
--- 328,353 ----
    (*prev)->desk = body[7];
    (*prev)->next = NULL;
    (*prev)->flags = body[8];
+   (*prev)->pager_view_width = 0;
+   (*prev)->pager_view_height = 0;
+   (*prev)->icon_view_width = 0;
+   (*prev)->icon_view_height = 0;
    (*prev)->icon_name = NULL;
+   (*prev)->mini_icon.picture = 0;
    (*prev)->title_height = body[9];
    (*prev)->border_width = body[10];
    (*prev)->icon_w = body[19];
    (*prev)->icon_pixmap_w = body[20];
+   if ((win_fore_pix != -1) && (win_back_pix != -1))
+   {
+ 	  (*prev)->text = win_fore_pix;
+ 	  (*prev)->back = win_back_pix;
+   }
+   else
+   {
  	  (*prev)->text = body[22];
  	  (*prev)->back = body[23];
+   }
    AddNewWindow(*prev);
  }
  
***************
*** 358,365 ****
--- 386,401 ----
        t->flags = body[8];
        t->icon_w = body[19];
        t->icon_pixmap_w = body[20];
+ 	  if ((win_fore_pix != -1) && (win_back_pix != -1))
+ 	  {
+ 	      t->text = win_fore_pix;
+ 	      t->back = win_back_pix;
+ 	  }
+ 	  else
+ 	  {
  	      t->text = body[22];
  	      t->back = body[23];
+ 	  }
        if(t->flags & ICONIFIED)
  	{
  	  t->x = t->icon_x;
***************
*** 440,447 ****
--- 476,491 ----
    extern Pixel focus_pix, focus_fore_pix;
    target_w = body[0];
    
+   if ((win_hi_fore_pix != -1) && (win_hi_back_pix != -1))
+   {
+ 	  focus_pix			= win_hi_back_pix;
+ 	  focus_fore_pix	= win_hi_fore_pix;
+   }
+   else
+   {
  	  focus_pix			= body[4];
  	  focus_fore_pix	= body[3];
+   }
    t = Start;
    while((t!= NULL)&&(t->w != target_w))
      {
***************
*** 679,686 ****
--- 723,754 ----
  }

+ void list_mini_icon(unsigned long *body)
+ {
+ 	PagerWindow	*t;
+ 	Window		target_w;
  
+ 	target_w	= body[0];
+ 	t			= Start;
  
+ 	while (t && (t->w != target_w))
+ 		t = t->next;
+ 
+ 	if (t)
+ 	{
+ 		t->mini_icon.picture	= body[1];
+ 		t->mini_icon.mask		= body[2];
+ 		t->mini_icon.width		= body[3];
+ 		t->mini_icon.height		= body[4];
+ 		t->mini_icon.depth		= body[5];
+ 		PictureWindow (t);
+ 		PictureIconWindow (t);
+ 	}
+ }
+ 
+ 
+ 
+ 
  /***********************************************************************
   *
   *  Procedure:
***************
*** 788,793 ****
--- 856,862 ----
  {
    char *tend,*tstart;
    char *tline= NULL,*tmp;
+   char *colors;
    int Clength,n,desk;
  
    Scr.FvwmRoot = NULL;
***************
*** 952,959 ****
--- 1021,1039 ----
  	      (strncasecmp(tline,CatString3("*",MyName,"SmallFont"),
  			     Clength+10)==0))
  	{
+ 		if (MiniIcons == 0)
  		  CopyString(&smallFont,&tline[Clength+10]);
  	}	
+ 	else if ((strlen (&tline[0]) > 1) && (strncasecmp (tline, CatString3 ("*", MyName, "MiniIcons"), Clength + 9) == 0))
+ 	{
+ 		if (smallFont)
+ 		{
+ 			free (smallFont);
+ 			smallFont = NULL;
+ 		}
+ 
+ 		MiniIcons = 1;
+ 	}
        else if((strlen(&tline[0])>1)&&
  	      (strncasecmp(tline,CatString3("*",MyName,"StartIconic"),
  			     Clength+12)==0))
***************
*** 978,986 ****
--- 1058,1149 ----
          {
            sscanf(&tline[Clength+13],"%d",&Scr.VScale);
          }
+ 	else if ((strlen (&tline[0]) > 1) && (strncasecmp (tline, CatString3 ("*", MyName, "WindowColors"), Clength + 13) == 0))
+ 	{
+ 		if (Scr.d_depth > 1)
+ 		{
+ 			colors = &tline[Clength + 13];
+ 			colors = GetNextToken (colors, &WindowFore);
+ 			colors = GetNextToken (colors, &WindowBack);
+ 			colors = GetNextToken (colors, &WindowHiFore);
+ 			colors = GetNextToken (colors, &WindowHiBack);
+ 		}
+ 	}
        GetConfigLine(fd,&tline);
      }
    return;
+ }
+ 
+ char *GetNextToken(char *indata,char **token)
+ { 
+   char *t,*start, *end, *text;
+ 
+   t = indata;
+   if(t == NULL)
+     {
+       *token = NULL;
+       return NULL;
+     }
+   while(isspace(*t)&&(*t != 0))t++;
+   start = t;
+   while(!isspace(*t)&&(*t != 0))
+     {
+       /* Check for qouted text */
+       if(*t == '"')
+ 	{
+ 	  t++;
+ 	  while((*t != '"')&&(*t != 0))
+ 	    {
+ 	      /* Skip over escaped text, ie \" or \space */
+ 	      if((*t == '\\')&&(*(t+1) != 0))
+ 		t++;
+ 	      t++;
+ 	    }
+ 	  if(*t == '"')
+ 	    t++;
+ 	}
+       else
+ 	{
+ 	  /* Skip over escaped text, ie \" or \space */
+ 	  if((*t == '\\')&&(*(t+1) != 0))
+ 	    t++;
+ 	  t++;
+ 	}
+     }
+   end = t;
+ 
+   text = safemalloc(end-start+1);
+   *token = text;
+ 
+   while(start < end)
+     {
+       /* Check for qouted text */
+       if(*start == '"')
+ 	{	
+ 	  start++;
+ 	  while((*start != '"')&&(*start != 0))
+ 	    {
+ 	      /* Skip over escaped text, ie \" or \space */
+ 	      if((*start == '\\')&&(*(start+1) != 0))
+ 		start++;
+ 	      *text++ = *start++;
+ 	    }
+ 	  if(*start == '"')
+ 	    start++;
+ 	}
+       else
+ 	{
+ 	  /* Skip over escaped text, ie \" or \space */
+ 	  if((*start == '\\')&&(*(start+1) != 0))
+ 	    start++;
+ 	  *text++ = *start++;
+ 	}
+     }
+   *text = 0;
+   if(*end != 0)
+     end++;
+ 
+   return end;
  }

*** x_pager.orig.c	Tue Dec 10 11:41:46 1996
--- x_pager.c	Fri Jan 31 09:10:00 1997
***************
*** 28,40 ****
--- 28,43 ----
  Pixel back_pix, fore_pix, hi_pix;
  Pixel focus_pix;
  Pixel focus_fore_pix;
+ extern Pixel win_back_pix, win_fore_pix, win_hi_back_pix, win_hi_fore_pix;
  extern int window_w, window_h,window_x,window_y,usposition,uselabel,xneg,yneg;
  extern int StartIconic;
+ extern int MiniIcons;
  extern int icon_w, icon_h, icon_x, icon_y;
  XFontStruct *font, *windowFont;
  
  GC NormalGC,DashedGC,HiliteGC,rvGC;
  GC StdGC;
+ GC MiniIconGC;
  
  extern PagerWindow *Start;
  extern PagerWindow *FocusWin;
***************
*** 102,107 ****
--- 105,111 ----
    unsigned long valuemask;
    XSetWindowAttributes attributes;
    extern char *PagerFore, *PagerBack, *HilightC;
+   extern char *WindowBack, *WindowFore, *WindowHiBack, *WindowHiFore;
    extern char *font_string, *smallFont;
    int n,m,w,h,i,x,y;
    XGCValues gcv;
***************
*** 141,146 ****
--- 145,158 ----
    back_pix = GetColor(PagerBack);
    hi_pix = GetColor(HilightC);
  
+   if (WindowBack && WindowFore && WindowHiBack && WindowHiFore)
+   {
+   	win_back_pix	= GetColor (WindowBack);
+   	win_fore_pix	= GetColor (WindowFore);
+   	win_hi_back_pix	= GetColor (WindowHiBack);
+   	win_hi_fore_pix	= GetColor (WindowHiFore);
+   }
+ 
    /* Load pixmaps for mono use */
    if(Scr.d_depth<2)
      {
***************
*** 360,365 ****
--- 372,378 ----
  
    gcv.font =  font->fid;
    NormalGC = XCreateGC(dpy, Scr.Root, gcm, &gcv);  
+   MiniIconGC = XCreateGC(dpy, Scr.Root, gcm, &gcv);  
  
    gcv.foreground = hi_pix;
    if(Scr.d_depth < 2)
***************
*** 558,567 ****
--- 571,582 ----
        if(t->PagerView == Event->xany.window)
  	{
  	  LabelWindow(t);
+ 	  PictureWindow(t);
  	}
        else if(t->IconView == Event->xany.window)
  	{
  	  LabelIconWindow(t);
+ 	  PictureIconWindow(t);
  	}
        
        t = t->next;
***************
*** 723,728 ****
--- 738,746 ----
        if (h < 1)
  	h = 1;
  
+ 	t->icon_view_width	= w;
+ 	t->icon_view_height	= h;
+       
        if(Scr.CurrentDesk == t->desk)
  	XMoveResizeWindow(dpy,t->IconView,x,y,w,h);
        else
***************
*** 929,934 ****
--- 947,955 ----
    if(h<1)
      h = 1;
  
+ 	t->pager_view_width		= w;
+ 	t->pager_view_height	= h;
+       
    valuemask = (CWBackPixel | CWBorderPixel | CWEventMask);
    attributes.background_pixel = t->back;
    attributes.border_pixel = fore_pix;
***************
*** 958,963 ****
--- 979,987 ----
    if(h<1)
      h = 1;
  
+ 	t->icon_view_width	= w;
+ 	t->icon_view_height	= h;
+       
    if(Scr.CurrentDesk == t->desk)
      {
        t->IconView = XCreateWindow(dpy,icon_win, x, y, w, h,1,
***************
*** 1009,1014 ****
--- 1033,1042 ----
      w = 1;
    if (h < 1)
      h = 1;
+ 
+ 	t->pager_view_width		= w;
+ 	t->pager_view_height	= h;
+       
    if((i >= 0)&&(i < ndesks))
      {
        XReparentWindow(dpy, t->PagerView, Desks[i].w, x,y);
***************
*** 1029,1034 ****
--- 1057,1066 ----
      w = 1;
    if (h < 1)
      h = 1;
+ 
+ 	t->icon_view_width	= w;
+ 	t->icon_view_height	= h;
+ 
    if(Scr.CurrentDesk == t->desk)
      XMoveResizeWindow(dpy,t->IconView,x,y,w,h);
    else
***************
*** 1054,1059 ****
--- 1086,1095 ----
      w = 1;
    if (h < 1)
      h = 1;
+ 
+ 	t->pager_view_width		= w;
+ 	t->pager_view_height	= h;
+ 
    if(t->PagerView != None)
      XMoveResizeWindow(dpy,t->PagerView,x,y,w,h);
    else if((t->desk >= desk1)&&(t->desk <= desk2))
***************
*** 1074,1079 ****
--- 1110,1119 ----
      w = 1;
    if (h < 1)
      h = 1;
+ 
+ 	t->icon_view_width	= w;
+ 	t->icon_view_height	= h;
+       
    if(Scr.CurrentDesk == t->desk)
      XMoveResizeWindow(dpy,t->IconView,x,y,w,h);
    else
***************
*** 1158,1163 ****
--- 1198,1205 ----
    XClearWindow(dpy,t->IconView);
    LabelWindow(t);
    LabelIconWindow(t);
+   PictureWindow(t);
+   PictureIconWindow(t);
  }
  
  void Scroll(int Desk, int x, int y)
***************
*** 1535,1540 ****
--- 1577,1583 ----
        Globalgcv.foreground = focus_fore_pix;
        Globalgcv.background = focus_pix;
        Globalgcm = GCForeground|GCBackground;
+       XChangeGC(dpy,StdGC,Globalgcm,&Globalgcv); 
      }
    else
      {
***************
*** 1548,1553 ****
--- 1591,1696 ----
    XDrawString (dpy, t->IconView,StdGC,2,windowFont->ascent+2 , 
  	       t->icon_name, strlen(t->icon_name));        
  
+ }
+ 
+ void PictureWindow (PagerWindow *t)
+ {
+ 	XGCValues		Globalgcv;
+ 	unsigned long	Globalgcm;
+ 	int				iconX;
+ 	int				iconY;
+ 
+ 	if (MiniIcons)
+ 	{
+ 		if (t->mini_icon.picture && (t->PagerView != None))
+ 		{
+ 			if (t->pager_view_width > t->mini_icon.width)
+ 				iconX = (t->pager_view_width - t->mini_icon.width) / 2;
+ 			else if (t->pager_view_width < t->mini_icon.width)
+ 				iconX = -((t->mini_icon.width - t->pager_view_width) / 2);
+ 			else
+ 				iconX = 0;
+ 
+ 			if (t->pager_view_height > t->mini_icon.height)
+ 				iconY = (t->pager_view_height - t->mini_icon.height) / 2;
+ 			else if (t->pager_view_height < t->mini_icon.height)
+ 				iconY = -((t->mini_icon.height - t->pager_view_height) / 2);
+ 			else
+ 				iconY = 0;
+ 
+ 			Globalgcm				= GCForeground | GCBackground | GCClipMask | GCClipXOrigin | GCClipYOrigin;
+ 			Globalgcv.clip_mask		= t->mini_icon.mask;
+ 			Globalgcv.clip_x_origin	= iconX;
+ 			Globalgcv.clip_y_origin	= iconY;
+ 
+ 			if (t == FocusWin)
+ 			{
+ 				Globalgcv.foreground	= focus_fore_pix;
+ 				Globalgcv.background	= focus_pix;
+ 			}
+ 			else
+ 			{
+ 				Globalgcv.foreground	= t->text;
+ 				Globalgcv.background	= t->back;
+ 			}
+ 
+ 			XChangeGC (dpy, MiniIconGC, Globalgcm, &Globalgcv);
+ 
+ 			XClearWindow (dpy, t->PagerView);
+ 			XCopyArea (dpy, t->mini_icon.picture, t->PagerView, MiniIconGC,
+ 							0, 0, t->mini_icon.width, t->mini_icon.height, iconX, iconY);
+ 		}
+ 	}
+ }
+ 
+ void PictureIconWindow (PagerWindow *t)
+ {
+ 	XGCValues		Globalgcv;
+ 	unsigned long	Globalgcm;
+ 	int				iconX;
+ 	int				iconY;
+ 
+ 	if (MiniIcons)
+ 	{
+ 		if (t->mini_icon.picture && (t->IconView != None))
+ 		{
+ 			if (t->icon_view_width > t->mini_icon.width)
+ 				iconX = (t->icon_view_width - t->mini_icon.width) / 2;
+ 			else if (t->icon_view_width < t->mini_icon.width)
+ 				iconX = -((t->mini_icon.width - t->icon_view_width) / 2);
+ 			else
+ 				iconX = 0;
+ 
+ 			if (t->icon_view_height > t->mini_icon.height)
+ 				iconY = (t->icon_view_height - t->mini_icon.height) / 2;
+ 			else if (t->icon_view_height < t->mini_icon.height)
+ 				iconY = -((t->mini_icon.height - t->icon_view_height) / 2);
+ 			else
+ 				iconY = 0;
+ 
+ 			Globalgcm				= GCForeground | GCBackground | GCClipMask | GCClipXOrigin | GCClipYOrigin;
+ 			Globalgcv.clip_mask		= t->mini_icon.mask;
+ 			Globalgcv.clip_x_origin	= iconX;
+ 			Globalgcv.clip_y_origin	= iconY;
+ 
+ 			if (t == FocusWin)
+ 			{
+ 				Globalgcv.foreground	= focus_fore_pix;
+ 				Globalgcv.background	= focus_pix;
+ 			}
+ 			else
+ 			{
+ 				Globalgcv.foreground	= t->text;
+ 				Globalgcv.background	= t->back;
+ 			}
+ 
+ 			XChangeGC (dpy, MiniIconGC, Globalgcm, &Globalgcv);
+ 
+ 			XClearWindow (dpy, t->IconView);
+ 			XCopyArea (dpy, t->mini_icon.picture, t->IconView, MiniIconGC,
+ 							0, 0, t->mini_icon.width, t->mini_icon.height, iconX, iconY);
+ 		}
+ 	}
  }
  
  void IconMoveWindow(XEvent *Event,PagerWindow *t)
--
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 [email-masked].
To report problems, send mail to [email-masked].