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

📄 macterm.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 4 页
字号:
static void mac_growterm(WindowPtr window, EventRecord *event)
{
    Rect limits;
    long grow_result;
    int newrows, newcols;
    Session *s;
#if !TARGET_API_MAC_CARBON
    DragGrayRgnUPP draghooksave;
    GrafPtr portsave;
    FontInfo fi;
#endif

    s = mac_windowsession(window);

#if !TARGET_API_MAC_CARBON
    draghooksave = LMGetDragHook();
    growterm_state.oldmsg[0] = '\0';
    growterm_state.zeromouse = event->where;
    growterm_state.zeromouse.h -= s->term->cols * s->font_width;
    growterm_state.zeromouse.v -= s->term->rows * s->font_height;
    growterm_state.s = s;
    GetPort(&portsave);
    SetPort(s->window);
    BackColor(whiteColor);
    ForeColor(blackColor);
    TextFont(systemFont);
    TextFace(0);
    TextSize(12);
    GetFontInfo(&fi);
    SetRect(&growterm_state.msgrect, 0, 0,
	    StringWidth("\p99999x99999") + 4, fi.ascent + fi.descent + 4);
    SetPt(&growterm_state.msgorigin, 2, fi.ascent + 2);
    LMSetDragHook(NewDragGrayRgnUPP(mac_growtermdraghook));
#endif

    SetRect(&limits, s->font_width + 15, s->font_height, SHRT_MAX, SHRT_MAX);
    grow_result = GrowWindow(window, event->where, &limits);

#if !TARGET_API_MAC_CARBON
    DisposeDragGrayRgnUPP(LMGetDragHook());
    LMSetDragHook(draghooksave);
    InvalRect(&growterm_state.msgrect);

    SetPort(portsave);
#endif

    if (grow_result != 0) {
	newrows = HiWord(grow_result) / s->font_height;
	newcols = (LoWord(grow_result) - 15) / s->font_width;
	mac_adjustsize(s, newrows, newcols);
	term_size(s->term, newrows, newcols, s->cfg.savelines);
    }
}

#if !TARGET_API_MAC_CARBON
static pascal void mac_growtermdraghook(void)
{
    Session *s = growterm_state.s;
    GrafPtr portsave;
    Point mouse;
    char buf[20];
    unsigned char pbuf[20];
    int newrows, newcols;
    
    GetMouse(&mouse);
    newrows = (mouse.v - growterm_state.zeromouse.v) / s->font_height;
    if (newrows < 1) newrows = 1;
    newcols = (mouse.h - growterm_state.zeromouse.h) / s->font_width;
    if (newcols < 1) newcols = 1;
    sprintf(buf, "%dx%d", newcols, newrows);
    if (strcmp(buf, growterm_state.oldmsg) == 0)
	return;
    strcpy(growterm_state.oldmsg, buf);
    c2pstrcpy(pbuf, buf);

    GetPort(&portsave);
    SetPort(growterm_state.s->window);
    EraseRect(&growterm_state.msgrect);
    MoveTo(growterm_state.msgorigin.h, growterm_state.msgorigin.v);
    DrawString(pbuf);
    SetPort(portsave);
}
#endif

void mac_closeterm(WindowPtr window)
{
    Session *s = mac_windowsession(window);

    /* XXX warn on close */
    HideWindow(s->window);
    *s->prev = s->next;
    s->next->prev = s->prev;
    ldisc_free(s->ldisc);
    s->back->free(s->backhandle);
    log_free(s->logctx);
    if (s->uni_to_font != NULL)
	DisposeUnicodeToTextInfo(&s->uni_to_font);
    term_free(s->term);
    mac_freeeventlog(s);
    sfree((WinInfo *)GetWRefCon(s->window));
    DisposeWindow(s->window);
    DisposePalette(s->palette);
    sfree(s);
}

static void mac_activateterm(WindowPtr window, EventRecord *event)
{
    Session *s;
    Boolean active = (event->modifiers & activeFlag) != 0;

    s = mac_windowsession(window);
    s->term->has_focus = active;
    term_update(s->term);
    if (active)
	ShowControl(s->scrollbar);
    else {
	if (HAVE_COLOR_QD())
	    PmBackColor(DEFAULT_BG);/* HideControl clears behind the control */
	else
	    BackColor(blackColor);
	HideControl(s->scrollbar);
    }
    mac_drawgrowicon(s);
}

static void mac_updateterm(WindowPtr window)
{
    Session *s;
    Rect bbox;
#if TARGET_API_MAC_CARBON
    RgnHandle visrgn;
#endif

    s = mac_windowsession(window);
    SetPort((GrafPtr)GetWindowPort(window));
    BeginUpdate(window);
    pre_paint(s);
#if TARGET_API_MAC_CARBON
    visrgn = NewRgn();
    GetPortVisibleRegion(GetWindowPort(window), visrgn);
    GetRegionBounds(visrgn, &bbox);
#else
    bbox = (*window->visRgn)->rgnBBox;
#endif
    term_paint(s->term, s, PTOCC(bbox.left), PTOCR(bbox.top),
	       PTOCC(bbox.right), PTOCR(bbox.bottom), 1);
    /* Restore default colours in case the Window Manager uses them */
    if (HAVE_COLOR_QD()) {
	PmForeColor(DEFAULT_FG);
	PmBackColor(DEFAULT_BG);
    } else {
	ForeColor(whiteColor);
	BackColor(blackColor);
    }
    if (FrontWindow() != window)
#if TARGET_API_MAC_CARBON
	EraseRect(GetControlBounds(s->scrollbar, &bbox));
    UpdateControls(window, visrgn);
    DisposeRgn(visrgn);
#else
	EraseRect(&(*s->scrollbar)->contrlRect);
    UpdateControls(window, window->visRgn);
#endif
    mac_drawgrowicon(s);
    post_paint(s);
    EndUpdate(window);
}

static void mac_drawgrowicon(Session *s)
{
    Rect clip;
    RgnHandle savergn;

    SetPort((GrafPtr)GetWindowPort(s->window));
    /*
     * Stop DrawGrowIcon giving us space for a horizontal scrollbar
     * See Tech Note TB575 for details.
     */
#if TARGET_API_MAC_CARBON
    GetPortBounds(GetWindowPort(s->window), &clip);
#else
    clip = s->window->portRect;
#endif
    clip.left = clip.right - 15;
    savergn = NewRgn();
    GetClip(savergn);
    ClipRect(&clip);
    DrawGrowIcon(s->window);
    SetClip(savergn);
    DisposeRgn(savergn);
}    

struct do_text_args {
    Session *s;
    Rect textrect;
    char *text;
    int len;
    unsigned long attr;
    int lattr;
    Point numer, denom;
};

/*
 * Call from the terminal emulator to draw a bit of text
 *
 * x and y are text row and column (zero-based)
 */
void do_text(Context ctx, int x, int y, char *text, int len,
	     unsigned long attr, int lattr)
{
    Session *s = ctx;
    int style;
    struct do_text_args a;
    RgnHandle textrgn, saveclip;
#if TARGET_API_MAC_CARBON
    RgnHandle visrgn;
#endif
    char mactextbuf[1024];
    UniChar unitextbuf[1024];
    wchar_t *unitextptr;
    int i, fontwidth;
    ByteCount iread, olen;
    OSStatus err;
    static DeviceLoopDrawingUPP do_text_for_device_upp = NULL;

    assert(len <= 1024);

    SetPort((GrafPtr)GetWindowPort(s->window));

    fontwidth = s->font_width;
    if ((lattr & LATTR_MODE) != LATTR_NORM)
	fontwidth *= 2;

    /* First check this text is relevant */
    a.textrect.top = y * s->font_height;
    a.textrect.bottom = (y + 1) * s->font_height;
    a.textrect.left = x * fontwidth;
    a.textrect.right = (x + len) * fontwidth;
    if (a.textrect.right > s->term->cols * s->font_width)
	a.textrect.right = s->term->cols * s->font_width;
#if TARGET_API_MAC_CARBON
    visrgn = NewRgn();
    GetPortVisibleRegion(GetWindowPort(s->window), visrgn);
    if (!RectInRgn(&a.textrect, visrgn)) {
	DisposeRgn(visrgn);
	return;
    }
    DisposeRgn(visrgn);
#else
    if (!RectInRgn(&a.textrect, s->window->visRgn))
	return;
#endif

    /* Unpack Unicode from the mad format we get passed */
    for (i = 0; i < len; i++)
	unitextbuf[i] = (unsigned char)text[i] | (attr & CSET_MASK);

    if (s->uni_to_font != NULL) {
	err = ConvertFromUnicodeToText(s->uni_to_font, len * sizeof(UniChar),
				       unitextbuf, kUnicodeUseFallbacksMask,
				       0, NULL, NULL, NULL,
				       1024, &iread, &olen, mactextbuf);
	if (err != noErr && err != kTECUsedFallbacksStatus)
	    olen = 0;
    } else  if (s->font_charset != CS_NONE) {
	/* XXX this is bogus if wchar_t and UniChar are different sizes. */
	unitextptr = (wchar_t *)unitextbuf;
	olen = charset_from_unicode(&unitextptr, &len, mactextbuf, 1024,
				    s->font_charset, NULL, ".", 1);
    } else
	olen = 0;

    a.s = s;
    a.text = mactextbuf;
    a.len = olen;
    a.attr = attr;
    a.lattr = lattr;
    switch (lattr & LATTR_MODE) {
      case LATTR_NORM:
	TextSize(s->cfg.font.size);
	a.numer = s->font_stdnumer;
	a.denom = s->font_stddenom;
	break;
      case LATTR_WIDE:
	TextSize(s->cfg.font.size);
	a.numer = s->font_widenumer;
	a.denom = s->font_widedenom;
	break;
      case LATTR_TOP:
      case LATTR_BOT:
	TextSize(s->cfg.font.size * 2);
	a.numer = s->font_bignumer;
	a.denom = s->font_bigdenom;
	break;
    }
    SetPort((GrafPtr)GetWindowPort(s->window));
    TextFont(s->fontnum);
    style = s->cfg.font.face;
    if ((attr & ATTR_BOLD) && !s->cfg.bold_colour)
    	style |= bold;
    if (attr & ATTR_UNDER)
	style |= underline;
    TextFace(style);
    TextMode(srcOr);
    if (HAVE_COLOR_QD())
	if (style & bold) {
	    SpaceExtra(s->font_boldadjust << 16);
	    CharExtra(s->font_boldadjust << 16);
	} else {
	    SpaceExtra(0);
	    CharExtra(0);
	}
    saveclip = NewRgn();
    GetClip(saveclip);
    ClipRect(&a.textrect);
    textrgn = NewRgn();
    RectRgn(textrgn, &a.textrect);
    if (HAVE_COLOR_QD()) {
	if (do_text_for_device_upp == NULL)
	    do_text_for_device_upp =
		NewDeviceLoopDrawingUPP(&do_text_for_device);
	DeviceLoop(textrgn, do_text_for_device_upp, (long)&a, 0);
    } else
	do_text_for_device(1, 0, NULL, (long)&a);
    SetClip(saveclip);
    DisposeRgn(saveclip);
    DisposeRgn(textrgn);
    /* Tell the window manager about it in case this isn't an update */
#if TARGET_API_MAC_CARBON
    ValidWindowRect(s->window, &a.textrect);
#else
    ValidRect(&a.textrect);
#endif
}

static pascal void do_text_for_device(short depth, short devflags,
				      GDHandle device, long cookie)
{
    struct do_text_args *a = (struct do_text_args *)cookie;
    int bgcolour, fgcolour, bright, reverse, tmp;
#if TARGET_API_MAC_CARBON
    CQDProcsPtr gp = GetPortGrafProcs(GetWindowPort(a->s->window));
#else
    QDProcsPtr gp = a->s->window->grafProcs;
#endif

    bright = (a->attr & ATTR_BOLD) && a->s->cfg.bold_colour;
    reverse = a->attr & ATTR_REVERSE;

    if (depth == 1 && (a->attr & TATTR_ACTCURS))
	reverse = !reverse;

    if (HAVE_COLOR_QD()) {
	if (depth > 2) {
	    fgcolour = ((a->attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
	    fgcolour = (fgcolour & 0xF) * 2 + (fgcolour & 0x10 ? 1 : 0);
	    bgcolour = ((a->attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
	    bgcolour = (bgcolour & 0xF) * 2 + (bgcolour & 0x10 ? 1 : 0);
	} else {
	    /*
	     * NB: bold reverse in 2bpp breaks with the usual PuTTY model and
	     * boldens the background, because that's all we can do.
	     */
	    fgcolour = bright ? DEFAULT_FG_BOLD : DEFAULT_FG;
	    bgcolour = DEFAULT_BG;
	}
	if (reverse) {
	    tmp = fgcolour;
	    fgcolour = bgcolour;
	    bgcolour = tmp;
	}
	if (bright && depth > 2)
	    fgcolour |= 1;
	if ((a->attr & TATTR_ACTCURS) && depth > 1) {
	    fgcolour = CURSOR_FG;
	    bgcolour = CURSOR_BG;
	}
	PmForeColor(fgcolour);
	PmBackColor(bgcolour);
    } else { /* No Color Quickdraw */
	/* XXX This should be done with a _little_ more configurability */
	if (reverse) {
	    ForeColor(blackColor);
	    BackColor(whiteColor);
	} else {
	    ForeColor(whiteColor);
	    BackColor(blackColor);
	}
    }

    EraseRect(&a->textrect);
    switch (a->lattr & LATTR_MODE) {
      case LATTR_NORM:
      case LATTR_WIDE:
	MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent);
	break;
      case LATTR_TOP:
	MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent * 2);
	break;
      case LATTR_BOT:
	MoveTo(a->textrect.left,
	       a->textrect.top - a->s->font_height + a->s->font_ascent * 2);
	break;
    }
    /* FIXME: Sort out bold width adjustments on Original QuickDraw. */
    if (gp != NULL)
	InvokeQDTextUPP(a->len, a->text, a->numer, a->denom, gp->textProc);
    else
	StdText(a->len, a->text, a->numer, a->denom);

    if (a->attr & TATTR_PASCURS) {
	PenNormal();
	switch (depth) {
	  case 1:
	    PenMode(patXor);
	    break;
	  default:
	    PmForeColor(CURSOR_BG);
	    break;
	}
	FrameRect(&a->textrect);
    }
}

void do_cursor(Context ctx, int x, int y, char *text, int len,
	     unsigned long attr, int lattr)
{

    do_text(ctx, x, y, text, len, attr, lattr);
}

/*
 * Call from the terminal emulator to get its graphics context.
 * Should probably be called start_redraw or something.
 */
void pre_paint(Session *s)
{
    GDHandle gdh;
    Rect myrect, tmprect;
#if TARGET_API_MAC_CARBON
    RgnHandle visrgn;
#endif

    if (HAVE_COLOR_QD()) {
	s->term->attr_mask = 0;
	SetPort((GrafPtr)GetWindowPort(s->window));
#if TARGET_API_MAC_CARBON
	visrgn = NewRgn();
	GetPortVisibleRegion(GetWindowPort(s->window), visrgn);
	GetRegionBounds(visrgn, &myrect);
	DisposeRgn(visrgn);
#else
	myrect = (*s->window->visRgn)->rgnBBox;
#endif
	LocalToGlobal((Point *)&myrect.top);
	LocalToGlobal((Point *)&myrect.bottom);
	for (gdh = GetDeviceList();
	     gdh != NULL;
	     gdh = GetNextDevice(gdh)) {
	    if (TestDeviceAttribute(gdh, screenDevice) &&
		TestDeviceAttribute(gdh, screenActive) &&
		SectRect(&(*gdh)->gdRect, &myrect, &tmprect)) {
		switch ((*(*gdh)->gdPMap)->pixelSize) {
		  case 1:
		    if (s->cfg.bold_colour)
			s->term->attr_mask |= ~(ATTR_COLOURS |
			    (s->cfg.bold_colour ? ATTR_BOLD : 0));

⌨️ 快捷键说明

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