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

📄 pterm.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (inst->cfg.bold_colour && (attr & ATTR_BOLD))	nfg |= 1;    if (inst->cfg.bold_colour && (attr & ATTR_BLINK))	nbg |= 1;    if (attr & TATTR_ACTCURS) {	nfg = NCOLOURS-2;	nbg = NCOLOURS-1;    }    fontid = shadow = 0;    if (attr & ATTR_WIDE) {	widefactor = 2;	fontid |= 2;    } else {	widefactor = 1;    }    if ((attr & ATTR_BOLD) && !inst->cfg.bold_colour) {	if (inst->fonts[fontid | 1])	    fontid |= 1;	else	    shadow = 1;    }    if ((lattr & LATTR_MODE) != LATTR_NORM) {	x *= 2;	if (x >= inst->term->cols)	    return;	if (x + len*2*widefactor > inst->term->cols)	    len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */	rlen = len * 2;    } else	rlen = len;    {	GdkRectangle r;	r.x = x*inst->font_width+inst->cfg.window_border;	r.y = y*inst->font_height+inst->cfg.window_border;	r.width = rlen*widefactor*inst->font_width;	r.height = inst->font_height;	gdk_gc_set_clip_rectangle(gc, &r);    }    gdk_gc_set_foreground(gc, &inst->cols[nbg]);    gdk_draw_rectangle(inst->pixmap, gc, 1,		       x*inst->font_width+inst->cfg.window_border,		       y*inst->font_height+inst->cfg.window_border,		       rlen*widefactor*inst->font_width, inst->font_height);    gdk_gc_set_foreground(gc, &inst->cols[nfg]);    {	GdkWChar *gwcs;	gchar *gcs;	wchar_t *wcs;	int i;	wcs = snewn(len*ncombining+1, wchar_t);	for (i = 0; i < len*ncombining; i++) {	    wcs[i] = text[i];	}	if (inst->fonts[fontid] == NULL) {	    /*	     * The font for this contingency does not exist.	     * Typically this means we've been given ATTR_WIDE	     * character and have no wide font. So we display	     * nothing at all; such is life.	     */	} else if (inst->fontinfo[fontid].is_wide) {	    /*	     * At least one version of gdk_draw_text_wc() has a	     * weird bug whereby it reads `len' elements of the	     * input string, but only draws `len/2'. Hence I'm	     * going to make its input array twice as long as it	     * theoretically needs to be, and pass in twice the	     * actual number of characters. If a fixed gdk actually	     * takes the doubled length seriously, then (a) the	     * array will stand scrutiny up to the full length, (b)	     * the spare elements of the array are full of zeroes	     * which will probably be an empty glyph in the font,	     * and (c) the clip rectangle should prevent it causing	     * trouble anyway.	     */	    gwcs = snewn(len*2+1, GdkWChar);	    memset(gwcs, 0, sizeof(GdkWChar) * (len*2+1));	    /*	     * FIXME: when we have a wide-char equivalent of	     * from_unicode, use it instead of this.	     */	    for (combining = 0; combining < ncombining; combining++) {		for (i = 0; i <= len; i++)		    gwcs[i] = wcs[i + combining];		gdk_draw_text_wc(inst->pixmap, inst->fonts[fontid], gc,				 x*inst->font_width+inst->cfg.window_border,				 y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,				 gwcs, len*2);		if (shadow)		    gdk_draw_text_wc(inst->pixmap, inst->fonts[fontid], gc,				     x*inst->font_width+inst->cfg.window_border+inst->cfg.shadowboldoffset,				     y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,				     gwcs, len*2);	    }	    sfree(gwcs);	} else {	    gcs = snewn(len+1, gchar);	    for (combining = 0; combining < ncombining; combining++) {		wc_to_mb(inst->fontinfo[fontid].charset, 0,			 wcs + combining, len, gcs, len, ".", NULL, NULL);		gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc,			      x*inst->font_width+inst->cfg.window_border,			      y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,			      gcs, len);		if (shadow)		    gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc,				  x*inst->font_width+inst->cfg.window_border+inst->cfg.shadowboldoffset,				  y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,				  gcs, len);	    }	    sfree(gcs);	}	sfree(wcs);    }    if (attr & ATTR_UNDER) {	int uheight = inst->fonts[0]->ascent + 1;	if (uheight >= inst->font_height)	    uheight = inst->font_height - 1;	gdk_draw_line(inst->pixmap, gc, x*inst->font_width+inst->cfg.window_border,		      y*inst->font_height + uheight + inst->cfg.window_border,		      (x+len)*widefactor*inst->font_width-1+inst->cfg.window_border,		      y*inst->font_height + uheight + inst->cfg.window_border);    }    if ((lattr & LATTR_MODE) != LATTR_NORM) {	/*	 * I can't find any plausible StretchBlt equivalent in the	 * X server, so I'm going to do this the slow and painful	 * way. This will involve repeated calls to	 * gdk_draw_pixmap() to stretch the text horizontally. It's	 * O(N^2) in time and O(N) in network bandwidth, but you	 * try thinking of a better way. :-(	 */	int i;	for (i = 0; i < len * widefactor * inst->font_width; i++) {	    gdk_draw_pixmap(inst->pixmap, gc, inst->pixmap,			    x*inst->font_width+inst->cfg.window_border + 2*i,			    y*inst->font_height+inst->cfg.window_border,			    x*inst->font_width+inst->cfg.window_border + 2*i+1,			    y*inst->font_height+inst->cfg.window_border,			    len * widefactor * inst->font_width - i, inst->font_height);	}	len *= 2;	if ((lattr & LATTR_MODE) != LATTR_WIDE) {	    int dt, db;	    /* Now stretch vertically, in the same way. */	    if ((lattr & LATTR_MODE) == LATTR_BOT)		dt = 0, db = 1;	    else		dt = 1, db = 0;	    for (i = 0; i < inst->font_height; i+=2) {		gdk_draw_pixmap(inst->pixmap, gc, inst->pixmap,				x*inst->font_width+inst->cfg.window_border,				y*inst->font_height+inst->cfg.window_border+dt*i+db,				x*inst->font_width+inst->cfg.window_border,				y*inst->font_height+inst->cfg.window_border+dt*(i+1),				len * widefactor * inst->font_width, inst->font_height-i-1);	    }	}    }}void do_text(Context ctx, int x, int y, wchar_t *text, int len,	     unsigned long attr, int lattr){    struct draw_ctx *dctx = (struct draw_ctx *)ctx;    struct gui_data *inst = dctx->inst;    GdkGC *gc = dctx->gc;    int widefactor;    do_text_internal(ctx, x, y, text, len, attr, lattr);    if (attr & ATTR_WIDE) {	widefactor = 2;    } else {	widefactor = 1;    }    if ((lattr & LATTR_MODE) != LATTR_NORM) {	x *= 2;	if (x >= inst->term->cols)	    return;	if (x + len*2*widefactor > inst->term->cols)	    len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */	len *= 2;    }    gdk_draw_pixmap(inst->area->window, gc, inst->pixmap,		    x*inst->font_width+inst->cfg.window_border,		    y*inst->font_height+inst->cfg.window_border,		    x*inst->font_width+inst->cfg.window_border,		    y*inst->font_height+inst->cfg.window_border,		    len*widefactor*inst->font_width, inst->font_height);}void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,	       unsigned long attr, int lattr){    struct draw_ctx *dctx = (struct draw_ctx *)ctx;    struct gui_data *inst = dctx->inst;    GdkGC *gc = dctx->gc;    int active, passive, widefactor;    if (attr & TATTR_PASCURS) {	attr &= ~TATTR_PASCURS;	passive = 1;    } else	passive = 0;    if ((attr & TATTR_ACTCURS) && inst->cfg.cursor_type != 0) {	attr &= ~TATTR_ACTCURS;        active = 1;    } else        active = 0;    do_text_internal(ctx, x, y, text, len, attr, lattr);    if (attr & TATTR_COMBINING)	len = 1;    if (attr & ATTR_WIDE) {	widefactor = 2;    } else {	widefactor = 1;    }    if ((lattr & LATTR_MODE) != LATTR_NORM) {	x *= 2;	if (x >= inst->term->cols)	    return;	if (x + len*2*widefactor > inst->term->cols)	    len = (inst->term->cols-x)/2/widefactor;/* trim to LH half */	len *= 2;    }    if (inst->cfg.cursor_type == 0) {	/*	 * An active block cursor will already have been done by	 * the above do_text call, so we only need to do anything	 * if it's passive.	 */	if (passive) {	    gdk_gc_set_foreground(gc, &inst->cols[NCOLOURS-1]);	    gdk_draw_rectangle(inst->pixmap, gc, 0,			       x*inst->font_width+inst->cfg.window_border,			       y*inst->font_height+inst->cfg.window_border,			       len*widefactor*inst->font_width-1, inst->font_height-1);	}    } else {	int uheight;	int startx, starty, dx, dy, length, i;	int char_width;	if ((attr & ATTR_WIDE) || (lattr & LATTR_MODE) != LATTR_NORM)	    char_width = 2*inst->font_width;	else	    char_width = inst->font_width;	if (inst->cfg.cursor_type == 1) {	    uheight = inst->fonts[0]->ascent + 1;	    if (uheight >= inst->font_height)		uheight = inst->font_height - 1;	    startx = x * inst->font_width + inst->cfg.window_border;	    starty = y * inst->font_height + inst->cfg.window_border + uheight;	    dx = 1;	    dy = 0;	    length = len * widefactor * char_width;	} else {	    int xadjust = 0;	    if (attr & TATTR_RIGHTCURS)		xadjust = char_width - 1;	    startx = x * inst->font_width + inst->cfg.window_border + xadjust;	    starty = y * inst->font_height + inst->cfg.window_border;	    dx = 0;	    dy = 1;	    length = inst->font_height;	}	gdk_gc_set_foreground(gc, &inst->cols[NCOLOURS-1]);	if (passive) {	    for (i = 0; i < length; i++) {		if (i % 2 == 0) {		    gdk_draw_point(inst->pixmap, gc, startx, starty);		}		startx += dx;		starty += dy;	    }	} else if (active) {	    gdk_draw_line(inst->pixmap, gc, startx, starty,			  startx + (length-1) * dx, starty + (length-1) * dy);	} /* else no cursor (e.g., blinked off) */    }    gdk_draw_pixmap(inst->area->window, gc, inst->pixmap,		    x*inst->font_width+inst->cfg.window_border,		    y*inst->font_height+inst->cfg.window_border,		    x*inst->font_width+inst->cfg.window_border,		    y*inst->font_height+inst->cfg.window_border,		    len*widefactor*inst->font_width, inst->font_height);}GdkCursor *make_mouse_ptr(struct gui_data *inst, int cursor_val){    /*     * Truly hideous hack: GTK doesn't allow us to set the mouse     * cursor foreground and background colours unless we've _also_     * created our own cursor from bitmaps. Therefore, I need to     * load the `cursor' font and draw glyphs from it on to     * pixmaps, in order to construct my cursors with the fg and bg     * I want. This is a gross hack, but it's more self-contained     * than linking in Xlib to find the X window handle to     * inst->area and calling XRecolorCursor, and it's more     * futureproof than hard-coding the shapes as bitmap arrays.     */    static GdkFont *cursor_font = NULL;    GdkPixmap *source, *mask;    GdkGC *gc;    GdkColor cfg = { 0, 65535, 65535, 65535 };    GdkColor cbg = { 0, 0, 0, 0 };    GdkColor dfg = { 1, 65535, 65535, 65535 };    GdkColor dbg = { 0, 0, 0, 0 };    GdkCursor *ret;    gchar text[2];    gint lb, rb, wid, asc, desc, w, h, x, y;    if (cursor_val == -2) {	gdk_font_unref(cursor_font);	return NULL;    }    if (cursor_val >= 0 && !cursor_font)	cursor_font = gdk_font_load("cursor");    /*     * Get the text extent of the cursor in question. We use the     * mask character for this, because it's typically slightly     * bigger than the main character.     */    if (cursor_val >= 0) {	text[1] = '\0';	text[0] = (char)cursor_val + 1;	gdk_string_extents(cursor_font, text, &lb, &rb, &wid, &asc, &desc);	w = rb-lb; h = asc+desc; x = -lb; y = asc;    } else {	w = h = 1;	x = y = 0;    }    source = gdk_pixmap_new(NULL, w, h, 1);    mask = gdk_pixmap_new(NULL, w, h, 1);    /*     * Draw the mask character on the mask pixmap.     */    gc = gdk_gc_new(mask);    gdk_gc_set_foreground(gc, &dbg);    gdk_draw_rectangle(mask, gc, 1, 0, 0, w, h);    if (cursor_val >= 0) {	text[1] = '\0';	text[0] = (char)cursor_val + 1;	gdk_gc_set_foreground(gc, &dfg);	gdk_draw_text(mask, cursor_font, gc, x, y, text, 1);    }    gdk_gc_unref(gc);    /*     * Draw the main character on the source pixmap.     */    gc = gdk_gc_new(source);    gdk_gc_set_foreground(gc, &dbg);    gdk_draw_rectangle(source, gc, 1, 0, 0, w, h);    if (cursor_val >= 0) {	text[1] = '\0';	text[0] = (char)cursor_val;	gdk_gc_set_foreground(gc, &dfg);	gdk_draw_text(source, cursor_font, gc, x, y, text, 1);    }    gdk_gc_unref(gc);    /*     * Create the cursor.     */    ret = gdk_cursor_new_from_pixmap(source, mask, &cfg, &cbg, x, y);    /*     * Clean up.     */    gdk_pixmap_unref(source);    gdk_pixmap_unref(mask);    return ret;}void modalfatalbox(char *p, ...){    va_list ap;    fprintf(stderr, "FATAL ERROR: ");    va_start(ap, p);    vfprintf(stderr, p, ap);    va_end(ap);    fputc('\n', stderr);    exit(1);}void cmdline_error(char *p, ...){    va_list ap;    fprintf(stderr, "%s: ", appname);    va_start(ap, p);    vfprintf(stderr, p, ap);    va_end(ap);    fputc('\n', stderr);    exit(1);}char *get_x_display(void *frontend){    return gdk_get_display();}long get_windowid(void *frontend){    struct gui_data *inst = (struct gui_data *)frontend;    return (long)GDK_WINDOW_XWINDOW(inst->area->window);}static void help(FILE *fp) {    if(fprintf(fp,"pterm option summary:\n""\n""  --display DISPLAY         Specify X display to use (note '--')\n""  -name PREFIX              Prefix when looking up resources (default: pterm)\n""  -fn FONT                  Normal text font\n""  -fb FONT                  Bold text font\n""  -geometry GEOMETRY        Position and size of window (size in characters)\n""  -sl LINES                 Number of lines of scrollback\n""  -fg COLOUR, -bg COLOUR    Foreground/background colour\n""  -bfg COLOUR, -bbg COLOUR  Foreground/background bold colour\n""  -cfg COLOUR, -bfg COLOUR  Foreground/background cursor colour\n""  -T TITLE                  Window title\n""  -ut, +ut                  Do(default) or do not update utmp\n""  -ls, +ls                  Do(default) or do not make shell a login shell\n""  -sb, +sb                  Do(default) or do not display

⌨️ 快捷键说明

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