📄 pterm.c
字号:
if (inst->cfg.funky_type == FUNKY_XTERM && code >= 11 && code <= 14) { if (inst->term->vt52_mode) end = 1 + sprintf(output+1, "\x1B%c", code + 'P' - 11); else end = 1 + sprintf(output+1, "\x1BO%c", code + 'P' - 11); use_ucsoutput = FALSE; goto done; } if (inst->cfg.rxvt_homeend && (code == 1 || code == 4)) { end = 1 + sprintf(output+1, code == 1 ? "\x1B[H" : "\x1BOw"); use_ucsoutput = FALSE; goto done; } if (code) { end = 1 + sprintf(output+1, "\x1B[%d~", code); use_ucsoutput = FALSE; goto done; } } /* * Cursor keys. (This includes the numberpad cursor keys, * if we haven't already done them due to app keypad mode.) * * Here we also process un-numlocked un-appkeypadded KP5, * which sends ESC [ G. */ { int xkey = 0; switch (event->keyval) { case GDK_Up: case GDK_KP_Up: xkey = 'A'; break; case GDK_Down: case GDK_KP_Down: xkey = 'B'; break; case GDK_Right: case GDK_KP_Right: xkey = 'C'; break; case GDK_Left: case GDK_KP_Left: xkey = 'D'; break; case GDK_Begin: case GDK_KP_Begin: xkey = 'G'; break; } if (xkey) { /* * The arrow keys normally do ESC [ A and so on. In * app cursor keys mode they do ESC O A instead. * Ctrl toggles the two modes. */ if (inst->term->vt52_mode) { end = 1 + sprintf(output+1, "\033%c", xkey); } else if (!inst->term->app_cursor_keys ^ !(event->state & GDK_CONTROL_MASK)) { end = 1 + sprintf(output+1, "\033O%c", xkey); } else { end = 1 + sprintf(output+1, "\033[%c", xkey); } use_ucsoutput = FALSE; goto done; } } goto done; } done: if (end-start > 0) {#ifdef KEY_DEBUGGING int i; printf("generating sequence:"); for (i = start; i < end; i++) printf(" %02x", (unsigned char) output[i]); printf("\n");#endif if (special) { /* * For special control characters, the character set * should never matter. */ output[end] = '\0'; /* NUL-terminate */ if (inst->ldisc) ldisc_send(inst->ldisc, output+start, -2, 1); } else if (!inst->direct_to_font) { if (!use_ucsoutput) { /* * The stuff we've just generated is assumed to be * ISO-8859-1! This sounds insane, but `man * XLookupString' agrees: strings of this type * returned from the X server are hardcoded to * 8859-1. Strictly speaking we should be doing * this using some sort of GtkIMContext, which (if * we're lucky) would give us our data directly in * Unicode; but that's not supported in GTK 1.2 as * far as I can tell, and it's poorly documented * even in 2.0, so it'll have to wait. */ if (inst->ldisc) lpage_send(inst->ldisc, CS_ISO8859_1, output+start, end-start, 1); } else { /* * We generated our own Unicode key data from the * keysym, so use that instead. */ if (inst->ldisc) luni_send(inst->ldisc, ucsoutput+start, end-start, 1); } } else { /* * In direct-to-font mode, we just send the string * exactly as we received it. */ if (inst->ldisc) ldisc_send(inst->ldisc, output+start, end-start, 1); } show_mouseptr(inst, 0); term_seen_key_event(inst->term); term_out(inst->term); } return TRUE;}gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data){ struct gui_data *inst = (struct gui_data *)data; int shift, ctrl, alt, x, y, button, act; /* Remember the timestamp. */ inst->input_event_time = event->time; show_mouseptr(inst, 1); if (event->button == 4 && event->type == GDK_BUTTON_PRESS) { term_scroll(inst->term, 0, -5); return TRUE; } if (event->button == 5 && event->type == GDK_BUTTON_PRESS) { term_scroll(inst->term, 0, +5); return TRUE; } shift = event->state & GDK_SHIFT_MASK; ctrl = event->state & GDK_CONTROL_MASK; alt = event->state & GDK_MOD1_MASK; if (event->button == 3 && ctrl) { gtk_menu_popup(GTK_MENU(inst->menu), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } if (event->button == 1) button = MBT_LEFT; else if (event->button == 2) button = MBT_MIDDLE; else if (event->button == 3) button = MBT_RIGHT; else return FALSE; /* don't even know what button! */ switch (event->type) { case GDK_BUTTON_PRESS: act = MA_CLICK; break; case GDK_BUTTON_RELEASE: act = MA_RELEASE; break; case GDK_2BUTTON_PRESS: act = MA_2CLK; break; case GDK_3BUTTON_PRESS: act = MA_3CLK; break; default: return FALSE; /* don't know this event type */ } if (send_raw_mouse && !(inst->cfg.mouse_override && shift) && act != MA_CLICK && act != MA_RELEASE) return TRUE; /* we ignore these in raw mouse mode */ x = (event->x - inst->cfg.window_border) / inst->font_width; y = (event->y - inst->cfg.window_border) / inst->font_height; term_mouse(inst->term, button, translate_button(button), act, x, y, shift, ctrl, alt); return TRUE;}gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data){ struct gui_data *inst = (struct gui_data *)data; int shift, ctrl, alt, x, y, button; /* Remember the timestamp. */ inst->input_event_time = event->time; show_mouseptr(inst, 1); shift = event->state & GDK_SHIFT_MASK; ctrl = event->state & GDK_CONTROL_MASK; alt = event->state & GDK_MOD1_MASK; if (event->state & GDK_BUTTON1_MASK) button = MBT_LEFT; else if (event->state & GDK_BUTTON2_MASK) button = MBT_MIDDLE; else if (event->state & GDK_BUTTON3_MASK) button = MBT_RIGHT; else return FALSE; /* don't even know what button! */ x = (event->x - inst->cfg.window_border) / inst->font_width; y = (event->y - inst->cfg.window_border) / inst->font_height; term_mouse(inst->term, button, translate_button(button), MA_DRAG, x, y, shift, ctrl, alt); return TRUE;}void frontend_keypress(void *handle){ struct gui_data *inst = (struct gui_data *)handle; /* * If our child process has exited but not closed, terminate on * any keypress. */ if (inst->exited) exit(0);}gint timer_func(gpointer data){ struct gui_data *inst = (struct gui_data *)data; int exitcode; if (!inst->exited && (exitcode = inst->back->exitcode(inst->backhandle)) >= 0) { inst->exited = TRUE; if (inst->cfg.close_on_exit == FORCE_ON || (inst->cfg.close_on_exit == AUTO && exitcode == 0)) exit(0); /* just go. */ if (inst->ldisc) { ldisc_free(inst->ldisc); inst->ldisc = NULL; } if (inst->back) { inst->back->free(inst->backhandle); inst->backhandle = NULL; inst->back = NULL; update_specials_menu(inst); } gtk_widget_show(inst->restartitem); } term_update(inst->term); term_blink(inst->term, 0); return TRUE;}void fd_input_func(gpointer data, gint sourcefd, GdkInputCondition condition){ /* * We must process exceptional notifications before ordinary * readability ones, or we may go straight past the urgent * marker. */ if (condition & GDK_INPUT_EXCEPTION) select_result(sourcefd, 4); if (condition & GDK_INPUT_READ) select_result(sourcefd, 1); if (condition & GDK_INPUT_WRITE) select_result(sourcefd, 2);}void destroy(GtkWidget *widget, gpointer data){ gtk_main_quit();}gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data){ struct gui_data *inst = (struct gui_data *)data; inst->term->has_focus = event->in; term_out(inst->term); term_update(inst->term); show_mouseptr(inst, 1); return FALSE;}/* * set or clear the "raw mouse message" mode */void set_raw_mouse_mode(void *frontend, int activate){ struct gui_data *inst = (struct gui_data *)frontend; activate = activate && !inst->cfg.no_mouse_rep; send_raw_mouse = activate; if (send_raw_mouse) inst->currcursor = inst->rawcursor; else inst->currcursor = inst->textcursor; show_mouseptr(inst, inst->mouseptr_visible);}void request_resize(void *frontend, int w, int h){ struct gui_data *inst = (struct gui_data *)frontend; int large_x, large_y; int offset_x, offset_y; int area_x, area_y; GtkRequisition inner, outer; /* * This is a heinous hack dreamed up by the gnome-terminal * people to get around a limitation in gtk. The problem is * that in order to set the size correctly we really need to be * calling gtk_window_resize - but that needs to know the size * of the _whole window_, not the drawing area. So what we do * is to set an artificially huge size request on the drawing * area, recompute the resulting size request on the window, * and look at the difference between the two. That gives us * the x and y offsets we need to translate drawing area size * into window size for real, and then we call * gtk_window_resize. */ /* * We start by retrieving the current size of the whole window. * Adding a bit to _that_ will give us a value we can use as a * bogus size request which guarantees to be bigger than the * current size of the drawing area. */ get_window_pixels(inst, &large_x, &large_y); large_x += 32; large_y += 32;#if GTK_CHECK_VERSION(2,0,0) gtk_widget_set_size_request(inst->area, large_x, large_y);#else gtk_widget_set_usize(inst->area, large_x, large_y);#endif gtk_widget_size_request(inst->area, &inner); gtk_widget_size_request(inst->window, &outer); offset_x = outer.width - inner.width; offset_y = outer.height - inner.height; area_x = inst->font_width * w + 2*inst->cfg.window_border; area_y = inst->font_height * h + 2*inst->cfg.window_border; /* * Now we must set the size request on the drawing area back to * something sensible before we commit the real resize. Best * way to do this, I think, is to set it to what the size is * really going to end up being. */#if GTK_CHECK_VERSION(2,0,0) gtk_widget_set_size_request(inst->area, area_x, area_y);#else gtk_widget_set_usize(inst->area, area_x, area_y); gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), area_x, area_y);#endif gtk_container_dequeue_resize_handler(GTK_CONTAINER(inst->window));#if GTK_CHECK_VERSION(2,0,0) gtk_window_resize(GTK_WINDOW(inst->window), area_x + offset_x, area_y + offset_y);#else gdk_window_resize(inst->window->window, area_x + offset_x, area_y + offset_y);#endif}static void real_palette_set(struct gui_data *inst, int n, int r, int g, int b){ gboolean success[1]; inst->cols[n].red = r * 0x0101; inst->cols[n].green = g * 0x0101; inst->cols[n].blue = b * 0x0101; gdk_colormap_free_colors(inst->colmap, inst->cols + n, 1); gdk_colormap_alloc_colors(inst->colmap, inst->cols + n, 1, FALSE, FALSE, success); if (!success[0]) g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", appname, n, r, g, b);}void set_window_background(struct gui_data *inst){ if (inst->area && inst->area->window) gdk_window_set_background(inst->area->window, &inst->cols[18]); if (inst->window && inst->window->window) gdk_window_set_background(inst->window->window, &inst->cols[18]);}void palette_set(void *frontend, int n, int r, int g, int b){ struct gui_data *inst = (struct gui_data *)frontend; static const int first[21] = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, 16, 17, 18, 20, 22 }; real_palette_set(inst, first[n], r, g, b); if (first[n] >= 18) real_palette_set(inst, first[n] + 1, r, g, b); if (first[n] == 18) set_window_background(inst);}void palette_reset(void *frontend){ struct gui_data *inst = (struct gui_data *)frontend; /* This maps colour indices in inst->cfg to those used in inst->cols. */ static const int ww[] = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 1, 2, 3, 4, 5 }; gboolean success[NCOLOURS]; int i; assert(lenof(ww) == NCOLOURS); if (!inst->colmap) { inst->colmap = gdk_colormap_get_system(); } else { gdk_colormap_free_colors(inst->colmap, inst->cols, NCOLOURS); } for (i = 0; i < NCOLOURS; i++) { inst->cols[i].red = inst->cfg.colours[ww[i]][0] * 0x0101; inst->cols[i].green = inst->cfg.colours[ww[i]][1] * 0x0101; inst->cols[i].blue = inst->cfg.colours[ww[i]][2] * 0x0101; } gdk_colormap_alloc_colors(inst->colmap, inst->cols, NCOLOURS, FALSE, FALSE, success); for (i = 0; i < NCOLOURS; i++) { if (!success[i]) g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", appname, i, inst->cfg.colours[i][0], inst->cfg.colours[i][1], inst->cfg.colours[i][2]); } set_window_background(inst);}/* Ensure that all the cut buffers exist - according to the ICCCM, we must * do this before we start using cut buffers. */void init_cutbuffers(){ XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), XA_CUT_BUFFER0, XA_STRING, 8, PropModeAppend, "", 0); XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), XA_CUT_BUFFER1, XA_STRING, 8, PropModeAppend, "", 0); XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), XA_CUT_BUFFER2, XA_STRING, 8, PropModeAppend, "", 0); XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), XA_CUT_BUFFER3, XA_STRING, 8, PropModeAppend, "", 0); XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), XA_CUT_BUFFER4, XA_STRING, 8, PropModeAppend, "", 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -