[Pkg-wmaker-commits] [wmix] 26/44: wmix: added function to handle Multimedia keys related to volume

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Sep 29 10:40:14 UTC 2017


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

dtorrance-guest pushed a commit to branch upstream
in repository wmix.

commit 3d82c7ab18af993e4f215c14cf41272864e3b000
Author: Christophe CURIS <christophe.curis at free.fr>
Date:   Sat Jun 7 21:21:54 2014 +0200

    wmix: added function to handle Multimedia keys related to volume
    
    We can handle the keys AudioRaiseVolume, AudioLowerVolume and AudioMute,
    so we ask the X server to send the key press event for them to us and
    update the volume appropriately.
    
    Signed-off-by: Christophe CURIS <christophe.curis at free.fr>
---
 Makefile                       |   2 +-
 include/common.h               |   8 ++
 include/{common.h => mmkeys.h} |  29 ++++---
 mmkeys.c                       | 168 +++++++++++++++++++++++++++++++++++++++++
 wmix.1x                        |   4 +-
 wmix.c                         |  37 +++++++++
 6 files changed, 231 insertions(+), 17 deletions(-)

diff --git a/Makefile b/Makefile
index f7a44b7..8f9a2eb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC		= gcc
 CFLAGS		= -O3 -W -Wall
 LDFLAGS		= -L/usr/X11R6/lib
 LIBS		= -lXpm -lXext -lX11 -lm
-OBJECTS		= misc.o config.o mixer-oss.o ui_x.o wmix.o
+OBJECTS		= misc.o config.o mixer-oss.o ui_x.o mmkeys.o wmix.o
 
 # where to install this program (also for packaging stuff)
 PREFIX		= /usr/local
diff --git a/include/common.h b/include/common.h
index 8d9b303..6d6e895 100644
--- a/include/common.h
+++ b/include/common.h
@@ -33,3 +33,11 @@ typedef unsigned int bool;
 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
 
 #define MAX_DOUBLE_CLICK_TIME 0.5
+
+/*
+ * Get the number of element in a static array
+ *
+ * Do not use on an allocated array, it will not work
+ */
+#define lengthof(arr)  \
+	((ssize_t)(sizeof( arr ) / sizeof( arr[0] )))
diff --git a/include/common.h b/include/mmkeys.h
similarity index 58%
copy from include/common.h
copy to include/mmkeys.h
index 8d9b303..2d0fc99 100644
--- a/include/common.h
+++ b/include/mmkeys.h
@@ -1,7 +1,5 @@
-/* WMix 3.0 -- a mixer using the OSS mixer API.
- * Copyright (C) 2000, 2001
- *	Daniel Richard G. <skunk at mit.edu>,
- *	timecop <timecop at japan.co.jp>
+/* WMix -- a mixer using the OSS mixer API
+ * Copyright (C)2014 Christophe CURIS for the WindowMaker Team
  *
  * 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
@@ -17,19 +15,20 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+/* include/mmkeys.h: functions related to handling Multimedia keys */
 
-typedef unsigned int bool;
+#ifndef WMIX_MMKEYS_H
+#define WMIX_MMKEYS_H
 
-#define false 0
-#define true (!false)
 
-#define NULL_CURSOR 1
-#define NORMAL_CURSOR 2
-#define HAND_CURSOR 3
-#define BAR_CURSOR 4
+/* Global Configuration */
+extern struct multimedia_keys {
+	KeyCode raise_volume;
+	KeyCode lower_volume;
+	KeyCode mute;
+} mmkeys;
 
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+/* Grab the multimedia keys */
+void mmkey_install(Display *display);
 
-#define MAX_DOUBLE_CLICK_TIME 0.5
+#endif	/* WMIX_MMKEYS_H */
diff --git a/mmkeys.c b/mmkeys.c
new file mode 100644
index 0000000..bc22625
--- /dev/null
+++ b/mmkeys.c
@@ -0,0 +1,168 @@
+/* WMix -- a mixer using the OSS mixer API.
+ * Copyright (C) 2014 Christophe CURIS for the WindowMaker Team
+ *
+ * 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 of the License, 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * mmkeys.c: functions related to grabing the Multimedia Keys on keyboard
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
+
+#include "include/common.h"
+#include "include/config.h"
+#include "include/mmkeys.h"
+
+
+/* The global configuration */
+struct multimedia_keys mmkeys;
+
+/* The list of keys we're interrested in */
+static const struct {
+	KeySym  symbol;
+	KeyCode *store;
+	const char *name;
+} key_list[] = {
+	{ XF86XK_AudioRaiseVolume, &mmkeys.raise_volume, "AudioRaiseVolume" },
+	{ XF86XK_AudioLowerVolume, &mmkeys.lower_volume, "AudioLowerVolume" },
+	{ XF86XK_AudioMute,        &mmkeys.mute,         "AudioMute"        }
+};
+
+/* The modifiers that should not have impact on the key grabbed */
+static const struct {
+	KeySym symbol;
+	const char *name;
+} modifier_symbol[] = {
+	{ XK_Caps_Lock, "CapsLock" },
+	{ XK_Num_Lock,  "NumLock"  }
+};
+
+typedef struct {
+	int count;
+	unsigned int list[1 << lengthof(modifier_symbol)];
+} modifier_masks;
+
+/* Local functions */
+static void mmkey_build_modifier_list(Display *display, modifier_masks *result);
+
+
+/*
+ * Grab the multimedia keys on the X server
+ *
+ * That basically means that whenever these keys are pressed
+ * the events will be sent to us instead of the application
+ * that has current focus.
+ */
+void mmkey_install(Display *display)
+{
+	modifier_masks mod_masks;
+	Window root_window;
+	int i, j;
+
+	mmkey_build_modifier_list(display, &mod_masks);
+
+	root_window = DefaultRootWindow(display);
+
+	for (i = 0; i < lengthof(key_list); i++) {
+		KeyCode key;
+
+		key = XKeysymToKeycode(display, key_list[i].symbol);
+		*(key_list[i].store) = key;
+
+		if (key == None)
+			continue;
+
+		for (j = 0; j < mod_masks.count; j++) {
+			XGrabKey(display, key, mod_masks.list[j], root_window,
+			         False, GrabModeAsync, GrabModeAsync);
+		}
+		if (config.verbose)
+			printf("Found multimedia key: %s\n", key_list[i].name);
+	}
+}
+
+/*
+ * Build the list of bit-masks for all the modifiers we want to not have impact on our grab
+ */
+static void mmkey_build_modifier_list(Display *display, modifier_masks *result)
+{
+	XModifierKeymap *mods;
+	KeyCode mod_code[lengthof(modifier_symbol)];
+	unsigned int mod_mask[lengthof(modifier_symbol)];
+	char buffer[256];
+	int nb_modifiers;
+	int i, j, k;
+
+	/* Get the bitmask associated with the modifiers */
+	for (i = 0; i < lengthof(modifier_symbol); i++) {
+		mod_code[i] = XKeysymToKeycode(display, modifier_symbol[i].symbol);
+		mod_mask[i] = 0L;
+	}
+
+	mods = XGetModifierMapping(display);
+	for (i = 0; i < 8; i++) {
+		for (j = 0; j < mods->max_keypermod; j++) {
+			KeyCode key_mod;
+
+			key_mod = mods->modifiermap[i * mods->max_keypermod + j];
+			for (k = 0; k < lengthof(mod_code); k++) {
+				if ((mod_code[k] != None) && (key_mod == mod_code[k]))
+					mod_mask[k] |= 1 << i;
+			}
+		}
+	}
+	XFreeModifiermap(mods);
+
+	/* Count the number of modifiers found (and display the list to the user) */
+	if (config.verbose)
+		strcpy(buffer, "Found key modifiers: ");
+
+	nb_modifiers = 0;
+	for (i = 0; i < lengthof(modifier_symbol); i++) {
+		if (mod_mask[i] != 0) {
+			if (config.verbose) {
+				if (nb_modifiers > 0)
+					strcat(buffer, ", ");
+				strcat(buffer, modifier_symbol[i].name);
+			}
+			nb_modifiers++;
+		}
+	}
+	if (config.verbose) {
+		if (nb_modifiers == 0)
+			strcat(buffer, "None");
+		puts(buffer);
+	}
+
+	/* Build the list of possible combinations of modifiers */
+	result->count = 1 << nb_modifiers;
+	for (i = 0; i < lengthof(result->list); i++)
+		result->list[i] = 0L;
+	k = 1;
+	for (i = 0; i < lengthof(mod_mask); i++) {
+		if (mod_mask[i] != 0) {
+			for (j = 1; j < result->count; j++)
+				if (j & k)
+					result->list[j] |= mod_mask[i];
+
+			k <<= 1;
+		}
+	}
+}
diff --git a/wmix.1x b/wmix.1x
index e077f21..117f42e 100644
--- a/wmix.1x
+++ b/wmix.1x
@@ -15,7 +15,8 @@ Allows toggling record source,
 muting individual channels, adjusting volume and balance, all in a
 compact dockapp size, with TV\-like on\-screen\-display for volume levels.
 .LP
-Supports mouse wheel to adjust current channel's volume
+Supports mouse wheel to adjust current channel's volume,
+supports also the volume control keys on \(lqmultimedia\(rq keyboards
 and can be controlled remotely with unix signals
 .IR SIGUSR1 / SIGUSR2
 to raise/lower the volume.
@@ -144,3 +145,4 @@ It was expanded by Christophe CURIS for the Window Maker Dev Team.
 .PP
 wmix was written by Tim, timecop <timecop at japan.co.jp>,
 with some code by Daniel Richard G. <skunk at mit.edu>
+and some addition by Christophe CURIS.
diff --git a/wmix.c b/wmix.c
index 1f7ddab..ae8bce5 100644
--- a/wmix.c
+++ b/wmix.c
@@ -37,6 +37,7 @@
 #include "include/mixer.h"
 #include "include/misc.h"
 #include "include/ui_x.h"
+#include "include/mmkeys.h"
 #include "include/config.h"
 
 
@@ -55,6 +56,7 @@ static int idle_loop;
 static void signal_catch(int sig);
 static void button_press_event(XButtonEvent *event);
 static void button_release_event(XButtonEvent *event);
+static int  key_press_event(XKeyEvent *event);
 static void motion_event(XMotionEvent *event);
 
 
@@ -91,6 +93,7 @@ int main(int argc, char **argv)
     dockapp_init(display);
     new_window("wmix", 64, 64);
     new_osd(DisplayWidth(display, DefaultScreen(display)) - 200, 60);
+    mmkey_install(display);
 
     config_release();
 
@@ -116,6 +119,10 @@ int main(int argc, char **argv)
 	if (button_pressed || slider_pressed || (XPending(display) > 0)) {
 	    XNextEvent(display, &event);
 	    switch (event.type) {
+		case KeyPress:
+		    if (key_press_event(&event.xkey))
+			idle_loop = 0;
+		    break;
 		case Expose:
 		    redraw_window();
 		    break;
@@ -276,6 +283,36 @@ static void button_press_event(XButtonEvent *event)
     }
 }
 
+static int key_press_event(XKeyEvent *event)
+{
+	if (event->keycode == mmkeys.raise_volume) {
+		mixer_set_volume_rel(config.scrollstep);
+		if (!osd_mapped())
+			map_osd();
+		if (osd_mapped())
+			update_osd(mixer_get_volume(), false);
+		ui_update();
+		return 1;
+	}
+	if (event->keycode == mmkeys.lower_volume) {
+		mixer_set_volume_rel(-config.scrollstep);
+		if (!osd_mapped())
+			map_osd();
+		if (osd_mapped())
+			update_osd(mixer_get_volume(), false);
+		ui_update();
+		return 1;
+	}
+	if (event->keycode == mmkeys.mute) {
+		mixer_toggle_mute();
+		ui_update();
+		return 1;
+	}
+
+	/* Ignore other keys */
+	return 0;
+}
+
 static void button_release_event(XButtonEvent *event)
 {
     int x = event->x;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmix.git



More information about the Pkg-wmaker-commits mailing list