Alexander Pyhalov
2017-05-01 3320dfd7a50b10851cef1649d8a4e2544d4a38e5
xscreensaver: show current xkb layout (#3017)

1 files added
1 files modified
225 ■■■■■ changed files
components/desktop/xscreensaver/Makefile 11 ●●●●● patch | view | raw | blame | history
components/desktop/xscreensaver/patches/xscreensaver-26-keyboard-indicator.patch 214 ●●●●● patch | view | raw | blame | history
components/desktop/xscreensaver/Makefile
@@ -1,21 +1,23 @@
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL)". You may
# only use this file in accordance with the terms of the CDDL.
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2013 Alexander Pyhalov
# Copyright 2017 Alexander Pyhalov
#
include ../../../make-rules/shared-macros.mk
COMPONENT_NAME=        xscreensaver
COMPONENT_VERSION=    5.35
COMPONENT_REVISION=    1
COMPONENT_PROJECT_URL=    http://www.jwz.org/xscreensaver/
COMPONENT_SRC=        $(COMPONENT_NAME)-$(COMPONENT_VERSION)
COMPONENT_ARCHIVE=    $(COMPONENT_SRC).tar.gz
@@ -117,6 +119,7 @@
REQUIRED_PACKAGES += x11/library/libxft
REQUIRED_PACKAGES += x11/library/libxi
REQUIRED_PACKAGES += x11/library/libxinerama
REQUIRED_PACKAGES += x11/library/libxkbfile
REQUIRED_PACKAGES += x11/library/libxmu
REQUIRED_PACKAGES += x11/library/libxrandr
REQUIRED_PACKAGES += x11/library/libxxf86misc
components/desktop/xscreensaver/patches/xscreensaver-26-keyboard-indicator.patch
New file
@@ -0,0 +1,214 @@
--- driver/lock-Gtk.c.~5~    2017-04-27 21:23:36.284040048 +0300
+++ driver/lock-Gtk.c    2017-04-27 21:24:01.766618624 +0300
@@ -61,9 +61,11 @@
 #include <ctype.h>
 #include <X11/Xos.h>
 #include <X11/Xlib.h>
+#include <X11/XKBlib.h>
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
 #include <X11/Xmu/WinUtil.h>
+#include <X11/extensions/XKBrules.h>
 #include <gconf/gconf-client.h>
 #include <libbonobo.h>
@@ -90,6 +92,7 @@
   GtkWidget *button;
   GtkWidget *msg_label;
   GtkWidget *pam_message_label;
+  GtkWidget *layout_label;
 } PasswdDialog;
 /*Global info */
@@ -100,6 +103,55 @@
 #define FD_TO_PARENT  9
+static int xkb_opcode;
+static int xkb_event_base;
+static int xkb_error_base;
+
+static gchar*
+getGroup()
+{
+  XkbStateRec state;
+  XkbRF_VarDefsRec vd;
+  Display *dpy;
+  XkbDescRec desc[1];
+  int i;
+  gchar *s1 = NULL;
+  char* tmp = NULL;
+
+  dpy = gdk_x11_get_default_xdisplay();
+  memset(desc, 0, sizeof(desc));
+  desc->device_spec = XkbUseCoreKbd;
+  if (XkbGetControls(dpy, XkbGroupsWrapMask, desc) == Success) {
+    if (XkbGetNames(dpy, XkbGroupNamesMask, desc) == Success) {
+      if (XkbGetState(dpy, XkbUseCoreKbd, &state) == Success) {
+        if (XkbRF_GetNamesProp(dpy, &tmp, &vd) && tmp && vd.layout) {
+           char *layout, *t;
+           int j=0;
+
+           layout=strtok_r(vd.layout,",", &t);
+           for(j=0; j<state.group;j++) {
+             layout = strtok_r(NULL, ",", &t);
+             if(layout == NULL)
+               break;
+           }
+           if (layout) {
+            s1 = g_strdup(layout);
+
+            /* debug only
+            fprintf(stderr, "Got group %d %s\n", state.group, s1);
+            fprintf(stderr, "My uid is %d euid is %d\n", getuid(), geteuid());
+            fflush(stderr); */
+
+           }
+        }
+      }
+      XkbFreeNames(desc, XkbGroupNamesMask, True);
+    }
+    XkbFreeControls(desc, XkbGroupsWrapMask, True);
+  }
+  return s1;
+}
+
 /* Send a command to the xscreensaver parent daemon
    Arguments:
     - msg - type of message - "input", "raise_wid", etc.
@@ -179,7 +231,7 @@
   GtkWidget *entry;
   AtkObject *atk_entry;
   GtkWidget *title_label, *msg_label, *prompt_label,
-    *user_label, *date_label, *pam_msg_label;
+    *user_label, *date_label, *pam_msg_label, *layout_label;
   AtkObject *atk_title_label, *atk_prompt_label;
   GtkWidget *button;
   GtkWidget *image;
@@ -274,7 +326,7 @@
             _("Percent of time you have left to unlock the screen."));
   /* text fields */
-  vbox2 = gtk_vbox_new (FALSE, 20);
+  vbox2 = gtk_vbox_new (FALSE, 15);
   gtk_box_pack_start (GTK_BOX (hbox1), vbox2,
                       TRUE, TRUE, 0);
   /* AT role =filler */
@@ -368,6 +420,27 @@
   gtk_box_pack_start (GTK_BOX (vbox2), pam_msg_label, FALSE, FALSE, 0);
+  /* current layout */
+  {
+    gchar *s1;
+
+    s1 = getGroup();
+    if (s1) {
+      s = g_markup_printf_escaped ("<small>Layout: %s</small>", s1);
+      g_free(s1);
+    } else {
+      s = g_strdup("");
+    }
+    layout_label = g_object_new (GTK_TYPE_LABEL,
+                                 "use-markup", TRUE,
+                                 "label", s,
+                                 NULL);
+    pwd->layout_label = layout_label;
+    gtk_box_pack_start (GTK_BOX (vbox2), layout_label,
+                                    FALSE, FALSE, 0);
+    g_free(s);
+  }
+
   /* date string */
   tm = localtime (&now);
   memset (buf, 0, sizeof (buf));
@@ -464,6 +537,53 @@
 }
 static GdkFilterReturn
+xkb_filter_func (GdkXEvent *xevent, GdkEvent *gevent, gpointer data)
+{
+  PasswdDialog *pwd = data;
+  XEvent *event = xevent;
+
+  if (event->xany.type == xkb_event_base + XkbEventCode) {
+
+     /* debug only
+     fprintf(stderr, "Got xkb event\n");
+     fflush(stderr); */
+
+     /* Xkb event. */
+      XkbEvent * xkbev = (XkbEvent *) event;
+      if (xkbev->any.xkb_type == XkbStateNotify)
+      {
+          gchar *group;
+
+          /* debug only
+          fprintf(stderr, "Got XkbStateNotify event\n");
+          fflush(stderr); */
+          group = getGroup();
+
+          if (group) {
+            char * s;
+
+            s = g_markup_printf_escaped ("<small>Layout: %s</small>", group);
+            gtk_label_set_markup (GTK_LABEL (pwd->layout_label), s);
+
+            /* debug only
+            fprintf(stderr, "Got group %s\n", group);
+            fflush (stderr); */
+
+            g_free (s);
+
+            g_free(group);
+          } /* debug only else {
+            fprintf(stderr, "Got empty group\n");
+            fflush(stderr);
+          }  */
+      }
+  }
+
+  return GDK_FILTER_CONTINUE;
+}
+
+
+static GdkFilterReturn
 dialog_filter_func (GdkXEvent *xevent, GdkEvent *gevent, gpointer data)
 {
   PasswdDialog *pwd = data;
@@ -716,6 +836,16 @@
     request_atoms (dpy, atom_lists);
   }
+  /* Init XKB extension */
+  {
+    Display *dpy = gdk_x11_get_default_xdisplay ();
+
+    if(XkbQueryExtension (dpy, &xkb_opcode, &xkb_event_base, &xkb_error_base,
+                      NULL, NULL)!=True){
+         g_warning ("Couldn't find XKB extension\n");
+    }
+  }
+
   /* bugid 6346056(P1):
      ATOK pallet sometimes appears in screensave/lock-screen mode
   */
@@ -773,6 +903,7 @@
   gdk_display_sync (gtk_widget_get_display (pwd->dialog));
+  gdk_window_add_filter (NULL, xkb_filter_func, pwd);
   gdk_window_add_filter (GET_WINDOW (pwd->dialog), dialog_filter_func, pwd);
   write_windowid ("dialog_win", GDK_WINDOW_XID (GET_WINDOW (pwd->dialog)));
--- driver/Makefile.in.1    2017-04-27 11:30:28.951331543 +0300
+++ driver/Makefile.in    2017-04-27 11:31:24.174573370 +0300
@@ -827,7 +827,7 @@
     $(CC) $(LDFLAGS) -o $@ $(GTK_LOCK_OBJS) $(LIBS) $(X_LIBS) \
     $(TRUSTED_OBJS) $(TRUSTED_LIBS) \
     $(GTK_LIBS) $(XML_LIBS) $(X_PRE_LIBS) -lXt -lX11 \
-    $(XDPMS_LIBS) -lXext \
+    $(XDPMS_LIBS) -lXext -lxkbfile \
     $(X_EXTRA_LIBS)
 xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS)