Powered by
Movable Type 3.38 mod_perl/2

2010, July 08 (Thu)

Linux Multiseat hacks (gnome gdm)

I have two screens connected to a powerful box. Mostly, I’m using these for coding and it’s running Xinerama with radeon (sssh don’t say anything).

Only sometimes however, I would like to share the machine with a second user.

There are several recommended ways for multiseat setup:

  • Configure the Xserver with seperate screens (not Xinerama). Start Xephyr/Xnest on each screen
  • Start two seperate Xserver (this requires seperate graphic cards or maybe this patch which I couldn’t get to work)

Furthermore, you need to fiddle with the login manager to do everything “right”.

As my setup is more temporary, I opted for a middle way. It remains not without rough edged though… The main login remains running on two screens, and in the case of wanting to share, I will set up a Xephyr instance on one monitor.

Because of Xinerama, Xephyr doesn’t work out of the box like that. So I chose a small hack: I open an empty xterm (which has the netwm ability to go to fullscreen) and embed the Xephyr in it:

uxterm -title Xephyr +sb -hold -e ''

move the xterm window to the second monitor and switch it to fullscreen… I am using Gnome and have assigned a keybinding for that. That way, Xephyr will be running “full screen” on just one monitor, something that it isn’t able to do on its own (Xephyrs fullscreen would expand over both monitors due to Xinerama)

Now we need to start the Xephyr and allow the login for the other account. Again, we have two possibilities. One is to use the xdmcp mode of gdm, and another to use gdmflexiserver — the Gnome user switcher.

Update: I can’t get the SCIM input method editor to work with xdmcp… anyone knows why? So I’ve resorted to the gdmflexiserver one for now.

For the xdmcp, we need to enable it. For example, in SuSE, set DISPLAYMANAGER_REMOTE_ACCESS="yes" in /etc/sysconfig/displaymanager. Then it is enough to use a wrapper script. For access to the input devices, root permission is required though.

For the gdmflexiserver approach on the other hand, it is necessary to replace /usr/bin/Xorg — since gdmflexiserver --xnest is “not implemented”…

The wrapper script or Xorg replacement thus works like this:

First, we define the devices which we want to give the Xephyr use:

#!/bin/zsh
mouse=Razer_Razer_1600dpi_3_button_optical_mouse
keybd=046a_0011

These are examples from my box, the Razer is a mouse and the strange keyboard is a cheap Cherry one — who knows why they can’t afford to brand its ID. Look in /dev/input/by-id after connecting your devices to find out their IDs. This approach is more flexible than using the “event#” devices, whose numbering might change if connected differently.

Now construct the real paths and add some checks to see if the devices are connected:

mouse=/dev/input/by-id/usb-${mouse}-event-mouse
keybd=/dev/input/by-id/usb-${keybd}-event-kbd
if [[ -h $keybd && -h $mouse ]] {

only in the Xorg case, we now loop over all available displays and find the first one which has a empty xterm window created as outlined above, to plant the Xephyr into:

	for ((disp=0;disp<$((${DISPLAY#*:}+0));++disp)) {

in the wrapper case, we set the dummy disp variable instead

	disp=$((${DISPLAY#*:}+0))

finally, we locate the empty window using xwininfo and the -title as specified on top:

	OIFS=$IFS; IFS=$'\n'
	winin=($(DISPLAY=:$disp xwininfo -name Xephyr -children)); IFS=$OIFS
	if [[ $winin[1]  'xwininfo: Window id: '*' "Xephyr"' && \
		$winin[4]  '     1 child:' && \
		$winin[5]  *' (has no name): ()'* ]] {
		winid=($=winin[1])
		if [[ $winid[4]  0x* ]] {
			fontsdir=(/usr/share/fonts/*(/))

Xephyr doesn’t seem to know about the default fonts, so we construct a fontsdir here, might need to adjust this to your local site font dirs. Now for the start command. In case of the Xorg replacement for use with gdmflexiserver, it is important to get rid of the -verbose flag which Xephyr does not understand. The -parent switch designs Xephyr to embed itself into another window:

exec env DISPLAY=:$disp Xephyr -retro \
	-mouse evdev,,,device=$mouse \
	-keybd evdev,,device=$keybd,xkbmodel=evdev \
	-fp ${(j:,:)fontsdir} -parent $winid[4] \
	${@:#-verbose}

for the wrapper script, we use the -query parameter for xdmcp query:

exec gnomesu -- Xephyr -retro \
	-mouse evdev,,,device=$mouse \
	-keybd evdev,,device=$keybd,xkbmodel=evdev \
	-fp ${(j:,:)fontsdir} -parent $winid[4] \
	-once -query $@

just finish all the open blocks now…

		}
	}
}

however, in the Xorg replacement script, we will want to fall back to the real Xorg when we haven’t prepared any special window for Xephyr:

}
exec Xorg.old $@

As you can see, we moved /usr/bin/Xorg to /usr/bin/Xorg.old and put the replacement script up as /usr/bin/Xorg instead. That way, you can now prepare an xterm window as per above and execute gdmflexiserver without need for root.

With the wrapper script, just save it somewhere. You can then call it like this:

./xephyr-xdmcp 127.0.0.1 :3

Where 127.0.0.1 means your local host which you are going to query using xdmcp and :3 is a free display number for Xephyr to listen on.

An outstanding trouble I’m having in both cases is with the Gnome keyboard-properties tool which will set the keyboard layout upon login. Since it needs a different layout — evdev layout in the case of Xephyr, and local connected keyboard layout in the case of plain X, it will break the keyboard layout directly after login.

So far the only workaround is to rightclick on the desktop, “Open Terminal” and type in the command

setxkbmap -model evdev

before you can start working proper in the Xephyr instance. Maybe someone can come up with a better fix?


2010, June 18 (Fri)

Programmierung int log2 in gcc / c++

I wonder why this result isn’t on google’s #1 for int log2 gcc.

To get the integer logarithm to the base of 2, try

      sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(   n );
     sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(  n );
sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll( n ); 


2010, June 02 (Wed)

Linux SUN UNIX Keyboard & Linux Gnome

I shot a UNIX keyboard on ebay.

sun_unix_keyb.jpg

Of course, it “just works” when you plug it in. However, I want it to work properly, that is, the special keys on the left should show their labels when assigning them e.g. in gnome-keybinding-properties. To do that, it is apparently necessary to edit the xkb rules & xml files which are found in /usr/share/X11/xkb/rules on my distribution.

There is a “Sun Type 5/6” Layout available in gnome-keyboard-properties, but it mysteriously renders the BackSpace key unusuable — this might be a particular bug of my installation, any hints appreciated. (has apparently been fixed in this commit, which probably means fixed in xkeyboard-config 1.8)

Update; the old solution provided problematic (it has been hidden below.) Here is the new approach:

Fix the BackSpace key with this patch:

--- a/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-16 20:39:59.937546375 +0200
+++ b/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-15 00:56:22.547604150 +0200
@@ -62,6 +62,8 @@ xkb_symbols "sunbasic" {
     include "inet(evdev)"
 
     include "us(basic)"
+    // these keys are common to all layouts
+    key <BKSP> {	[ BackSpace	]	};
     include "pc(function)"
     include "pc(editing)"
     include "keypad(x11)"

Fix the “too old” AltGr mapping (XOrg changed it from Mode_switch to ISO_Level3_Shift, which is defined in the level3 symbols:)

--- a/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-16 20:39:59.937546375 +0200
+++ b/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-15 00:56:22.547604150 +0200
@@ -74,7 +76,8 @@ xkb_symbols "sunbasic" {
     key <LFSH> { [ Shift_L		]			};
     key <RTSH> { [ Shift_R		]			};
     key <LALT> { [ Alt_L		]			};
-    key <ALGR> { [ Mode_switch		]			};
+//  key <ALGR> { [ Mode_switch		]			};
+    include "level3(ralt_switch)"
     key <LMTA> { [ Meta_L		]			};
     key <RMTA> { [ Meta_R		]			};
     key <LCTL> { [ Control_L		]			};

Shuffle the modifier maps:

--- a/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-16 20:39:59.937546375 +0200
+++ b/usr/share/X11/xkb/symbols/sun_vndr/us	2010-06-15 00:56:22.547604150 +0200
@@ -116,9 +119,9 @@ xkb_symbols "sunbasic" {
     modifier_map Control { Control_L, Control_R };
     modifier_map Shift   { Shift_R, Shift_L };
     modifier_map Mod1    { Meta_L, Meta_R };
-    modifier_map Mod2    { Mode_switch };
-    modifier_map Mod3    { Num_Lock };
-    modifier_map Mod4    { Alt_L };
+//  modifier_map Mod2    { Mode_switch };
+    modifier_map Mod2    { Num_Lock };
+    modifier_map Mod3    { Alt_L };
 };
 
 hidden

Gnome wants its so-called “<Alt>”-binding on Mod1. I put the ♦Meta-keys there, because they’re in the right place. It further requires Mod2 to be Num_Lock, otherwise it is not happy and a lot of modifier keys stop working when Num_Lock is enabled. (Only the Mod2 is ignored when calculating the overlaps.) The former Mode_switch is mapped to Mod5 by the include above.

With this configuration, the following is now an useful addition to your .Xresources:

xterm*metaSendsEscape: true
xterm*altIsNotMeta: true
xterm*altSendsEscape: false

That way, Alt can be used to generate “Alternate keys” and ♦Meta works for key movement.

(X)Emacs on the other hand wants all kinds of “Meta” to be on one modifier, and (optionally) all kinds of “Alt” on the same, or another. My previous setup was causing one Meta key and the Alt key mapped to Mod1, and another one to Mod4. With the modifier mappings above, Meta correctly generates M- and Alt — generates A- (Super, aka Win-key, would get interpreted as S- in XEmacs.)

I suspect since I have not bound any <Super> keys, Gnome-Do is now confused and launches on a simple press of the Space-bar! Makes you unable to types spaces. I don’t know how to fix this. Trying to assign Alt+space as the Summon Key fails — it only displays “space”… since I don’t use Gnome-Do anyway, I removed it for now using gnome-session-properties.

I wanted to add the UNIX layout to the keyboard image display in the Gnome keyboard properties, so I made a new layout in the rules directory:

1. Added a new model to base.xml:

    <model>
      <configItem>
        <name>sun_unix</name>
        <description>Sun Type USB UNIX Layout</description>
        <vendor>Sun Microsystems</vendor>
      </configItem>
    </model>

2. Do the same for base.lst

! model
  sun_unix        Sun Type USB UNIX Layout

3. Add rules to base that set the desired options, on the way also fixing the missing geometry for the type6 and euro keyboard:

! model		=	keycodes
  sun_unix 	=	sun(type6_usb)

! model		=	geometry
  sun6	 	=	sun(type6)
  sun_unix 	=	sun(type6unix)
  sun6euro 	=	sun(type6tuv)

! model		layout			=	symbols
  sun_unix	us			=	sun_vndr/us(type6)
  sun_unix	*			=	sun_vndr/us(type6)+%l%(v)

Fix a bug in the rules that manifests when you use more than keyboard layout — because of the missing rules, the “pc” symbols are added, causing havok in the modifier mappings

! model		layout[1]		=	symbols
  sun6		*			=	sun_vndr/us(type6)+%l[1]%(v[1])
  sun_unix	*			=	sun_vndr/us(type6)+%l[1]%(v[1])
  sun6euro	*			=	sun_vndr/us(type6)+%l[1]%(v[1])

Modify the ctrl:nocaps rule to make CapsLock an additional right Control (the default key for example in VirtualBox) with this patch: (optional)

--- a/usr/share/X11/xkb/symbols/ctrl	2010-06-16 20:39:59.922548680 +0200
+++ b/usr/share/X11/xkb/symbols/ctrl	2010-06-14 22:21:41.482666941 +0200
@@ -5,7 +5,8 @@
 // eliminate the caps lock key completely (replace with control)
 partial modifier_keys 
 xkb_symbols "nocaps" {
-    replace key <CAPS>	{  [ Control_L, Control_L ] };
+//  replace key <CAPS>	{  [ Control_L, Control_L ] };
+    replace key <CAPS>	{  [ Control_R ] };
     modifier_map  Control { <CAPS>, <LCTL> };
 };
 

Fix the geometry (caps and control are swapped):

--- a/usr/share/X11/xkb/geometry/sun	2010-06-16 20:39:59.910515296 +0200
+++ b/usr/share/X11/xkb/geometry/sun	2010-06-14 22:29:08.208691859 +0200
@@ -2885,7 +2885,7 @@ xkb_geometry "t6unix" {
 	};
 	row {
 	    top= 39;
-	    keys { <FRNT>, <COPY>, { <CAPS>, 9, shape="CAPS" },
+	    keys { <FRNT>, <COPY>, { <LCTL>, 9, shape="LCTL" },
 		   <AC01>, <AC02>, <AC03>, <AC04>, <AC05>, 
 		   <AC06>, <AC07>, <AC08>, <AC09>, <AC10>, 
 		   <AC11>,
@@ -2902,7 +2902,7 @@ xkb_geometry "t6unix" {
 	};
 	row {
 	    top= 77;
-	    keys { <FIND>, <CUT>, { <LCTL>, 9, shape="LCTL" },
+	    keys { <FIND>, <CUT>, { <CAPS>, 9, shape="CAPS" },
 		   <LALT>, {<LMTA>, "LMTA"},
 		 { <SPCE>, "SPCE" },
 		   {<RMTA>, "RMTA"}, <COMP>, <ALGR>

Other problems

Unfortunately, I cannot get the Compose LED to light up.

Gnome doesn’t accept the SunFront keybinding to bring windows to the front — what’s up with that?? It works when I just assign it, but stops working on next login. As a workaround, I could get it to work by setting /apps/metacity/window_keybindings/raise_or_lower to the magical value 0x8c in gconf-editor

It is not neccessary to choose any options in the gnome-keyboard-properties.

Continue reading “SUN UNIX Keyboard & Linux Gnome” »


Tag cloud