diff --git a/moo/mooterm/dcs b/moo/mooterm/dcs new file mode 100644 index 00000000..ebaa24a3 --- /dev/null +++ b/moo/mooterm/dcs @@ -0,0 +1,107 @@ +Assign User-Preference +Supp Set DCS Ps ! u Dscs ST DECAUPSS + Ps + 0 94-Character Set + 1 96-Character Set + + Dscs Default 94-Character Set + % 5 DEC Supplemental + " ? DEC Greek + " 4 DEC Hebrew + % 0 DEC Turkish + & 4 DEC Cyrillic + < User-preferred supplemental + + Dscs Default 96-Character Set + A ISO Latin-1 Supplemental + B ISO Latin-2 Supplemental + F ISO Greek Supplemental + H ISO Hebrew Supplemental + L ISO Latin-Cyrillic + M ISO Latin-5 Supplemental + < User-preferred supplemental + + +Request Selection or +Setting DECRQSS +Request (DECRQSS): DCS $ q D...D ST +Report (DECRPSS): DCS Ps $ r D...D ST + +Setting Control Sequence Final Characters Mnemonic + +Select Active Status +Display $ g DECSASD +Select Attribute Change +Extent * x DECSACE +Set Character Attribute " q DECSCA +Set Conformance Level " p DECSCL +Set Columns Per Page $ | DECSCPP +Set Lines Per Page t DECSLPP +Set Number of Lines per +Screen * | DECSNLS +Set Status Line Type $ ~ DECSSDT +Set Left and Right Margins s DECSLRM +Set Top and Bottom Margins r DECSTBM +Set Graphic Rendition m SGR +Select Set-Up Language p DECSSL +Select Printer Type $ s DECSPRTT +Select Refresh Rate " t DECSRFR +Select Digital Printed +Data Type ) p DECSDPT +Select ProPrinter Character +Set * p DECSPPCS +Select Communication Speed * r DECSCS +Select Communication Port * u DECSCP +Set Scroll Speed SP p DECSSCLS +Set Cursor Style SP q DECSCUSR +Set Key Click Volume SP r DECSKCV +Set Warning Bell Volume SP t DECSWBV +Set Margin Bell Volume SP u DECSMBV +Set Lock Key Style SP v DECSLCK +Select Flow Control Type * s DECSFC +Select Disconnect Delay +Time $ q DECSDDT +Set Transmit Rate Limit " u DECSTRL +Set Port Parameter + w DECSPP + + + +Restore Presentation State DCS Ps $ t D...D ST DECRSPS + + Ps Data String Format + 0 Error, restore ignored. + 1 Selects the format of the cursor information report (DECCIR). + 2 Selects the format of the tab stop report (DECTABSR). + + D...D + Data string of tab stops or cursor position. + + +Restore Terminal State DCS Ps $ p D...D ST DECRSTS + + Ps Data String Format + 0 Error, restore ignored. + 1 Selects the format of the terminal state report (DECTSR). + + D...D Data string of restored information. + + +Tabulation Stop Report DCS 2 $ u D...D ST DECTABSR + + D...D Column numbers of tab stops. + +Report Terminal Unit ID DCS ! | D...D ST DECRPTUI + +Report Function Key +Definition DCS " } D...D ST DECRPFK + +Report Modifiers/Key State DCS " ~ D...D ST DECRPAK + +Load Answerback Message DCS Ps v D...D ST DECLANS + + The answerback data string may consist of from 0 to 30, 7- or 8-bit characters, + which are hex pairs in the 3/0 through 3/9 (0 through 9) range, 4/1 through 4/6 + (A through F) range, and 6/1 through 6/6 (A through F) range. Pressing Ctrl/Break + or receiving an ENQ code causes the VT510 to transmit the answerback message. + +Load Banner Message DCS Ps r D...D ST DECLBAN diff --git a/moo/mooterm/mooterm-input.c b/moo/mooterm/mooterm-input.c index 5ba31692..b8a09cf8 100644 --- a/moo/mooterm/mooterm-input.c +++ b/moo/mooterm/mooterm-input.c @@ -9,15 +9,18 @@ * (at your option) any later version. * * See COPYING file that comes with this distribution. + * + * moo_term_key_press() code is taken from libvte vte.c, + * Copyright (C) 2001-2004 Red Hat, Inc. */ #define MOOTERM_COMPILATION -#include "mooterm/mooterm-private.h" #include "mooterm/mooterm-keymap.h" #include "mooterm/mootermpt.h" /* must be enough to fit '^' + one unicode character + 0 byte */ -#define MANY_CHARS 16 +#define MANY_CHARS 16 +#define META_MASK GDK_MOD1_MASK static GtkWidgetClass *widget_class (void) @@ -38,136 +41,257 @@ void moo_term_im_commit (G_GNUC_UNUSED GtkIMContext *imcontext } +/* shamelessly taken from vte.c */ gboolean moo_term_key_press (GtkWidget *widget, GdkEventKey *event) { - MooTerm *term = MOO_TERM (widget); - gboolean handled = FALSE; - gboolean scroll = FALSE; - gboolean clear_selection = FALSE; - char buffer[MANY_CHARS]; - const char *string = NULL; - char *freeme = NULL; - guint len = 0; - guint key = event->keyval; - GdkModifierType mods = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK); + MooTerm *term; + char *string = NULL; + gssize string_length = 0; + int i; + gboolean scrolled = FALSE; + gboolean steal = FALSE; + gboolean is_modifier = FALSE; + gboolean handled; + gboolean suppress_meta_esc = FALSE; + guint keyval = 0; + gunichar keychar = 0; + char keybuf[6]; /* 6 bytes for UTF-8 character */ + GdkModifierType modifiers; - if (gtk_im_context_filter_keypress (term->priv->im, event)) + term = MOO_TERM (widget); + + /* First, check if GtkWidget's behavior already does something with + * this key. */ + if (widget_class()->key_press_event (widget, event)) { - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; + return TRUE; } - else if (ignore (key)) + + keyval = event->keyval; + + /* If it's a keypress, record that we got the event, in case the + * input method takes the event from us. */ + term->priv->modifiers = modifiers = event->state; + modifiers &= (GDK_SHIFT_MASK | GDK_CONTROL_MASK | META_MASK); + + /* Determine if this is just a modifier key. */ + is_modifier = key_is_modifier (keyval); + + /* Unless it's a modifier key, hide the pointer. */ + if (!is_modifier && + term->priv->settings.hide_cursor_on_keypress && + moo_term_pt_child_alive (term->priv->pt)) { - handled = TRUE; + moo_term_set_pointer_visible (term, FALSE); } - else if (!mods) + + /* We steal many keypad keys here. */ + if (!term->priv->im_preedit_active) { - if (get_vt_key (term, event->keyval, &string, &len)) + switch (keyval) { - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; + CASE_GDK_KP_SOMETHING + steal = TRUE; + } + + if (modifiers & META_MASK) + { + steal = TRUE; } } - else if (mods == GDK_SHIFT_MASK) - { - switch (key) - { - case GDK_Up: - moo_term_scroll_lines (term, -1); - handled = TRUE; - break; - case GDK_Down: - moo_term_scroll_lines (term, 1); - handled = TRUE; - break; - case GDK_Insert: + /* Let the input method at this one first. */ + if (!steal) + { + if (gtk_im_context_filter_keypress(term->priv->im, event)) + return TRUE; + } + + if (is_modifier) + return FALSE; + + /* Now figure out what to send to the child. */ + handled = FALSE; + + switch (keyval) + { + case GDK_BackSpace: + get_backspace_key (term, &string, + &string_length, + &suppress_meta_esc); + handled = TRUE; + break; + + case GDK_Delete: + get_delete_key (term, &string, + &string_length, + &suppress_meta_esc); + handled = TRUE; + suppress_meta_esc = TRUE; + break; + + case GDK_Insert: + if (modifiers & GDK_SHIFT_MASK) + { moo_term_paste_clipboard (term); handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; - break; - - default: - /* ignore Shift key*/ - if (get_vt_key (term, event->keyval, &string, &len)) - { - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; - } - } - } - else if (mods == GDK_CONTROL_MASK) - { - if (get_vt_ctl_key (term, event->keyval, &string, &len)) - { - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; - } - else - { - switch (key) + suppress_meta_esc = TRUE; + } + else if (modifiers & GDK_CONTROL_MASK) { - case GDK_Insert: - moo_term_copy_clipboard (term); - handled = TRUE; - break; + moo_term_copy_clipboard (term); + handled = TRUE; + suppress_meta_esc = TRUE; + } + break; - case GDK_Break: - get_vt_ctl_key (term, GDK_C, &string, &len); - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; - break; + case GDK_Page_Up: + case GDK_KP_Page_Up: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_pages (term, -1); + scrolled = TRUE; + handled = TRUE; + suppress_meta_esc = TRUE; + } + break; + + case GDK_Page_Down: + case GDK_KP_Page_Down: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_pages (term, 1); + scrolled = TRUE; + handled = TRUE; + suppress_meta_esc = TRUE; + } + break; + + case GDK_Home: + case GDK_KP_Home: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_to_top (term); + scrolled = TRUE; + handled = TRUE; + } + break; + case GDK_End: + case GDK_KP_End: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_to_bottom (term); + scrolled = TRUE; + handled = TRUE; + } + break; + case GDK_Up: + case GDK_KP_Up: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_lines (term, -1); + scrolled = TRUE; + handled = TRUE; + } + break; + case GDK_Down: + case GDK_KP_Down: + if (modifiers & GDK_SHIFT_MASK) + { + moo_term_scroll_lines (term, 1); + scrolled = TRUE; + handled = TRUE; + } + break; + + case GDK_Break: + moo_term_ctrl_c (term); + handled = TRUE; + break; + } + + /* If the above switch statement didn't do the job, try mapping + * it to a literal or capability name. */ + if (!handled) + { + if (!(modifiers & GDK_CONTROL_MASK)) + get_vt_key (term, keyval, &string, &string_length); + else + get_vt_ctl_key (term, keyval, &string, &string_length); + + /* If we found something this way, suppress + * escape-on-meta. */ + if (string != NULL && string_length > 0) + suppress_meta_esc = TRUE; + } + + /* If we didn't manage to do anything, try to salvage a + * printable string. */ + if (!handled && !string) + { + /* Convert the keyval to a gunichar. */ + keychar = gdk_keyval_to_unicode(keyval); + string_length = 0; + + if (keychar != 0) + { + /* Convert the gunichar to a string. */ + string_length = g_unichar_to_utf8(keychar, keybuf); + + if (string_length) + { + string = g_malloc0 (string_length + 1); + memcpy (string, keybuf, string_length); + } + else + { + string = NULL; + } + } + + if (string && (modifiers & GDK_CONTROL_MASK)) + { + /* Replace characters which have "control" + * counterparts with those counterparts. */ + for (i = 0; i < string_length; i++) + { + if ((((guint8)string[i]) >= 0x40) && + (((guint8)string[i]) < 0x80)) + { + string[i] &= (~(0x60)); + } } } } - else if (mods == (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) + + /* If we got normal characters, send them to the child. */ + if (string) { - } - - - if (!handled) - { - gunichar c = gdk_keyval_to_unicode (event->keyval); - - if (c && g_unichar_isgraph (c)) + if (moo_term_pt_child_alive (term->priv->pt)) { - len = 0; + if (term->priv->settings.meta_sends_escape && + !suppress_meta_esc && + string_length > 0 && + (modifiers & META_MASK)) + { + moo_term_feed_child (term, "\033", 1); + } - if (mods & GDK_CONTROL_MASK) - buffer[len++] = '^'; - - len += g_unichar_to_utf8 (c, &buffer[len]); - buffer[len] = 0; - string = buffer; - - handled = TRUE; - scroll = TRUE; - clear_selection = TRUE; + if (string_length > 0) + { + moo_term_feed_child (term, string, string_length); + } } + + /* Keep the cursor on-screen. */ + if (!scrolled && term->priv->settings.scroll_on_keystroke) + moo_term_scroll_to_bottom (term); + + g_free(string); } - if (clear_selection) - term_selection_clear (term); - - if (string && moo_term_pt_child_alive (term->priv->pt)) - moo_term_feed_child (term, string, len); - - if (handled && term->priv->scroll_on_keystroke && scroll) - moo_term_scroll_to_bottom (term); - - g_free (freeme); - - if (!handled) - return widget_class()->key_press_event (widget, event); - else - return TRUE; + return TRUE; } diff --git a/moo/mooterm/mooterm-keymap.h b/moo/mooterm/mooterm-keymap.h index 9bb95d3c..5389e8de 100644 --- a/moo/mooterm/mooterm-keymap.h +++ b/moo/mooterm/mooterm-keymap.h @@ -16,6 +16,8 @@ #include #include +#include "mooterm/mooterm-private.h" +#include "mooterm/mootermpt.h" /* When the auxiliary keypad is in keypad numeric mode @@ -52,35 +54,485 @@ position reports to the host. */ -#define set_key(str) \ - *string = str; \ +static void get_vt_key (MooTerm *term, + guint keyval, + char **string, + guint *len); + + + +#define set_key(str) \ + *string = g_strdup (str); \ *len = strlen (str); -static gboolean get_arrow_key (MooTerm *term, - guint keyval, - const char **string, - guint *len); -static gboolean get_backspace_key (MooTerm *term, - const char **string, - guint *len); -static gboolean get_delete_key (MooTerm *term, - const char **string, - guint *len); -static gboolean get_keypad_key (MooTerm *term, - guint keyval, - const char **string, - guint *len); -static gboolean get_vt_ctl_key (MooTerm *term, - guint keyval, - const char **string, - guint *len); -static gboolean ignore (guint keyval); +#define CASE_GDK_KP_SOMETHING \ + case GDK_KP_F1: \ + case GDK_KP_F2: \ + case GDK_KP_F3: \ + case GDK_KP_F4: \ + case GDK_KP_Enter: \ + case GDK_KP_Home: \ + case GDK_KP_Left: \ + case GDK_KP_Up: \ + case GDK_KP_Right: \ + case GDK_KP_Down: \ + case GDK_KP_Page_Up: \ + case GDK_KP_Page_Down: \ + case GDK_KP_End: \ + case GDK_KP_Begin: \ + case GDK_KP_Insert: \ + case GDK_KP_Delete: \ + case GDK_KP_Separator: \ + case GDK_KP_Subtract: \ + case GDK_KP_Decimal: \ + case GDK_KP_0: \ + case GDK_KP_1: \ + case GDK_KP_2: \ + case GDK_KP_3: \ + case GDK_KP_4: \ + case GDK_KP_5: \ + case GDK_KP_6: \ + case GDK_KP_7: \ + case GDK_KP_8: \ + case GDK_KP_9: -static gboolean get_vt_key (MooTerm *term, - guint keyval, - const char **string, - guint *len) + +/* these are from VT102 manual */ +static void get_keypad_key (MooTerm *term, + guint keyval, + char **string, + guint *len) +{ + if (!term_get_mode (MODE_DECNKM)) + { + switch (keyval) + { + case GDK_KP_Enter: + get_vt_key (term, GDK_Return, string, len); + break; + case GDK_KP_Subtract: + set_key ("-"); + break; + case GDK_KP_0: + case GDK_KP_Insert: + set_key ("0"); + break; + case GDK_KP_1: + case GDK_KP_End: + set_key ("1"); + break; + case GDK_KP_2: + case GDK_KP_Down: + set_key ("2"); + break; + case GDK_KP_3: + case GDK_KP_Page_Down: + set_key ("3"); + break; + case GDK_KP_4: + case GDK_KP_Left: + set_key ("4"); + break; + case GDK_KP_5: + set_key ("5"); + break; + case GDK_KP_6: + case GDK_KP_Right: + set_key ("6"); + break; + case GDK_KP_7: + case GDK_KP_Home: + case GDK_KP_Begin: + set_key ("7"); + break; + case GDK_KP_8: + case GDK_KP_Up: + set_key ("8"); + break; + case GDK_KP_9: + case GDK_KP_Page_Up: + set_key ("9"); + break; + case GDK_KP_Decimal: + case GDK_KP_Delete: + set_key ("."); /* TODO should it be period/comma depending on locale? */ + break; + case GDK_KP_Separator: + set_key (","); /* TODO should it be period/comma depending on locale? */ + break; + case GDK_KP_F1: + set_key ("\033OP"); + break; + case GDK_KP_F2: + set_key ("\033OQ"); + break; + case GDK_KP_F3: + set_key ("\033OR"); + break; + case GDK_KP_F4: + set_key ("\033OS"); + break; + + default: + g_assert_not_reached (); + } + } + else + { + switch (keyval) + { + case GDK_KP_0: + case GDK_KP_Insert: + set_key ("\033Op"); + break; + case GDK_KP_1: + case GDK_KP_End: + set_key ("\033Oq"); + break; + case GDK_KP_2: + case GDK_KP_Down: + set_key ("\033Or"); + break; + case GDK_KP_3: + case GDK_KP_Page_Down: + set_key ("\033Os"); + break; + case GDK_KP_4: + case GDK_KP_Left: + set_key ("\033Ot"); + break; + case GDK_KP_5: + set_key ("\033Ou"); + break; + case GDK_KP_6: + case GDK_KP_Right: + set_key ("\033Ov"); + break; + case GDK_KP_7: + case GDK_KP_Home: + case GDK_KP_Begin: + set_key ("\033Ow"); + break; + case GDK_KP_8: + case GDK_KP_Up: + set_key ("\033Ox"); + break; + case GDK_KP_9: + case GDK_KP_Page_Up: + set_key ("\033Oy"); + break; + + case GDK_KP_Subtract: + set_key ("\033Om"); + break; + case GDK_KP_Decimal: + case GDK_KP_Delete: + set_key ("\033On"); /* TODO should it be period/comma depending on locale? */ + break; + case GDK_KP_Separator: + set_key ("\033Ol"); /* TODO should it be period/comma depending on locale? */ + break; + + case GDK_KP_Enter: + set_key ("\033OM"); + break; + + case GDK_KP_F1: + set_key ("\033OP"); + break; + case GDK_KP_F2: + set_key ("\033OQ"); + break; + case GDK_KP_F3: + set_key ("\033OR"); + break; + case GDK_KP_F4: + set_key ("\033OS"); + break; + + default: + g_assert_not_reached (); + } + } +} + + +/* VT102 manual */ +static void get_arrow_key (MooTerm *term, + guint keyval, + char **string, + guint *len) +{ + if (term_get_mode (MODE_DECNKM) && term_get_mode (MODE_DECCKM)) + { + switch (keyval) + { + case GDK_Left: + set_key ("\033OD"); + break; + case GDK_Up: + set_key ("\033OA"); + break; + case GDK_Right: + set_key ("\033OC"); + break; + case GDK_Down: + set_key ("\033OB"); + break; + + default: + g_assert_not_reached (); + } + } + else + { + switch (keyval) + { + case GDK_Left: + set_key ("\033[D"); + break; + case GDK_Up: + set_key ("\033[A"); + break; + case GDK_Right: + set_key ("\033[C"); + break; + case GDK_Down: + set_key ("\033[B"); + break; + + default: + g_assert_not_reached (); + } + } +} + + +/* +print ''.join(['case GDK_%s:\ncase GDK_%s:\n set_key ("\\%03o");\n break;\n' % (chr(i), chr(i+32), i-64) for i in range(ord('A'), ord('Z') + 1)]) +*/ +static void get_vt_ctl_key (G_GNUC_UNUSED MooTerm *term, + guint keyval, + char **string, + guint *len) +{ + switch (keyval) + { + case GDK_A: + case GDK_a: + set_key ("\001"); + break; + case GDK_B: + case GDK_b: + set_key ("\002"); + break; + case GDK_C: + case GDK_c: + set_key ("\003"); + break; + case GDK_D: + case GDK_d: + set_key ("\004"); + break; + case GDK_E: + case GDK_e: + set_key ("\005"); + break; + case GDK_F: + case GDK_f: + set_key ("\006"); + break; + case GDK_G: + case GDK_g: + set_key ("\007"); + break; + case GDK_H: + case GDK_h: + set_key ("\010"); + break; + case GDK_I: + case GDK_i: + set_key ("\011"); + break; + case GDK_J: + case GDK_j: + set_key ("\012"); + break; + case GDK_K: + case GDK_k: + set_key ("\013"); + break; + case GDK_L: + case GDK_l: + set_key ("\014"); + break; + case GDK_M: + case GDK_m: + set_key ("\015"); + break; + case GDK_N: + case GDK_n: + set_key ("\016"); + break; + case GDK_O: + case GDK_o: + set_key ("\017"); + break; + case GDK_P: + case GDK_p: + set_key ("\020"); + break; + case GDK_Q: + case GDK_q: + set_key ("\021"); + break; + case GDK_R: + case GDK_r: + set_key ("\022"); + break; + case GDK_S: + case GDK_s: + set_key ("\023"); + break; + case GDK_T: + case GDK_t: + set_key ("\024"); + break; + case GDK_U: + case GDK_u: + set_key ("\025"); + break; + case GDK_V: + case GDK_v: + set_key ("\026"); + break; + case GDK_W: + case GDK_w: + set_key ("\027"); + break; + case GDK_X: + case GDK_x: + set_key ("\030"); + break; + case GDK_Y: + case GDK_y: + set_key ("\031"); + break; + case GDK_Z: + case GDK_z: + set_key ("\032"); + break; + + case GDK_space: + *string = g_strdup ("\000"); + *len = 1; + break; + + case GDK_bracketleft: + case GDK_braceleft: + set_key ("\033"); + break; + case GDK_backslash: + case GDK_bar: + set_key ("\034"); + break; + case GDK_bracketright: + case GDK_braceright: + set_key ("\035"); + break; + case GDK_asciitilde: + case GDK_quoteleft: + set_key ("\036"); + break; + case GDK_question: + case GDK_slash: + set_key ("\037"); + break; + } +} + + +static void get_backspace_key (MooTerm *term, + char **normal, + guint *normal_length, + gboolean *suppress_meta_esc) +{ + char c; + + switch (term->priv->settings.backspace_binding) + { + case MOO_TERM_ERASE_ASCII_BACKSPACE: + *normal = g_strdup ("\010"); + *normal_length = 1; + *suppress_meta_esc = FALSE; + break; + + case MOO_TERM_ERASE_ASCII_DELETE: + *normal = g_strdup ("\177"); + *normal_length = 1; + *suppress_meta_esc = FALSE; + break; + + case MOO_TERM_ERASE_DELETE_SEQUENCE: + *normal = g_strdup ("\033[3~"); + *normal_length = 4; + *suppress_meta_esc = TRUE; + break; + + /* Use the tty's erase character. */ + case MOO_TERM_ERASE_AUTO: + default: + c = moo_term_pt_get_erase_char (term->priv->pt); + if (c) + { + *normal = g_strdup_printf("%c", c); + *normal_length = 1; + *suppress_meta_esc = FALSE; + } + else + { + *normal = g_strdup ("\010"); + *normal_length = 1; + *suppress_meta_esc = FALSE; + } + break; + } +} + + +static void get_delete_key (MooTerm *term, + char **normal, + guint *normal_length, + gboolean *suppress_meta_esc) +{ + switch (term->priv->settings.delete_binding) + { + case MOO_TERM_ERASE_ASCII_BACKSPACE: + *normal = g_strdup("\010"); + *normal_length = 1; + break; + + case MOO_TERM_ERASE_ASCII_DELETE: + *normal = g_strdup("\177"); + *normal_length = 1; + break; + + case MOO_TERM_ERASE_DELETE_SEQUENCE: + case MOO_TERM_ERASE_AUTO: + default: + *normal = g_strdup ("\033[3~"); + *normal_length = 4; + *suppress_meta_esc = TRUE; + break; + } +} + + +static void get_vt_key (MooTerm *term, + guint keyval, + char **string, + guint *len) { switch (keyval) { @@ -88,54 +540,15 @@ static gboolean get_vt_key (MooTerm *term, case GDK_Up: case GDK_Right: case GDK_Down: - return get_arrow_key (term, keyval, string, len); + get_arrow_key (term, keyval, string, len); + break; - case GDK_BackSpace: - return get_backspace_key (term, string, len); - case GDK_Delete: - return get_delete_key (term, string, len); - - case GDK_KP_Space: - return get_vt_key (term, GDK_space, string, len); - case GDK_KP_Tab: - return get_vt_key (term, GDK_Tab, string, len); - - case GDK_KP_F1: - case GDK_KP_F2: - case GDK_KP_F3: - case GDK_KP_F4: - case GDK_KP_Enter: - case GDK_KP_Home: - case GDK_KP_Left: - case GDK_KP_Up: - case GDK_KP_Right: - case GDK_KP_Down: - case GDK_KP_Page_Up: - case GDK_KP_Page_Down: - case GDK_KP_End: - case GDK_KP_Begin: - case GDK_KP_Insert: - case GDK_KP_Delete: - case GDK_KP_Equal: - case GDK_KP_Multiply: - case GDK_KP_Add: - case GDK_KP_Separator: - case GDK_KP_Subtract: - case GDK_KP_Decimal: - case GDK_KP_Divide: - case GDK_KP_0: - case GDK_KP_1: - case GDK_KP_2: - case GDK_KP_3: - case GDK_KP_4: - case GDK_KP_5: - case GDK_KP_6: - case GDK_KP_7: - case GDK_KP_8: - case GDK_KP_9: - return get_keypad_key (term, keyval, string, len); + CASE_GDK_KP_SOMETHING + get_keypad_key (term, keyval, string, len); + break; case GDK_Tab: + case GDK_KP_Tab: set_key ("\011"); break; case GDK_Linefeed: @@ -276,437 +689,14 @@ static gboolean get_vt_key (MooTerm *term, case GDK_F35: set_key ("\033[23;5~"); break; - - default: - return FALSE; - } - - return TRUE; -} - - -/* VT102 manual */ -static gboolean get_arrow_key (MooTerm *term, - guint keyval, - const char **string, - guint *len) -{ - if (term_get_mode (MODE_DECNKM) && term_get_mode (MODE_DECCKM)) - { - switch (keyval) - { - case GDK_Left: - set_key ("\033OD"); - break; - case GDK_Up: - set_key ("\033OA"); - break; - case GDK_Right: - set_key ("\033OC"); - break; - case GDK_Down: - set_key ("\033OB"); - break; - - default: - g_assert_not_reached (); - } - } - else - { - switch (keyval) - { - case GDK_Left: - set_key ("\033[D"); - break; - case GDK_Up: - set_key ("\033[A"); - break; - case GDK_Right: - set_key ("\033[C"); - break; - case GDK_Down: - set_key ("\033[B"); - break; - - default: - g_assert_not_reached (); - } - } - - return TRUE; -} - - -static gboolean get_backspace_key (MooTerm *term, - const char **string, - guint *len) -{ - if (term_get_mode (MODE_DECBKM)) - { - set_key ("\010"); - return TRUE; - } - else - { - return get_delete_key (term, string, len); } } -/* TODO */ -static gboolean get_delete_key (G_GNUC_UNUSED MooTerm *term, - const char **string, - guint *len) -{ - set_key ("\033[3~"); - return TRUE; -} - - -/* these are from VT102 manual */ -static gboolean get_keypad_key (MooTerm *term, - guint keyval, - const char **string, - guint *len) -{ - if (!term_get_mode (MODE_DECNKM)) - { - switch (keyval) - { - case GDK_KP_Subtract: - set_key ("-"); - break; - case GDK_KP_Equal: - set_key ("="); - break; - case GDK_KP_Multiply: - set_key ("*"); - break; - case GDK_KP_Add: - set_key ("+"); - break; - - case GDK_KP_Divide: - set_key ("/"); - break; - case GDK_KP_0: - case GDK_KP_Insert: - set_key ("0"); - break; - case GDK_KP_1: - case GDK_KP_End: - set_key ("1"); - break; - case GDK_KP_2: - case GDK_KP_Down: - set_key ("2"); - break; - case GDK_KP_3: - case GDK_KP_Page_Down: - set_key ("3"); - break; - case GDK_KP_4: - case GDK_KP_Left: - set_key ("4"); - break; - case GDK_KP_5: - set_key ("5"); - break; - case GDK_KP_6: - case GDK_KP_Right: - set_key ("6"); - break; - case GDK_KP_7: - case GDK_KP_Home: - case GDK_KP_Begin: - set_key ("7"); - break; - case GDK_KP_8: - case GDK_KP_Up: - set_key ("8"); - break; - case GDK_KP_9: - case GDK_KP_Page_Up: - set_key ("9"); - break; - case GDK_KP_Decimal: - case GDK_KP_Delete: - set_key ("."); /* TODO should it be period/comma depending on locale? */ - break; - case GDK_KP_Separator: - set_key (","); /* TODO should it be period/comma depending on locale? */ - break; - case GDK_KP_Enter: - return get_vt_key (term, GDK_Return, string, len); - case GDK_KP_F1: - set_key ("\033OP"); - break; - case GDK_KP_F2: - set_key ("\033OQ"); - break; - case GDK_KP_F3: - set_key ("\033OR"); - break; - case GDK_KP_F4: - set_key ("\033OS"); - break; - - default: - g_assert_not_reached (); - } - } - else - { - switch (keyval) - { - case GDK_KP_0: - case GDK_KP_Insert: - set_key ("\033Op"); - break; - case GDK_KP_1: - case GDK_KP_End: - set_key ("\033Oq"); - break; - case GDK_KP_2: - case GDK_KP_Down: - set_key ("\033Or"); - break; - case GDK_KP_3: - case GDK_KP_Page_Down: - set_key ("\033Os"); - break; - case GDK_KP_4: - case GDK_KP_Left: - set_key ("\033Ot"); - break; - case GDK_KP_5: - set_key ("\033Ou"); - break; - case GDK_KP_6: - case GDK_KP_Right: - set_key ("\033Ov"); - break; - case GDK_KP_7: - case GDK_KP_Home: - case GDK_KP_Begin: - set_key ("\033Ow"); - break; - case GDK_KP_8: - case GDK_KP_Up: - set_key ("\033Ox"); - break; - case GDK_KP_9: - case GDK_KP_Page_Up: - set_key ("\033Oy"); - break; - - case GDK_KP_Subtract: - set_key ("\033Om"); - break; - case GDK_KP_Decimal: - case GDK_KP_Delete: - set_key ("\033On"); /* TODO should it be period/comma depending on locale? */ - break; - case GDK_KP_Separator: - set_key ("\033Ol"); /* TODO should it be period/comma depending on locale? */ - break; - - case GDK_KP_Enter: - set_key ("\033OM"); - break; - - case GDK_KP_F1: - set_key ("\033OP"); - break; - case GDK_KP_F2: - set_key ("\033OQ"); - break; - case GDK_KP_F3: - set_key ("\033OR"); - break; - case GDK_KP_F4: - set_key ("\033OS"); - break; - - case GDK_KP_Equal: - set_key ("="); - break; - case GDK_KP_Multiply: - set_key ("*"); - break; - case GDK_KP_Add: - set_key ("+"); - break; - case GDK_KP_Divide: - set_key ("/"); - break; - - default: - g_assert_not_reached (); - } - } - - return TRUE; -} - - -/* -print ''.join(['case GDK_%s:\ncase GDK_%s:\n set_key ("\\%03o");\n break;\n' % (chr(i), chr(i+32), i-64) for i in range(ord('A'), ord('Z') + 1)]) -*/ -static gboolean get_vt_ctl_key (G_GNUC_UNUSED MooTerm *term, - guint keyval, - const char **string, - guint *len) +static gboolean key_is_modifier (guint keyval) { switch (keyval) { - case GDK_A: - case GDK_a: - set_key ("\001"); - break; - case GDK_B: - case GDK_b: - set_key ("\002"); - break; - case GDK_C: - case GDK_c: - set_key ("\003"); - break; - case GDK_D: - case GDK_d: - set_key ("\004"); - break; - case GDK_E: - case GDK_e: - set_key ("\005"); - break; - case GDK_F: - case GDK_f: - set_key ("\006"); - break; - case GDK_G: - case GDK_g: - set_key ("\007"); - break; - case GDK_H: - case GDK_h: - set_key ("\010"); - break; - case GDK_I: - case GDK_i: - set_key ("\011"); - break; - case GDK_J: - case GDK_j: - set_key ("\012"); - break; - case GDK_K: - case GDK_k: - set_key ("\013"); - break; - case GDK_L: - case GDK_l: - set_key ("\014"); - break; - case GDK_M: - case GDK_m: - set_key ("\015"); - break; - case GDK_N: - case GDK_n: - set_key ("\016"); - break; - case GDK_O: - case GDK_o: - set_key ("\017"); - break; - case GDK_P: - case GDK_p: - set_key ("\020"); - break; - case GDK_Q: - case GDK_q: - set_key ("\021"); - break; - case GDK_R: - case GDK_r: - set_key ("\022"); - break; - case GDK_S: - case GDK_s: - set_key ("\023"); - break; - case GDK_T: - case GDK_t: - set_key ("\024"); - break; - case GDK_U: - case GDK_u: - set_key ("\025"); - break; - case GDK_V: - case GDK_v: - set_key ("\026"); - break; - case GDK_W: - case GDK_w: - set_key ("\027"); - break; - case GDK_X: - case GDK_x: - set_key ("\030"); - break; - case GDK_Y: - case GDK_y: - set_key ("\031"); - break; - case GDK_Z: - case GDK_z: - set_key ("\032"); - break; - - case GDK_space: - *string = "\000"; - *len = 1; - break; - - case GDK_bracketleft: - case GDK_braceleft: - set_key ("\033"); - break; - case GDK_backslash: - case GDK_bar: - set_key ("\034"); - break; - case GDK_bracketright: - case GDK_braceright: - set_key ("\035"); - break; - case GDK_asciitilde: - case GDK_quoteleft: - set_key ("\036"); - break; - case GDK_question: - case GDK_slash: - set_key ("\037"); - break; - - default: - return FALSE; - } - - return TRUE; -} - - -static gboolean ignore (guint keyval) -{ - switch (keyval) - { - case GDK_VoidSymbol: - case GDK_Menu: - case GDK_Alt_L: case GDK_Alt_R: case GDK_Caps_Lock: diff --git a/moo/mooterm/mooterm-private.h b/moo/mooterm/mooterm-private.h index 4d3c33af..d11973bb 100644 --- a/moo/mooterm/mooterm-private.h +++ b/moo/mooterm/mooterm-private.h @@ -45,10 +45,10 @@ G_BEGIN_DECLS typedef enum { - CURSOR_NONE = 0, - CURSOR_TEXT = 1, - CURSOR_POINTER = 2, - CURSORS_NUM = 3 + POINTER_NONE = 0, + POINTER_TEXT = 1, + POINTER_NORMAL = 2, + POINTERS_NUM = 3 } TermCursorType; enum { @@ -104,14 +104,25 @@ struct _MooTermPrivate { TermCaretShape caret_shape; guint caret_height; - GdkCursor *cursor[CURSORS_NUM]; - GtkIMContext *im; + GdkCursor *pointer[POINTERS_NUM]; + guint tracking_mouse; + gboolean pointer_visible; - gboolean scroll_on_keystroke; + GtkIMContext *im; + gboolean im_preedit_active; + GdkModifierType modifiers; GtkAdjustment *adjustment; guint pending_adjustment_changed; guint pending_adjustment_value_changed; + + struct { + gboolean hide_cursor_on_keypress; /* = TRUE */ + gboolean meta_sends_escape; /* = TRUE */ + gboolean scroll_on_keystroke; /* = TRUE */ + MooTermEraseBinding backspace_binding; + MooTermEraseBinding delete_binding; + } settings; }; void moo_term_set_window_title (MooTerm *term, @@ -132,18 +143,23 @@ void moo_term_buf_size_changed (MooTerm *term); void moo_term_init_font_stuff (MooTerm *term); void moo_term_setup_palette (MooTerm *term); -void moo_term_im_commit (GtkIMContext *imcontext, - gchar *arg, - MooTerm *term); +void moo_term_set_pointer_visible (MooTerm *term, + gboolean visible); gboolean moo_term_button_press (GtkWidget *widget, GdkEventButton *event); gboolean moo_term_button_release (GtkWidget *widget, GdkEventButton *event); + gboolean moo_term_key_press (GtkWidget *widget, GdkEventKey *event); gboolean moo_term_key_release (GtkWidget *widget, GdkEventKey *event); +void moo_term_im_commit (GtkIMContext *imcontext, + gchar *arg, + MooTerm *term); +void moo_term_im_preedit_start (MooTerm *term); +void moo_term_im_preedit_end (MooTerm *term); void moo_term_init_back_pixmap (MooTerm *term); void moo_term_resize_back_pixmap (MooTerm *term); @@ -169,6 +185,9 @@ inline static void moo_term_invalidate_all (MooTerm *term) /* vt commands */ +void moo_term_reset (MooTerm *term); +void moo_term_soft_reset (MooTerm *term); + void moo_term_bell (MooTerm *term); void moo_term_decid (MooTerm *term); void moo_term_set_dec_modes (MooTerm *term, @@ -203,6 +222,13 @@ void moo_term_da1 (MooTerm *term); void moo_term_da2 (MooTerm *term); void moo_term_da3 (MooTerm *term); +void moo_term_setting_request (MooTerm *term, + int setting); +void moo_term_dsr (MooTerm *term, + int type, + int arg, + gboolean extended); + /*************************************************************************/ /* font info diff --git a/moo/mooterm/mooterm-vt.h b/moo/mooterm/mooterm-vt.h index 91ef3cf2..0e5cae8f 100644 --- a/moo/mooterm/mooterm-vt.h +++ b/moo/mooterm/mooterm-vt.h @@ -110,6 +110,7 @@ enum { from the host. */ MODE_CA, + MODE_REVERSE_WRAPAROUND, MODE_PRESS_TRACKING, MODE_PRESS_AND_RELEASE_TRACKING, @@ -129,9 +130,10 @@ enum { #define DEFAULT_MODE_DECAWM TRUE #define DEFAULT_MODE_DECTCEM TRUE #define DEFAULT_MODE_DECNKM FALSE -#define DEFAULT_MODE_DECBKM FALSE +#define DEFAULT_MODE_DECBKM TRUE /* Backspace key send BS */ #define DEFAULT_MODE_DECKPM FALSE #define DEFAULT_MODE_CA FALSE +#define DEFAULT_MODE_REVERSE_WRAPAROUND FALSE #define DEFAULT_MODE_PRESS_TRACKING FALSE #define DEFAULT_MODE_PRESS_AND_RELEASE_TRACKING FALSE #define DEFAULT_MODE_HILITE_MOUSE_TRACKING FALSE @@ -152,6 +154,7 @@ enum { ar[MODE_DECBKM] = DEFAULT_MODE_DECBKM; \ ar[MODE_DECKPM] = DEFAULT_MODE_DECKPM; \ ar[MODE_CA] = DEFAULT_MODE_CA; \ + ar[MODE_REVERSE_WRAPAROUND] = DEFAULT_MODE_REVERSE_WRAPAROUND; \ ar[MODE_PRESS_TRACKING] = DEFAULT_MODE_PRESS_TRACKING; \ ar[MODE_PRESS_AND_RELEASE_TRACKING] = DEFAULT_MODE_PRESS_AND_RELEASE_TRACKING; \ ar[MODE_HILITE_MOUSE_TRACKING] = MODE_HILITE_MOUSE_TRACKING; \ @@ -195,6 +198,9 @@ enum { case 9: \ mode = MODE_PRESS_TRACKING; \ break; \ + case 45: \ + mode = MODE_REVERSE_WRAPAROUND; \ + break; \ case 1000: \ mode = MODE_PRESS_AND_RELEASE_TRACKING; \ break; \ @@ -213,6 +219,7 @@ enum { case 34: \ case 35: \ case 36: \ + case 40: \ case 42: \ case 57: \ case 60: \ @@ -316,4 +323,22 @@ typedef enum { } AnsiTextAttr; +/* DECRQSS parameters */ +typedef enum { + CODE_DECSASD, /* Select Active Status Display*/ + CODE_DECSCL, /* Set Conformance Level */ + CODE_DECSCPP, /* Set Columns Per Page */ + CODE_DECSLPP, /* Set Lines Per Page */ + CODE_DECSNLS, /* Set Number of Lines per Screen */ + CODE_DECSTBM, /* Set Top and Bottom Margins */ +} DECRQSSCode; + +#define FINAL_DECSASD "$g" +#define FINAL_DECSCL "\"p" +#define FINAL_DECSCPP "$|" +#define FINAL_DECSLPP "t" +#define FINAL_DECSNLS "*|" +#define FINAL_DECSTBM "r" + + #endif /* MOOTERM_MOOTERM_VT_H */ diff --git a/moo/mooterm/mooterm-vtctls.h b/moo/mooterm/mooterm-vtctls.h index c9b2bd0a..80526ad3 100644 --- a/moo/mooterm/mooterm-vtctls.h +++ b/moo/mooterm/mooterm-vtctls.h @@ -24,8 +24,15 @@ term_implement_me_warning ("'%s': implement me", s); \ g_free (s); \ } +#define vt_ignored() \ +{ \ + char *s = _moo_term_current_ctl (parser); \ + g_warning ("'%s' ignored", s); \ + g_free (s); \ +} #else #define vt_not_implemented() +#define vt_ignored() #endif @@ -39,7 +46,7 @@ #define vt_BEL() moo_term_bell (parser->term) #define vt_BS() moo_term_buffer_backspace (parser->term->priv->buffer) -#define vt_TAB() moo_term_buffer_tab (parser->term->priv->buffer) +#define vt_TAB() moo_term_buffer_tab (parser->term->priv->buffer, 1) #define vt_LF() moo_term_buffer_linefeed (parser->term->priv->buffer) #define vt_CR() moo_term_buffer_carriage_return (parser->term->priv->buffer) #define vt_SO() moo_term_buffer_shift (parser->term->priv->buffer, 1) @@ -47,6 +54,7 @@ #define vt_IND() moo_term_buffer_index (parser->term->priv->buffer) #define vt_NEL() moo_term_buffer_new_line (parser->term->priv->buffer) #define vt_HTS() moo_term_buffer_set_tab_stop (parser->term->priv->buffer) +#define vt_TBC(w) moo_term_buffer_clear_tab_stop (parser->term->priv->buffer, w) #define vt_RI() moo_term_buffer_reverse_index (parser->term->priv->buffer) #define vt_SS2() moo_term_buffer_single_shift (parser->term->priv->buffer, 2) #define vt_SS3() moo_term_buffer_single_shift (parser->term->priv->buffer, 3) @@ -97,6 +105,20 @@ #define vt_DA1() moo_term_da1 (parser->term) #define vt_DA2() moo_term_da2 (parser->term) #define vt_DA3() moo_term_da3 (parser->term) +#define vt_DECRQSS(s) moo_term_setting_request (parser->term, s) +#define vt_DSR(t,a,e) moo_term_dsr (parser->term, t, a, e) +#define vt_DECSTR() moo_term_soft_reset (parser->term) +#define vt_RIS() moo_term_reset (parser->term) + +#define vt_CBT(n) moo_term_buffer_back_tab (parser->term->priv->buffer, n) +#define vt_CHA(n) moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, n) +#define vt_CHT(n) moo_term_buffer_tab (parser->term->priv->buffer, n) +#define vt_CNL(n) moo_term_buffer_cursor_next_line (parser->term->priv->buffer, n) +#define vt_CPL(n) moo_term_buffer_cursor_prev_line (parser->term->priv->buffer, n) +#define vt_HPA(n) moo_term_buffer_cursor_move_to (parser->term->priv->buffer, -1, n) +#define vt_HPR(n) moo_term_buffer_cursor_move (parser->term->priv->buffer, 0, n) +#define vt_VPA(n) moo_term_buffer_cursor_move_to (parser->term->priv->buffer, n, -1) +#define vt_VPR(n) moo_term_buffer_cursor_move (parser->term->priv->buffer, n, 0) #endif /* MOOTERM_MOOTERM_CTLFUNCS_H */ diff --git a/moo/mooterm/mooterm.c b/moo/mooterm/mooterm.c index 4bce6749..d0d0747e 100644 --- a/moo/mooterm/mooterm.c +++ b/moo/mooterm/mooterm.c @@ -59,12 +59,16 @@ static void width_changed (MooTerm *term, static void height_changed (MooTerm *term, GParamSpec *pspec); +static void im_preedit_start (MooTerm *term); +static void im_preedit_end (MooTerm *term); + enum { SET_SCROLL_ADJUSTMENTS, SET_WINDOW_TITLE, SET_ICON_NAME, BELL, + CHILD_DIED, LAST_SIGNAL }; @@ -139,6 +143,15 @@ static void moo_term_class_init (MooTermClass *klass) NULL, NULL, _moo_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[CHILD_DIED] = + g_signal_new ("child-died", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MooTermClass, child_died), + NULL, NULL, + _moo_marshal_VOID__VOID, + G_TYPE_NONE, 0); } @@ -159,7 +172,14 @@ static void moo_term_init (MooTerm *term) term->priv->selection = term_selection_new (); term->priv->cursor_visible = TRUE; - term->priv->scroll_on_keystroke = TRUE; + + term->priv->settings.hide_cursor_on_keypress = TRUE; + term->priv->settings.meta_sends_escape = TRUE; + term->priv->settings.scroll_on_keystroke = TRUE; + term->priv->settings.backspace_binding = MOO_TERM_ERASE_AUTO; + term->priv->settings.delete_binding = MOO_TERM_ERASE_AUTO; + + term->priv->pointer_visible = TRUE; set_default_modes (term->priv->modes); set_default_modes (term->priv->saved_modes); @@ -241,9 +261,9 @@ static void moo_term_finalize (GObject *object) if (term->priv->adjustment) g_object_unref (term->priv->adjustment); - for (i = 0; i < CURSORS_NUM; ++i) - if (term->priv->cursor[i]) - gdk_cursor_unref (term->priv->cursor[i]); + for (i = 0; i < POINTERS_NUM; ++i) + if (term->priv->pointer[i]) + gdk_cursor_unref (term->priv->pointer[i]); /* TODO TODO TODO */ for (i = 0; i < 1; ++i) @@ -297,16 +317,16 @@ static void moo_term_realize (GtkWidget *widget) term = MOO_TERM (widget); empty_bitmap = gdk_bitmap_create_from_data (NULL, invisible_cursor_bits, 1, 1); - term->priv->cursor[CURSOR_NONE] = + term->priv->pointer[POINTER_NONE] = gdk_cursor_new_from_pixmap (empty_bitmap, empty_bitmap, &useless, &useless, 0, 0); display = gtk_widget_get_display (widget); - term->priv->cursor[CURSOR_TEXT] = + term->priv->pointer[POINTER_TEXT] = gdk_cursor_new_for_display (display, GDK_XTERM); - term->priv->cursor[CURSOR_POINTER] = NULL; + term->priv->pointer[POINTER_NORMAL] = NULL; attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; @@ -316,7 +336,7 @@ static void moo_term_realize (GtkWidget *widget) attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); - attributes.cursor = term->priv->cursor[CURSOR_TEXT]; + attributes.cursor = term->priv->pointer[POINTER_TEXT]; attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | @@ -349,10 +369,26 @@ static void moo_term_realize (GtkWidget *widget) gtk_im_context_set_use_preedit (term->priv->im, FALSE); g_signal_connect (term->priv->im, "commit", G_CALLBACK (moo_term_im_commit), term); + g_signal_connect_swapped (term->priv->im, "preedit-start", + G_CALLBACK (im_preedit_start), term); + g_signal_connect_swapped (term->priv->im, "preedit-end", + G_CALLBACK (im_preedit_end), term); gtk_im_context_focus_in (term->priv->im); } +static void im_preedit_start (MooTerm *term) +{ + term->priv->im_preedit_active = TRUE; +} + + +static void im_preedit_end (MooTerm *term) +{ + term->priv->im_preedit_active = FALSE; +} + + static void moo_term_set_scroll_adjustments (GtkWidget *widget, G_GNUC_UNUSED GtkAdjustment *hadj, GtkAdjustment *vadj) @@ -679,7 +715,7 @@ void moo_term_feed_child (MooTerm *term, const char *string, int len) { - g_return_if_fail (MOO_IS_TERM (term)); + g_return_if_fail (MOO_IS_TERM (term) && string != NULL); moo_term_pt_write (term->priv->pt, string, len); } @@ -783,7 +819,6 @@ void moo_term_set_icon_name (MooTerm *term, void moo_term_bell (MooTerm *term) { g_signal_emit (term, signals[BELL], 0); - g_message ("BELL"); } @@ -887,6 +922,63 @@ void moo_term_set_mode (MooTerm *term, int mode, gboolean set) { +#if 1 + switch (mode) + { + case MODE_DECSCNM: + g_message ("set MODE_DECSCNM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECTCEM: + g_message ("set MODE_DECTCEM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_CA: + g_message ("set MODE_CA %s", set ? "TRUE" : "FALSE"); + break; + case MODE_REVERSE_WRAPAROUND: + g_message ("set MODE_REVERSE_WRAPAROUND %s", set ? "TRUE" : "FALSE"); + break; + case MODE_PRESS_TRACKING: + g_message ("set MODE_PRESS_TRACKING %s", set ? "TRUE" : "FALSE"); + break; + case MODE_PRESS_AND_RELEASE_TRACKING: + g_message ("set MODE_PRESS_AND_RELEASE_TRACKING %s", set ? "TRUE" : "FALSE"); + break; + case MODE_HILITE_MOUSE_TRACKING: + g_message ("set MODE_HILITE_MOUSE_TRACKING %s", set ? "TRUE" : "FALSE"); + break; + case MODE_SRM: + g_message ("set MODE_SRM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_LNM: + g_message ("set MODE_LNM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECNKM: + g_message ("set MODE_DECNKM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECCKM: + g_message ("set MODE_DECCKM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECANM: + g_message ("set MODE_DECANM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECBKM: + g_message ("set MODE_DECBKM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECKPM: + g_message ("set MODE_DECKPM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_IRM: + g_message ("set MODE_IRM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECOM: + g_message ("set MODE_DECOM %s", set ? "TRUE" : "FALSE"); + break; + case MODE_DECAWM: + g_message ("set MODE_DECAWM %s", set ? "TRUE" : "FALSE"); + break; + } +#endif + switch (mode) { case MODE_DECSCNM: @@ -926,6 +1018,7 @@ void moo_term_set_mode (MooTerm *term, case MODE_DECANM: case MODE_DECBKM: case MODE_DECKPM: + case MODE_REVERSE_WRAPAROUND: term->priv->modes[mode] = set; moo_term_buffer_set_mode (term->priv->buffer, mode, set); break; @@ -995,3 +1088,168 @@ void moo_term_da3 (MooTerm *term) /* TODO */ moo_term_feed_child (term, "\220!|FFFFFFFF\234", -1); } + + +#define make_DECRQSS(c) \ + answer = g_strdup_printf ("\220%s$r" FINAL_##c "\234", ps) + +void moo_term_setting_request (MooTerm *term, + int setting) +{ + DECRQSSCode code = setting; + char *ps = NULL, *answer = NULL; + + switch (code) + { + case CODE_DECSASD: /* Select Active Status Display*/ + ps = g_strdup ("0"); + make_DECRQSS (DECSASD); + break; + case CODE_DECSCL: /* Set Conformance Level */ + ps = g_strdup ("61"); + make_DECRQSS (DECSCL); + break; + case CODE_DECSCPP: /* Set Columns Per Page */ + ps = g_strdup_printf ("%d", term->priv->width); + make_DECRQSS (DECSCPP); + break; + case CODE_DECSLPP: /* Set Lines Per Page */ + ps = g_strdup_printf ("%d", term->priv->height); + make_DECRQSS (DECSLPP); + break; + case CODE_DECSNLS: /* Set Number of Lines per Screen */ + ps = g_strdup_printf ("%d", term->priv->height); + make_DECRQSS (DECSNLS); + break; + case CODE_DECSTBM: /* Set Top and Bottom Margins */ + ps = g_strdup_printf ("%d;%d", + term->priv->buffer->priv->top_margin + 1, + term->priv->buffer->priv->bottom_margin + 1); + make_DECRQSS (DECSTBM); + break; + } + + moo_term_feed_child (term, answer, -1); + g_free (answer); + g_free (ps); +} + + +void moo_term_reset (MooTerm *term) +{ + moo_term_buffer_freeze_changed_notify (term->priv->primary_buffer); + moo_term_buffer_freeze_cursor_notify (term->priv->primary_buffer); + + term->priv->buffer = term->priv->primary_buffer; + moo_term_buffer_reset (term->priv->primary_buffer); + moo_term_buffer_reset (term->priv->alternate_buffer); + set_default_modes (term->priv->modes); + set_default_modes (term->priv->saved_modes); + + moo_term_buffer_thaw_changed_notify (term->priv->primary_buffer); + moo_term_buffer_thaw_cursor_notify (term->priv->primary_buffer); + moo_term_buffer_changed (term->priv->primary_buffer); + moo_term_buffer_cursor_moved (term->priv->primary_buffer); +} + + +void moo_term_soft_reset (MooTerm *term) +{ + moo_term_buffer_freeze_changed_notify (term->priv->buffer); + moo_term_buffer_freeze_cursor_notify (term->priv->buffer); + + moo_term_buffer_soft_reset (term->priv->buffer); + set_default_modes (term->priv->modes); + set_default_modes (term->priv->saved_modes); + + moo_term_buffer_thaw_changed_notify (term->priv->primary_buffer); + moo_term_buffer_thaw_cursor_notify (term->priv->primary_buffer); + moo_term_buffer_changed (term->priv->primary_buffer); + moo_term_buffer_cursor_moved (term->priv->primary_buffer); +} + + +void moo_term_dsr (MooTerm *term, + int type, + int arg, + gboolean extended) +{ + char *answer = NULL; + MooTermBuffer *buf = term->priv->buffer; + + switch (type) + { + case 6: + if (extended) + answer = g_strdup_printf ("\233%d;%d;0R", + buf_cursor_row (buf) + 1, + buf_cursor_col (buf) + 1); + else + answer = g_strdup_printf ("\233%d;%dR", + buf_cursor_row (buf) + 1, + buf_cursor_col (buf) + 1); + break; + + break; + case 75: + answer = g_strdup ("\233?70n"); + break; + case 26: + answer = g_strdup ("\233?27;1;0;5n"); + break; + case 62: + answer = g_strdup ("\2330*{"); + break; + case 63: + if (arg > 0) + answer = g_strdup_printf ("\220%d!~30303030\234", arg); + else + answer = g_strdup ("\220!~30303030\234"); + break; + case 5: + answer = g_strdup ("\2330n"); + break; + case 15: + answer = g_strdup ("\233?13n"); + break; + case 25: + answer = g_strdup ("\233?21n"); + break; + + default: + g_warning ("%s: unknown request", G_STRFUNC); + } + + if (answer) + { + moo_term_feed_child (term, answer, -1); + g_free (answer); + } +} + + +void moo_term_set_pointer_visible (MooTerm *term, + gboolean visible) +{ + g_return_if_fail (GTK_WIDGET_REALIZED (term)); + + if (visible != term->priv->pointer_visible) + { + if (visible) + { + if (term->priv->tracking_mouse) + gdk_window_set_cursor (GTK_WIDGET(term)->window, + term->priv->pointer[POINTER_NORMAL]); + else + gdk_window_set_cursor (GTK_WIDGET(term)->window, + term->priv->pointer[POINTER_TEXT]); + } + else + { + gdk_window_set_cursor (GTK_WIDGET(term)->window, + term->priv->pointer[POINTER_NONE]); + } + + term->priv->pointer_visible = visible; + } +} diff --git a/moo/mooterm/mooterm.h b/moo/mooterm/mooterm.h index de52ca5b..eaf7691e 100644 --- a/moo/mooterm/mooterm.h +++ b/moo/mooterm/mooterm.h @@ -51,40 +51,50 @@ struct _MooTermClass const char *title); void (*set_icon_name) (MooTerm *term, const char *icon); + void (*child_died) (MooTerm *term); }; +typedef enum { + MOO_TERM_ERASE_AUTO, + MOO_TERM_ERASE_ASCII_BACKSPACE, + MOO_TERM_ERASE_ASCII_DELETE, + MOO_TERM_ERASE_DELETE_SEQUENCE +} MooTermEraseBinding; -GType moo_term_get_type (void) G_GNUC_CONST; -void moo_term_set_buffer (MooTerm *term, - MooTermBuffer *buffer); -MooTermBuffer *moo_term_get_buffer (MooTerm *term); -void moo_term_set_adjustment (MooTerm *term, +GType moo_term_get_type (void) G_GNUC_CONST; +GType moo_term_erase_binding_get_type (void) G_GNUC_CONST; + + +void moo_term_set_adjustment (MooTerm *term, GtkAdjustment *vadj); -gboolean moo_term_fork_command (MooTerm *term, +gboolean moo_term_fork_command (MooTerm *term, const char *cmd, const char *working_dir, char **envp); -void moo_term_feed (MooTerm *term, +void moo_term_feed (MooTerm *term, const char *data, int len); -void moo_term_feed_child (MooTerm *term, +void moo_term_feed_child (MooTerm *term, const char *string, int len); -void moo_term_scroll_to_top (MooTerm *term); -void moo_term_scroll_to_bottom (MooTerm *term); -void moo_term_scroll_lines (MooTerm *term, +void moo_term_scroll_to_top (MooTerm *term); +void moo_term_scroll_to_bottom (MooTerm *term); +void moo_term_scroll_lines (MooTerm *term, int lines); -void moo_term_scroll_pages (MooTerm *term, +void moo_term_scroll_pages (MooTerm *term, int pages); -void moo_term_copy_clipboard (MooTerm *term); -void moo_term_paste_clipboard (MooTerm *term); +void moo_term_copy_clipboard (MooTerm *term); +void moo_term_paste_clipboard (MooTerm *term); -void moo_term_ctrl_c (MooTerm *term); +void moo_term_ctrl_c (MooTerm *term); + +void moo_term_set_pointer_visible (MooTerm *term, + gboolean visible); G_END_DECLS diff --git a/moo/mooterm/mootermbuffer-private.h b/moo/mooterm/mootermbuffer-private.h index a2b241d9..4b251d8f 100644 --- a/moo/mooterm/mootermbuffer-private.h +++ b/moo/mooterm/mootermbuffer-private.h @@ -33,7 +33,6 @@ struct _MooTermBufferPrivate { guint8 modes[MODE_MAX]; MooTermTextAttr current_attr; - gboolean cursor_visible; int single_shift; gunichar *graph_sets[4]; @@ -51,7 +50,7 @@ struct _MooTermBufferPrivate { guint bottom_margin; gboolean scrolling_region_set; - /* independent of screen region */ + /* independent of scrolling region */ guint cursor_row; guint cursor_col; @@ -91,6 +90,9 @@ void moo_term_buffer_freeze_cursor_notify (MooTermBuffer *buf); void moo_term_buffer_thaw_changed_notify (MooTermBuffer *buf); void moo_term_buffer_thaw_cursor_notify (MooTermBuffer *buf); +void moo_term_buffer_reset (MooTermBuffer *buf); +void moo_term_buffer_soft_reset (MooTermBuffer *buf); + void moo_term_buffer_set_mode (MooTermBuffer *buf, guint mode, gboolean val); @@ -115,7 +117,8 @@ guint moo_term_buffer_next_tab_stop (MooTermBuffer *buf, guint current); guint moo_term_buffer_prev_tab_stop (MooTermBuffer *buf, guint current); -void moo_term_buffer_clear_tab_stop (MooTermBuffer *buf); +void moo_term_buffer_clear_tab_stop (MooTermBuffer *buf, + int what); void moo_term_buffer_set_tab_stop (MooTermBuffer *buf); void moo_term_buffer_select_charset (MooTermBuffer *buf, @@ -177,7 +180,7 @@ inline static GdkRegion *buf_get_changed(MooTermBuffer *buf) } -#define buf_changed_add_rect(rect) \ +#define buf_changed_add_rect(buf,rect) \ { \ if (!buf->priv->changed_all) \ { \ @@ -188,23 +191,23 @@ inline static GdkRegion *buf_get_changed(MooTermBuffer *buf) } \ } -#define buf_changed_add_range(row, start, len) \ +#define buf_changed_add_range(buf, row, start, len) \ { \ if (!buf->priv->changed_all) \ { \ GdkRectangle rec = {start, row, len, 1}; \ - buf_changed_add_rect (rec); \ + buf_changed_add_rect (buf, rec); \ } \ } -#define buf_changed_set_all() \ +#define buf_changed_set_all(buf) \ { \ if (!buf->priv->changed_all) \ { \ GdkRectangle rec = { \ 0, 0, buf->priv->screen_width, buf->priv->screen_height \ }; \ - buf_changed_add_rect (rec); \ + buf_changed_add_rect (buf, rec); \ buf->priv->changed_all = TRUE; \ } \ } @@ -270,7 +273,14 @@ inline static MooTermLine *buf_screen_line (MooTermBuffer *buf, void moo_term_buffer_new_line (MooTermBuffer *buf); void moo_term_buffer_index (MooTermBuffer *buf); void moo_term_buffer_backspace (MooTermBuffer *buf); -void moo_term_buffer_tab (MooTermBuffer *buf); +void moo_term_buffer_tab (MooTermBuffer *buf, + guint n); +void moo_term_buffer_back_tab (MooTermBuffer *buf, + guint n); +void moo_term_buffer_cursor_next_line (MooTermBuffer *buf, + guint n); +void moo_term_buffer_cursor_prev_line (MooTermBuffer *buf, + guint n); void moo_term_buffer_linefeed (MooTermBuffer *buf); void moo_term_buffer_carriage_return (MooTermBuffer *buf); void moo_term_buffer_reverse_index (MooTermBuffer *buf); diff --git a/moo/mooterm/mootermbuffer.c b/moo/mooterm/mootermbuffer.c index 14b9d94a..b3fa4dcb 100644 --- a/moo/mooterm/mootermbuffer.c +++ b/moo/mooterm/mootermbuffer.c @@ -32,6 +32,8 @@ static GObject *moo_term_buffer_constructor (GType type, GObjectConstructParam *construct_param); static void moo_term_buffer_finalize (GObject *object); +static void set_defaults (MooTermBuffer *buf); + /* MOO_TYPE_TERM_BUFFER */ G_DEFINE_TYPE (MooTermBuffer, moo_term_buffer, G_TYPE_OBJECT) @@ -146,12 +148,7 @@ static void moo_term_buffer_init (MooTermBuffer *buf) buf->priv->changed = NULL; buf->priv->changed_all = FALSE; - buf->priv->single_shift = -1; - buf->priv->graph_sets[0] = buf->priv->graph_sets[1] = - buf->priv->graph_sets[2] = buf->priv->graph_sets[3] = NULL; - buf->priv->current_graph_set = NULL; - - set_default_modes (buf->priv->modes); + set_defaults (buf); moo_term_buffer_clear_saved (buf); } @@ -308,7 +305,7 @@ void moo_term_buffer_set_screen_width (MooTermBuffer *buf, width - old_width }; - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); moo_term_buffer_changed (buf); } else @@ -348,7 +345,7 @@ void moo_term_buffer_set_screen_height (MooTermBuffer *buf, g_ptr_array_add (buf->priv->lines, term_line_new (width)); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); content_changed = TRUE; } else /* height < old_height */ @@ -385,7 +382,7 @@ void moo_term_buffer_set_screen_height (MooTermBuffer *buf, g_ptr_array_add (buf->priv->lines, term_line_new (width)); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); content_changed = TRUE; } else /* height < old_height */ @@ -418,7 +415,7 @@ void moo_term_buffer_set_screen_height (MooTermBuffer *buf, } buf->priv->_screen_offset += remove; - buf_changed_set_all (); + buf_changed_set_all (buf); scrollback_changed = TRUE; content_changed = TRUE; } @@ -494,9 +491,6 @@ void moo_term_buffer_cursor_move_to (MooTermBuffer *buf, guint old_row = buf_cursor_row (buf); guint old_col = buf_cursor_col (buf); - g_return_if_fail (row < (int) buf_screen_height (buf)); - g_return_if_fail (col < (int) buf_screen_width (buf)); - if (row < 0) row = old_row; else if (row >= height) @@ -551,19 +545,19 @@ static void buf_print_unichar_real (MooTermBuffer *buf, if (buf_get_mode (MODE_IRM)) { term_line_insert_unichar (buf_screen_line (buf, cursor_row), - buf->priv->cursor_col++, - c, 1, attr, width); - buf_changed_add_range (cursor_row, - buf->priv->cursor_col - 1, - width - buf->priv->cursor_col + 1); + buf->priv->cursor_col++, + c, 1, attr, width); + buf_changed_add_range (buf, cursor_row, + buf->priv->cursor_col - 1, + width - buf->priv->cursor_col + 1); } else { term_line_set_unichar (buf_screen_line (buf, cursor_row), - buf->priv->cursor_col++, - c, 1, attr, width); - buf_changed_add_range (cursor_row, - buf->priv->cursor_col - 1, 1); + buf->priv->cursor_col++, + c, 1, attr, width); + buf_changed_add_range (buf, cursor_row, + buf->priv->cursor_col - 1, 1); } if (buf->priv->cursor_col == width) @@ -691,11 +685,20 @@ guint moo_term_buffer_prev_tab_stop (MooTermBuffer *buf, return 0; } -void moo_term_buffer_clear_tab_stop (MooTermBuffer *buf) +void moo_term_buffer_clear_tab_stop (MooTermBuffer *buf, + int what) { - buf->priv->tab_stops = - g_list_remove (buf->priv->tab_stops, - GUINT_TO_POINTER (buf_cursor_col (buf))); + g_return_if_fail (what == 0 || what == 3); + + if (what == 0) + buf->priv->tab_stops = + g_list_remove (buf->priv->tab_stops, + GUINT_TO_POINTER (buf_cursor_col (buf))); + else + { + g_list_free (buf->priv->tab_stops); + buf->priv->tab_stops = NULL; + } } static int cmp_guints (gconstpointer a, gconstpointer b) @@ -921,7 +924,7 @@ void moo_term_buffer_index (MooTermBuffer *buf) /* TODO: attributes */ buf->priv->lines->pdata[bottom] = term_line_new (width); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); } else { @@ -940,7 +943,7 @@ void moo_term_buffer_index (MooTermBuffer *buf) buf->priv->_screen_offset += 1; moo_term_buffer_scrollback_changed (buf); - buf_changed_set_all (); + buf_changed_set_all (buf); } else { @@ -976,7 +979,7 @@ void moo_term_buffer_reverse_index (MooTermBuffer *buf) /* TODO: attributes */ buf->priv->lines->pdata[top] = term_line_new (width); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); } else { @@ -993,10 +996,26 @@ void moo_term_buffer_backspace (MooTermBuffer *buf) } -void moo_term_buffer_tab (MooTermBuffer *buf) +void moo_term_buffer_tab (MooTermBuffer *buf, + guint n) { - moo_term_buffer_cursor_move_to (buf, -1, - moo_term_buffer_next_tab_stop (buf, buf->priv->cursor_col)); + guint i; + for (i = 0; i < n; ++i) + { + moo_term_buffer_cursor_move_to (buf, -1, + moo_term_buffer_next_tab_stop (buf, buf->priv->cursor_col)); + } +} + +void moo_term_buffer_back_tab (MooTermBuffer *buf, + guint n) +{ + guint i; + for (i = 0; i < n; ++i) + { + moo_term_buffer_cursor_move_to (buf, -1, + moo_term_buffer_prev_tab_stop (buf, buf->priv->cursor_col)); + } } @@ -1100,7 +1119,7 @@ void moo_term_buffer_delete_char (MooTermBuffer *buf, term_line_delete_range (buf_screen_line (buf, cursor_row), cursor_col, n); - buf_changed_add_range(cursor_row, cursor_col, + buf_changed_add_range(buf, cursor_row, cursor_col, buf_screen_width (buf) - cursor_col); notify_changed (); } @@ -1120,7 +1139,7 @@ void moo_term_buffer_erase_range (MooTermBuffer *buf, term_line_erase_range (buf_screen_line (buf, row), col, len); - buf_changed_add_range(row, col, len); + buf_changed_add_range (buf, row, col, len); notify_changed (); } @@ -1223,8 +1242,8 @@ void moo_term_buffer_insert_char (MooTermBuffer *buf, term_line_insert_unichar (buf_screen_line (buf, cursor_row), cursor_col, EMPTY_CHAR, n, &ZERO_ATTR, buf_screen_width (buf)); - buf_changed_add_range(cursor_row, cursor_col, - buf_screen_width (buf) - cursor_col); + buf_changed_add_range (buf, cursor_row, cursor_col, + buf_screen_width (buf) - cursor_col); notify_changed (); } @@ -1277,7 +1296,7 @@ void moo_term_buffer_delete_line (MooTermBuffer *buf, g_ptr_array_index (buf->priv->lines, i) = term_line_new (buf->priv->screen_width); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); moo_term_buffer_changed (buf); } @@ -1316,7 +1335,7 @@ void moo_term_buffer_insert_line (MooTermBuffer *buf, g_ptr_array_index (buf->priv->lines, i) = term_line_new (buf->priv->screen_width); - buf_changed_add_rect (changed); + buf_changed_add_rect (buf, changed); moo_term_buffer_changed (buf); } @@ -1386,6 +1405,7 @@ void moo_term_buffer_set_mode (MooTermBuffer *buf, case MODE_DECANM: case MODE_DECOM: case MODE_DECAWM: + case MODE_REVERSE_WRAPAROUND: /* TODO*/ buf->priv->modes[mode] = set; break; @@ -1415,3 +1435,104 @@ void moo_term_buffer_set_ca_mode (MooTermBuffer *buf, buf->priv->modes[MODE_CA] = set; moo_term_buffer_scrollback_changed (buf); } + + +static void set_defaults (MooTermBuffer *buf) +{ + buf->priv->cursor_col = buf->priv->cursor_row = 0; + + buf->priv->top_margin = 0; + buf->priv->bottom_margin = buf->priv->screen_height - 1; + buf->priv->scrolling_region_set = FALSE; + + set_default_modes (buf->priv->modes); + buf->priv->current_attr.mask = 0; + buf->priv->single_shift = -1; + buf->priv->graph_sets[0] = buf->priv->graph_sets[1] = + buf->priv->graph_sets[2] = buf->priv->graph_sets[3] = NULL; + buf->priv->current_graph_set = NULL; + + moo_term_buffer_clear_saved (buf); +} + + +void moo_term_buffer_reset (MooTermBuffer *buf) +{ + guint i; + + freeze_notify (); + + for (i = 0; i < buf->priv->lines->len; ++i) + term_line_free (g_ptr_array_index (buf->priv->lines, i)); + g_ptr_array_free (buf->priv->lines, TRUE); + + buf->priv->_screen_offset = 0; + buf->priv->lines = g_ptr_array_sized_new (buf->priv->screen_height); + for (i = 0; i < buf->priv->screen_height; ++i) + g_ptr_array_add (buf->priv->lines, + term_line_new (buf->priv->screen_width)); + + set_defaults (buf); + + buf_changed_set_all (buf); + thaw_and_notify (); +} + + +void moo_term_buffer_soft_reset (MooTermBuffer *buf) +{ + set_default_modes (buf->priv->modes); + + buf->priv->top_margin = 0; + buf->priv->bottom_margin = buf->priv->screen_height - 1; + buf->priv->scrolling_region_set = FALSE; + + buf->priv->current_attr.mask = 0; + buf->priv->single_shift = -1; + buf->priv->graph_sets[0] = buf->priv->graph_sets[1] = + buf->priv->graph_sets[2] = buf->priv->graph_sets[3] = NULL; + buf->priv->current_graph_set = NULL; + + buf_changed_set_all (buf); + moo_term_buffer_changed (buf); +} + + +void moo_term_buffer_cursor_next_line (MooTermBuffer *buf, + guint n) +{ + guint i; + + moo_term_buffer_freeze_cursor_notify (buf); + + for (i = 0; i < n ; ++i) + { + if (buf->priv->cursor_row + 1 < buf->priv->screen_height) + moo_term_buffer_cursor_move_to (buf, buf->priv->cursor_row + 1, 0); + else + break; + } + + moo_term_buffer_thaw_cursor_notify (buf); + moo_term_buffer_cursor_moved (buf); +} + + +void moo_term_buffer_cursor_prev_line (MooTermBuffer *buf, + guint n) +{ + guint i; + + moo_term_buffer_freeze_cursor_notify (buf); + + for (i = 0; i < n ; ++i) + { + if (buf->priv->cursor_row > 0) + moo_term_buffer_cursor_move_to (buf, buf->priv->cursor_row - 1, 0); + else + break; + } + + moo_term_buffer_thaw_cursor_notify (buf); + moo_term_buffer_cursor_moved (buf); +} diff --git a/moo/mooterm/mootermparser.h b/moo/mooterm/mootermparser.h index 265390bb..41842988 100644 --- a/moo/mooterm/mootermparser.h +++ b/moo/mooterm/mootermparser.h @@ -44,12 +44,15 @@ typedef enum { PART_INTERMEDIATE, PART_PARAMETERS, PART_FINAL, + PART_DATA, + PART_ST, PART_DONE } SequencePartType; typedef enum { LEX_ESCAPE, - LEX_CONTROL + LEX_CONTROL, + LEX_DCS } LexType; typedef struct { @@ -60,15 +63,15 @@ typedef struct { typedef enum { - INITIAL = 0, - ESCAPE, - ESCAPE_INTERMEDIATE, - DCS, - CSI, - OSC, - PM, - APC, - ERROR + INITIAL_ = 0, + ESCAPE_, + ESCAPE_INTERMEDIATE_, + DCS_, + CSI_, + OSC_, + PM_, + APC_, + ERROR_ } ParserState; @@ -80,7 +83,6 @@ typedef struct _MooTermParser { InputIter current; InputIter cmd_start; - gboolean escape_two_bytes; ParserState state; diff --git a/moo/mooterm/mootermpt.c b/moo/mooterm/mootermpt.c index a4f65ee1..f4d6e0bd 100644 --- a/moo/mooterm/mootermpt.c +++ b/moo/mooterm/mootermpt.c @@ -125,3 +125,9 @@ void moo_term_pt_write (MooTermPt *pt, g_return_if_fail (MOO_IS_TERM_PT (pt)); MOO_TERM_PT_GET_CLASS(pt)->write (pt, data, len); } + + +gboolean moo_term_pt_child_alive (MooTermPt *pt) +{ + return pt->priv->child_alive; +} diff --git a/moo/mooterm/mootermpt.h b/moo/mooterm/mootermpt.h index 87cfa6dc..c9bd5fa8 100644 --- a/moo/mooterm/mootermpt.h +++ b/moo/mooterm/mootermpt.h @@ -71,12 +71,16 @@ void moo_term_pt_set_size (MooTermPt *pt, guint width, guint height); +char moo_term_pt_get_erase_char (MooTermPt *pt); + gboolean moo_term_pt_fork_command (MooTermPt *pt, const char *cmd, const char *working_dir, char **envp); void moo_term_pt_kill_child (MooTermPt *pt); +gboolean moo_term_pt_child_alive (MooTermPt *pt); + void moo_term_pt_write (MooTermPt *pt, const char *data, gssize len);