gschem
|
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