示例#1
0
文件: key.c 项目: morenko/sven
void glist_grab_ungrab_key (Sven *sven,GList* list,int i)
{
	if(sven == NULL)
		return;
		
	GList *p = g_list_first (list);
	
	while (p)
	{
		int modifer=0;
		
		ConfigSection *section = (ConfigSection *) p->data;

		gchar **key_modifer = g_strsplit(section->name,":",2);
		if(key_modifer[1]==NULL)
			modifer=0;
		else
			modifer=atoi(key_modifer[1]);
		if(i==0)
		{
			gint y=0;
			sven_cfg_read_int(sven->config->key,section->name, "enable",&y);
			if(y)
			{
				grab_key (atoi(key_modifer[0]),modifer);
			}
		}
		else
			ungrab_key(atoi(key_modifer[0]));

		g_strfreev(key_modifer);
			
		p = g_list_next (p);
	}
}
示例#2
0
void grab_keys ( )
{
    Display* xdisplay;
    int screen;
    PluginConfig* plugin_cfg = get_config();
    HotkeyConfiguration *hotkey;

    XErrorHandler old_handler = 0;
     xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());

    if (grabbed) return;


    XSync(xdisplay, False);
    old_handler = XSetErrorHandler (x11_error_handler);

    get_offending_modifiers(xdisplay);
    hotkey = &(plugin_cfg->first);
    while (hotkey)
    {
        for (screen=0;screen<ScreenCount(xdisplay);screen++)
        {
            grab_key(hotkey, xdisplay, RootWindow(xdisplay, screen));
        }
        hotkey = hotkey->next;
    }

    XSync(xdisplay, False);
    XSetErrorHandler (old_handler);

    grabbed = 1;
}
示例#3
0
/*
 * initialize hotkeys
 */
void
hotkeys_init()
{
	char	msg_str[128];

	begin_func("hotkeys_init");

	if (hotkey_parse(menukey_str, &menukey, &menukey_mask) != 0) {
		sprintf(msg_str, "Invalid menu hotkey '%s'.\nFalling back to "
				"default (" DEF_MENUKEY ")\n", menukey_str);
		show_message(msg_str, "Warning", "OK", NULL, NULL);
		strcpy(menukey_str, DEF_MENUKEY);
		hotkey_parse(menukey_str, &menukey, &menukey_mask);
	}
	if (hotkey_parse(prev_item_key_str, &prev_item_key, &prev_item_mask) != 0) {
		sprintf(msg_str, "Invalid previous item hotkey '%s'.\n"
				"Falling back to default (" DEF_PREV_ITEM_KEY
				")\n", prev_item_key_str);
		show_message(msg_str, "Warning", "OK", NULL, NULL);
		hotkey_parse(DEF_PREV_ITEM_KEY, &prev_item_key,
				&prev_item_mask);
	}
	if (hotkey_parse(exec_item_key_str, &exec_item_key, &exec_item_mask) != 0) {
		sprintf(msg_str, "Invalid exec hotkey '%s'.\n"
				"Falling back to default (" DEF_EXEC_ITEM_KEY
				")\n", exec_item_key_str);
		show_message(msg_str, "Warning", "OK", NULL, NULL);
		hotkey_parse(DEF_EXEC_ITEM_KEY, &exec_item_key,
				&exec_item_mask);
	}
	gdk_window_add_filter(gdk_get_default_root_window(), global_keys_filter, NULL);
	grab_key(menukey, menukey_mask);
	grab_key(prev_item_key, prev_item_mask);
	grab_key(exec_item_key, exec_item_mask);

	return_void();
}
示例#4
0
static void grab_keys()
{
	KeyCode code;
	
	if ((code = grab_key("XF86AudioNext")) != 0)
		map[XF86AUDIO_NEXT] = code;
	if ((code = grab_key("XF86AudioPrev")) != 0)
		map[XF86AUDIO_PREV] = code;
	if ((code = grab_key("XF86AudioPlay")) != 0)
		map[XF86AUDIO_PLAY] = code;
	if ((code = grab_key("XF86AudioStop")) != 0)
		map[XF86AUDIO_STOP] = code;
/*	if ((code = grab_key("XF86AudioPause")) != 0)
		map[XF86AUDIO_PAUSE] = code;
	if ((code = grab_key("XF86AudioRaiseVolume")) != 0)
		map[XF86AUDIO_RAISEVOLUME] = code;
	if ((code = grab_key("XF86AudioLowerVolume")) != 0)
		map[XF86AUDIO_LOWERVOLUME] = code;
	if ((code = grab_key("XF86AudioMute")) != 0)
		map[XF86AUDIO_MUTE] = code;
	if ((code = grab_key("XF86AudioMedia")) != 0)
		map[XF86AUDIO_MEDIA] = code;
*/
}
示例#5
0
void
sugar_key_grabber_grab_keys(SugarKeyGrabber *grabber, const char **keys)
{
    const char **cur = keys;
    const char *key;
    Key *keyinfo = NULL;
    int min_keycodes, max_keycodes;

    XDisplayKeycodes(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
                     &min_keycodes, &max_keycodes);

    while (*cur != NULL) {
        key = *cur;
        cur += 1;

        keyinfo = g_new0 (Key, 1);
        keyinfo->key = g_strdup(key);

        if (!egg_accelerator_parse_virtual (key, &keyinfo->keysym,
                                            &keyinfo->keycode,
                                            &keyinfo->state)) {
            g_warning ("Invalid key specified: %s", key);
            continue;
        }

        if (keyinfo->keycode < min_keycodes || keyinfo->keycode > max_keycodes) {
            g_warning ("Keycode out of bounds: %d for key %s", keyinfo->keycode, key);
            continue;
        }

        gdk_error_trap_push();

        grab_key(grabber, keyinfo, TRUE);

        gdk_flush();
        gint error_code = gdk_error_trap_pop ();
        if(!error_code)
            grabber->keys = g_list_append(grabber->keys, keyinfo);
        else if(error_code == BadAccess)
            g_warning ("Grab failed, another application may already have access to key '%s'", key);
        else if(error_code == BadValue)
            g_warning ("Grab failed, invalid key %s specified. keysym: %u keycode: %u state: %u",
                       key, keyinfo->keysym, keyinfo->keycode, keyinfo->state);
        else
            g_warning ("Grab failed for key '%s' for unknown reason '%d'", key, error_code);
    }
}
示例#6
0
/*
 * Create all bindings, using stored configuration
 */
static void
create_bindings()
{
    GdkDisplay *display = gdk_display_get_default();
    GdkScreen *screen = gdk_display_get_default_screen(display);

    if (!screen)
        return;

    GdkWindow *root = gdk_screen_get_root_window(screen);
    gdk_window_add_filter(root, (GdkFilterFunc) filter_keys, NULL);

    /* bind shortcuts */
    for (Accelerator *acl = accelerators_list; acl->action != NULL; ++acl)
        if (acl->key != 0)
            grab_key(acl->key, acl->mask, root);
}
示例#7
0
static TUI_MENU_CALLBACK(keyset_callback)
{
    int direction, number;
    int value;
    char *rname;

    number = (int)param >> 8;
    direction = (int)param & 0xff;
    rname = lib_msprintf("KeySet%d%s", number, joystick_direction_to_string(direction));

    if (been_activated) {
        kbd_code_t key;
        int width = 60, height = 5;
        int x = CENTER_X(width), y = CENTER_Y(height);
        tui_area_t backing_store = NULL;
        char *msg;

        msg = lib_msprintf("Press key for %s%s (Esc for none)...", direction == KEYSET_FIRE ? "" : "direction ", joystick_direction_to_string(direction));
        tui_display_window(x, y, width, height, MESSAGE_BORDER, MESSAGE_BACK, NULL, &backing_store);
        tui_set_attr(MESSAGE_FORE, MESSAGE_BACK, 0);
        tui_display(CENTER_X(strlen(msg)), y + 2, 0, msg);
        lib_free(msg);

        /* Do not allow Alt as we need it for hotkeys.  */
        do {
            key = grab_key();
        } while (key == K_LEFTALT || key == K_RIGHTALT);

        tui_area_put(backing_store, x, y);
        tui_area_free(backing_store);

        if (key == K_ESC) {
            key = K_NONE;
        }
        resources_set_int(rname, (int)key);
    }

    resources_get_int(rname, &value);
    lib_free(rname);
    return kbd_code_to_string((kbd_code_t)value);
}
示例#8
0
void icon_set_shortcut(Icon *icon, const gchar *shortcut)
{
	g_return_if_fail(icon != NULL);

	if (shortcut && !*shortcut)
		shortcut = NULL;
	if (icon->shortcut == shortcut)
		return;
	if (icon->shortcut && shortcut && strcmp(icon->shortcut, shortcut) == 0)
		return;

	initModifiers();

	ungrab_key(icon);

	g_free(icon->shortcut);
	icon->shortcut = g_strdup(shortcut);
	parseKeyString(&icon->shortcut_key, shortcut);

	grab_key(icon);
}
示例#9
0
void build_mainwindow(void) {
    mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_widget_set_app_paintable(mainwindow, TRUE);
    gtk_widget_set_size_request(mainwindow, conf_get_width(), conf_get_height());
    gtk_window_set_decorated(GTK_WINDOW(mainwindow), FALSE);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwindow), TRUE);
    gtk_window_set_skip_pager_hint(GTK_WINDOW(mainwindow), TRUE);
    gtk_window_set_resizable(GTK_WINDOW(mainwindow), TRUE);
    mainwindow_reset_position();

    fullscreen = FALSE;
    toggled = FALSE;
    
    GtkAccelGroup* accel_group;
    GClosure *new_tab, *delete_tab, *next_tab, *prev_tab, *delete_all,
        *maximize, *copy, *paste;

    accel_group = gtk_accel_group_new();
    gtk_window_add_accel_group(GTK_WINDOW(mainwindow), accel_group);

    maximize = g_cclosure_new_swap(G_CALLBACK(mainwindow_toggle_fullscreen),
            NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_F11, 0,
            GTK_ACCEL_VISIBLE, maximize);
    
    new_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_new_tab), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, 't', conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, new_tab);

    delete_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_delete_tab), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, 'w', conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, delete_tab);

    next_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_next_tab), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_Page_Down, conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, next_tab);

    prev_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_prev_tab), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_Page_Up, conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, prev_tab);

    delete_all = g_cclosure_new_swap(G_CALLBACK(mainwindow_destroy), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, 'q', conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, delete_all);
            
    copy = g_cclosure_new_swap(G_CALLBACK(mainwindow_copy), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, 'c', conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, copy);
            
    paste = g_cclosure_new_swap(G_CALLBACK(mainwindow_paste), 
            NULL, NULL);
    gtk_accel_group_connect(accel_group, 'v', conf_get_key_mod(),
            GTK_ACCEL_VISIBLE, paste);

    activetab = -1;
    tabs = g_array_new(TRUE, FALSE, sizeof(VteTerminal*));
    tabcount = 0;
    GtkVBox* mainbox = GTK_VBOX(gtk_vbox_new(FALSE, 0));
    tabbar = GTK_NOTEBOOK(gtk_notebook_new());
    g_signal_connect(G_OBJECT(tabbar), "switch-page",
            G_CALLBACK(mainwindow_switch_tab), NULL);

    if (conf_get_opacity() < 100) {
        GdkScreen *screen = gdk_screen_get_default();
        GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
        screen_is_composited = (colormap != NULL
                && gdk_screen_is_composited(screen));

        if (screen_is_composited) {
            gtk_widget_set_colormap(GTK_WIDGET(mainwindow), colormap);
            gdk_screen_set_default_colormap(screen, colormap);
        }
    }

    gtk_box_pack_start(GTK_BOX(mainbox), GTK_WIDGET(tabbar), TRUE, TRUE, 0);

    mainwindow_create_tab();

    gtk_widget_show_all(GTK_WIDGET(mainbox));
    gtk_container_add(GTK_CONTAINER(mainwindow), GTK_WIDGET(mainbox));

    int border = conf_get_border();
    if (border == BORDER_THIN)
        gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 1);
    else if (border == BORDER_THICK)
        gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 5);
    if (border != BORDER_NONE)
        g_signal_connect(G_OBJECT(mainwindow), "expose-event",
                G_CALLBACK(mainwindow_expose_event), NULL);
    /*
     * g_signal_connect connects a GCallback function to a signal for a 
     * particular object.  For example, when the 'focus-out-event' signal is
     * triggered (That is, when Stjerm loses focus), the 
     * 'mainwindow_focus_out_event' function will run.
     */
    if (conf_get_auto_hide())
        g_signal_connect(G_OBJECT(mainwindow), "focus-out-event",
                G_CALLBACK(mainwindow_focus_out_event), NULL);
    g_signal_connect(G_OBJECT(mainwindow), "show", G_CALLBACK(mainwindow_show), 
            NULL);
    g_signal_connect(G_OBJECT(mainwindow), "destroy",
            G_CALLBACK(mainwindow_destroy), NULL);

    gtk_notebook_set_show_border(tabbar, FALSE);
    gtk_notebook_set_scrollable(tabbar, TRUE);
    if (conf_get_show_tab() == TABS_ONE|| conf_get_show_tab() == TABS_NEVER)
        gtk_notebook_set_show_tabs(tabbar, FALSE);
    gtk_notebook_set_tab_pos(tabbar, conf_get_tab_pos());

    XSetErrorHandler(handle_x_error);
    init_key(); // init_key and grab_key are
    grab_key(); // defined globally in stjerm.h
    g_thread_create((GThreadFunc)wait_key, NULL, FALSE, NULL);
}
int main()
{
	x_grab_key_init();
	grab_key();
}
示例#11
0
int main(int argc, char **argv)
{
	int opt = 0, port_num, client_len;
	struct sockaddr_in server_addr, client_addr;
	static struct option long_opts[] =
	{
		{"port", required_argument, 0, 'p'},
		{"encrypt", no_argument, 0, 'e'}
	};

	while((opt = getopt_long(argc, argv, "p:e", long_opts, NULL)) != -1)
	{
		switch(opt)
		{
			case 'p':
				//Grab port number
				port_num = atoi(optarg);
				break;
			case 'e':
				//Turn on Encryption
				crypt_flag = 1;
				//Get the key
				char* key = grab_key("my.key");
				//Initialize encryption and decryption
				encryption_decryption_init(key, key_len);
				break;
			default:
				//Usage message
				fprintf(stderr, "Usage [e] port_number");
				break;
		}
	}
	//Set up socket connection
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_fd < 0) { perror("Error opening socket"); exit(1); }
	memset((char*) &server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port_num);
	server_addr.sin_addr.s_addr = INADDR_ANY;
	if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
	{
		perror("Error binding socket");
		exit(1);
	}
	//Listen for data over the socket
	listen(socket_fd, 5);
	client_len = sizeof(client_addr);
	//Block while accepting data input as a stream
	newsocket_fd = accept(socket_fd, (struct sockaddr *) &client_addr, &client_len);
	if(newsocket_fd < 0) { perror("Error accepting the socket"); exit(1); }
	create_pipe(p1_fd);
	create_pipe(p2_fd);
	child_id = fork();
	if(child_id < 0) { perror("Error forking"); exit(1); }
	//Run the child process that is the shell
	else if(child_id == 0)	{ exec_shell(); }
	else
	{
		//Create the thread to send shell's output to the client
		pthread_create(&thread_id, NULL, transfer_shell, &newsocket_fd);
	}
	//Redirect stdin/stdout/stderr to the socket
	dup2(newsocket_fd, 0);
	dup2(newsocket_fd, 1);
	dup2(newsocket_fd, 2);
	close(newsocket_fd);
	read_write(0, p1_fd[1], 1);
	encryption_decryption_deinit();
	exit(0);
}
示例#12
0
void build_mainwindow(void)
{
    guint ic;
  
    uri_regex_count = G_N_ELEMENTS(uri_patterns);
    uri_regex = g_new0(GRegex*, uri_regex_count);

    for(ic = 0; ic < uri_regex_count; ++ic)
    {
        GError *error = NULL;
        
        uri_regex[ic] = g_regex_new(uri_patterns[ic].pattern,
            uri_patterns[ic].flags | G_REGEX_OPTIMIZE, 0, &error);
        
        if(error)
        {
            g_message("%s", error->message);
            g_error_free (error);
        }
    }

    mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_widget_set_app_paintable(mainwindow, TRUE);
    gtk_widget_set_size_request(mainwindow, conf_get_width(), conf_get_height());
    gtk_window_set_decorated(GTK_WINDOW(mainwindow), FALSE);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwindow), TRUE);
    gtk_window_set_skip_pager_hint(GTK_WINDOW(mainwindow), TRUE);
    gtk_window_set_resizable(GTK_WINDOW(mainwindow), TRUE);
    mainwindow_reset_position();

    fullscreen = FALSE;
    toggled = FALSE;

    GtkAccelGroup* accel_group;
    GClosure *new_tab, *delete_tab, *next_tab, *prev_tab, *delete_all,
        *maximize, *copy, *paste;

    GClosure *goto_tab_closure[10];
    long i;

    accel_group = gtk_accel_group_new();
    gtk_window_add_accel_group(GTK_WINDOW(mainwindow), accel_group);

    maximize = g_cclosure_new_swap(G_CALLBACK(mainwindow_toggle_fullscreen),
        NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_F11, 0,
        GTK_ACCEL_VISIBLE, maximize);

    new_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_new_tab), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, 't', conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, new_tab);

    delete_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_delete_tab), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, 'w', conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, delete_tab);

    next_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_next_tab), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_Page_Up, conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, next_tab);

    prev_tab = g_cclosure_new_swap(G_CALLBACK(mainwindow_prev_tab), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, GDK_Page_Down, conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, prev_tab);

    delete_all = g_cclosure_new_swap(G_CALLBACK(mainwindow_destroy), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, 'q', conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, delete_all);

    /* tab hotkeys, inspired by Tilda -- thanks to castorinop for the patch */
    for(i = 0; i < 10; i++)
    {
        goto_tab_closure[i] = g_cclosure_new_swap(G_CALLBACK(mainwindow_goto_tab),
            (gpointer) i, NULL);
        gtk_accel_group_connect(accel_group, '0' + ((i+1)%10), GDK_MOD1_MASK,
            GTK_ACCEL_VISIBLE, goto_tab_closure[i]);
    }

    copy = g_cclosure_new_swap(G_CALLBACK(mainwindow_copy), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, 'c', conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, copy);

    paste = g_cclosure_new_swap(G_CALLBACK(mainwindow_paste), 
        NULL, NULL);
    gtk_accel_group_connect(accel_group, 'v', conf_get_key_mod(),
        GTK_ACCEL_VISIBLE, paste);

    activetab = -1;
    tabcount = 0;
    GtkVBox* mainbox = GTK_VBOX(gtk_vbox_new(FALSE, 0));
    
    tabbar = GTK_NOTEBOOK(gtk_notebook_new());
    
    g_signal_connect(G_OBJECT(tabbar), "switch-page",
        G_CALLBACK(mainwindow_switch_tab), NULL);

    if(conf_get_opacity() < 100)
    {
        GdkScreen *screen = gdk_screen_get_default();
        GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
        screen_is_composited = (colormap != NULL
            && gdk_screen_is_composited(screen));

        if(screen_is_composited)
        {
            gtk_widget_set_colormap(GTK_WIDGET(mainwindow), colormap);
            gdk_screen_set_default_colormap(screen, colormap);
        }
    }

    gtk_box_pack_start(GTK_BOX(mainbox), GTK_WIDGET(tabbar), TRUE, TRUE, 0);

    mainwindow_create_tab();

    gtk_widget_show_all(GTK_WIDGET(mainbox));
    gtk_container_add(GTK_CONTAINER(mainwindow), GTK_WIDGET(mainbox));

    int border = conf_get_border();
    if(border == BORDER_THIN)
        gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 1);
    else if(border == BORDER_THICK)
        gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 5);
    if(border != BORDER_NONE)
        g_signal_connect(G_OBJECT(mainwindow), "expose-event",
            G_CALLBACK(mainwindow_expose_event), NULL);

    if(conf_get_auto_hide())
        g_signal_connect(G_OBJECT(mainwindow), "focus-out-event",
            G_CALLBACK(mainwindow_focus_out_event), NULL);
    g_signal_connect(G_OBJECT(mainwindow), "show", G_CALLBACK(mainwindow_show), 
        NULL);
    g_signal_connect(G_OBJECT(mainwindow), "destroy",
        G_CALLBACK(mainwindow_destroy), NULL);

    g_signal_connect_after(G_OBJECT(tabbar), "button_press_event", 
        G_CALLBACK(mainwindow_notebook_clicked), NULL);

    gtk_notebook_set_show_border(tabbar, FALSE);
    gtk_notebook_set_scrollable(tabbar, TRUE);
    if (conf_get_show_tab() == TABS_ONE|| conf_get_show_tab() == TABS_NEVER)
        gtk_notebook_set_show_tabs(tabbar, FALSE);
    gtk_notebook_set_tab_pos(tabbar, conf_get_tab_pos());
    gtk_notebook_set_homogeneous_tabs(tabbar, FALSE);

    XSetErrorHandler(handle_x_error);
    init_key();
    grab_key();
    g_thread_new("stjerm", (GThreadFunc)wait_key, NULL);
    
    // If stjerm has been started for the first time with --toggle, then
    // show the window straight away. Make haste!
    if(conf_get_toggled()) {
        mainwindow_toggle(1);
    }
}
示例#13
0
int XttHotkey::read_file()
{
  FILE *fp;
  char line[200];
  int row = 0;
  char p1[2][200];
  char p2[10][200];
  int i, n;
  char *s;

  dcli_translate_filename( m_filename, m_filename);
  fp = fopen( m_filename, "r");
  if ( !fp)
    return 0;

  while ( dcli_read_line( line, sizeof(line), fp)) {
    int mod = 0;
    int keysym;
    char keystr[20] = "";
    char action_arg[200];
    char action_name[200];

    row++;

    dcli_trim( line, line);
    if ( line[0] == 0 || line[0] == '#')
      continue;

    n = dcli_parse( line, ":", "", (char *)p1, 
		    sizeof( p1) / sizeof( p1[0]), sizeof( p1[0]), 0);
    if ( n != 2) {
      printf( "Syntax error, %s, row %d\n", m_filename, row);
      continue;
    }
    dcli_trim( p1[0], p1[0]);
    dcli_trim( p1[1], p1[1]);

    n = dcli_parse(  p1[0], " 	", "", (char *)p2, 
		    sizeof( p2) / sizeof( p2[0]), sizeof( p2[0]), 0);
    if ( n < 1) {
      printf( "Syntax error, %s, row %d\n", m_filename, row);
      continue;
    }
    for ( i = 0; i < n; i++) {
      if ( cdh_NoCaseStrcmp( p2[i], "Control") == 0)
	mod |= ControlMask;
      else if ( cdh_NoCaseStrcmp( p2[i], "Shift") == 0)
	mod |= ShiftMask; 
      else if ( cdh_NoCaseStrcmp( p2[i], "Alt") == 0)
	mod |= Mod1Mask; 
      else if ( cdh_NoCaseStrncmp( p2[i], "<key>", 5) == 0) {
	strcpy( keystr, &p2[i][5]);
      	dcli_trim( keystr, keystr);
      }
      else {
	printf( "Syntax error, %s, row %d\n", m_filename, row);
	break;
      }
    }

    n = dcli_parse(  p1[1], "(", "", (char *)p2, 
		     sizeof( p2) / sizeof( p2[0]), sizeof( p2[0]), 0);
    if ( n < 2) {
      printf( "Syntax error, %s, row %d\n", m_filename, row);
      continue;
    }
    strcpy( action_name, p2[0]);
    dcli_trim( action_name, action_name);
    strcpy( action_arg, p2[1]);
    if ( (s = strrchr( action_arg, ')')))
      *s = 0;
    else {
      printf( "Syntax error, %s, row %d\n", m_filename, row);
      continue;
    }
    keysym = XStringToKeysym( keystr);
    if ( !keysym) {
      printf( "Syntax error, %s, row %d\n", m_filename, row);
      continue;
    }

    HotkeyKey key( mod, keysym, action_name, action_arg);
    m_keys.push_back( key);
  }

  fclose( fp);

  for ( i = 0; i < (int)m_keys.size(); i++) {
    grab_key( m_keys[i].m_keysym, m_keys[i].m_mod);
  }

  return 1;
}