Bug 2165

Summary: XDM Chooser enhancements scrollwheel, no mouse
Product: xorg Reporter: Thomas Reifferscheid <reiffert>
Component: App/xdmAssignee: Alan Coopersmith <alan.coopersmith>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: lowest CC: ajax, alan.coopersmith
Version: git   
Hardware: x86 (IA32)   
OS: Linux (All)   
URL: http://student.physik.uni-mainz.de/~reiffert/xdm.php
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Patch for chooser.c and Chooser.ad
none
Additional change none

Description Thomas Reifferscheid 2004-12-28 09:11:40 UTC
The major goals were to enhance the xdm chooser by at least the following:

- select a host from chooser list without the presence of a mouse
- scroll through the hostlist with a scrollwheel

A minor goal was also considered, not selecting hosts that are unwilling,
and backward compatibility for older Chooser.ad files
(eg in debian it's /etc/X11/app-defaults/Chooser)

The patch contains some documentation and was made against the Xorg CVS.

A quick overview to the new features:

- When no host is initially selected, scrolling the mousewheel or
  XK_Up or XK_Down will the select the first willing host
- pressing return has the same function as selecting the Accept-Button
- When one host is selected, pressing XK_Down, XK_Up or ScrollWheel
  will select the next willing host, either direction, or stay
  at the only willing host.

It has been tested with Xorg CVS, Xfree4.3 and Xfree4.4


The patch can be found here:

http://student.physik.uni-mainz.de/~reiffert/xdm.diff

--- xc.orig/programs/xdm/Chooser.ad	2004-04-23 21:54:42.000000000 +0200
+++ xc.new/programs/xdm/Chooser.ad	2004-12-28 16:50:46.000000000 +0100
@@ -17,8 +17,13 @@
 *viewport.allowResize:	true
 
 *list.translations:	#override \
-	<BtnDown>:	Set() CheckWilling() \n\
-	<BtnUp>(2):	Accept()
+	<Key>Return:    Accept() \n\
+	<Key>:          KeySwitch() \n\
+	<Btn1Down>:     Store() Set() CheckWilling() Setold() \n\
+	<Btn1Up>(2):    Accept() \n\
+	<Btn4Down>:     BtnSwitch() \n\
+	<Btn5Down>:     BtnSwitch()
+
 *list.defaultColumns:	1
 *list.forceColumns:	true
 
--- xc.orig/programs/xdm/chooser.c	2004-04-23 21:54:42.000000000 +0200
+++ xc.new/programs/xdm/chooser.c	2004-12-28 16:03:58.000000000 +0100
@@ -135,8 +135,10 @@
 #endif /* hpux */
 
 #include    <netdb.h>
+#include    <X11/keysym.h>
 
 static int FromHex (char *s, char *d, int len);
+static int oldline;
 
 Widget	    toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
 
@@ -996,6 +998,173 @@
     }
 }
 
+/*
+  next_line returns the next line in a list
+  across the list end.
+  (0, 1, 2, 3, 0, 1, 2, 3 ....)
+*/
+
+static int 
+next_line(unsigned int current, unsigned int size, int event)
+{
+  switch(event) {
+    case Button5:
+      return (current + 1) % size;
+    case Button4:
+      return (current + size - 1) % size;
+    case XK_Down:
+      return (current + 1) % size;
+    case XK_Up:
+      return (current + size - 1) % size;
+  }  
+  return -1;
+}
+
+/* 
+  Hostselect selects a given chooser line.
+  Returns 1 when host is willing and 0 if not
+*/
+
+static int
+Hostselect (int line)
+{
+  XawListReturnStruct	*r;
+  HostName		*h;
+  r = XawListShowCurrent (list);
+  /* Assume the next host is willing */
+  XawListHighlight (list,line);
+  r = XawListShowCurrent (list);
+  /* copied from DoCheckWilling */
+  for (h = hostNamedb; h; h = h->next)
+  {
+    if (!strcmp (r->string, h->fullname))
+    {
+      if (!h->willing)
+	XawListUnhighlight (list);
+      else
+        return 1;
+    }
+  } 
+  return 0; 
+}
+
+/* 
+  Selectfirst selects the first willing host
+  in the chooser list (so you can select a host without
+  presence of mouse, but with pressing space or return,
+  or XK_Down / XK_Up
+*/
+
+static void
+Selectfirst (void)
+{
+  int line;
+  
+  for (line = 0; line < NameTableSize; line++)
+  {
+    if (Hostselect(line))
+      return;
+  }        
+  return;
+}
+
+/*
+  Storeold stores the selected line into global int oldentry
+*/
+
+static void
+Storeold (Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+  oldline = (XawListShowCurrent(list))->list_index;
+}
+
+/*
+  Setold restores the global int oldentry 
+  when you try to select a host with your mouse
+  who is unwilling as follows:
+  <Btn1Down>:     Store() Set() CheckWilling() Setold() \n\
+*/
+
+static void
+Setold (Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+
+  if ( (XawListShowCurrent(list))->list_index == XAW_LIST_NONE && oldline !=
XAW_LIST_NONE)
+    XawListHighlight (list, oldline);
+}
+
+/*
+  HostCycle tries to select the next willing host across
+  the list end and will stop at the first found willing host
+  or after trying all entries.
+*/
+
+static void
+HostCycle(unsigned int line, unsigned int size, KeySym keysym)
+{
+  unsigned int newline = line;
+  /* Do it only once around the chooser list, either direction */
+  while ( (newline = next_line(newline,size,keysym)) != line && newline != -1)
+  {
+    if (Hostselect(newline))
+      return;
+  }
+  /* No other willing host could be found, stay at the old one*/
+  XawListHighlight (list, line);
+  return;
+}
+
+/*
+  Switch_Key handles XK_Up and XK_Down
+  and highlights an appropriate line in the chooser list.
+*/
+
+static void
+Switch_Key (Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+  char strbuf[128];
+  KeySym keysym = 0;
+  static XComposeStatus compose_status = {NULL, 0};
+  XawListReturnStruct	*r;
+
+  XLookupString (&event->xkey, strbuf, sizeof (strbuf),
+                           &keysym, &compose_status);    
+
+  if (keysym != XK_Up && keysym != XK_Down)
+    return;
+
+  r = XawListShowCurrent (list);
+    
+  if (r->list_index == XAW_LIST_NONE)
+    Selectfirst();
+  else
+    HostCycle(r->list_index,NameTableSize,keysym);
+
+  return;
+}
+
+
+
+/*
+  Switch_Btn handles ScrollWheel Forward (Button5) and Backward
+  (Button4) and highlights an appropriate line in the chooser list.
+*/
+
+static void
+Switch_Btn (Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+    XawListReturnStruct	*r;
+    r = XawListShowCurrent (list);
+    
+    if (r->list_index == XAW_LIST_NONE)
+      Selectfirst();
+    else
+      HostCycle(r->list_index,NameTableSize,event->xbutton.button);
+
+  return;
+}
+
+
 /* ARGSUSED */
 static void
 DoAccept (Widget w, XEvent *event, String *params, Cardinal *num_params)
@@ -1058,6 +1227,10 @@
     { "Cancel",	      DoCancel },
     { "CheckWilling", DoCheckWilling },
     { "Ping",	      DoPing },
+    { "KeySwitch",    Switch_Key },
+    { "BtnSwitch",    Switch_Btn },
+    { "Store",	      Storeold },
+    { "Setold",	      Setold },    
 };
 
 int
Comment 1 Thomas Reifferscheid 2004-12-28 09:13:27 UTC
Created attachment 1599 [details] [review]
Patch for chooser.c and Chooser.ad
Comment 2 Alan Coopersmith 2005-03-21 18:18:27 UTC
Since this is a patch against the xdm in the Xorg tree, moving to the Xorg product.
Comment 3 Alan Coopersmith 2005-05-15 12:51:38 UTC
I'll take this.
Comment 4 Alan Coopersmith 2005-05-23 17:07:37 UTC
Created attachment 2754 [details] [review]
Additional change

A small enhancement to original patch to ensure that when the list is longer
than
the current screensize, it's scrolled to show the current selection when you
use
the arrow keys or wheel to change it.
Comment 5 Alan Coopersmith 2005-05-23 17:11:43 UTC
Committed to CVS head - should be included in 6.9 & 7.0 releases:

CVSROOT:	/cvs/xorg
Module name:	xc
Changes by:	alanc@gabe.freedesktop.org	05/05/23 17:10:17

Log message:
  2005-05-23  Alan Coopersmith  <alan.coopersmith@sun.com>
  
  	* programs/xdm/chooser.c:
  	* programs/xdm/Chooser.ad:
  	Bugzilla #2165 <https://bugs.freedesktop.org/show_bug.cgi?id=2165>
  	Patches #1599 & 2754
  	XDM Chooser enhancements: scrollwheel, no mouse (Thomas Reifferscheid)

Modified files:
      ./:
        ChangeLog 
      xc/programs/xdm/:
        Chooser.ad chooser.c 
  
  Revision      Changes    Path
  1.958         +8 -0      xc/ChangeLog
  1.3           +7 -2      xc/programs/xdm/Chooser.ad
  1.3           +199 -1    xc/programs/xdm/chooser.c

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.