gschem

g_keys.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * gschem - gEDA Schematic Capture
00003  * Copyright (C) 1998-2010 Ales Hvezda
00004  * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 #include <config.h>
00021 #include <missing.h>
00022 
00023 #include <stdio.h>
00024 #include <sys/stat.h>
00025 #include <ctype.h>
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 #ifdef HAVE_STDLIB_H
00030 #include <stdlib.h>
00031 #endif
00032 #ifdef HAVE_UNISTD_H
00033 #include <unistd.h>
00034 #endif
00035 
00036 #include "gschem.h"
00037 
00038 #ifdef HAVE_LIBDMALLOC
00039 #include <dmalloc.h>
00040 #endif
00041 
00042 #include <gdk/gdkkeysyms.h>
00043 
00044 
00045 #define DEFINE_G_KEYS(name)             \
00046 SCM g_keys_ ## name(SCM rest)               \
00047 {                           \
00048    GSCHEM_TOPLEVEL *w_current = g_current_window ();    \
00049    i_callback_ ## name(w_current, 0, NULL);                   \
00050    return SCM_BOOL_T;               \
00051 }
00052 
00056 DEFINE_G_KEYS(file_new)
00057 
00058 DEFINE_G_KEYS(file_new_window)
00059 
00060 /* don't use the widget parameter on this function, or do some checking... */
00061 /* since there is a call: widget = NULL, data = 0 (will be w_current) */
00062 /* This should be renamed to page_open perhaps... */
00063 DEFINE_G_KEYS(file_open)
00064 
00065 /* don't use the widget parameter on this function, or do some checking... */
00066 /* since there is a call: widget = NULL, data = 0 (will be w_current) */
00067 DEFINE_G_KEYS(file_script)
00068 
00069 /* don't use the widget parameter on this function, or do some checking... */
00070 /* since there is a call: widget = NULL, data = 0 (will be w_current) */
00071 DEFINE_G_KEYS(file_save)
00072 DEFINE_G_KEYS(file_save_as)
00073 DEFINE_G_KEYS(file_save_all)
00074 DEFINE_G_KEYS(file_print)
00075 DEFINE_G_KEYS(file_write_png)
00076 
00077 /* don't use the widget parameter on this function, or do some checking... */
00078 /* since there is a call: widget = NULL, data = 0 (will be w_current) */
00079 /* this function closes a window */
00080 DEFINE_G_KEYS(file_close)
00081 DEFINE_G_KEYS(file_quit)
00082 
00083 /* Select also does not update the middle button shortcut */
00084 DEFINE_G_KEYS(edit_undo)
00085 DEFINE_G_KEYS(edit_redo)
00086 DEFINE_G_KEYS(edit_select)
00087 DEFINE_G_KEYS(edit_select_all)
00088 DEFINE_G_KEYS(edit_deselect)
00089 DEFINE_G_KEYS(edit_copy)
00090 DEFINE_G_KEYS(edit_copy_hotkey)
00091 DEFINE_G_KEYS(edit_mcopy)
00092 DEFINE_G_KEYS(edit_mcopy_hotkey)
00093 DEFINE_G_KEYS(edit_move)
00094 DEFINE_G_KEYS(edit_move_hotkey)
00095 DEFINE_G_KEYS(edit_delete)
00096 DEFINE_G_KEYS(edit_rotate_90)
00097 DEFINE_G_KEYS(edit_rotate_90_hotkey)
00098 DEFINE_G_KEYS(edit_mirror)
00099 DEFINE_G_KEYS(edit_mirror_hotkey)
00100 DEFINE_G_KEYS(edit_slot)
00101 DEFINE_G_KEYS(edit_color)
00102 DEFINE_G_KEYS(edit_edit)
00103 DEFINE_G_KEYS(edit_pin_type)
00104 DEFINE_G_KEYS(edit_text)
00105 DEFINE_G_KEYS(edit_lock)
00106 DEFINE_G_KEYS(edit_unlock)
00107 DEFINE_G_KEYS(edit_linetype)
00108 DEFINE_G_KEYS(edit_filltype)
00109 DEFINE_G_KEYS(edit_translate)
00110 DEFINE_G_KEYS(edit_invoke_macro)
00111 DEFINE_G_KEYS(edit_embed)
00112 DEFINE_G_KEYS(edit_unembed)
00113 DEFINE_G_KEYS(edit_update)
00114 DEFINE_G_KEYS(edit_show_hidden)
00115 DEFINE_G_KEYS(edit_find)
00116 DEFINE_G_KEYS(edit_show_text)
00117 DEFINE_G_KEYS(edit_hide_text)
00118 DEFINE_G_KEYS(edit_autonumber_text)
00119 
00120 DEFINE_G_KEYS(clipboard_copy)
00121 DEFINE_G_KEYS(clipboard_cut)
00122 DEFINE_G_KEYS(clipboard_paste)
00123 DEFINE_G_KEYS(clipboard_paste_hotkey)
00124 
00125 DEFINE_G_KEYS(buffer_copy1)
00126 DEFINE_G_KEYS(buffer_copy2)
00127 DEFINE_G_KEYS(buffer_copy3)
00128 DEFINE_G_KEYS(buffer_copy4)
00129 DEFINE_G_KEYS(buffer_copy5)
00130 DEFINE_G_KEYS(buffer_cut1)
00131 DEFINE_G_KEYS(buffer_cut2)
00132 DEFINE_G_KEYS(buffer_cut3)
00133 DEFINE_G_KEYS(buffer_cut4)
00134 DEFINE_G_KEYS(buffer_cut5)
00135 DEFINE_G_KEYS(buffer_paste1)
00136 DEFINE_G_KEYS(buffer_paste2)
00137 DEFINE_G_KEYS(buffer_paste3)
00138 DEFINE_G_KEYS(buffer_paste4)
00139 DEFINE_G_KEYS(buffer_paste5)
00140 DEFINE_G_KEYS(buffer_paste1_hotkey)
00141 DEFINE_G_KEYS(buffer_paste2_hotkey)
00142 DEFINE_G_KEYS(buffer_paste3_hotkey)
00143 DEFINE_G_KEYS(buffer_paste4_hotkey)
00144 DEFINE_G_KEYS(buffer_paste5_hotkey)
00145 
00146 /* repeat middle shortcut doesn't make sense on redraw, just hit right
00147  * button */
00148 DEFINE_G_KEYS(view_redraw)
00149 
00150 /* for these functions, repeat middle shortcut would get into the way
00151  * of what user is try to do */
00152 DEFINE_G_KEYS(view_zoom_full)
00153 DEFINE_G_KEYS(view_zoom_extents)
00154 DEFINE_G_KEYS(view_zoom_in)
00155 DEFINE_G_KEYS(view_zoom_out)
00156 DEFINE_G_KEYS(view_zoom_in_hotkey)
00157 DEFINE_G_KEYS(view_zoom_out_hotkey)
00158 
00159 DEFINE_G_KEYS(view_zoom_box)
00160 DEFINE_G_KEYS(view_zoom_box_hotkey)
00161 DEFINE_G_KEYS(view_pan)
00162 DEFINE_G_KEYS(view_pan_left)
00163 DEFINE_G_KEYS(view_pan_right)
00164 DEFINE_G_KEYS(view_pan_up)
00165 DEFINE_G_KEYS(view_pan_down)
00166 DEFINE_G_KEYS(view_pan_hotkey)
00167 DEFINE_G_KEYS(view_dark_colors)
00168 DEFINE_G_KEYS(view_light_colors)
00169 DEFINE_G_KEYS(view_bw_colors)
00170 DEFINE_G_KEYS(page_manager)
00171 DEFINE_G_KEYS(page_next)
00172 DEFINE_G_KEYS(page_prev)
00173 DEFINE_G_KEYS(page_new)
00174 DEFINE_G_KEYS(page_close)
00175 DEFINE_G_KEYS(page_revert)
00176 DEFINE_G_KEYS(page_discard)
00177 DEFINE_G_KEYS(page_print)
00178 DEFINE_G_KEYS(add_component)
00179 DEFINE_G_KEYS(add_attribute)
00180 DEFINE_G_KEYS(add_attribute_hotkey)
00181 DEFINE_G_KEYS(add_net)
00182 DEFINE_G_KEYS(add_net_hotkey)
00183 DEFINE_G_KEYS(add_bus)
00184 DEFINE_G_KEYS(add_bus_hotkey)
00185 DEFINE_G_KEYS(add_text)
00186 DEFINE_G_KEYS(add_line)
00187 DEFINE_G_KEYS(add_line_hotkey)
00188 DEFINE_G_KEYS(add_box)
00189 DEFINE_G_KEYS(add_box_hotkey)
00190 DEFINE_G_KEYS(add_picture)
00191 DEFINE_G_KEYS(add_picture_hotkey)
00192 DEFINE_G_KEYS(add_circle)
00193 DEFINE_G_KEYS(add_circle_hotkey)
00194 DEFINE_G_KEYS(add_arc)
00195 DEFINE_G_KEYS(add_arc_hotkey)
00196 DEFINE_G_KEYS(add_pin)
00197 DEFINE_G_KEYS(add_pin_hotkey)
00198 DEFINE_G_KEYS(hierarchy_down_schematic)
00199 DEFINE_G_KEYS(hierarchy_down_symbol)
00200 DEFINE_G_KEYS(hierarchy_up)
00201 DEFINE_G_KEYS(attributes_attach)
00202 DEFINE_G_KEYS(attributes_detach)
00203 DEFINE_G_KEYS(attributes_show_name)
00204 DEFINE_G_KEYS(attributes_show_value)
00205 DEFINE_G_KEYS(attributes_show_both)
00206 DEFINE_G_KEYS(attributes_visibility_toggle)
00207 
00208 /* i_callback_script_console is not currently implemented */
00209 DEFINE_G_KEYS(script_console)
00210 
00211 /* repeat last command doesn't make sense on options either??? (does
00212  * it?) */
00213 DEFINE_G_KEYS(options_text_size)
00214 
00215 /* repeat last command doesn't make sense on options either??? (does
00216  * it?) */
00217 DEFINE_G_KEYS(options_afeedback)
00218 DEFINE_G_KEYS(options_grid)
00219 DEFINE_G_KEYS(options_snap)
00220 DEFINE_G_KEYS(options_snap_size)
00221 DEFINE_G_KEYS(options_scale_up_snap_size)
00222 DEFINE_G_KEYS(options_scale_down_snap_size)
00223 DEFINE_G_KEYS(options_rubberband)
00224 DEFINE_G_KEYS(options_magneticnet)
00225 DEFINE_G_KEYS(options_show_log_window)
00226 DEFINE_G_KEYS(options_show_coord_window)
00227 DEFINE_G_KEYS(misc)
00228 DEFINE_G_KEYS(misc2)
00229 DEFINE_G_KEYS(misc3)
00230 
00231 DEFINE_G_KEYS(help_about)
00232 DEFINE_G_KEYS(help_hotkeys)
00233 
00234 /* be sure that you don't use the widget parameter in this one, since it is
00235 being called with a null, I suppose we should call it with the right param.
00236 hack */
00237 DEFINE_G_KEYS(cancel)
00238 
00240 static scm_t_bits g_key_smob_tag;
00241 #define G_SCM_IS_KEY(x) SCM_SMOB_PREDICATE (g_key_smob_tag, (x))
00242 
00244 typedef struct {
00245   guint keyval;
00246   GdkModifierType modifiers;
00247   gchar *str; /* UTF-8. Free with g_free(). */
00248   gchar *disp_str; /* UTF-8. Free with g_free(). */
00249 } GschemKey;
00250 
00262 static gboolean
00263 g_key_is_valid (guint keyval, GdkModifierType modifiers)
00264 {
00265   static const guint invalid_keyvals[] = {
00266     GDK_Shift_L, GDK_Shift_R, GDK_Shift_Lock, GDK_Caps_Lock, GDK_ISO_Lock,
00267     GDK_Control_L, GDK_Control_R, GDK_Meta_L, GDK_Meta_R,
00268     GDK_Alt_L, GDK_Alt_R, GDK_Super_L, GDK_Super_R, GDK_Hyper_L, GDK_Hyper_R,
00269     GDK_ISO_Level3_Shift, GDK_ISO_Next_Group, GDK_ISO_Prev_Group,
00270     GDK_ISO_First_Group, GDK_ISO_Last_Group,
00271     GDK_Mode_switch, GDK_Num_Lock, GDK_Multi_key,
00272     GDK_Scroll_Lock, GDK_Sys_Req,
00273     GDK_Tab, GDK_ISO_Left_Tab, GDK_KP_Tab,
00274     GDK_First_Virtual_Screen, GDK_Prev_Virtual_Screen,
00275     GDK_Next_Virtual_Screen, GDK_Last_Virtual_Screen,
00276     GDK_Terminate_Server, GDK_AudibleBell_Enable,
00277     0
00278   };
00279   const guint *val;
00280 
00281   /* Exclude a bunch of control chars */
00282   if (keyval <= 0xFF) return keyval >= 0x20;
00283 
00284   /* Exclude special & modifier keys */
00285   val = invalid_keyvals;
00286   while (*val) {
00287     if (keyval == *val++) return FALSE;
00288   }
00289 
00290   return TRUE;
00291 }
00292 
00304 static SCM
00305 g_make_key (guint keyval, GdkModifierType modifiers)
00306 {
00307   SCM result = SCM_BOOL_F;
00308   if (g_key_is_valid (keyval, modifiers)) {
00309     GschemKey *k = g_new0 (GschemKey, 1);
00310     k->keyval = keyval;
00311     k->modifiers = modifiers & GDK_MODIFIER_MASK;
00312     SCM_NEWSMOB (result, g_key_smob_tag, k);
00313   }
00314   return result;
00315 }
00316 
00328 SCM_DEFINE (g_keyp, "%key?", 1, 0, 0, (SCM key_s),
00329             "Test if value is a gschem key.")
00330 {
00331   if (G_SCM_IS_KEY (key_s)) {
00332     return SCM_BOOL_T;
00333   } else {
00334     return SCM_BOOL_F;
00335   }
00336 }
00337 
00350 SCM_DEFINE (g_string_to_key, "%string->key", 1, 0, 0, (SCM str_s),
00351             "Create a gschem key by parsing a string.")
00352 {
00353   SCM_ASSERT (scm_is_string (str_s), str_s, SCM_ARG1, s_g_string_to_key);
00354 
00355   guint keyval;
00356   GdkModifierType modifiers;
00357   char *str = scm_to_utf8_string (str_s);
00358   gtk_accelerator_parse (str, &keyval, &modifiers);
00359   if ((keyval == 0) && (modifiers == 0)) return SCM_BOOL_F;
00360   return g_make_key (keyval, modifiers);
00361 }
00362 
00374 SCM_DEFINE (g_key_to_string, "%key->string", 1, 0, 0, (SCM key_s),
00375             "Create a string from a gschem key.")
00376 {
00377   SCM_ASSERT (G_SCM_IS_KEY (key_s), key_s, SCM_ARG1, s_g_key_to_string);
00378 
00379   GschemKey *key = (GschemKey *) SCM_SMOB_DATA (key_s);
00380   if (key->str != NULL) return scm_from_utf8_string (key->str);
00381 
00382   key->str = gtk_accelerator_name (key->keyval, key->modifiers);
00383   return scm_from_utf8_string (key->str);
00384 }
00385 
00398 SCM_DEFINE (g_key_to_display_string, "%key->display-string", 1, 0, 0,
00399             (SCM key_s), "Create a display string from a gschem key.")
00400 {
00401   SCM_ASSERT (G_SCM_IS_KEY (key_s), key_s, SCM_ARG1,
00402               s_g_key_to_display_string);
00403 
00404   GschemKey *key = (GschemKey *) SCM_SMOB_DATA (key_s);
00405   if (key->disp_str != NULL) return scm_from_utf8_string (key->disp_str);
00406 
00407   key->disp_str = gtk_accelerator_get_label (key->keyval, key->modifiers);
00408   return scm_from_utf8_string (key->disp_str);
00409 }
00410 
00418 static int
00419 g_key_print (SCM smob, SCM port, scm_print_state *pstate)
00420 {
00421   scm_puts ("#<gschem-key ", port);
00422   scm_write (g_key_to_display_string (smob), port);
00423   scm_puts (">", port);
00424 
00425   /* Non-zero means success */
00426   return 1;
00427 }
00428 
00429 /* \brief Test if two key combinations are equivalent.
00430  * \par Function Description
00431  * Tests if the two gschem key objects \a a and \a b represent the
00432  * same key event.
00433  *
00434  * Used internally to Guile.
00435  */
00436 static SCM
00437 g_key_equalp (SCM a, SCM b)
00438 {
00439   GschemKey *akey = (GschemKey *) SCM_SMOB_DATA (a);
00440   GschemKey *bkey = (GschemKey *) SCM_SMOB_DATA (b);
00441   if (akey->keyval != bkey->keyval) return SCM_BOOL_F;
00442   if (akey->modifiers != bkey->modifiers) return SCM_BOOL_F;
00443   return SCM_BOOL_T;
00444 }
00445 
00446 /* \brief Destroy a bindable key object
00447  * \par Function Description
00448  * Destroys the contents of a gschem key object on garbage collection.
00449  *
00450  * Used internally to Guile.
00451  */
00452 static size_t
00453 g_key_free (SCM key) {
00454   GschemKey *k = (GschemKey *) SCM_SMOB_DATA (key);
00455   g_free (k->str);
00456   g_free (k->disp_str);
00457   g_free (k);
00458   return 0;
00459 }
00460 
00461 SCM_SYMBOL (reset_keys_sym, "reset-keys");
00462 SCM_SYMBOL (press_key_sym, "press-key");
00463 SCM_SYMBOL (prefix_sym, "prefix");
00464 
00475 static gboolean clear_keyaccel_string(gpointer data)
00476 {
00477   GSCHEM_TOPLEVEL *w_current = data;
00478 
00479   /* If the window context has disappeared, do nothing. */
00480   if (g_list_find(global_window_list, w_current) == NULL) {
00481     return FALSE;
00482   }
00483 
00484   g_free(w_current->keyaccel_string);
00485   w_current->keyaccel_string = NULL;
00486   w_current->keyaccel_string_source_id = 0;
00487   i_show_state(w_current, NULL);
00488   return FALSE;
00489 }
00490 
00498 void
00499 g_keys_reset (GSCHEM_TOPLEVEL *w_current)
00500 {
00501   SCM s_expr = scm_list_1 (reset_keys_sym);
00502 
00503   /* Reset the status bar */
00504   g_free (w_current->keyaccel_string);
00505   w_current->keyaccel_string = NULL;
00506   i_show_state(w_current, NULL);
00507 
00508   /* Reset the Scheme keybinding state */
00509   scm_dynwind_begin (0);
00510   g_dynwind_window (w_current);
00511   g_scm_eval_protected (s_expr, scm_interaction_environment ());
00512   scm_dynwind_end ();
00513 }
00514 
00526 int
00527 g_keys_execute(GSCHEM_TOPLEVEL *w_current, GdkEventKey *event)
00528 {
00529   SCM s_retval, s_key, s_expr;
00530   guint key, mods, upper, lower, caps;
00531   GdkDisplay *display;
00532   GdkKeymap *keymap;
00533   GdkModifierType consumed_modifiers;
00534 
00535   g_return_val_if_fail (w_current != NULL, 0);
00536   g_return_val_if_fail (event != NULL, 0);
00537 
00538   display = gtk_widget_get_display (w_current->main_window);
00539   keymap = gdk_keymap_get_for_display (display);
00540 
00541   /* Figure out what modifiers went into determining the key symbol */
00542   gdk_keymap_translate_keyboard_state (keymap,
00543                                        event->hardware_keycode,
00544                                        event->state, event->group,
00545                                        NULL, NULL, NULL, &consumed_modifiers);
00546 
00547   key = event->keyval;
00548   gdk_keyval_convert_case (event->keyval, &lower, &upper);
00549   mods = (event->state & gtk_accelerator_get_default_mod_mask ()
00550                 & ~consumed_modifiers);
00551 
00552   /* Handle Caps Lock. The idea is to obtain the same keybindings
00553    * whether Caps Lock is enabled or not. */
00554   if (upper != lower) {
00555     caps = gdk_keymap_get_caps_lock_state (keymap);
00556     if ((caps && (key == lower)) || (!caps && (key == upper))) {
00557       mods |= GDK_SHIFT_MASK;
00558     }
00559   }
00560 
00561   /* Always process key as lower case */
00562   key = lower;
00563 
00564   /* Validate the key -- there are some keystrokes we mask out. */
00565   if (!g_key_is_valid (key, mods)) {
00566     return FALSE;
00567   }
00568 
00569   /* Create Scheme key value */
00570   s_key = g_make_key (key, mods);
00571 
00572   /* Update key hint string for status bar. */
00573   gchar *keystr = gtk_accelerator_get_label (key, mods);
00574 
00575   /* If no current hint string, or the hint string is going to be
00576    * cleared anyway, use key string directly */
00577   if ((w_current->keyaccel_string == NULL) ||
00578       w_current->keyaccel_string_source_id) {
00579     g_free (w_current->keyaccel_string);
00580     w_current->keyaccel_string = keystr;
00581 
00582   } else {
00583     gchar *p = w_current->keyaccel_string;
00584     w_current->keyaccel_string = g_strconcat (p, " ", keystr, NULL);
00585     g_free (p);
00586     g_free (keystr);
00587   }
00588 
00589   /* Update status bar */
00590   i_show_state(w_current, NULL);
00591 
00592   /* Build and evaluate Scheme expression. */
00593   scm_dynwind_begin (0);
00594   g_dynwind_window (w_current);
00595   s_expr = scm_list_2 (press_key_sym, s_key);
00596   s_retval = g_scm_eval_protected (s_expr, scm_interaction_environment ());
00597   scm_dynwind_end ();
00598 
00599   /* If the keystroke was not part of a prefix, start a timer to clear
00600    * the status bar display. */
00601   if (w_current->keyaccel_string_source_id) {
00602     /* Cancel any existing timers that haven't fired yet. */
00603     GSource *timer =
00604       g_main_context_find_source_by_id (NULL,
00605                                         w_current->keyaccel_string_source_id);
00606     g_source_destroy (timer);
00607     w_current->keyaccel_string_source_id = 0;
00608   }
00609   if (!scm_is_eq (s_retval, prefix_sym)) {
00610     w_current->keyaccel_string_source_id =
00611       g_timeout_add(400, clear_keyaccel_string, w_current);
00612   }
00613 
00614   return !scm_is_false (s_retval);
00615 }
00616 
00630 GtkListStore *
00631 g_keys_to_list_store (void)
00632 {
00633   SCM s_expr;
00634   SCM s_lst;
00635   SCM s_iter;
00636   GtkListStore *list_store;
00637 
00638   /* Call Scheme procedure to dump global keymap into list */
00639   s_expr = scm_list_1 (scm_from_utf8_symbol ("dump-global-keymap"));
00640   s_lst = g_scm_eval_protected (s_expr, scm_interaction_environment ());
00641 
00642   g_return_val_if_fail (scm_is_true (scm_list_p (s_lst)), NULL);
00643 
00644   /* Convert to  */
00645   scm_dynwind_begin (0);
00646   list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
00647   scm_dynwind_unwind_handler (g_object_unref, list_store, 0);
00648 
00649   for (s_iter = s_lst; !scm_is_null (s_iter); s_iter = scm_cdr (s_iter)) {
00650     SCM s_binding = scm_caar (s_iter);
00651     SCM s_keys = scm_cdar (s_iter);
00652     char *binding, *keys;
00653     GtkTreeIter iter;
00654 
00655     scm_dynwind_begin (0);
00656 
00657     binding = scm_to_utf8_string (s_binding);
00658     scm_dynwind_free (binding);
00659 
00660     keys = scm_to_utf8_string (s_keys);
00661     scm_dynwind_free (keys);
00662 
00663     gtk_list_store_insert_with_values (list_store, &iter, -1,
00664                                        0, binding,
00665                                        1, keys,
00666                                        -1);
00667 
00668     scm_dynwind_end ();
00669   }
00670 
00671   scm_dynwind_end ();
00672   return list_store;
00673 }
00674 
00680 static void
00681 init_module_gschem_core_keymap ()
00682 {
00683   /* Register the functions */
00684   #include "g_keys.x"
00685 
00686   /* Add them to the module's public definitions */
00687   scm_c_export (s_g_keyp, s_g_string_to_key, s_g_key_to_string,
00688                 s_g_key_to_display_string, NULL);
00689 }
00690 
00696 void
00697 g_init_keys ()
00698 {
00699   /* Register key smob type */
00700   g_key_smob_tag = scm_make_smob_type ("gschem-key", 0);
00701   scm_set_smob_print (g_key_smob_tag, g_key_print);
00702   scm_set_smob_equalp (g_key_smob_tag, g_key_equalp);
00703   scm_set_smob_free (g_key_smob_tag, g_key_free);
00704 
00705   scm_c_define_module ("gschem core keymap",
00706                        init_module_gschem_core_keymap,
00707                        NULL);
00708 }
00709 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines