Subject: FVWM: FvwmPager patch (again...)

From: Thimo Jansen <[email-masked]>
Date: Sun, 9 Feb 1997 02:22:17 +0100

Hi again,

A few minutes ago, I posted a message concerning the FvwmPager patch and
not everything did go very well. My own mailreader (Mutt 0.61) didn't
even understand it's own PGP-signature and segfaults when I tried to view
the message. I don't know what all the other mailreaders thought about
it, but I'll try it again, this time without the PGP-sig. Hope you
forgive me for this abuse of bandwidth! :)

*** Original message follows ***

Hi everyone,

A little while ago, Rob Whapham ([email-masked]) posted a patch to
let the FvwmPager of fvwm95 do mini-icons and the possibility to define
WindowColors used in the pager.

Now I've patched my FvwmPager from the fvwm-2.0.45 tree with this patch
(partly by hand) and made a diff that works with fvwm2. For all of you
who didn't want, or could, patch with the fvwm95 version of the patch,
here's the fvwm2 version, as an attachment to this mail.

To patch FvwmPager, go inside the FvwmPager dir
(fvwm-2.0.45/modules/FvwmPager) and type "patch -p0 <
the_location_and_name_of_the_patch_goes_here". Good luck! :)

And this is to Chuck. Can you take a look at the code and consider adding
this to fvwm2? I think this is a great addition, especially the
WindowColors part. Now with the new-and-enhanced border/titlestyle
options, I've got all my windows with a Grey75 background. FvwmPager
became a lot less handy, untill I run into this patch. So (on my knees):
Please, please add it to fvwm2... ;)

That's it and that's that. Mail you later.

Greetings,

Thimo Jansen

-- 
TeeJay signing off:  Avoid the Gates of Hell.  Use Linux
*** Finger for PGP PUBLIC KEY ***
*** FvwmPager.orig.c	Thu Feb  6 12:13:35 1997
--- FvwmPager.c	Thu Feb  6 11:16:43 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 ****
    (*prev)->desk = body[7];
    (*prev)->next = NULL;
    (*prev)->flags = body[8];
    (*prev)->icon_name = NULL;
    (*prev)->title_height = body[9];
    (*prev)->border_width = body[10];
    (*prev)->icon_w = body[19];
    (*prev)->icon_pixmap_w = body[20];
!   (*prev)->text = body[22];
!   (*prev)->back = body[23];
    AddNewWindow(*prev);
  }
  
--- 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 ****
        t->flags = body[8];
        t->icon_w = body[19];
        t->icon_pixmap_w = body[20];
!       t->text = body[22];
!       t->back = body[23];
        if(t->flags & ICONIFIED)
  	{
  	  t->x = t->icon_x;
--- 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 ****
    extern Pixel focus_pix, focus_fore_pix;
    target_w = body[0];
    
!   focus_pix = body[4];
!   focus_fore_pix = body[3];
    t = Start;
    while((t!= NULL)&&(t->w != target_w))
      {
--- 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,684 ****
--- 723,752 ----
  }

+ 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);
+ 	}
+ }
+ 
+ 

  /***********************************************************************
***************
*** 788,793 ****
--- 856,862 ----
  {
    char *tend,*tstart;
    char *tline= NULL,*tmp;
+   char *colors;
    int Clength,n,desk;
  
    Scr.FvwmRoot = NULL;
***************
*** 952,959 ****
  	      (mystrncasecmp(tline,CatString3("*",MyName,"SmallFont"),
  			     Clength+10)==0))
  	{
! 	  CopyString(&smallFont,&tline[Clength+10]);
  	}	
        else if((strlen(&tline[0])>1)&&
  	      (mystrncasecmp(tline,CatString3("*",MyName,"StartIconic"),
  			     Clength+12)==0))
--- 1021,1039 ----
  	      (mystrncasecmp(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)&&
  	      (mystrncasecmp(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;
  }

*** FvwmPager.orig.h	Thu Feb  6 12:13:44 1997
--- FvwmPager.h	Thu Feb  6 11:07:05 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.man	Thu Feb  6 12:13:50 1997
--- FvwmPager.man	Thu Feb  6 11:52:28 1997
***************
*** 146,151 ****
--- 146,156 ----
  The active page and desk label will be highlighted by using this
  background pattern instead of the normal background.
  
+ .IP "*FvwmPagerWindowColors \fIfore back hiFore hiBack\fP"
+ Change the normal/highlight colors of the windows. \fIfore\fP and
+ \fIhiFore\fP specify the colors as used for the font inside the windows.
+ \fIback\fP and \fIhiBack\fP are used to fill the windows with.
+ 
  .IP "*FvwmPagerLabel \fIdesk label\fP"
  Assigns the text \fIlabel\fP to desk \fIdesk\fP in the pager window.
  Useful for assigning symbolic names to desktops, ie
***************
*** 172,180 ****
--- 177,191 ----
  used to calculate the pager's size. Things in the pager window
  are shown at 1/\fInumber\fP of the actual size.
  
+ .IP "*FvwmPagerMiniIcons"
+ Allow the pager to display a window's title/mini icon in the pager.
+ 
  
  .SH AUTHOR
  Robert Nation 
  .br
  DeskColor patch contributed by Alan Wild
+ .br
+ MiniIcons and WindowColors patch contributed by Rob Whapham
+ 
  
*** x_pager.orig.c	Thu Feb  6 12:10:10 1997
--- x_pager.c	Thu Feb  6 11:18:05 1997
***************
*** 29,41 ****
--- 29,44 ----
  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;
***************
*** 103,108 ****
--- 106,112 ----
    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;
***************
*** 142,147 ****
--- 146,159 ----
    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)
      {
***************
*** 361,366 ****
--- 373,379 ----
  
    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)
***************
*** 559,568 ****
--- 572,583 ----
        if(t->PagerView == Event->xany.window)
  	{
  	  LabelWindow(t);
+ 	  PictureWindow(t);
  	}
        else if(t->IconView == Event->xany.window)
  	{
  	  LabelIconWindow(t);
+ 	  PictureIconWindow(t);
  	}
        
        t = t->next;
***************
*** 724,729 ****
--- 739,747 ----
        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
***************
*** 930,935 ****
--- 948,956 ----
    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;
***************
*** 959,964 ****
--- 980,988 ----
    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,
***************
*** 1010,1015 ****
--- 1034,1043 ----
      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);
***************
*** 1030,1035 ****
--- 1058,1067 ----
      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
***************
*** 1055,1060 ****
--- 1087,1096 ----
      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))
***************
*** 1075,1080 ****
--- 1111,1120 ----
      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
***************
*** 1159,1164 ****
--- 1199,1206 ----
    XClearWindow(dpy,t->IconView);
    LabelWindow(t);
    LabelIconWindow(t);
+   PictureWindow(t);
+   PictureIconWindow(t);
  }
  
  void Scroll(int Desk, int x, int y)
***************
*** 1539,1544 ****
--- 1581,1587 ----
        Globalgcv.foreground = focus_fore_pix;
        Globalgcv.background = focus_pix;
        Globalgcm = GCForeground|GCBackground;
+       XChangeGC(dpy,StdGC,Globalgcm,&Globalgcv); 
      }
    else
      {
***************
*** 1552,1557 ****
--- 1595,1700 ----
    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)