Subject: FVWM: FvwmButtons "Variable Relief" patch

From: Gregory Lauckhart <[email-masked]>
Date: Tue, 20 Feb 1996 21:46:13 -0800 (PST)

Here's a patch that allows the user to specify the depth of the reliefs 
in FvwmButtons on a per-button basis.  The .fvwm2rc line

	*FvwmButtons(w x h) ...

may now be written

	*FvwmButtons(w x h , r) ...

where r specifies the new relief, from -5 (sunken 5 pixels) to 5 (raised 
five pixels).  The default is 2.

Apply the patch in the "modules" subdirectory of a clean 2.0.41 
distribution.  I even updated the man page!  Let me know how it works.

Greg

---8<----cut----8<------------------------------------------------------

diff -u fb-old/FvwmButtons.c FvwmButtons/FvwmButtons.c
--- fb-old/FvwmButtons.c	Wed Feb 14 13:02:05 1996
+++ FvwmButtons/FvwmButtons.c	Tue Feb 20 20:49:01 1996
@@ -106,7 +106,6 @@
   if (s != NULL)
     temp = s + 1;
 
-
   MyName = safemalloc(strlen(temp)+1);
   strcpy(MyName, temp);
 
@@ -119,6 +118,7 @@
       Buttons[i].icon_h = 0;
       Buttons[i].BWidth = 1;
       Buttons[i].BHeight = 1;
+      Buttons[i].BRelief = 2;
       Buttons[i].IconWin = None;
       Buttons[i].icon_maskPixmap = None;	/* pixmap for the icon mask */
       Buttons[i].iconPixmap = None;
@@ -167,12 +167,13 @@
 		 M_END_CONFIG_INFO| M_WINDOW_NAME);
   
   ParseOptions();
+
   if(num_buttons == 0)
     {
       fprintf(stderr,"%s: No Buttons defined. Quitting\n", MyName);
       exit(0);
     }
-
+  
   /* load the font, or none */
   if (mystrncasecmp(font_string,"none",4)==0)
     {
@@ -497,7 +498,7 @@
  ***********************************************************************/
 void RedrawWindow(int newbutton)
 {
-  int i,j,w,yoff,button,len,yoff2,BW,BH;
+  int i,j,w,yoff,button,len,yoff2,BW,BH,BR;
   XEvent dummy;
   int val1,val2;
 
@@ -509,9 +510,10 @@
   for(i=0;i<num_rows;i++)
     for(j=0;j<num_columns; j++)
       {
-	button = i*num_columns + j;
-	BW = ButtonWidth*Buttons[button].BWidth;
-	BH = ButtonHeight*Buttons[button].BHeight;
+        button = i*num_columns + j;
+        BW = ButtonWidth*Buttons[button].BWidth;
+        BH = ButtonHeight*Buttons[button].BHeight;
+        BR = Buttons[button].BRelief;
 	if((newbutton == -1)||(newbutton == button))
 	  {
 	    if((Buttons[button].swallow == 3)&&
@@ -554,27 +556,26 @@
 		  {
 		    sscanf(&Buttons[button].action[4],"%d %d",&val1,&val2);
 		    if((val1 == 0)&&(val2 == new_desk))
-		      {
-			RelieveWindow(main_win,j*ButtonWidth, i*ButtonHeight,
-				      BW, BH, ShadowGC,ReliefGC);
+                      {
+                        RelieveWindow(main_win,j*ButtonWidth, i*ButtonHeight,
+                        BW, BH, -BR,
+                        ReliefGC, ShadowGC);
 		      }
 		    else
 		      RelieveWindow(main_win,j*ButtonWidth, i*ButtonHeight,
-				    BW, BH,
-				    (CurrentButton==button)?ShadowGC:ReliefGC,
-				    (CurrentButton==button)?ReliefGC:ShadowGC);
+				    BW, BH, (BR<0)?BR:((CurrentButton==button)?-BR:BR),
+				    ReliefGC, ShadowGC);
 		  }
 		else if(Buttons[button].up == 1)
 		  {
 		    RelieveWindow(main_win,j*ButtonWidth, i*ButtonHeight,
-				  BW, BH,
-				  (CurrentButton == button)?ShadowGC:ReliefGC,
-				  (CurrentButton == button)?ReliefGC:ShadowGC);
+                  BW, BH, (BR<0)?BR:((CurrentButton==button)?-BR:BR),
+				  ReliefGC,ShadowGC);
 		  }
 		else
 		  {
 		    RelieveWindow(main_win,j*ButtonWidth, i*ButtonHeight,
-				  BW, BH, ShadowGC,ReliefGC);
+				  BW, BH, -BR, ReliefGC, ShadowGC);
 		  }
 	      }
 	  }
@@ -585,46 +586,50 @@
  *
  *  Draws the relief pattern around a window
  *
+ *  1/20/95 - Added support for user specified reliefs.  The bulk of the
+ *            modifications were in this routine.  [email-masked]
+ *
  ****************************************************************************/
-FVWM_INLINE void RelieveWindow(Window win,int x,int y,int w,int h,
+FVWM_INLINE void RelieveWindow(Window win,int x,int y,int w,int h, int r,
 		   GC rgc,GC sgc)
 {
   XSegment seg[4];
-  int i;
+  int i, j;
 
-  i=0;
-  seg[i].x1 = x;        seg[i].y1   = y;
-  seg[i].x2 = w+x-1;    seg[i++].y2 = y;
-
-  seg[i].x1 = x;        seg[i].y1   = y;
-  seg[i].x2 = x;        seg[i++].y2 = h+y-1;
-
-  seg[i].x1 = x+1;      seg[i].y1   = y+1;
-  seg[i].x2 = x+w-2;    seg[i++].y2 = y+1;
-
-  seg[i].x1 = x+1;      seg[i].y1   = y+1;
-  seg[i].x2 = x+1;      seg[i++].y2 = y+h-2;
-  XDrawSegments(dpy, win, rgc, seg, i);
-
-  i=0;
-  seg[i].x1 = x;        seg[i].y1   = y+h-1;
-  seg[i].x2 = w+x-1;    seg[i++].y2 = y+h-1;
-
-  seg[i].x1 = x+w-1;    seg[i].y1   = y;
-  seg[i].x2 = x+w-1;    seg[i++].y2 = y+h-1;
-  if(d_depth<2)
-    XDrawSegments(dpy, win, ShadowGC, seg, i);
-  else
-    XDrawSegments(dpy, win, sgc, seg, i);
-
-  i=0;
-  seg[i].x1 = x+1;      seg[i].y1   = y+h-2;
-  seg[i].x2 = x+w-2;    seg[i++].y2 = y+h-2;
-
-  seg[i].x1 = x+w-2;    seg[i].y1   = y+1;
-  seg[i].x2 = x+w-2;    seg[i++].y2 = y+h-2;
-
-  XDrawSegments(dpy, win, sgc, seg, i);
+  GC gcAmono, gcA, gcBmono, gcB;
+  if (r < 0) {
+    gcAmono = ShadowGC; gcA = sgc;
+    gcBmono = rgc; gcB = rgc;
+    r = -r;
+  } else {
+    gcAmono = rgc; gcA = rgc;
+    gcBmono = ShadowGC; gcB = sgc;
+  }
+  
+  for (j = 0; j < r; j++) {
+    i=0;
+    seg[i].x1 = x+j;        seg[i].y1   = y+j;
+    seg[i].x2 = w+x-1-j;    seg[i++].y2 = y+j;
+
+    seg[i].x1 = x+j;        seg[i].y1   = y+j;
+    seg[i].x2 = x+j;        seg[i++].y2 = h+y-1-j;
+
+    if(d_depth<2 && !j)
+      XDrawSegments(dpy, win, gcAmono, seg, i);
+    else
+      XDrawSegments(dpy, win, gcA, seg, i);
+        
+    i=0;
+    seg[i].x1 = x+j;        seg[i].y1   = y+h-1-j;
+    seg[i].x2 = w+x-1-j;    seg[i++].y2 = y+h-1-j;
+
+    seg[i].x1 = x+w-1-j;    seg[i].y1   = y+j;
+    seg[i].x2 = x+w-1-j;    seg[i++].y2 = y+h-1-j;
+    if(d_depth<2 && !j)
+        XDrawSegments(dpy, win, gcBmono, seg, i);
+    else
+        XDrawSegments(dpy, win, gcB, seg, i);
+  }
 }
 
 /************************************************************************
@@ -732,7 +737,6 @@
  /* That's why I used this full WHILE-Codelines                  */                            
  /* tb := TARGET_BOTTON sb := SOURCE_BOTTON for shifting         */
  /* [email-masked]                                 */
-   
                          tb=first_avail_button;
                          sb=tb-1;
                          while(sb>=(i+j+k*num_columns))
@@ -759,6 +763,7 @@
                          Buttons[tb].icon_file         = Buttons[sb].icon_file;
                          Buttons[tb].BWidth            = Buttons[sb].BWidth;
                          Buttons[tb].BHeight           = Buttons[sb].BHeight;
+                         Buttons[tb].BRelief           = Buttons[sb].BRelief;
                          Buttons[tb].icon_w            = Buttons[sb].icon_w;
                          Buttons[tb].icon_h            = Buttons[sb].icon_h;
                          Buttons[tb].iconPixmap        = Buttons[sb].iconPixmap;
@@ -788,10 +793,9 @@
                                ) tb--; /* ignore Targed_Botton if this is a freed one */
                            sb--;
                          }  
- 
  /* No follows the Original Code which frees the current Botton */
- 		    
-/*			Buttons[first_avail_button].action = 
+/* 		    
+			Buttons[first_avail_button].action = 
 			  Buttons[i+j+k*num_columns].action;
 			Buttons[first_avail_button].title = 
 			  Buttons[i+j+k*num_columns].title;
@@ -801,6 +805,8 @@
 			  Buttons[i+j+k*num_columns].BWidth;
 			Buttons[first_avail_button].BHeight = 
 			  Buttons[i+j+k*num_columns].BHeight;
+			Buttons[filst_avail_button].BRelief =
+			  Buttons[i+j+k*num_columns].BRelief;
 			Buttons[first_avail_button].icon_w = 
 			  Buttons[i+j+k*num_columns].icon_w;
 			Buttons[first_avail_button].icon_h = 
@@ -835,7 +841,7 @@
 			Buttons[i+j+k*num_columns].up = 1;
 			Buttons[i+j+k*num_columns].BWidth = 0;
 			Buttons[i+j+k*num_columns].BHeight = 0;
-
+			Buttons[i+j+k*num_columns].BRelief = 2;
 		      }
 		  }
 	      }
@@ -1187,24 +1193,31 @@
     tline++;
   if( *tline == '(')
     {
-      int thisw= 0,thish = 0;
+      int thisw= 0,thish = 0, thisr = -6;
 
       tline++;
       sscanf((tline),"%dx%d",&thisw,&thish);
       while((*tline != ')')&&(*tline != '\n')&&(*tline != 0))
-	tline++;   
+        {
+          tline++;
+          /* Get the relief, if any */
+          if(*tline == ',')
+            sscanf ((tline),",%d",&thisr);
+        }
       tline++;
       if(thisw > 0)
-	Buttons[num_buttons].BWidth = thisw;
+        Buttons[num_buttons].BWidth = thisw;
       if(thish > 0)
-	Buttons[num_buttons].BHeight = thish;
+        Buttons[num_buttons].BHeight = thish;
+      if(thisr > -6 && thisr < 6) /* Max. height/depth is 5 */
+        Buttons[num_buttons].BRelief = thisr;
     }
 
   /* skip spaces */
   while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
     tline++;
 
-  /* read next word. Its the button label. Users can specify "" 
+  /* read next word. Its the button label. Users can specify ""
    * NoIcon, or whatever to skip the label */
   /* read to next space */
   start = tline;
diff -u fb-old/FvwmButtons.h FvwmButtons/FvwmButtons.h
--- fb-old/FvwmButtons.h	Fri Mar 10 12:04:32 1995
+++ FvwmButtons/FvwmButtons.h	Tue Feb 20 18:28:07 1996
@@ -16,7 +16,7 @@
 extern char   *safemalloc(int length);
 extern void   change_window_name(char *str);
 extern int    My_XNextEvent(Display *dpy, XEvent *event);
-extern FVWM_INLINE void RelieveWindow(Window win,int x,int y,int w,int h,GC rGC,GC sGC);
+extern FVWM_INLINE void RelieveWindow(Window win,int x,int y,int w,int h, int r,GC rGC,GC sGC);
 extern void   DeadPipe(int nonsense);
 extern void   LoadIconFile(int button);
 extern void   CreateIconWindow(int button);
@@ -48,6 +48,7 @@
   char *icon_file;
   int BWidth;                   /* Width of this button in "buttons" */
   int BHeight;
+  int BRelief;
   int icon_w;
   int icon_h;
   Pixmap iconPixmap;		/* pixmap for the icon */
diff -u fb-old/FvwmButtons.man FvwmButtons/FvwmButtons.man
--- fb-old/FvwmButtons.man	Sun Feb 18 19:07:06 1996
+++ FvwmButtons/FvwmButtons.man	Tue Feb 20 20:59:01 1996
@@ -77,7 +77,7 @@
 .IP "*FvwmButtonsBack \fIcolor\fP"
 Specifies the color for the buttons.
 
-.IP "*FvwmButtons\fI[(w x h)]\fP \fIlabel icon command\fP"
+.IP "*FvwmButtons\fI[(w x h [, r])]\fP \fIlabel icon command\fP"
 Specifies a window manager built-in command, as described in the fvwm
 man page, which should be executed when a button is pressed.  The
 label field is the text which will be written on the button.  The icon
@@ -86,8 +86,10 @@
 the path specified in the fvwm IconPath or PixmapPath configuration
 items to find the icon file.  If the optional \fI(w x h)\fP is
 specified, then this button will be \fIw\fP times the normal button
-width and \fIh\fP times the normal button height.  If label is "-"
-then the button label will not be displayed.
+width and \fIh\fP times the normal button height.  If the full 
+\fI(w x h , r)\fP form is used, the \fIr\fP parameter specifies the
+"height" of the relief.  Valid values for \fIr\fP are from -5 to 5.
+If label is "-" then the button label will not be displayed.
 
 If \fIcommand\fP is an fvwm Exec command, then the button will remain
 pushed in until a window whose name or class matches the qouted

--
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].