diff -u -r -d wmx-6.orig/Buttons.C wmx-6/Buttons.C
--- wmx-6.orig/Buttons.C	Wed Apr  4 10:58:31 2001
+++ wmx-6/Buttons.C	Tue Feb 26 15:11:37 2002
@@ -18,7 +18,7 @@
     Client *c = windowToClient(e->window);
 
 #if CONFIG_GNOME_BUTTON_COMPLIANCE == False
-    if (e->button == Button3 && m_channelChangeTime == 0) {
+    if (e->button == Button3 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) {
 	if (dConfig.rightCirculate())
 	    circulate(e->window == e->root);
 	else if (dConfig.rightLower())
@@ -41,11 +41,11 @@
  
     if (e->button == Button4 && CONFIG_CHANNEL_SURF) {
         // wheel "up" - increase channel
-        flipChannel(False, False, True, c);
+        flipChannel(screen(), False, False, True, c);
         return ;
     } else if (e->button == Button5 && CONFIG_CHANNEL_SURF) {
         // wheel "down" - decrease channel
-        flipChannel(False, True, True, c);
+        flipChannel(screen(), False, True, True, c);
         return ;
     }
     
@@ -53,20 +53,20 @@
 
 #if CONFIG_GNOME_BUTTON_COMPLIANCE != False
         if ((e->button == Button1 || e->button == Button3)
-            && m_channelChangeTime == 0) {
+            && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) {
 
 	    XUngrabPointer(m_display, CurrentTime);
 	    XSendEvent(m_display, gnome_win, False, SubstructureNotifyMask, ev);
 	    return;
 	} 
         
-	if (e->button == Button2 && m_channelChangeTime == 0) {
+	if (e->button == Button2 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) {
 	    ClientMenu menu(this, (XEvent *)e);
 	    return;
 	}
 #endif
 
-	if (e->button == Button1 && m_channelChangeTime == 0) {
+	if (e->button == Button1 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) {
 	    ClientMenu menu(this, (XEvent *)e);
 
 	} else if (e->x > DisplayWidth(display(), screen()) -
@@ -77,16 +77,16 @@
 #if CONFIG_USE_CHANNEL_MENU	
                 ChannelMenu(this, (XEvent *)e);
 #else
-                if (m_channelChangeTime == 0) flipChannel(True, False, False, 0);
-                else flipChannel(False, False, False, 0);
+                if (m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) flipChannel(screen(), True, False, False, 0);
+                else flipChannel(screen(), False, False, False, 0);
                 
-            } else if (e->button == Button1 && m_channelChangeTime != 0) {
+            } else if (e->button == Button1 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] != 0) {
                 
-                flipChannel(False, True, False, 0);
+                flipChannel(screen(), False, True, False, 0);
 #endif
 	    }
 
-	} else if (e->button == Button2 && m_channelChangeTime == 0) {
+	} else if (e->button == Button2 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) {
 	    dConfig.scan();
 	    CommandMenu menu(this, (XEvent *)e);
 	}
@@ -97,13 +97,13 @@
 #if CONFIG_USE_CHANNEL_MENU	
 	    ChannelMenu menu(this, (XEvent *)e);
 #else
-            if (m_channelChangeTime == 0) flipChannel(True, False, False, 0);
-            else flipChannel(False, False, False, c);
+            if (m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] == 0) flipChannel(screen(), True, False, False, 0);
+            else flipChannel(screen(), False, False, False, c);
 #endif
 	    return;
-	} else if (e->button == Button1 && m_channelChangeTime != 0) {
+	} else if (e->button == Button1 && m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] != 0) {
 	    // allow left-button to push down a channel --cc 19991001
-	    flipChannel(False, True, False, c);
+	    flipChannel(screen(), False, True, False, c);
 	    return;
  	}
 
@@ -254,11 +254,11 @@
 		switch (key) {
 
 		case CONFIG_FLIP_DOWN_KEY:
-		    flipChannel(False, True, False, 0);
+		    flipChannel(screen(), False, True, False, 0);
 		    break;
 
 		case CONFIG_FLIP_UP_KEY:
-		    flipChannel(False, False, False, 0);
+		    flipChannel(screen(), False, False, False, 0);
 		    break;
 	
 		case CONFIG_CIRCULATE_KEY:
@@ -406,14 +406,14 @@
 	if (count > 0) {
 	    x = grouping.item(group)->item(count-1);
 	    // it seems like there should be a better way of doing this...
-	    while (m_currentChannel != x->channel()) {
+	    while (channel() != x->channel()) {
 		
 		raise = 2;
 
-		if (m_currentChannel < x->channel()) {
-		    flipChannel(False, False, True, 0);
+		if (channel() < x->channel()) {
+		    flipChannel(screen(), False, False, True, 0);
 		} else {
-		    flipChannel(False, True, True, 0);
+		    flipChannel(screen(), False, True, True, 0);
 		}
 		XSync(display(), False);
 	    }
@@ -630,7 +630,7 @@
 		x = nx;
 		y = ny;
 
-		geometry.update(x, y);
+		geometry.update(screen(), x, y);
 		m_border->moveTo(x + xi, y + yi);
 		doSomething = True;
 	    }
@@ -638,7 +638,7 @@
 	}
     }
 
-    geometry.remove();
+    geometry.remove(screen());
 
     if (doSomething) {
 	m_x = x + xi;
@@ -767,7 +767,7 @@
 		m_border->configure(m_x, m_y, w, h, CWWidth | CWHeight, 0);
 		if (CONFIG_RESIZE_UPDATE)
 		    XResizeWindow(display(), m_window, w, h);
-		geometry.update(dw, dh);
+		geometry.update(screen(), dw, dh);
 		doSomething = True;
 
 	    } else if (vertical) {
@@ -777,7 +777,7 @@
 		m_border->configure(m_x, m_y, w, h, CWHeight, 0);
 		if (CONFIG_RESIZE_UPDATE)
 		    XResizeWindow(display(), m_window, w, h);
-		geometry.update(dw, dh);
+		geometry.update(screen(), dw, dh);
 		doSomething = True;
 
 	    } else {
@@ -787,7 +787,7 @@
 		m_border->configure(m_x, m_y, w, h, CWWidth, 0);
 		if (CONFIG_RESIZE_UPDATE)
 		    XResizeWindow(display(), m_window, w, h);
-		geometry.update(dw, dh);
+		geometry.update(screen(), dw, dh);
 		doSomething = True;
 	    }
 
@@ -797,7 +797,7 @@
 
     if (doSomething) {
 
-	geometry.remove();
+	geometry.remove(screen());
 
 	if (vertical && horizontal) {
 	    m_w = x - m_x;
diff -u -r -d wmx-6.orig/Channel.C wmx-6/Channel.C
--- wmx-6.orig/Channel.C	Wed May 24 17:46:14 2000
+++ wmx-6/Channel.C	Tue Feb 26 15:18:55 2002
@@ -17,7 +17,7 @@
 };
 
 
-void WindowManager::flipChannel(Boolean statusOnly, Boolean flipDown,
+void WindowManager::flipChannel(int scr, Boolean statusOnly, Boolean flipDown,
 				Boolean quickFlip, Client *push)
 {
     int x, y, i, sc;
@@ -52,14 +52,14 @@
 
     int nextChannel;
 
-    if (statusOnly) nextChannel = m_currentChannel;
+    if (statusOnly) nextChannel = channel();
     else {
 	if (!flipDown) {
-	    nextChannel = m_currentChannel + 1;
-	    if (nextChannel > m_channels) nextChannel = 1;
+	    nextChannel = channel() + 1;
+	    if (nextChannel > channels()) nextChannel = 1;
 	} else {
-	    nextChannel = m_currentChannel - 1;
-	    if (nextChannel < 1) nextChannel = m_channels;
+	    nextChannel = channel() - 1;
+	    if (nextChannel < 1) nextChannel = channels();
 	}
     }
 
@@ -81,6 +81,8 @@
                     r.width = r.height = CONFIG_CHANNEL_NUMBER_SIZE;
                     for(sc = 0; sc < screensTotal(); sc++)
                     {
+		    if ((m_screenNumber % MAX_CHANNEL_SCREENS) != (sc % MAX_CHANNEL_SCREENS))
+			continue;
 		    XShapeCombineRectangles
                           (display(), m_channelWindow[sc], ShapeBounding,
                            0, 0, &r, 1, first ? ShapeSet : ShapeUnion,
@@ -94,16 +96,17 @@
 
     for(sc = 0; sc < screensTotal(); sc++)
     {
-/*
-        XMoveResizeWindow(display(), m_channelWindow[sc],
-			  DisplayWidth(display(), sc) - 30 -
-		      110 * strlen(number), 30, 500, 160);
- */
-
-        XMoveResizeWindow(display(), m_channelWindow[sc],
-                          DisplayWidth(display(), sc) - 30 -
-                          (5 * CONFIG_CHANNEL_NUMBER_SIZE + 10) *
-                          strlen(number), 30, 500, 160);
+	if ((m_screenNumber % MAX_CHANNEL_SCREENS) != (sc % MAX_CHANNEL_SCREENS))
+	    continue;
+	x = CONFIG_CHANNEL_NUMBER_XPOS;
+	if (x < 0) {
+	    x = DisplayWidth(display(), sc) + CONFIG_CHANNEL_NUMBER_XPOS - (5 * CONFIG_CHANNEL_NUMBER_SIZE + 10) * strlen(number);
+	} else if (strlen(number) == 1)
+	    x -= 10;
+	y = CONFIG_CHANNEL_NUMBER_YPOS;
+	if (y < 0)
+		y = DisplayHeight(display(), sc) + CONFIG_CHANNEL_NUMBER_YPOS - (7 * CONFIG_CHANNEL_NUMBER_SIZE);
+        XMoveResizeWindow(display(), m_channelWindow[sc],x , y, 500, 160);
 	XMapRaised(display(), m_channelWindow[sc]);
     }
 
@@ -116,6 +119,8 @@
 	}
 
 	for (i = 0; i < considering.count(); ++i) {
+	    if (considering.item(i)->screen() != m_screenNumber)
+		continue;
 	    if (considering.item(i) == push || considering.item(i)->isSticky()
 #ifdef CONFIG_USE_WINDOW_GROUPS
 		|| (push &&
@@ -131,23 +136,36 @@
 	considering.remove_all();
     }
 
-    m_currentChannel = nextChannel;
-    m_channelChangeTime = timestamp(True) +
-	(quickFlip ? CONFIG_QUICK_FLIP_DELAY : CONFIG_FLIP_DELAY);
+    for(sc = 0; sc < screensTotal(); sc++)
+    {
+	if ((m_screenNumber % MAX_CHANNEL_SCREENS) != (sc % MAX_CHANNEL_SCREENS))
+	    continue;
+	m_currentChannel[m_screenNumber % MAX_CHANNEL_SCREENS] = nextChannel;
+	m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] = timestamp(True) +
+	    (quickFlip ? CONFIG_QUICK_FLIP_DELAY : CONFIG_FLIP_DELAY);
+    }
 
 #if CONFIG_GNOME_COMPLIANCE != False
     gnomeUpdateChannelList();
 #endif
+#ifdef CONFIG_CHANNEL_ALWAYS_VISIBLE
+    instateChannel();
+#endif
 }
 
 
 void WindowManager::instateChannel()
 {
     int i;
-    m_channelChangeTime = 0;
+
     for(i = 0; i < screensTotal(); i++)
     {
+	if ((m_screenNumber % MAX_CHANNEL_SCREENS) != (i % MAX_CHANNEL_SCREENS))
+	    continue;
+	m_channelChangeTime[i % MAX_CHANNEL_SCREENS] = 0;
+#ifndef CONFIG_CHANNEL_ALWAYS_VISIBLE
 	XUnmapWindow(display(), m_channelWindow[i]);
+#endif
     }
 
     ClientList considering;
@@ -157,34 +175,42 @@
     }
 
     for (i = 0; i < considering.count(); ++i) {
-	considering.item(i)->flipChannel(False, m_currentChannel);
-	if (considering.item(i)->channel() == m_channels &&
+	if (considering.item(i)->screen() != m_screenNumber)
+	    continue;
+	considering.item(i)->flipChannel(False, channel());
+	if (considering.item(i)->channel() == channels() &&
 	    !considering.item(i)->isSticky()) createNewChannel();
     }
 
-    if (m_activeClient && m_activeClient->channel() != channel()) {
+    if (m_activeClient && 
+	(m_activeClient->channel() != channel() ||
+	 m_activeClient->screen() != m_screenNumber)) {
 	m_activeClient = 0;
     }
 
-    checkChannel(m_channels-1);
+    checkChannel(channels()-1);
 }    
 
 
 void WindowManager::checkChannel(int ch)
 {
-    if (m_channels <= 2 || ch < m_channels - 1) return;
+    if (channels() <= 2 || ch < channels() - 1) return;
 
     for (int i = m_orderedClients.count()-1; i >= 0; --i) {
-	if (m_orderedClients.item(i)->channel() == ch) return;
+	if (m_orderedClients.item(i)->channel() == ch &&
+	    m_orderedClients.item(i)->screen() == m_screenNumber)
+		return;
+
     }
 
-    --m_channels;
+    --m_channels[m_screenNumber % MAX_CHANNEL_SCREENS];
 
 #if CONFIG_GNOME_COMPLIANCE != False
     gnomeUpdateChannelList();
 #endif
 
-    if (m_currentChannel > m_channels) m_currentChannel = m_channels;
+    if (channel() > channels())
+	m_currentChannel[m_screenNumber % MAX_CHANNEL_SCREENS] = channels();
 
     checkChannel(ch - 1);
 }
@@ -192,27 +218,30 @@
 
 void WindowManager::createNewChannel()
 {
-    ++m_channels;
+    ++m_channels[m_screenNumber % MAX_CHANNEL_SCREENS];
 #if CONFIG_GNOME_COMPLIANCE != False
     gnomeUpdateChannelList();
 #endif
 
 }
 
-void WindowManager::gotoChannel(int channel, Client *push)
+void WindowManager::gotoChannel(int ch, Client *push)
 {
-    if (channel == m_currentChannel) {
-	flipChannel(True, False, False, 0);
+    if (ch == channel()) {
+	flipChannel(screen(), True, False, False, 0);
 	return;
    }
 
-    if (channel > 0 && channel <= m_channels) {
+    if (ch > 0 && ch <= channels()) {
 
-	while (m_currentChannel != channel) {
-	    if (m_channels < channel) {
-		flipChannel(False, False, True, push);
+	while (channel() != ch) {
+	    if (channels() == ch) {
+		createNewChannel();
+		flipChannel(screen(), False, False, True, push);
+	    } else if (channels() < ch) {
+		flipChannel(screen(), False, False, True, push);
 	    } else {
-		flipChannel(False, True, True, push);
+		flipChannel(screen(), False, True, True, push);
 	    }
 	    XSync(display(), False);
 	}
diff -u -r -d wmx-6.orig/Config.h wmx-6/Config.h
--- wmx-6.orig/Config.h	Wed May 24 17:48:59 2000
+++ wmx-6/Config.h	Thu Jan 24 17:38:41 2002
@@ -73,6 +73,9 @@
 // Spawn a temporary new shell between the wm and each new process?
 #define CONFIG_EXEC_USING_SHELL   False
 
+// Allow command parameters
+#define CONFIG_COMMAND_PARAMETERS True
+
 // What to run to get a new window (from the "New" menu option)
 #define CONFIG_NEW_WINDOW_LABEL "New"
 //#define CONFIG_NEW_WINDOW_COMMAND "xterm"
@@ -94,7 +97,8 @@
 #define CONFIG_SYSTEM_COMMAND_MENU	"/usr/local/lib/wmx/menu"
 // append screennumber to COMMAND_MENU directory;
 // use non screen style as fallback
-#define CONFIG_ADD_SCREEN_TO_COMMAND_MENU False
+//#define CONFIG_ADD_SCREEN_TO_COMMAND_MENU False
+#define CONFIG_ADD_SCREEN_TO_COMMAND_MENU True
  
 // Focus possibilities.
 // 
@@ -205,8 +209,8 @@
 #define CONFIG_CIRCULATE_KEY	XK_Tab
 //#define CONFIG_CIRCULATE_KEY	XK_grave
 //#define CONFIG_CIRCULATE_KEY	XK_section
-#define CONFIG_DESTROY_KEY	XK_BackSpace
-//#define CONFIG_DESTROY_KEY	XK_Delete
+//#define CONFIG_DESTROY_KEY	XK_BackSpace
+#define CONFIG_DESTROY_KEY	XK_Delete
 //#define CONFIG_DESTROY_KEY	XK_Insert
 
 // If WANT_KEYBOARD_MENU is True, then the MENU_KEY, when pressed with
@@ -316,12 +320,23 @@
 // changes, provided USE_KEYBOARD is also True.  Set USE_CHANNEL_MENU
 // if you want to change channels via a keyboard-controlled menu
 // instead of linearly up and down one at a time like TV.
+// Draw number at (CHANNEL_NUMBER_XPOS,CHANNEL_NUMBER_YPOS)
 
 #define CONFIG_CHANNEL_SURF       True
 #define CONFIG_CHANNEL_CLICK_SIZE 120
 #define CONFIG_CHANNEL_NUMBER_SIZE 20
 #define CONFIG_USE_CHANNEL_KEYS   True
-#define CONFIG_USE_CHANNEL_MENU   False
+//#define CONFIG_USE_CHANNEL_MENU   False
+#define CONFIG_USE_CHANNEL_MENU   True
+#define CONFIG_CHANNEL_NUMBER_XPOS -30
+#define CONFIG_CHANNEL_NUMBER_YPOS 30
+
+// CHANNEL_ALWAYS_VISIBLE keeps channel number permanently visible
+#define CONFIG_CHANNEL_ALWAYS_VISIBLE True
+
+// MAX_CHANNEL_SCREENS is the maximum number of screens we use for separate
+// channel-switching. Set it 1 to switch all screens together.
+#define MAX_CHANNEL_SCREENS 4
 
 // FLIP_DELAY is the length of time the big green number stays in the
 // top-right when flipping channels, before the windows reappear.
diff -u -r -d wmx-6.orig/Events.C wmx-6/Events.C
--- wmx-6.orig/Events.C	Thu May 11 16:25:37 2000
+++ wmx-6/Events.C	Thu Jan 24 17:56:50 2002
@@ -21,6 +21,7 @@
 void WindowManager::dispatchEvent(XEvent *ev)
 {
     m_currentTime = CurrentTime;
+    setScreenFromRoot(((XAnyEvent *)(ev))->window);
 
     switch (ev->type) {
 
@@ -137,10 +138,11 @@
 
     waiting:
 
-	if (m_channelChangeTime > 0) {
+	setScreenFromRoot(((XAnyEvent *)(e))->window);
+	if (m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] > 0) {
 	    Time t = timestamp(True);
 //!!!	    if (t < m_channelChangeTime || t - m_channelChangeTime > 1000) {
-	    if (t >= m_channelChangeTime) {
+	    if (t >= m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS]) {
 		instateChannel();
 	    }
 	}
@@ -200,7 +202,7 @@
 #endif
 
 	if ((r = select(fd + 1, &rfds, NULL, NULL,
-			(m_channelChangeTime > 0 || m_focusChanging) ? &t :
+			(m_channelChangeTime[m_screenNumber % MAX_CHANNEL_SCREENS] > 0 || m_focusChanging) ? &t :
 			(struct timeval *)NULL)) > 0) {
 
 #if CONFIG_USE_SESSION_MANAGER != False
@@ -636,19 +638,19 @@
     
     if (strncmp(atomName, "_WIN_WORKSPACE", 13) == 0) {
 
-	int channel = (int)e->data.l[0] + 1;
+	int ch = (int)e->data.l[0] + 1;
 
 	// gnome is not up-to-date and asked us to flip to a 
 	// non-existing channel
-	if (channel > m_channels) {
+	if (ch > channels()) {
 	    
 	    gnomeUpdateChannelList();
 	    return;
 	}
 
 	// it seems like there should be a better way of doing this...
-	while (m_currentChannel != channel) {
-	    if (m_currentChannel < channel) {
+	while (channel() != ch) {
+	    if (channel() < ch) {
 		flipChannel(False, False, True, 0);
 	    } else {
 		flipChannel(False, True, True, 0);
diff -u -r -d wmx-6.orig/Makefile wmx-6/Makefile
--- wmx-6.orig/Makefile	Wed Jan 23 11:29:15 2002
+++ wmx-6/Makefile	Thu Jan 24 18:03:50 2002
@@ -17,6 +17,7 @@
 # and Xlocale, please add -DX_LOCALE.
 #CFLAGS = -g -O2 -I/usr/include -I/usr/openwin/include
 CXXFLAGS=-g -O2 -I/usr/X11R6/include
+CXXFLAGS=-O2 -I/usr/X11R6/include
 
 OBJECTS	= Border.o Buttons.o Channel.o Client.o Config.o Events.o Main.o Manager.o Menu.o Rotated.o Session.o
 
diff -u -r -d wmx-6.orig/Manager.C wmx-6/Manager.C
--- wmx-6.orig/Manager.C	Mon Apr 23 11:10:42 2001
+++ wmx-6/Manager.C	Tue Feb 26 15:12:55 2002
@@ -63,6 +63,7 @@
  	    "     Original keyboard-menu code Copyright (c) 1998 Nakayama Shintaro\n"
 	    "     Dynamic configuration code Copyright (c) 1998 Stefan `Sec' Zehl\n"
 	    "     Multihead display code Copyright (c) 2000 Sven Oliver `SvOlli' Moll\n"
+	    "     Command arguments Copyright (c) 2001,2002 <cougar@random.ee>\n"
 	    "     %s\n     Copying and redistribution encouraged.  "
 	    "No warranty.\n\n", XV_COPYRIGHT);
 
@@ -185,6 +186,10 @@
 	fprintf(stderr, "  No quick keyboard channel-surf.");
     }
 
+    if (CONFIG_CHANNEL_ALWAYS_VISIBLE) {
+	fprintf(stderr, "  Channel number always visible.");
+    }	
+
 #if I18N
     fprintf(stderr, "\n     Operating system locale is \"%s\".",
 	    ret_setlocale ? ret_setlocale : "(NULL)");
@@ -196,6 +201,10 @@
         fprintf(stderr, "\n     Not GNOME compliant.");
     }
 
+    if (CONFIG_COMMAND_PARAMETERS) {
+        fprintf(stderr, "\n     Command arguments support on.");
+    }
+
     fprintf(stderr, "\n     Command menu taken from ");
     if (wmxdir == NULL) {
 	fprintf(stderr, "%s/%s.\n", home, CONFIG_COMMAND_MENU);
@@ -239,11 +248,6 @@
     m_currentTime = -1;
     m_activeClient = 0;
 
-    m_channels = 2;
-    m_currentChannel = 1;
-    m_channelChangeTime = 0;
-    m_channelWindow = 0;
-
     Atoms::wm_state      = XInternAtom(m_display, "WM_STATE",            False);
     Atoms::wm_changeState= XInternAtom(m_display, "WM_CHANGE_STATE",     False);
     Atoms::wm_protocols  = XInternAtom(m_display, "WM_PROTOCOLS",        False);
@@ -273,6 +277,12 @@
         fprintf(stderr, "\n     Detected %d screens.", m_screensTotal);
     }
     
+    for (i = 0; i < m_screensTotal; i++) {
+	m_channels[i % MAX_CHANNEL_SCREENS] = 2;
+	m_currentChannel[i % MAX_CHANNEL_SCREENS] = 1;
+	m_channelChangeTime[i % MAX_CHANNEL_SCREENS] = 0;
+    }
+
     XSetSelectionOwner(m_display, Atoms::wmx_running,
 		       None, timestamp(True)); // used to have m_menuWindow
     XSync(m_display, False);
@@ -295,6 +305,14 @@
 
     clearFocus();
     scanInitialWindows();
+#ifdef CONFIG_CHANNEL_ALWAYS_VISIBLE
+
+    for(i = 0; i < screensTotal(); i++) {
+	m_screenNumber = i;
+	flipChannel(screen(), True, True, True, 0);
+    }
+    setScreenFromRoot(root());
+#endif
     loop();
     if(m_restart == True){
 	fprintf(stderr,"restarting wmx from SIGHUP\n");
@@ -673,7 +691,7 @@
         }
 
 	m_clients.append(newC);
-	if (m_currentChannel == m_channels) {
+	if (channel() == channels()) {
 	    createNewChannel();
 	}
 	return newC;
@@ -764,13 +782,13 @@
 	    m_hiddenClients.remove(i);
 
 #if CONFIG_GNOME_COMPLIANCE != False
-	    if (c->channel() != m_currentChannel) {
+	    if (c->channel() != channel()) {
 
-		while (c->channel() != m_currentChannel) {
-		    if (m_currentChannel < c->channel()) {
-			flipChannel(False, False, True, 0);
+		while (c->channel() != channel()) {
+		    if (channel() < c->channel()) {
+			flipChannel(screen(), False, False, True, 0);
 		    } else {
-			flipChannel(False, True, True, 0);
+			flipChannel(screen(), False, True, True, 0);
 		    }
 		    XSync(display(), False);
 		}
@@ -941,10 +959,13 @@
 		char *pstring = (char *)malloc(strlen(displayName) + 11 +
 					       numdigits(screen()));
 		sprintf(pstring, "DISPLAY=%s", displayName);
-                c = strrchr(pstring, '.');
-                if (c) {
-                  sprintf(c + 1, "%d", screen());
-                  putenv(pstring);
+		c = strrchr(pstring, ':');
+		if (c) {
+		    c = strrchr(pstring, '.');
+		    if (c) {
+			sprintf(c + 1, "%d", screen());
+			putenv(pstring);
+		    }
                 }
 	    }
 
@@ -956,6 +977,36 @@
 	    }
 
 	    if (file) {
+#if CONFIG_COMMAND_PARAMETERS
+		if (index(name, ';') != NULL) {
+		    char *c, *c1;
+		    int i = 0;
+		    char **argv;
+char *newname = name;
+ 		    newname = strdup(name);	// don't change func param
+		    for(c = newname; *c; c++) {
+			if (*c == '\\')			// translate \ -> /
+				*c = '/';
+			if (*c == ';')			// count parameters
+			    i++;
+		    }
+		    argv = (char **)malloc(i + 1);
+		    for(c1 = c = newname, i = 0; *c; c++)// create argv list
+			if (*c == ';') {
+			    *c = '\0';
+			    argv[i++] = c1;
+			    c1 = c + 1;
+			}
+		    argv[i++] = c1;
+		    argv[i] = NULL;
+		    execv(file, argv);
+		    fprintf(stderr, "wmx: exec %s:%s.. failed (errno %d)\n",
+			    file, argv[0], errno);
+		    perror("exec");
+		    exit(1);
+		}
+#endif
+
 		execl(file, name, 0);
 	    }
 	    else {
@@ -1077,16 +1128,16 @@
     CARD32  val;
    
     // how many channels are there?
-    val = (CARD32) m_channels;
+    val = (CARD32) channels();
  
     XChangeProperty
         (m_display, m_root[0], Atoms::gnome_workspaceCount, XA_CARDINAL, 32, 
          PropModeReplace, (unsigned char *)&val, 1);
 
     // set the names of the channels
-    names = (char **)malloc(sizeof(char *) * m_channels);
+    names = (char **)malloc(sizeof(char *) * channels());
 
-    for (i = 0; i < m_channels; i++) {
+    for (i = 0; i < channels(); i++) {
         snprintf(s, sizeof(s), "Channel %i", i + 1);
         names[i] = (char *)malloc(strlen(s) + 1);
         strcpy(names[i], s);
@@ -1094,13 +1145,13 @@
     
     XTextProperty textProp;
 
-    if (XStringListToTextProperty(names, m_channels, &textProp)) {
+    if (XStringListToTextProperty(names, channels(), &textProp)) {
 	XSetTextProperty
             (m_display, m_root[0], &textProp, Atoms::gnome_workspaceNames);
 	XFree(textProp.value);
     }
     
-    for (i = 0; i < m_channels; i++) free(names[i]);
+    for (i = 0; i < channels(); i++) free(names[i]);
     free(names);
 
     gnomeUpdateCurrentChannel();
@@ -1111,7 +1162,7 @@
     CARD32 val;
 
     // gnome numbers then 0... not 1...
-    val =(CARD32)(m_currentChannel - 1);
+    val =(CARD32)(channel() - 1);
 
     XChangeProperty
         (m_display, m_root[0], Atoms::gnome_workspace, XA_CARDINAL, 32, 
diff -u -r -d wmx-6.orig/Manager.h wmx-6/Manager.h
--- wmx-6.orig/Manager.h	Thu May 25 10:50:17 2000
+++ wmx-6/Manager.h	Tue Feb 26 15:11:54 2002
@@ -72,8 +72,8 @@
     void releaseGrabKeyMode(XKeyEvent *);
     void spawn(char *, char *);
 
-    int channel() { return m_currentChannel; }
-    int channels() { return m_channels; }
+    int channel() { return m_currentChannel[m_screenNumber % MAX_CHANNEL_SCREENS]; }
+    int channels() { return m_channels[m_screenNumber % MAX_CHANNEL_SCREENS]; }
     void setSignalled() { m_looping = False; } // ...
     void gotoChannel(int channel, Client *push);
     
@@ -100,7 +100,7 @@
 #endif
 
     // Stupid little helper function
-    static int numdigits(int);
+    int numdigits(int);
 
 private:
     int loop();
@@ -136,14 +136,14 @@
     int m_shapeEvent;
     int m_currentTime;
 
-    int m_channels;
-    int m_currentChannel;	// from 1 to ...
-    void flipChannel(Boolean statusOnly, Boolean flipDown,
+    int m_channels[MAX_CHANNEL_SCREENS];
+    int m_currentChannel[MAX_CHANNEL_SCREENS];	// from 1 to ...
+    void flipChannel(int scr, Boolean statusOnly, Boolean flipDown,
 		     Boolean quickFlip, Client *push); // bleah!
     void instateChannel();
     void createNewChannel();
     void checkChannel(int);
-    Time m_channelChangeTime;
+    Time m_channelChangeTime[MAX_CHANNEL_SCREENS];
     Window *m_channelWindow;
 
     Boolean m_looping;
diff -u -r -d wmx-6.orig/Menu.C wmx-6/Menu.C
--- wmx-6.orig/Menu.C	Wed May 24 17:50:27 2000
+++ wmx-6/Menu.C	Tue Feb 26 15:00:26 2002
@@ -155,8 +155,17 @@
 
     int width, maxWidth = 10;
     for(int i = 0; i < m_nItems; i++) {
+#if CONFIG_COMMAND_PARAMETERS
+	if (index(m_items[i], ';') != NULL) {
+	    width = XTextWidth(m_font[screen()], m_items[i],
+				(index(m_items[i], ';') - m_items[i]));
+	} else {
+#endif
 	width = XTextWidth(m_font[screen()], m_items[i],
 			   STRLEN_MITEMS(i));
+#if CONFIG_COMMAND_PARAMETERS
+	}
+#endif
 	if (width > maxWidth) maxWidth = width;
     }
     maxWidth += 32;
@@ -359,15 +368,36 @@
 
 	    for (i = 0; i < m_nItems; i++) {
 
-		int dx = XTextWidth(m_font[screen()], m_items[i], 
-				    STRLEN_MITEMS(i));
+		int dx;
+#if CONFIG_COMMAND_PARAMETERS
+		if (index(m_items[i], ';') != NULL) {
+		    dx = XTextWidth(m_font[screen()], m_items[i], 
+					(index(m_items[i], ';') - m_items[i]));
+		} else {
+#endif
+		dx = XTextWidth(m_font[screen()], m_items[i], 
+ 				    STRLEN_MITEMS(i));
+#if CONFIG_COMMAND_PARAMETERS
+		}
+#endif
 		int dy = i * entryHeight + m_font[screen()]->ascent + 10;
 
 		if (i >= m_nHidden) {
+#if CONFIG_COMMAND_PARAMETERS
+		    if (index(m_items[i], ';') != NULL) {
+		    XDrawString(display(), m_window[screen()],
+				Border::drawGC(m_windowManager,screen()),
+				maxWidth - 8 - dx, dy,
+				m_items[i], (index(m_items[i], ';') - m_items[i]));
+		    } else {
+#endif
 		    XDrawString(display(), m_window[screen()],
 				Border::drawGC(m_windowManager,screen()),
 				maxWidth - 8 - dx, dy,
 				m_items[i], STRLEN_MITEMS(i));
+#if CONFIG_COMMAND_PARAMETERS
+		    }
+#endif
 		} else {
 		    XDrawString(display(), m_window[screen()],
 				Border::drawGC(m_windowManager,screen()),
@@ -676,7 +706,7 @@
     if (i >= m_nHidden && i < m_nItems)
     {
 	char *commandFile =
-	    (char *)malloc(strlen(m_commandDir) + STRLEN_MITEMS(i) + 2);
+	    (char *)malloc(strlen(m_commandDir) + strlen(m_items[i]) + 2);
 
 	sprintf(commandFile, "%s/%s", m_commandDir, m_items[i]);
 	m_windowManager->spawn(m_items[i], commandFile);
@@ -705,7 +735,7 @@
     char *new_directory;
     int dirlen = strlen (m_commandDir);
     
-    new_directory = (char *)malloc (dirlen + STRLEN_MITEMS(i) + 2);
+    new_directory = (char *)malloc (dirlen + strlen(m_items[i]) + 2);
     strcpy (new_directory, m_commandDir);
     new_directory[dirlen] = '/';
     strcpy (new_directory + dirlen + 1, m_items[i]);
@@ -860,7 +890,7 @@
 
 char **ChannelMenu::getItems(int *niR, int *nhR)
 {
-    *niR = m_windowManager->channels();
+    *niR = m_windowManager->channels();;
     *nhR = 0;
 
     char **items = (char **)malloc(*niR * sizeof(char *));
@@ -871,6 +901,7 @@
 	strcpy (item, temp);
 	items[i] = item;
     }
+
     return m_items = items;
 }
 
@@ -884,17 +915,17 @@
     // empty
 }
 
-void ShowGeometry::update(int x, int y)
+void ShowGeometry::update(int scr, int x, int y)
 {
     char string[20];
 
     sprintf(string, "%d %d", x, y);
-    int width = XTextWidth(m_font[screen()], string, strlen(string)) + 8;
-    int height = m_font[screen()]->ascent + m_font[screen()]->descent + 8;
-    int mx = DisplayWidth (display(), screen()) - 1;
-    int my = DisplayHeight(display(), screen()) - 1;
+    int width = XTextWidth(m_font[scr], string, strlen(string)) + 8;
+    int height = m_font[scr]->ascent + m_font[screen()]->descent + 8;
+    int mx = DisplayWidth (display(), scr) - 1;
+    int my = DisplayHeight(display(), scr) - 1;
   
-    XMoveResizeWindow(display(), m_window[screen()],
+    XMoveResizeWindow(display(), m_window[scr],
 
 #if CONFIG_GEOMETRY_X_POS < 0
 		      0
@@ -913,17 +944,17 @@
 #endif
 		      , width, height);
 
-    XClearWindow(display(), m_window[screen()]);
-    XMapRaised(display(), m_window[screen()]);
+    XClearWindow(display(), m_window[scr]);
+    XMapRaised(display(), m_window[scr]);
     
-    XDrawString(display(), m_window[screen()],
-		Border::drawGC(m_windowManager,screen()),
-		4, 4 + m_font[screen()]->ascent, string, strlen(string));
+    XDrawString(display(), m_window[scr],
+		Border::drawGC(m_windowManager,scr),
+		4, 4 + m_font[scr]->ascent, string, strlen(string));
 }
 
-void ShowGeometry::remove()
+void ShowGeometry::remove(int scr)
 {
-    XUnmapWindow(display(), m_window[screen()]);
+    XUnmapWindow(display(), m_window[scr]);
 }
 
 ShowGeometry::~ShowGeometry()
diff -u -r -d wmx-6.orig/Menu.h wmx-6/Menu.h
--- wmx-6.orig/Menu.h	Wed May 17 12:52:56 2000
+++ wmx-6/Menu.h	Tue Feb 26 14:59:10 2002
@@ -109,8 +109,8 @@
     ShowGeometry(WindowManager *, XEvent *);
     virtual ~ShowGeometry();
     
-    void update(int x, int y);
-    void remove();
+    void update(int scr, int x, int y);
+    void remove(int scr);
 
 private:
     virtual char **getItems(int *, int *);
diff -u -r -d wmx-6.orig/README wmx-6/README
--- wmx-6.orig/README	Mon Apr 23 12:26:11 2001
+++ wmx-6/README	Wed Jan 23 13:09:42 2002
@@ -241,6 +241,23 @@
 are now held in Config.C instead.
 
 
+Menu extensions
+===============
+
+If you like to add parameters for menu command, use ';' as a separator.
+For example if you like to add xterm menu item with ssh command:
+
+  > ln -s /usr/X11R6/bin/xterm 'ROOT;-e;ssh;-l;root;localhost'
+
+Now if you choose menu item "ROOT", wmx executes command
+
+  /usr/X11R6/bin/xterm -e ssh -l root localhost
+
+If you need to use slash ('/') in parameter, use backslash ('\') instead.
+
+  > ln -s /usr/X11R6/bin/xpmroot 'Neptune;\usr\share\wallpapers\neptune.xpm.gz'
+
+
 Pixmaps
 =======
 

