⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pterm.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 5 页
字号:
		int offt = 0;
		if (code > 15)
		    offt++;
		if (code > 21)
		    offt++;
		if (inst->term->vt52_mode)
		    end = 1 + sprintf(output+1,
				      "\x1B%c", code + 'P' - 11 - offt);
		else
		    end = 1 + sprintf(output+1,
				      "\x1BO%c", code + 'P' - 11 - offt);
		use_ucsoutput = FALSE;
		goto done;
	    }
	    if (inst->cfg.funky_type == 1 && code >= 11 && code <= 15) {
		end = 1 + sprintf(output+1, "\x1B[[%c", code + 'A' - 11);
		use_ucsoutput = FALSE;
		goto done;
	    }
	    if (inst->cfg.funky_type == 2 && 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 */
	    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.
		 */
		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.
		 */
		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.
	     */
	    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. */
    }

    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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -