Subject: FVWM: Patch: an implementation of 'Goto' built-in function

From: まつしたまこと <[email-masked]>
Date: Fri, 03 May 1996 05:34:13 +0900

chuck_hines> Perhaps something like the following would work better:
chuck_hines>   Goto [Page x y | RelativePage dx dy] [Desk z | RelativeDesk dz]
chuck_hines> Verbose, but no suprises.

I support this idea. To proof this fact, I wrote a code.

***

Here is an implementation of 'Desk' for 2.0.42, to discuss what's the
cool specification of 'Goto'.

Following is the BUGS list of this patch:

	* It USES the features of old functions.
	* It does NOT remove 'GotoPage' and/or 'Desk'.
	* It does NOT update manual.
	* It's NOT THE SAME SYNTAX of Chuck's idea, i.e.,
		Goto [Page x y |
		      RelativePage dx dy |
		      Desk z |
		      RelativeDesk dz]*
	* It's DIRTY. I've never write such a code :-p, and
	* Author is very SLEEPY (See Data: field of this mail).

I hope that anybody writes more cool implementation :-) It should be
avoided that this code is included to the next release of fvwm :-)

- -
Makoto `MAR_kun' MATSUSHITA

--- fvwm/functions.c.dist	Fri Mar 29 00:24:23 1996
+++ fvwm/functions.c	Fri May  3 04:02:17 1996
@@ -56,6 +56,7 @@
   {"Focus",        focus_func,       F_FOCUS,               FUNC_NEEDS_WINDOW},
   {"Function",     ComplexFunction,  F_FUNCTION,            FUNC_NO_WINDOW},
   {"GotoPage",     goto_page_func,   F_GOTO_PAGE,           FUNC_NO_WINDOW},
+  {"Goto",         goto_func,        F_GOTO,                FUNC_NO_WINDOW},
   {"HilightColor", SetHiColor,       F_HICOLOR,             FUNC_NO_WINDOW},
   {"Iconify",      iconify_function, F_ICONIFY,             FUNC_NEEDS_WINDOW},
   {"IconFont",     LoadIconFont,     F_ICONFONT,            FUNC_NO_WINDOW},
--- fvwm/misc.h.dist	Fri Apr  5 08:47:30 1996
+++ fvwm/misc.h	Fri May  3 04:03:01 1996
@@ -376,6 +376,8 @@
 int GetOneArgument(char *action, long *val1, int *val1_unit);
 void goto_page_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
 		    unsigned long context, char *action, int *Module);
+void goto_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+		    unsigned long context, char *action, int *Module);
 
 void wait_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
 	       unsigned long context,char *action, int *Module);
--- fvwm/parse.h.dist	Fri Mar 29 00:24:48 1996
+++ fvwm/parse.h	Fri May  3 04:02:37 1996
@@ -73,6 +73,7 @@
 #define F_COLORMAP_FOCUS        55
 #define F_TITLESTYLE            56
 #define F_EXEC_SETUP            57
+#define F_GOTO                  58
 /* Functions which require a target window */
 #define F_RESIZE		100
 #define F_RAISE			101
--- fvwm/virtual.c.dist	Wed Apr  3 03:24:38 1996
+++ fvwm/virtual.c	Fri May  3 04:56:53 1996
@@ -593,6 +593,107 @@
   MoveViewport(x,y,True);
 }
 
+void goto_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+		    unsigned long context,char *action, int *Module)
+{
+  int val1, val2, val1_unit, val2_unit, n, x, y, delta_x, delta_y;
+  char *directive;	/* Should be freed when used */
+
+  action = GetNextToken(action, &directive);
+  while((directive != NULL) && (strcmp(directive, "") != 0)) {
+    if(mystrcasecmp(directive, "Page") == 0) {
+      n = GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit);
+      if (n != 2) {
+	fvwm_msg(ERR, "goto_func", "Goto/Page requires two arguments");
+	free(directive);
+	return;
+      }
+      if((val1_unit != Scr.MyDisplayWidth)||
+	 (val2_unit != Scr.MyDisplayHeight)) {
+	 fvwm_msg(ERR, "goto_func", "Goto/Page arguments should be unitless");
+      }
+      /* calculate where to go */
+      x = val1 * Scr.MyDisplayWidth;
+      y = val2 * Scr.MyDisplayHeight;
+      /* Let's go */
+      MoveViewport(x, y, True);
+      free(directive);
+      /* XXX: too dirty to skip arguments */
+      action = GetNextToken(action, &directive); free(directive);
+      action = GetNextToken(action, &directive); free(directive);
+    } else if (mystrcasecmp(directive, "RelativePage") == 0) {
+      n = GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit);
+      if (n != 2) {
+	fvwm_msg(ERR, "goto_func", "Goto/RelativePage requires two arguments");
+	free(directive);
+	return;
+      }
+      if((val1_unit != Scr.MyDisplayWidth)||
+	 (val2_unit != Scr.MyDisplayHeight)) {
+	 fvwm_msg(ERR, "goto_func", "Goto/RelativePage arguments should be unitless");
+      }
+      /* calculate where to go */
+      delta_x = val1 * Scr.MyDisplayWidth;
+      delta_y = val2 * Scr.MyDisplayHeight;
+      /* boundary checking */
+      if(Scr.Vx + delta_x < 0)
+	delta_x = -Scr.Vx;
+      if(Scr.Vy + delta_y < 0)
+	delta_y = -Scr.Vy;
+      if(Scr.Vx + delta_x > Scr.VxMax)
+	delta_x = Scr.VxMax - Scr.Vx;
+      if(Scr.Vy + delta_y > Scr.VyMax)
+	delta_y = Scr.VyMax - Scr.Vy;
+#if 0
+      /* boundary checking continued: Should be needed ? */
+      x = (Scr.Vx + delta_x) / Scr.MyDisplayWidth * Scr.MyDisplayWidth;
+      y = (Scr.Vy + delta_y) / Scr.MyDisplayHeight * Scr.MyDisplayHeight;
+#else
+      x = Scr.Vx + delta_x;
+      y = Scr.Vy + delta_y;
+#endif
+      /* Let's go */
+      MoveViewport(x, y, True);
+      free(directive);
+      /* XXX: too dirty to skip arguments */
+      action = GetNextToken(action, &directive); free(directive);
+      action = GetNextToken(action, &directive); free(directive);
+    } else if (mystrcasecmp(directive, "Desk") == 0) {
+      n = GetOneArgument(action, &val1, &val1_unit);
+      if (n != 1) {
+	fvwm_msg(ERR, "goto_func", "Goto/Desk requires one arguments");
+	free(directive);
+	return;
+      }
+      /* XXX: call old function */
+      changeDesks(0, val1);
+      free(directive);
+      /* XXX: too dirty to skip argument */
+      action = GetNextToken(action, &directive); free(directive);
+    } else if (mystrcasecmp(directive, "RelativeDesk") == 0) {
+      n = GetOneArgument(action, &val1, &val1_unit);
+      if (n != 1) {
+	fvwm_msg(ERR, "goto_func", "Goto/RelativeDesk requires one arguments");
+	free(directive);
+	return;
+      }
+      /* XXX: call old function */
+      changeDesks(val1, 0);
+      free(directive);
+      /* XXX: too dirty to skip argument */
+      action = GetNextToken(action, &directive); free(directive);
+    } else {
+      fvwm_msg(ERR, "goto_func", "No such directive: %s", directive);
+      free(directive);
+      return;
+    }
+
+    /* Prepare for the next directive */
+    action = GetNextToken(action, &directive);
+  }
+  if(directive) free(directive);
+}
+
 void goto_page_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
 		    unsigned long context,char *action, int *Module)
 {
--
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].