update copyright notices
[dana/openbox.git] / openbox / translate.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    translate.c for the Openbox window manager
4    Copyright (c) 2004        Mikael Magnusson
5    Copyright (c) 2003        Ben Jansens
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "openbox.h"
21 #include "mouse.h"
22 #include <glib.h>
23 #include <string.h>
24 #include <stdlib.h>
25
26 static guint translate_modifier(gchar *str)
27 {
28     if (!g_ascii_strcasecmp("Mod1", str) ||
29         !g_ascii_strcasecmp("A", str)) return Mod1Mask;
30     else if (!g_ascii_strcasecmp("Mod2", str)) return Mod2Mask;
31     else if (!g_ascii_strcasecmp("Mod3", str) ||
32              !g_ascii_strcasecmp("M", str)) return Mod3Mask;
33     else if (!g_ascii_strcasecmp("Mod4", str) ||
34              !g_ascii_strcasecmp("W", str)) return Mod4Mask;
35     else if (!g_ascii_strcasecmp("Mod5", str)) return Mod5Mask;
36     else if (!g_ascii_strcasecmp("Control", str) ||
37              !g_ascii_strcasecmp("C", str)) return ControlMask;
38     else if (!g_ascii_strcasecmp("Shift", str) ||
39              !g_ascii_strcasecmp("S", str)) return ShiftMask;
40     g_warning("Invalid modifier '%s' in binding.", str);
41     return 0;
42 }
43
44 gboolean translate_button(const gchar *str, guint *state, guint *button)
45 {
46     gchar **parsed;
47     gchar *l;
48     gint i;
49     gboolean ret = FALSE;
50
51     parsed = g_strsplit(str, "-", -1);
52     
53     /* first, find the button (last token) */
54     l = NULL;
55     for (i = 0; parsed[i] != NULL; ++i)
56         l = parsed[i];
57     if (l == NULL)
58         goto translation_fail;
59
60     /* figure out the mod mask */
61     *state = 0;
62     for (i = 0; parsed[i] != l; ++i) {
63         guint m = translate_modifier(parsed[i]);
64         if (!m) goto translation_fail;
65         *state |= m;
66     }
67
68     /* figure out the button */
69     if (!g_ascii_strcasecmp("Left", l)) *button = 1;
70     else if (!g_ascii_strcasecmp("Middle", l)) *button = 2;
71     else if (!g_ascii_strcasecmp("Right", l)) *button = 3;
72     else if (!g_ascii_strcasecmp("Up", l)) *button = 4;
73     else if (!g_ascii_strcasecmp("Down", l)) *button = 5;
74     else if (!g_ascii_strncasecmp("Button", l, 6)) *button = atoi(l+6);
75     if (!*button) {
76         g_warning("Invalid button '%s' in pointer binding.", l);
77         goto translation_fail;
78     }
79
80     ret = TRUE;
81
82 translation_fail:
83     g_strfreev(parsed);
84     return ret;
85 }
86
87 gboolean translate_key(const gchar *str, guint *state, guint *keycode)
88 {
89     gchar **parsed;
90     gchar *l;
91     gint i;
92     gboolean ret = FALSE;
93     KeySym sym;
94
95     parsed = g_strsplit(str, "-", -1);
96     
97     /* first, find the key (last token) */
98     l = NULL;
99     for (i = 0; parsed[i] != NULL; ++i)
100         l = parsed[i];
101     if (l == NULL)
102         goto translation_fail;
103
104     /* figure out the mod mask */
105     *state = 0;
106     for (i = 0; parsed[i] != l; ++i) {
107         guint m = translate_modifier(parsed[i]);
108         if (!m) goto translation_fail;
109         *state |= m;
110     }
111
112     if (!g_ascii_strncasecmp("0x", l, 2)) {
113         gchar *end;
114
115         /* take it directly */
116         *keycode = strtol(l, &end, 16);
117         if (*l == '\0' || *end != '\0') {
118             g_warning("Invalid key code '%s' in key binding.", l);
119             goto translation_fail;
120         }
121     } else {
122         /* figure out the keycode */
123         sym = XStringToKeysym(l);
124         if (sym == NoSymbol) {
125             g_warning("Invalid key name '%s' in key binding.", l);
126             goto translation_fail;
127         }
128         *keycode = XKeysymToKeycode(ob_display, sym);
129     }
130     if (!*keycode) {
131         g_warning("Key '%s' does not exist on the display.", l); 
132         goto translation_fail;
133     }
134
135     ret = TRUE;
136
137 translation_fail:
138     g_strfreev(parsed);
139     return ret;
140 }