[Xfce4-commits] [panel-plugins/xfce4-xkb-plugin] 05/06: Display capslock state with system style

noreply at xfce.org noreply at xfce.org
Thu Jun 22 09:54:43 CEST 2017


This is an automated email from the git hooks/post-receive script.

n   i   n   e   t   l   s       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository panel-plugins/xfce4-xkb-plugin.

commit 79d87c40bfe8126600bf5d861afe8f04dce9b985
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Thu Jun 22 03:11:43 2017 +0300

    Display capslock state with system style
---
 panel-plugin/Makefile.am    |   1 +
 panel-plugin/xkb-cairo.c    |  15 ++++
 panel-plugin/xkb-cairo.h    |   1 +
 panel-plugin/xkb-modifier.c | 190 ++++++++++++++++++++++++++++++++++++++++++++
 panel-plugin/xkb-modifier.h |  48 +++++++++++
 panel-plugin/xkb-plugin.c   |  24 ++++++
 6 files changed, 279 insertions(+)

diff --git a/panel-plugin/Makefile.am b/panel-plugin/Makefile.am
index 2e7d698..d341721 100644
--- a/panel-plugin/Makefile.am
+++ b/panel-plugin/Makefile.am
@@ -9,6 +9,7 @@ plugin_LTLIBRARIES = \
 libxkb_la_SOURCES = \
 	xkb-plugin.c \
 	xkb-keyboard.c \
+	xkb-modifier.c \
 	xkb-dialog.c \
 	xkb-xfconf.c \
 	xkb-cairo.c \
diff --git a/panel-plugin/xkb-cairo.c b/panel-plugin/xkb-cairo.c
index 106f1aa..135dd22 100644
--- a/panel-plugin/xkb-cairo.c
+++ b/panel-plugin/xkb-cairo.c
@@ -230,6 +230,7 @@ xkb_cairo_draw_label_system (cairo_t                    *cr,
                              gint                        actual_width,
                              gint                        actual_height,
                              gint                        variant_markers_count,
+                             gboolean                    capslock_enabled,
                              const PangoFontDescription *desc,
                              GdkRGBA                     rgba)
 {
@@ -278,6 +279,20 @@ xkb_cairo_draw_label_system (cairo_t                    *cr,
       cairo_fill (cr);
     }
 
+  if (capslock_enabled)
+    {
+      y = layouty - radius;
+
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+      cairo_set_line_width (cr, 1);
+      cairo_arc (cr, layoutx + radius, y, radius, 0, 2 * G_PI);
+      cairo_fill (cr);
+      cairo_arc (cr, layoutx + pango_width - radius, y, radius, 0, 2 * G_PI);
+      cairo_fill (cr);
+      cairo_rectangle (cr, layoutx + radius, layouty - diameter, pango_width - diameter, diameter);
+      cairo_fill (cr);
+    }
+
   g_free (normalized_group_name);
   g_object_unref (layout);
 }
diff --git a/panel-plugin/xkb-cairo.h b/panel-plugin/xkb-cairo.h
index f6dbcd5..d90b70d 100644
--- a/panel-plugin/xkb-cairo.h
+++ b/panel-plugin/xkb-cairo.h
@@ -51,6 +51,7 @@ void        xkb_cairo_draw_label_system     (cairo_t                        *cr,
                                              gint                            actual_width,
                                              gint                            actual_height,
                                              gint                            variant_markers_count,
+                                             gboolean                        capslock_enabled,
                                              const PangoFontDescription     *desc,
                                              GdkRGBA                         rgba);
 
diff --git a/panel-plugin/xkb-modifier.c b/panel-plugin/xkb-modifier.c
new file mode 100644
index 0000000..0c51bb2
--- /dev/null
+++ b/panel-plugin/xkb-modifier.c
@@ -0,0 +1,190 @@
+/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
+/* xkb-modifier.c
+ * Copyright (C) 2017 Alexander Iliev <sasoiliev at mamul.org>
+ *
+ * Parts of this program comes from the XfKC tool:
+ * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "xkb-modifier.h"
+
+#include <gdk/gdk.h>
+#include <X11/XKBlib.h>
+#include <X11/keysym.h>
+
+struct _XkbModifierClass
+{
+  GObjectClass         __parent__;
+};
+
+struct _XkbModifier
+{
+  GObject              __parent__;
+
+  gint                 xkb_event_type;
+  gboolean             capslock_enabled;
+};
+
+static GdkFilterReturn   xkb_modifier_handle_xevent            (GdkXEvent            *xev,
+                                                                GdkEvent             *event,
+                                                                gpointer              user_data);
+
+static void              xkb_modifier_finalize                 (GObject              *object);
+
+enum
+{
+  MODIFIER_CHANGED,
+  LAST_SIGNAL
+};
+
+static guint xkb_modifier_signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE (XkbModifier, xkb_modifier, G_TYPE_OBJECT)
+
+
+
+static void
+xkb_modifier_class_init (XkbModifierClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xkb_modifier_finalize;
+
+  xkb_modifier_signals[MODIFIER_CHANGED] =
+    g_signal_new (g_intern_static_string ("modifier-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+}
+
+
+
+static void
+xkb_modifier_init (XkbModifier *modifier)
+{
+  modifier->xkb_event_type = 0;
+  modifier->capslock_enabled = FALSE;
+}
+
+
+
+XkbModifier *
+xkb_modifier_new (void)
+{
+  XkbModifier *modifier;
+  Display     *display;
+  XkbDescRec  *xkb_desc;
+  gint         i, states, capslock_mask;
+  gchar       *atom_name;
+
+  modifier = g_object_new (TYPE_XKB_MODIFIER, NULL);
+
+  /* obtain xkb_event type and capslock state */
+  display = XOpenDisplay (NULL);
+  if (display != NULL)
+    {
+      XkbDescRec *xkb_desc = XkbGetKeyboard (display, XkbAllComponentsMask, XkbUseCoreKbd);
+      if (xkb_desc != NULL)
+        {
+          for (i = 0; i < XkbNumIndicators; i++)
+            {
+              if (xkb_desc->names->indicators[i])
+                {
+                  atom_name = XGetAtomName (display, xkb_desc->names->indicators[i]);
+                  if (g_strcmp0 (atom_name, "Caps Lock") == 0)
+                    {
+                      if (XkbGetIndicatorState (display, XkbUseCoreKbd, &states) == Success)
+                        {
+                          capslock_mask = 1 << i;
+                          modifier->capslock_enabled = (states & capslock_mask) == capslock_mask;
+                        }
+
+                      break;
+                    }
+                }
+             }
+
+          XkbFreeKeyboard(xkb_desc, 0, True);
+        }
+
+      XkbQueryExtension(display, NULL, &modifier->xkb_event_type, NULL, NULL, NULL);
+      XCloseDisplay(display);
+    }
+
+  gdk_window_add_filter (NULL, xkb_modifier_handle_xevent, modifier);
+
+  return modifier;
+}
+
+
+
+static void
+xkb_modifier_finalize (GObject *object)
+{
+  XkbModifier *modifier = XKB_MODIFIER (object);
+
+  gdk_window_remove_filter (NULL, xkb_modifier_handle_xevent, modifier);
+
+  G_OBJECT_CLASS (xkb_modifier_parent_class)->finalize (object);
+}
+
+
+
+static GdkFilterReturn
+xkb_modifier_handle_xevent (GdkXEvent *xev,
+                            GdkEvent  *event,
+                            gpointer   user_data)
+{
+  XkbModifier         *modifier = user_data;
+  Display             *display;
+  XkbStateNotifyEvent *state_event = xev;
+  gint                 modifier_flags;
+
+  if (modifier->xkb_event_type != 0 &&
+      state_event->type == modifier->xkb_event_type &&
+      state_event->xkb_type == XkbStateNotify &&
+      state_event->changed & XkbModifierLockMask)
+    {
+      display = XOpenDisplay (NULL);
+
+      if (display != NULL)
+        {
+          modifier_flags = XkbKeysymToModifiers (display, XK_Caps_Lock);
+          modifier->capslock_enabled = (state_event->locked_mods & modifier_flags) == modifier_flags;
+          XCloseDisplay (display);
+
+          g_signal_emit (G_OBJECT (modifier),
+                         xkb_modifier_signals[MODIFIER_CHANGED],
+                         0, FALSE);
+        }
+    }
+
+  return GDK_FILTER_CONTINUE;
+}
+
+
+
+gboolean
+xkb_modifier_get_capslock_enabled (XkbModifier *modifier)
+{
+  g_return_val_if_fail (IS_XKB_MODIFIER (modifier), 0);
+
+  return modifier->capslock_enabled;
+}
diff --git a/panel-plugin/xkb-modifier.h b/panel-plugin/xkb-modifier.h
new file mode 100644
index 0000000..c5a4970
--- /dev/null
+++ b/panel-plugin/xkb-modifier.h
@@ -0,0 +1,48 @@
+/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
+/* xkb-keyboard.h
+ * Copyright (C) 2008 Alexander Iliev <sasoiliev at mamul.org>
+ *
+ * Parts of this program comes from the XfKC tool:
+ * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _xkb_modifier_H_
+#define _xkb_modifier_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XkbModifierClass      XkbModifierClass;
+typedef struct _XkbModifier           XkbModifier;
+
+#define TYPE_XKB_MODIFIER             (xkb_modifier_get_type ())
+#define XKB_MODIFIER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_XKB_MODIFIER, XkbModifier))
+#define XKB_MODIFIER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  TYPE_XKB_MODIFIER, XkbModifierClass))
+#define IS_XKB_MODIFIER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_XKB_MODIFIER))
+#define IS_XKB_MODIFIER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  TYPE_XKB_MODIFIER))
+#define XKB_MODIFIER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  TYPE_XKB_MODIFIER, XkbModifier))
+
+GType             xkb_modifier_get_type                     (void)                           G_GNUC_CONST;
+
+XkbModifier      *xkb_modifier_new                          (void);
+
+gboolean          xkb_modifier_get_capslock_enabled         (XkbModifier     *modifier);
+
+G_END_DECLS
+
+#endif
diff --git a/panel-plugin/xkb-plugin.c b/panel-plugin/xkb-plugin.c
index 45b28e4..ccf3e3e 100644
--- a/panel-plugin/xkb-plugin.c
+++ b/panel-plugin/xkb-plugin.c
@@ -34,6 +34,7 @@
 #include "xkb-plugin.h"
 #include "xkb-properties.h"
 #include "xkb-keyboard.h"
+#include "xkb-modifier.h"
 #include "xkb-dialog.h"
 #include "xkb-cairo.h"
 
@@ -54,6 +55,7 @@ struct _XkbPlugin
     
   XkbXfconf           *config;
   XkbKeyboard         *keyboard;
+  XkbModifier         *modifier;
 
   GtkWidget           *button;
   GtkWidget           *layout_image;
@@ -81,6 +83,8 @@ static void         xkb_plugin_configure_plugin         (XfcePanelPlugin *plugin
 static void         xkb_plugin_state_changed            (XkbPlugin        *plugin,
                                                          gboolean          config_changed);
 
+static void         xkb_plugin_modifier_changed         (XkbPlugin        *plugin);
+
 static gboolean     xkb_plugin_calculate_sizes          (XkbPlugin        *plugin,
                                                          GtkOrientation    orientation,
                                                          gint              panel_size);
@@ -149,6 +153,7 @@ xkb_plugin_init (XkbPlugin *plugin)
 {
   plugin->config = NULL;
   plugin->keyboard = NULL;
+  plugin->modifier = NULL;
 
   plugin->button = NULL;
   plugin->layout_image = NULL;
@@ -240,6 +245,13 @@ xkb_plugin_construct (XfcePanelPlugin *plugin)
       xkb_plugin_popup_menu_populate (xkb_plugin);
     }
 
+  xkb_plugin->modifier = xkb_modifier_new ();
+
+  g_signal_connect_swapped (G_OBJECT (xkb_plugin->modifier),
+                            "modifier-changed",
+                            G_CALLBACK (xkb_plugin_modifier_changed),
+                            xkb_plugin);
+
   xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
 
   xfce_panel_plugin_menu_show_configure (plugin);
@@ -290,6 +302,7 @@ xkb_plugin_free_data (XfcePanelPlugin *plugin)
   gtk_widget_destroy (xkb_plugin->layout_image);
   gtk_widget_destroy (xkb_plugin->button);
 
+  g_object_unref (G_OBJECT (xkb_plugin->modifier));
   g_object_unref (G_OBJECT (xkb_plugin->keyboard));
   g_object_unref (G_OBJECT (xkb_plugin->config));
 }
@@ -327,6 +340,14 @@ xkb_plugin_state_changed (XkbPlugin *plugin,
 
 
 static void
+xkb_plugin_modifier_changed (XkbPlugin *plugin)
+{
+  xkb_plugin_refresh_gui (plugin);
+}
+
+
+
+static void
 xkb_plugin_set_group (GtkMenuItem *item,
                       gpointer     data)
 {
@@ -631,6 +652,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
   XkbDisplayType        display_type;
   XkbDisplayName        display_name;
   gint                  display_scale;
+  gboolean              capslock_enabled;
 
   display_type = xkb_xfconf_get_display_type (plugin->config);
   display_name = xkb_xfconf_get_display_name (plugin->config);
@@ -647,6 +669,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
   group_name = xkb_keyboard_get_group_name (plugin->keyboard, display_name, -1);
   pixbuf = xkb_keyboard_get_pixbuf (plugin->keyboard, FALSE, -1);
   variant_index = xkb_keyboard_get_variant_index (plugin->keyboard, display_name, -1);
+  capslock_enabled = xkb_modifier_get_capslock_enabled (plugin->modifier);
 
   if (pixbuf == NULL && display_type == DISPLAY_TYPE_IMAGE)
     display_type = DISPLAY_TYPE_TEXT;
@@ -677,6 +700,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
       xkb_cairo_draw_label_system (cr, group_name,
                                    actual_hsize, actual_vsize,
                                    variant_index,
+                                   capslock_enabled,
                                    desc, rgba);
       break;
     }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list