swat 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2007 Hemant Kumar ( mail [at] gnufied [dot] org )
2
+
3
+ The Library is dual licensed under terms of Ruby License or MIT License.
data/README ADDED
@@ -0,0 +1,18 @@
1
+ Swat is a todo list manager for Gnome & Emacs.
2
+
3
+ Heck : Emacs?
4
+
5
+ Features:
6
+ - Manage your todos, add them according to priority and category.
7
+ - Move your todos to wish list, when not feeling like working on them.
8
+ - libtomboy bindings for global shortcut(Alt-F11).
9
+ - Nice stats for your number of tasks finished and added.
10
+ - All your todos are in a .org file and hence can be managed from
11
+ Emacs as well.
12
+
13
+ KeyBindings:
14
+ - Alt-F11 : from anywhere, brings the todo window to front.
15
+ - Esc : do dismiss todo window.
16
+ - Control-N : to add a todo.
17
+
18
+
data/TODO ADDED
File without changes
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require 'libglade2'
5
+ require "erb"
6
+ require "yaml"
7
+ require "ostruct"
8
+ require "enumerator"
9
+ SWAT_APP = File.expand_path(File.dirname(__FILE__)+"/..")
10
+ ["lib","ext"].each { |x| $LOAD_PATH.unshift("#{SWAT_APP}/#{x}"); }
11
+
12
+ require "list_helper"
13
+ require "stat_box"
14
+ require "swat_meta_data"
15
+ require "todo_context_menu"
16
+ require "todo_window"
17
+ require "keybinder"
18
+ require "todo_data"
19
+ require "add_todo_dialog"
20
+ require "wish_list"
21
+ require "swat"
22
+
23
+ Swat::SwatMain.new
24
+ Gtk.main
@@ -0,0 +1,149 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = /usr/local/lib/ruby/1.8/i686-linux
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir):$(topdir):$(hdrdir)
10
+ prefix = $(DESTDIR)/usr/local
11
+ exec_prefix = $(prefix)
12
+ sitedir = $(prefix)/lib/ruby/site_ruby
13
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
14
+ docdir = $(datarootdir)/doc/$(PACKAGE)
15
+ dvidir = $(docdir)
16
+ datarootdir = $(prefix)/share
17
+ archdir = $(rubylibdir)/$(arch)
18
+ sbindir = $(exec_prefix)/sbin
19
+ psdir = $(docdir)
20
+ localedir = $(datarootdir)/locale
21
+ htmldir = $(docdir)
22
+ datadir = $(datarootdir)
23
+ includedir = $(prefix)/include
24
+ infodir = $(datarootdir)/info
25
+ sysconfdir = $(prefix)/etc
26
+ mandir = $(datarootdir)/man
27
+ libdir = $(exec_prefix)/lib
28
+ sharedstatedir = $(prefix)/com
29
+ oldincludedir = $(DESTDIR)/usr/include
30
+ pdfdir = $(docdir)
31
+ sitearchdir = $(sitelibdir)/$(sitearch)
32
+ bindir = $(exec_prefix)/bin
33
+ localstatedir = $(prefix)/var
34
+ sitelibdir = $(sitedir)/$(ruby_version)
35
+ libexecdir = $(exec_prefix)/libexec
36
+
37
+ CC = gcc
38
+ LIBRUBY = $(LIBRUBY_A)
39
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
40
+ LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir)
41
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
42
+
43
+ RUBY_EXTCONF_H =
44
+ CFLAGS = -fPIC -g -O2 -Wall -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gtk-unix-print-2.0 -I/usr/include/gtk-2.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng12
45
+ INCFLAGS = -I. -I. -I/usr/local/lib/ruby/1.8/i686-linux -I.
46
+ CPPFLAGS = -DHAVE_RB_DEFINE_ALLOC_FUNC -DHAVE_RB_BLOCK_PROC -DHAVE_OBJECT_ALLOCATE -DHAVE_NODE_ATTRASGN -DRUBY_GTK2_TARGET=\"x11\" -DHAVE_GTK_PLUG_GET_TYPE -DHAVE_GTK_SOCKET_GET_TYPE -DHAVE_PANGO_RENDER_PART_GET_TYPE -DHAVE_XREADBITMAPFILEDATA -DHAVE_X11_XLIB_H -DHAVE_XGETERRORTEXT -DHAVE_GTK_PRINT_UNIX_DIALOG_GET_TYPE -DHAVE_GTK_PRINT_JOB_GET_TYPE -DHAVE_GTK_PRINTER_GET_TYPE -I/usr/local/lib/ruby/site_ruby/1.8/i686-linux
47
+ CXXFLAGS = $(CFLAGS)
48
+ DLDFLAGS = -L. -rdynamic -Wl,-export-dynamic -pthread
49
+ LDSHARED = $(CC) -shared
50
+ AR = ar
51
+ EXEEXT =
52
+
53
+ RUBY_INSTALL_NAME = ruby
54
+ RUBY_SO_NAME = ruby
55
+ arch = i686-linux
56
+ sitearch = i686-linux
57
+ ruby_version = 1.8
58
+ ruby = /usr/local/bin/ruby
59
+ RUBY = $(ruby)
60
+ RM = rm -f
61
+ MAKEDIRS = mkdir -p
62
+ INSTALL = /usr/bin/install -c
63
+ INSTALL_PROG = $(INSTALL) -m 0755
64
+ INSTALL_DATA = $(INSTALL) -m 644
65
+ COPY = cp
66
+
67
+ #### End of system configuration section. ####
68
+
69
+ preload =
70
+
71
+ libpath = . $(libdir)
72
+ LIBPATH = -L'.' -L'$(libdir)' -Wl,-R'$(libdir)'
73
+ DEFFILE =
74
+
75
+ CLEANFILES = mkmf.log
76
+ DISTCLEANFILES = rbgdkkeysyms.h rbgtkinits.c
77
+
78
+ extout =
79
+ extout_prefix =
80
+ target_prefix =
81
+ LOCAL_LIBS =
82
+ LIBS = -lgthread-2.0 -lrt -lglib-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXcomposite -lXdamage -lpango-1.0 -lcairo -lX11 -lXfixes -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXcomposite -lXdamage -lpango-1.0 -lcairo -lX11 -lXfixes -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lcairo -ldl -lcrypt -lm -lc
83
+ SRCS = keybinder.c tomboykeybinder.c eggaccelerators.c
84
+ OBJS = keybinder.o tomboykeybinder.o eggaccelerators.o
85
+ TARGET = keybinder
86
+ DLLIB = $(TARGET).so
87
+ EXTSTATIC =
88
+ STATIC_LIB =
89
+
90
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
91
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
92
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
93
+
94
+ TARGET_SO = $(DLLIB)
95
+ CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
96
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
97
+
98
+ all: $(DLLIB)
99
+ static: $(STATIC_LIB)
100
+
101
+ clean:
102
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
103
+
104
+ distclean: clean
105
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
106
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
107
+
108
+ realclean: distclean
109
+ install: install-so install-rb
110
+
111
+ install-so: $(RUBYARCHDIR)
112
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
113
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
114
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
115
+ install-rb: pre-install-rb install-rb-default
116
+ install-rb-default: pre-install-rb-default
117
+ pre-install-rb: Makefile
118
+ pre-install-rb-default: Makefile
119
+ $(RUBYARCHDIR):
120
+ $(MAKEDIRS) $@
121
+
122
+ site-install: site-install-so site-install-rb
123
+ site-install-so: install-so
124
+ site-install-rb: install-rb
125
+
126
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
127
+
128
+ .cc.o:
129
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
130
+
131
+ .cxx.o:
132
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
133
+
134
+ .cpp.o:
135
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
136
+
137
+ .C.o:
138
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
139
+
140
+ .c.o:
141
+ $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
142
+
143
+ $(DLLIB): $(OBJS)
144
+ @-$(RM) $@
145
+ $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
146
+
147
+
148
+
149
+ $(OBJS): ruby.h defines.h
@@ -0,0 +1,657 @@
1
+ /* eggaccelerators.c
2
+ * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3
+ * Developed by Havoc Pennington, Tim Janik
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Library General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Library General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Library General Public
16
+ * License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ */
20
+
21
+ #include "eggaccelerators.h"
22
+
23
+ #include <string.h>
24
+ #include <gdk/gdkx.h>
25
+ #include <gdk/gdkkeysyms.h>
26
+
27
+ enum
28
+ {
29
+ EGG_MODMAP_ENTRY_SHIFT = 0,
30
+ EGG_MODMAP_ENTRY_LOCK = 1,
31
+ EGG_MODMAP_ENTRY_CONTROL = 2,
32
+ EGG_MODMAP_ENTRY_MOD1 = 3,
33
+ EGG_MODMAP_ENTRY_MOD2 = 4,
34
+ EGG_MODMAP_ENTRY_MOD3 = 5,
35
+ EGG_MODMAP_ENTRY_MOD4 = 6,
36
+ EGG_MODMAP_ENTRY_MOD5 = 7,
37
+ EGG_MODMAP_ENTRY_LAST = 8
38
+ };
39
+
40
+ #define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
41
+
42
+ typedef struct
43
+ {
44
+ EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
+
46
+ } EggModmap;
47
+
48
+ const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
+
50
+ static inline gboolean
51
+ is_alt (const gchar *string)
52
+ {
53
+ return ((string[0] == '<') &&
54
+ (string[1] == 'a' || string[1] == 'A') &&
55
+ (string[2] == 'l' || string[2] == 'L') &&
56
+ (string[3] == 't' || string[3] == 'T') &&
57
+ (string[4] == '>'));
58
+ }
59
+
60
+ static inline gboolean
61
+ is_ctl (const gchar *string)
62
+ {
63
+ return ((string[0] == '<') &&
64
+ (string[1] == 'c' || string[1] == 'C') &&
65
+ (string[2] == 't' || string[2] == 'T') &&
66
+ (string[3] == 'l' || string[3] == 'L') &&
67
+ (string[4] == '>'));
68
+ }
69
+
70
+ static inline gboolean
71
+ is_modx (const gchar *string)
72
+ {
73
+ return ((string[0] == '<') &&
74
+ (string[1] == 'm' || string[1] == 'M') &&
75
+ (string[2] == 'o' || string[2] == 'O') &&
76
+ (string[3] == 'd' || string[3] == 'D') &&
77
+ (string[4] >= '1' && string[4] <= '5') &&
78
+ (string[5] == '>'));
79
+ }
80
+
81
+ static inline gboolean
82
+ is_ctrl (const gchar *string)
83
+ {
84
+ return ((string[0] == '<') &&
85
+ (string[1] == 'c' || string[1] == 'C') &&
86
+ (string[2] == 't' || string[2] == 'T') &&
87
+ (string[3] == 'r' || string[3] == 'R') &&
88
+ (string[4] == 'l' || string[4] == 'L') &&
89
+ (string[5] == '>'));
90
+ }
91
+
92
+ static inline gboolean
93
+ is_shft (const gchar *string)
94
+ {
95
+ return ((string[0] == '<') &&
96
+ (string[1] == 's' || string[1] == 'S') &&
97
+ (string[2] == 'h' || string[2] == 'H') &&
98
+ (string[3] == 'f' || string[3] == 'F') &&
99
+ (string[4] == 't' || string[4] == 'T') &&
100
+ (string[5] == '>'));
101
+ }
102
+
103
+ static inline gboolean
104
+ is_shift (const gchar *string)
105
+ {
106
+ return ((string[0] == '<') &&
107
+ (string[1] == 's' || string[1] == 'S') &&
108
+ (string[2] == 'h' || string[2] == 'H') &&
109
+ (string[3] == 'i' || string[3] == 'I') &&
110
+ (string[4] == 'f' || string[4] == 'F') &&
111
+ (string[5] == 't' || string[5] == 'T') &&
112
+ (string[6] == '>'));
113
+ }
114
+
115
+ static inline gboolean
116
+ is_control (const gchar *string)
117
+ {
118
+ return ((string[0] == '<') &&
119
+ (string[1] == 'c' || string[1] == 'C') &&
120
+ (string[2] == 'o' || string[2] == 'O') &&
121
+ (string[3] == 'n' || string[3] == 'N') &&
122
+ (string[4] == 't' || string[4] == 'T') &&
123
+ (string[5] == 'r' || string[5] == 'R') &&
124
+ (string[6] == 'o' || string[6] == 'O') &&
125
+ (string[7] == 'l' || string[7] == 'L') &&
126
+ (string[8] == '>'));
127
+ }
128
+
129
+ static inline gboolean
130
+ is_release (const gchar *string)
131
+ {
132
+ return ((string[0] == '<') &&
133
+ (string[1] == 'r' || string[1] == 'R') &&
134
+ (string[2] == 'e' || string[2] == 'E') &&
135
+ (string[3] == 'l' || string[3] == 'L') &&
136
+ (string[4] == 'e' || string[4] == 'E') &&
137
+ (string[5] == 'a' || string[5] == 'A') &&
138
+ (string[6] == 's' || string[6] == 'S') &&
139
+ (string[7] == 'e' || string[7] == 'E') &&
140
+ (string[8] == '>'));
141
+ }
142
+
143
+ static inline gboolean
144
+ is_meta (const gchar *string)
145
+ {
146
+ return ((string[0] == '<') &&
147
+ (string[1] == 'm' || string[1] == 'M') &&
148
+ (string[2] == 'e' || string[2] == 'E') &&
149
+ (string[3] == 't' || string[3] == 'T') &&
150
+ (string[4] == 'a' || string[4] == 'A') &&
151
+ (string[5] == '>'));
152
+ }
153
+
154
+ static inline gboolean
155
+ is_super (const gchar *string)
156
+ {
157
+ return ((string[0] == '<') &&
158
+ (string[1] == 's' || string[1] == 'S') &&
159
+ (string[2] == 'u' || string[2] == 'U') &&
160
+ (string[3] == 'p' || string[3] == 'P') &&
161
+ (string[4] == 'e' || string[4] == 'E') &&
162
+ (string[5] == 'r' || string[5] == 'R') &&
163
+ (string[6] == '>'));
164
+ }
165
+
166
+ static inline gboolean
167
+ is_hyper (const gchar *string)
168
+ {
169
+ return ((string[0] == '<') &&
170
+ (string[1] == 'h' || string[1] == 'H') &&
171
+ (string[2] == 'y' || string[2] == 'Y') &&
172
+ (string[3] == 'p' || string[3] == 'P') &&
173
+ (string[4] == 'e' || string[4] == 'E') &&
174
+ (string[5] == 'r' || string[5] == 'R') &&
175
+ (string[6] == '>'));
176
+ }
177
+
178
+ /**
179
+ * egg_accelerator_parse_virtual:
180
+ * @accelerator: string representing an accelerator
181
+ * @accelerator_key: return location for accelerator keyval
182
+ * @accelerator_mods: return location for accelerator modifier mask
183
+ *
184
+ * Parses a string representing a virtual accelerator. The format
185
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186
+ * "&lt;Release&gt;z" (the last one is for key release). The parser
187
+ * is fairly liberal and allows lower or upper case, and also
188
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189
+ *
190
+ * If the parse fails, @accelerator_key and @accelerator_mods will
191
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
192
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193
+ * returned.
194
+ *
195
+ * The virtual vs. concrete accelerator distinction is a relic of
196
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
197
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
198
+ * the virtual modifier represents the keyboard key, the concrete
199
+ * modifier the actual Mod2-Mod5 bits in the key press event.
200
+ *
201
+ * Returns: %TRUE on success.
202
+ */
203
+ gboolean
204
+ egg_accelerator_parse_virtual (const gchar *accelerator,
205
+ guint *accelerator_key,
206
+ EggVirtualModifierType *accelerator_mods)
207
+ {
208
+ guint keyval;
209
+ GdkModifierType mods;
210
+ gint len;
211
+ gboolean bad_keyval;
212
+
213
+ if (accelerator_key)
214
+ *accelerator_key = 0;
215
+ if (accelerator_mods)
216
+ *accelerator_mods = 0;
217
+
218
+ g_return_val_if_fail (accelerator != NULL, FALSE);
219
+
220
+ bad_keyval = FALSE;
221
+
222
+ keyval = 0;
223
+ mods = 0;
224
+ len = strlen (accelerator);
225
+ while (len)
226
+ {
227
+ if (*accelerator == '<')
228
+ {
229
+ if (len >= 9 && is_release (accelerator))
230
+ {
231
+ accelerator += 9;
232
+ len -= 9;
233
+ mods |= EGG_VIRTUAL_RELEASE_MASK;
234
+ }
235
+ else if (len >= 9 && is_control (accelerator))
236
+ {
237
+ accelerator += 9;
238
+ len -= 9;
239
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
240
+ }
241
+ else if (len >= 7 && is_shift (accelerator))
242
+ {
243
+ accelerator += 7;
244
+ len -= 7;
245
+ mods |= EGG_VIRTUAL_SHIFT_MASK;
246
+ }
247
+ else if (len >= 6 && is_shft (accelerator))
248
+ {
249
+ accelerator += 6;
250
+ len -= 6;
251
+ mods |= EGG_VIRTUAL_SHIFT_MASK;
252
+ }
253
+ else if (len >= 6 && is_ctrl (accelerator))
254
+ {
255
+ accelerator += 6;
256
+ len -= 6;
257
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
258
+ }
259
+ else if (len >= 6 && is_modx (accelerator))
260
+ {
261
+ static const guint mod_vals[] = {
262
+ EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263
+ EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264
+ };
265
+
266
+ len -= 6;
267
+ accelerator += 4;
268
+ mods |= mod_vals[*accelerator - '1'];
269
+ accelerator += 2;
270
+ }
271
+ else if (len >= 5 && is_ctl (accelerator))
272
+ {
273
+ accelerator += 5;
274
+ len -= 5;
275
+ mods |= EGG_VIRTUAL_CONTROL_MASK;
276
+ }
277
+ else if (len >= 5 && is_alt (accelerator))
278
+ {
279
+ accelerator += 5;
280
+ len -= 5;
281
+ mods |= EGG_VIRTUAL_ALT_MASK;
282
+ }
283
+ else if (len >= 6 && is_meta (accelerator))
284
+ {
285
+ accelerator += 6;
286
+ len -= 6;
287
+ mods |= EGG_VIRTUAL_META_MASK;
288
+ }
289
+ else if (len >= 7 && is_hyper (accelerator))
290
+ {
291
+ accelerator += 7;
292
+ len -= 7;
293
+ mods |= EGG_VIRTUAL_HYPER_MASK;
294
+ }
295
+ else if (len >= 7 && is_super (accelerator))
296
+ {
297
+ accelerator += 7;
298
+ len -= 7;
299
+ mods |= EGG_VIRTUAL_SUPER_MASK;
300
+ }
301
+ else
302
+ {
303
+ gchar last_ch;
304
+
305
+ last_ch = *accelerator;
306
+ while (last_ch && last_ch != '>')
307
+ {
308
+ last_ch = *accelerator;
309
+ accelerator += 1;
310
+ len -= 1;
311
+ }
312
+ }
313
+ }
314
+ else
315
+ {
316
+ keyval = gdk_keyval_from_name (accelerator);
317
+
318
+ if (keyval == 0)
319
+ bad_keyval = TRUE;
320
+
321
+ accelerator += len;
322
+ len -= len;
323
+ }
324
+ }
325
+
326
+ if (accelerator_key)
327
+ *accelerator_key = gdk_keyval_to_lower (keyval);
328
+ if (accelerator_mods)
329
+ *accelerator_mods = mods;
330
+
331
+ return !bad_keyval;
332
+ }
333
+
334
+
335
+ /**
336
+ * egg_virtual_accelerator_name:
337
+ * @accelerator_key: accelerator keyval
338
+ * @accelerator_mods: accelerator modifier mask
339
+ * @returns: a newly-allocated accelerator name
340
+ *
341
+ * Converts an accelerator keyval and modifier mask
342
+ * into a string parseable by egg_accelerator_parse_virtual().
343
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344
+ * this function returns "&lt;Control&gt;q".
345
+ *
346
+ * The caller of this function must free the returned string.
347
+ */
348
+ gchar*
349
+ egg_virtual_accelerator_name (guint accelerator_key,
350
+ EggVirtualModifierType accelerator_mods)
351
+ {
352
+ static const gchar text_release[] = "<Release>";
353
+ static const gchar text_shift[] = "<Shift>";
354
+ static const gchar text_control[] = "<Control>";
355
+ static const gchar text_mod1[] = "<Alt>";
356
+ static const gchar text_mod2[] = "<Mod2>";
357
+ static const gchar text_mod3[] = "<Mod3>";
358
+ static const gchar text_mod4[] = "<Mod4>";
359
+ static const gchar text_mod5[] = "<Mod5>";
360
+ static const gchar text_meta[] = "<Meta>";
361
+ static const gchar text_super[] = "<Super>";
362
+ static const gchar text_hyper[] = "<Hyper>";
363
+ guint l;
364
+ gchar *keyval_name;
365
+ gchar *accelerator;
366
+
367
+ accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
+
369
+ keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370
+ if (!keyval_name)
371
+ keyval_name = "";
372
+
373
+ l = 0;
374
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375
+ l += sizeof (text_release) - 1;
376
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377
+ l += sizeof (text_shift) - 1;
378
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379
+ l += sizeof (text_control) - 1;
380
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381
+ l += sizeof (text_mod1) - 1;
382
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383
+ l += sizeof (text_mod2) - 1;
384
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385
+ l += sizeof (text_mod3) - 1;
386
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387
+ l += sizeof (text_mod4) - 1;
388
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389
+ l += sizeof (text_mod5) - 1;
390
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391
+ l += sizeof (text_meta) - 1;
392
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393
+ l += sizeof (text_hyper) - 1;
394
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395
+ l += sizeof (text_super) - 1;
396
+ l += strlen (keyval_name);
397
+
398
+ accelerator = g_new (gchar, l + 1);
399
+
400
+ l = 0;
401
+ accelerator[l] = 0;
402
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403
+ {
404
+ strcpy (accelerator + l, text_release);
405
+ l += sizeof (text_release) - 1;
406
+ }
407
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408
+ {
409
+ strcpy (accelerator + l, text_shift);
410
+ l += sizeof (text_shift) - 1;
411
+ }
412
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413
+ {
414
+ strcpy (accelerator + l, text_control);
415
+ l += sizeof (text_control) - 1;
416
+ }
417
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418
+ {
419
+ strcpy (accelerator + l, text_mod1);
420
+ l += sizeof (text_mod1) - 1;
421
+ }
422
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423
+ {
424
+ strcpy (accelerator + l, text_mod2);
425
+ l += sizeof (text_mod2) - 1;
426
+ }
427
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428
+ {
429
+ strcpy (accelerator + l, text_mod3);
430
+ l += sizeof (text_mod3) - 1;
431
+ }
432
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433
+ {
434
+ strcpy (accelerator + l, text_mod4);
435
+ l += sizeof (text_mod4) - 1;
436
+ }
437
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438
+ {
439
+ strcpy (accelerator + l, text_mod5);
440
+ l += sizeof (text_mod5) - 1;
441
+ }
442
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443
+ {
444
+ strcpy (accelerator + l, text_meta);
445
+ l += sizeof (text_meta) - 1;
446
+ }
447
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448
+ {
449
+ strcpy (accelerator + l, text_hyper);
450
+ l += sizeof (text_hyper) - 1;
451
+ }
452
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453
+ {
454
+ strcpy (accelerator + l, text_super);
455
+ l += sizeof (text_super) - 1;
456
+ }
457
+
458
+ strcpy (accelerator + l, keyval_name);
459
+
460
+ return accelerator;
461
+ }
462
+
463
+ void
464
+ egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465
+ EggVirtualModifierType virtual_mods,
466
+ GdkModifierType *concrete_mods)
467
+ {
468
+ GdkModifierType concrete;
469
+ int i;
470
+ const EggModmap *modmap;
471
+
472
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
473
+ g_return_if_fail (concrete_mods != NULL);
474
+
475
+ modmap = egg_keymap_get_modmap (keymap);
476
+
477
+ /* Not so sure about this algorithm. */
478
+
479
+ concrete = 0;
480
+ i = 0;
481
+ while (i < EGG_MODMAP_ENTRY_LAST)
482
+ {
483
+ if (modmap->mapping[i] & virtual_mods)
484
+ concrete |= (1 << i);
485
+
486
+ ++i;
487
+ }
488
+
489
+ *concrete_mods = concrete;
490
+ }
491
+
492
+ void
493
+ egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494
+ GdkModifierType concrete_mods,
495
+ EggVirtualModifierType *virtual_mods)
496
+ {
497
+ GdkModifierType virtual;
498
+ int i;
499
+ const EggModmap *modmap;
500
+
501
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
502
+ g_return_if_fail (virtual_mods != NULL);
503
+
504
+ modmap = egg_keymap_get_modmap (keymap);
505
+
506
+ /* Not so sure about this algorithm. */
507
+
508
+ virtual = 0;
509
+ i = 0;
510
+ while (i < EGG_MODMAP_ENTRY_LAST)
511
+ {
512
+ if ((1 << i) & concrete_mods)
513
+ {
514
+ EggVirtualModifierType cleaned;
515
+
516
+ cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517
+ EGG_VIRTUAL_MOD3_MASK |
518
+ EGG_VIRTUAL_MOD4_MASK |
519
+ EGG_VIRTUAL_MOD5_MASK);
520
+
521
+ if (cleaned != 0)
522
+ {
523
+ virtual |= cleaned;
524
+ }
525
+ else
526
+ {
527
+ /* Rather than dropping mod2->mod5 if not bound,
528
+ * go ahead and use the concrete names
529
+ */
530
+ virtual |= modmap->mapping[i];
531
+ }
532
+ }
533
+
534
+ ++i;
535
+ }
536
+
537
+ *virtual_mods = virtual;
538
+ }
539
+
540
+ static void
541
+ reload_modmap (GdkKeymap *keymap,
542
+ EggModmap *modmap)
543
+ {
544
+ XModifierKeymap *xmodmap;
545
+ int map_size;
546
+ int i;
547
+
548
+ /* FIXME multihead */
549
+ xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
+
551
+ memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
+
553
+ /* there are 8 modifiers, and the first 3 are shift, shift lock,
554
+ * and control
555
+ */
556
+ map_size = 8 * xmodmap->max_keypermod;
557
+ i = 3 * xmodmap->max_keypermod;
558
+ while (i < map_size)
559
+ {
560
+ /* get the key code at this point in the map,
561
+ * see if its keysym is one we're interested in
562
+ */
563
+ int keycode = xmodmap->modifiermap[i];
564
+ GdkKeymapKey *keys;
565
+ guint *keyvals;
566
+ int n_entries;
567
+ int j;
568
+ EggVirtualModifierType mask;
569
+
570
+ keys = NULL;
571
+ keyvals = NULL;
572
+ n_entries = 0;
573
+
574
+ gdk_keymap_get_entries_for_keycode (keymap,
575
+ keycode,
576
+ &keys, &keyvals, &n_entries);
577
+
578
+ mask = 0;
579
+ j = 0;
580
+ while (j < n_entries)
581
+ {
582
+ if (keyvals[j] == GDK_Num_Lock)
583
+ mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584
+ else if (keyvals[j] == GDK_Scroll_Lock)
585
+ mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586
+ else if (keyvals[j] == GDK_Meta_L ||
587
+ keyvals[j] == GDK_Meta_R)
588
+ mask |= EGG_VIRTUAL_META_MASK;
589
+ else if (keyvals[j] == GDK_Hyper_L ||
590
+ keyvals[j] == GDK_Hyper_R)
591
+ mask |= EGG_VIRTUAL_HYPER_MASK;
592
+ else if (keyvals[j] == GDK_Super_L ||
593
+ keyvals[j] == GDK_Super_R)
594
+ mask |= EGG_VIRTUAL_SUPER_MASK;
595
+ else if (keyvals[j] == GDK_Mode_switch)
596
+ mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
+
598
+ ++j;
599
+ }
600
+
601
+ /* Mod1Mask is 1 << 3 for example, i.e. the
602
+ * fourth modifier, i / keyspermod is the modifier
603
+ * index
604
+ */
605
+ modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
+
607
+ g_free (keyvals);
608
+ g_free (keys);
609
+
610
+ ++i;
611
+ }
612
+
613
+ /* Add in the not-really-virtual fixed entries */
614
+ modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615
+ modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616
+ modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621
+ modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
+
623
+ XFreeModifiermap (xmodmap);
624
+ }
625
+
626
+ const EggModmap*
627
+ egg_keymap_get_modmap (GdkKeymap *keymap)
628
+ {
629
+ EggModmap *modmap;
630
+
631
+ /* This is all a hack, much simpler when we can just
632
+ * modify GDK directly.
633
+ */
634
+
635
+ modmap = g_object_get_data (G_OBJECT (keymap),
636
+ "egg-modmap");
637
+
638
+ if (modmap == NULL)
639
+ {
640
+ modmap = g_new0 (EggModmap, 1);
641
+
642
+ /* FIXME modify keymap change events with an event filter
643
+ * and force a reload if we get one
644
+ */
645
+
646
+ reload_modmap (keymap, modmap);
647
+
648
+ g_object_set_data_full (G_OBJECT (keymap),
649
+ "egg-modmap",
650
+ modmap,
651
+ g_free);
652
+ }
653
+
654
+ g_assert (modmap != NULL);
655
+
656
+ return modmap;
657
+ }