Ubuntu Kylin技术论坛

 找回密码
查看: 1654|回复: 1

给Mate终端与GDB增加快捷键

[复制链接]
  • TA的每日心情
    无聊
    2018-10-20 14:22
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2018-8-16 14:17:37 | 显示全部楼层 |阅读模式
    最近开始学习Linux编程,在Mate终端里试用了GDB的调试方式,对于习惯了用F5、F10和F11来调试的我来说,还真有点不习惯。于是我就把给Mate终端与GDB增加快捷键当作学习Linux编程的第一个实验目标来完成。现在我就把总结出来的方法分享给大家。
    下载Mate终端源程序并解压缩:
    里面有两个文件:
    mate-terminal-1.21.0.tar.gz是原始源码包
    mate-terminal-1.21.1.tar.xz是我改完的源码包
    不想自己动手的的朋友可以下载我改过的包。编译安装方法在后面。
    1.      添加菜单
    1)      先将下面的菜单代码添加到src/terminal-window.c文件中的terminal_window_init函数,menu_entries数组,/* Terminal menu */段的前面。
    /* Debugmenu */
       {
                "DebugProgram", NULL, N_("DebugProgram"), "F2",
                NULL,
                G_CALLBACK (debug_program_callback)
            },
       {
                "DebugProcess", NULL,N_("Debug Process"), "F3",
                NULL,
                G_CALLBACK (debug_process_callback)
            },
       {
                "DebugStart", NULL, N_("Debug Start"),"F4",
                NULL,
                G_CALLBACK (debug_start_callback)
            },
       {
                "DebugContinue", NULL,N_("Debug Continue"), "F5",
                NULL,
                G_CALLBACK (debug_continue_callback)
            },
       {
                "DebugNext", NULL, N_("Debug Next"),"F10",
                NULL,
                G_CALLBACK (debug_next_callback)
            },
       {
                "DebugStep", NULL, N_("Debug Step"),"F11",
                NULL,
                G_CALLBACK (debug_step_callback)
            },
    再在/* Toplevel */段中的{ "Search", NULL, N_("_Search") },下面加入
    { "Debug", NULL, N_("Debug") },
    2)      将下面的菜单项添加到src/terminal.xml文件中的<menuaction="Terminal">段的前面。
    <menu action="Debug">
    <menuitem action="DebugProgram" />
    <menuitem action="DebugProcess" />
    <separator />
    <menuitem action="DebugStart" />
    <menuitem action="DebugContinue" />
    <menuitem action="DebugNext" />
    <menuitem action="DebugStep" />
    </menu>
    3)      打开po/ zh_CN.po文件,查找src/terminal-window.c段,将下面的字段添加到里面。
    msgid"Debug"
    msgstr"调试"
    msgid"Debug Program"
    msgstr"调试程序"
    msgid"Debug Process"
    msgstr"调试进程"
    msgid"Debug Start"
    msgstr"开始调试"
    msgid"Debug Continue"
    msgstr"继续执行"
    msgid"Debug Next"
    msgstr"单步执行"
    msgid"Debug Step"
    msgstr"进入函数"
    msgid"Program Name"
    msgstr"程序名称"
    msgid"Name:"
    msgstr"名称:"
    msgid"Process Id"
    msgstr"进程ID"
    2.      添加调用代码
    1)      将下面代码添加到/src/terminal-window.c文件中的terminal_window_init (TerminalWindow *window)函数前面。
    staticvoid
    terminal_get_program_name_dialog_response_cb(GtkWidget *dialog,
                                           intresponse,
                                          TerminalScreen *screen)
    {
        if (response == GTK_RESPONSE_OK)
        {
            GtkEntry *entry;
            const gchar *gtext;
                GString *gstr;
            entry = GTK_ENTRY (g_object_get_data(G_OBJECT (dialog), "name-entry"));
            gtext = gtk_entry_get_text (entry);
                gstr = g_string_new(NULL);
                gstr = g_string_assign(gstr,"gdb ");
                g_string_append(gstr, gtext);
                gstr = g_string_append_c(gstr,'\n');
                vte_terminal_feed_child(screen,gstr->str, gstr->len);
                g_string_free(gstr, TRUE);
        }
        gtk_widget_destroy (dialog);
    }
    staticvoid
    terminal_get_program_id_dialog_response_cb(GtkWidget *dialog,
                                           int response,
                                          TerminalScreen *screen)
    {
        if (response == GTK_RESPONSE_OK)
        {
            GtkEntry *entry;
            const gchar *gtext;
                GString *gstr;
            entry = GTK_ENTRY (g_object_get_data(G_OBJECT (dialog), "id-entry"));
            gtext = gtk_entry_get_text (entry);
                gstr = g_string_new(NULL);
                gstr = g_string_assign(gstr,"gdb --pid ");
                g_string_append(gstr, gtext);
                gstr = g_string_append_c(gstr,'\n');
                vte_terminal_feed_child(screen,gstr->str, gstr->len);
                g_string_free(gstr, TRUE);
        }
        gtk_widget_destroy (dialog);
    }
    staticvoid
    debug_program_callback(GtkAction *action,TerminalWindow *window)
    {
       TerminalWindowPrivate *priv =window->priv;
       GtkWidget *dialog, *message_area, *hbox,*label, *entry;
       if (priv->active_screen == NULL)
                return;
       dialog = gtk_message_dialog_new (GTK_WINDOW(window),
                         GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT,
                         GTK_MESSAGE_OTHER,
                         GTK_BUTTONS_OK_CANCEL,
                         "%s","");
       gtk_window_set_title (GTK_WINDOW (dialog),_("Program Name"));
       gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
       gtk_window_set_role (GTK_WINDOW (dialog),"Program Name");
       gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
       g_signal_connect (dialog,"response",
                         G_CALLBACK(terminal_get_program_name_dialog_response_cb),
                         priv->active_screen);
       g_signal_connect (dialog,"delete-event",
                         G_CALLBACK(terminal_util_dialog_response_on_delete), NULL);
       message_area =gtk_message_dialog_get_message_area
                         (GTK_MESSAGE_DIALOG(dialog));
       gtk_container_foreach (
                         GTK_CONTAINER(message_area),
                         (GtkCallback)gtk_widget_hide,
                         NULL);
       hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
       gtk_box_pack_start (GTK_BOX (message_area),hbox, FALSE, FALSE, 0);
       label = gtk_label_new_with_mnemonic(_("Name:"));
       gtk_label_set_xalign (GTK_LABEL (label),0.0);
       gtk_label_set_yalign (GTK_LABEL (label),0.5);
       gtk_box_pack_start (GTK_BOX (hbox), label,FALSE, FALSE, 0);
       entry = gtk_entry_new ();
       gtk_entry_set_width_chars (GTK_ENTRY (entry),32);
       gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
       gtk_label_set_mnemonic_widget (GTK_LABEL(label), entry);
       gtk_box_pack_start (GTK_BOX (hbox), entry,TRUE, TRUE, 0);
       gtk_widget_show_all (hbox);
       gtk_widget_grab_focus (entry);
        g_object_set_data (G_OBJECT (dialog),"name-entry", entry);
       gtk_window_present (GTK_WINDOW (dialog));
    }
    staticvoid
    debug_process_callback(GtkAction *action,TerminalWindow *window)
    {
       TerminalWindowPrivate *priv =window->priv;
       GtkWidget *dialog, *message_area, *hbox,*label, *entry;
       if (priv->active_screen == NULL)
                return;
       dialog = gtk_message_dialog_new (GTK_WINDOW(window),
                         GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT,
                         GTK_MESSAGE_OTHER,
                         GTK_BUTTONS_OK_CANCEL,
                         "%s","");
       gtk_window_set_title (GTK_WINDOW (dialog),_("Process Id"));
       gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
       gtk_window_set_role (GTK_WINDOW (dialog),"mate-terminal-change-title");
       gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
       g_signal_connect (dialog,"response",
                         G_CALLBACK(terminal_get_program_id_dialog_response_cb),
                         priv->active_screen);
       g_signal_connect (dialog,"delete-event",
                         G_CALLBACK(terminal_util_dialog_response_on_delete), NULL);
       message_area =gtk_message_dialog_get_message_area
                         (GTK_MESSAGE_DIALOG(dialog));
       gtk_container_foreach (
                         GTK_CONTAINER(message_area),
                         (GtkCallback)gtk_widget_hide,
                         NULL);
       hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
       gtk_box_pack_start (GTK_BOX (message_area),hbox, FALSE, FALSE, 0);
       label = gtk_label_new_with_mnemonic(_("ID:"));
       gtk_label_set_xalign (GTK_LABEL (label),0.0);
       gtk_label_set_yalign (GTK_LABEL (label),0.5);
       gtk_box_pack_start (GTK_BOX (hbox), label,FALSE, FALSE, 0);
       entry = gtk_entry_new ();
       gtk_entry_set_width_chars (GTK_ENTRY (entry),32);
       gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
       gtk_label_set_mnemonic_widget (GTK_LABEL(label), entry);
       gtk_box_pack_start (GTK_BOX (hbox), entry,TRUE, TRUE, 0);
       gtk_widget_show_all (hbox);
       gtk_widget_grab_focus (entry);
        g_object_set_data (G_OBJECT (dialog),"id-entry", entry);
       gtk_window_present (GTK_WINDOW (dialog));
    }
    staticvoid
    debug_start_callback(GtkAction *action,TerminalWindow *window)
    {
       GString *gstr;
       gstr = g_string_new(NULL);
       gstr = g_string_assign(gstr,"start\n");
       vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
       g_string_free(gstr, TRUE);
    }
    staticvoid
    debug_continue_callback(GtkAction *action,TerminalWindow *window)
    {
       GString *gstr;
       gstr = g_string_new(NULL);
       gstr = g_string_assign(gstr,"c\n");
       vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
       g_string_free(gstr, TRUE);
    }
    staticvoid
    debug_next_callback(GtkAction *action,TerminalWindow *window)
    {
       GString *gstr;
       gstr = g_string_new(NULL);
       gstr = g_string_assign(gstr,"n\n");
       vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
       g_string_free(gstr, TRUE);
    }
    staticvoid
    debug_step_callback(GtkAction *action,TerminalWindow *window)
    {
       GString *gstr;
       gstr = g_string_new(NULL);
       gstr = g_string_assign(gstr,"s\n");
       vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
       g_string_free(gstr, TRUE);
    }
    2)      本来这样就应该可以了,但试用发现F5、F10和F11这三个键与Mate终端的按键有冲突,不得不加入代码屏蔽掉原有的快捷键。代码如下,将它们添加到window_key_press_cb函数returnFALSE;语句之前。
    elseif(event->keyval == GDK_KEY_F5)
       {
                TerminalWindow *window =TERMINAL_WINDOW (widget);
                GString *gstr;
                gstr = g_string_new(NULL);
                gstr = g_string_assign(gstr,"c\n");
                vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
                g_string_free(gstr, TRUE);
                return TRUE;
       }
       else if(event->keyval == GDK_KEY_F10)
       {
                TerminalWindow *window =TERMINAL_WINDOW (widget);
                GString *gstr;
                gstr = g_string_new(NULL);
                gstr = g_string_assign(gstr,"n\n");
                vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
                g_string_free(gstr, TRUE);
                return TRUE;
       }
       else if(event->keyval == GDK_KEY_F11)
       {
                TerminalWindow *window =TERMINAL_WINDOW (widget);
                GString *gstr;
                gstr = g_string_new(NULL);
                gstr = g_string_assign(gstr,"s\n");
                vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
                g_string_free(gstr, TRUE);
                return TRUE;
    }
    编译安装
    本例是在ubuntukylin-18.04-enhanced-amd64系统下进行的,如果你没有安装过mate-commonyelp-tools执行下面命令安装它们。
    sudoapt-get install mate-common
    sudoapt-get install yelp-tools
             注意命令执行完后是否有错误提示,如果有重新执行它们即可解决。
             安装依赖库,执行:
        sudo apt-get install libglib2.0-dev
    sudo apt-get installlibvte-2.91-dev
    sudo apt-get installlibdconf-dev
    安装Mate终端,执行:
    ./autogen.sh
    make
    sudomake install
             安装完成。
    添加好的菜单界面如下图:


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2018-10-20 14:22
  • 签到天数: 4 天

    [LV.2]偶尔看看I

     楼主| 发表于 2018-8-16 14:25:23 | 显示全部楼层
    使用方法
             调试程序:
             按F2键弹出程序名称对话框, 在对话框里面填写要调试的程序名称,也可以包含路径,例如:
             Test
             ./ Test
             /home/用户名/ mate-terminal-1.21.1/src/ Test
             然后点确定即可进入调试了。先按F4开始调试,按F10一行一行的执行程序,如果该行是函数并且系统里面有该函数的源码,按F11即可进入该函数,按F5可以全速运行程序。

    调试进程
             当一些程序运行起来后会关闭父进程,这时候就需要进程调试了,先在终端中输入ps –d查看要调试的进程ID,然后输入su进入root用户,(如果你是第一次使用su命令,先需要更改root用户密码,命令为sudo passwd root)按F3弹出进程ID对话框,在里面输入需要调试的进程ID,点确定进入调试,然后下断点程序就会停下来,这时我们就可以调试子程序了,方法与调试程序相同。

             本次分享到此结束。好了,朋友们再见了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|Ubuntu Kylin    

    GMT+8, 2019-11-19 21:56 , Processed in 0.015062 second(s), 7 queries , File On.

    Copyright ©2013-2019 Ubuntu Kylin. All Rights Reserved .

    ICP No. 15002470-2 Tianjin

    快速回复 返回顶部 返回列表