📄 macterm.c
字号:
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 + -