📄 macterm.c
字号:
break;
case 2:
s->term->attr_mask |= ~ATTR_COLOURS;
break;
default:
s->term->attr_mask = ~0;
return; /* No point checking more screens. */
}
}
}
} else
s->term->attr_mask = ~(ATTR_COLOURS |
(s->cfg.bold_colour ? ATTR_BOLD : 0));
}
Context get_ctx(void *frontend)
{
Session *s = frontend;
pre_paint(s);
return s;
}
void free_ctx(Context ctx)
{
}
/*
* Presumably this does something in Windows
*/
void post_paint(Session *s)
{
}
/*
* Set the scroll bar position
*
* total is the line number of the bottom of the working screen
* start is the line number of the top of the display
* page is the length of the displayed page
*/
void set_sbar(void *frontend, int total, int start, int page)
{
Session *s = frontend;
/* We don't redraw until we've set everything up, to avoid glitches */
SetControlMinimum(s->scrollbar, 0);
SetControlMaximum(s->scrollbar, total - page);
SetControlValue(s->scrollbar, start);
#if !TARGET_CPU_68K
if (mac_gestalts.cntlattr & gestaltControlMgrPresent)
SetControlViewSize(s->scrollbar, page);
#endif
}
void sys_cursor(void *frontend, int x, int y)
{
/*
* I think his is meaningless under Mac OS.
*/
}
/*
* This is still called when mode==BELL_VISUAL, even though the
* visual bell is handled entirely within terminal.c, because we
* may want to perform additional actions on any kind of bell (for
* example, taskbar flashing in Windows).
*/
void beep(void *frontend, int mode)
{
if (mode != BELL_VISUAL)
SysBeep(30);
/*
* XXX We should indicate the relevant window and/or use the
* Notification Manager
*/
}
int char_width(Context ctx, int uc)
{
/*
* Until we support exciting character-set stuff, assume all chars are
* single-width.
*/
return 1;
}
/*
* Set icon string -- a no-op here (Windowshade?)
*/
void set_icon(void *frontend, char *icon) {
Session *s = frontend;
}
/*
* Set the window title
*/
void set_title(void *frontend, char *title)
{
Session *s = frontend;
Str255 mactitle;
c2pstrcpy(mactitle, title);
SetWTitle(s->window, mactitle);
}
/*
* set or clear the "raw mouse message" mode
*/
void set_raw_mouse_mode(void *frontend, int activate)
{
Session *s = frontend;
s->raw_mouse = activate;
/* FIXME: Should call mac_updatetermcursor as appropriate. */
}
/*
* Resize the window at the emulator's request
*/
void request_resize(void *frontend, int w, int h)
{
Session *s = frontend;
RgnHandle grayrgn;
Rect graybox;
int wlim, hlim;
/* Arbitrarily clip to the size of the desktop. */
grayrgn = GetGrayRgn();
#if TARGET_API_MAC_CARBON
GetRegionBounds(grayrgn, &graybox);
#else
graybox = (*grayrgn)->rgnBBox;
#endif
wlim = (graybox.right - graybox.left) / s->font_width;
hlim = (graybox.bottom - graybox.top) / s->font_height;
if (w > wlim) w = wlim;
if (h > hlim) h = hlim;
term_size(s->term, h, w, s->cfg.savelines);
mac_initfont(s);
}
/*
* Iconify (actually collapse) the window at the emulator's request.
*/
void set_iconic(void *frontend, int iconic)
{
Session *s = frontend;
UInt32 features;
if (mac_gestalts.apprvers >= 0x0100 &&
GetWindowFeatures(s->window, &features) == noErr &&
(features & kWindowCanCollapse))
CollapseWindow(s->window, iconic);
}
/*
* Move the window in response to a server-side request.
*/
void move_window(void *frontend, int x, int y)
{
Session *s = frontend;
MoveWindow(s->window, x, y, FALSE);
}
/*
* Move the window to the top or bottom of the z-order in response
* to a server-side request.
*/
void set_zorder(void *frontend, int top)
{
Session *s = frontend;
/*
* We also change the input focus to point to the topmost window,
* since that's probably what the Human Interface Guidelines would
* like us to do.
*/
if (top)
SelectWindow(s->window);
else
SendBehind(s->window, NULL);
}
/*
* Refresh the window in response to a server-side request.
*/
void refresh_window(void *frontend)
{
Session *s = frontend;
term_invalidate(s->term);
}
/*
* Maximise or restore the window in response to a server-side
* request.
*/
void set_zoomed(void *frontend, int zoomed)
{
Session *s = frontend;
ZoomWindow(s->window, zoomed ? inZoomOut : inZoomIn, FALSE);
}
/*
* Report whether the window is iconic, for terminal reports.
*/
int is_iconic(void *frontend)
{
Session *s = frontend;
UInt32 features;
if (mac_gestalts.apprvers >= 0x0100 &&
GetWindowFeatures(s->window, &features) == noErr &&
(features & kWindowCanCollapse))
return IsWindowCollapsed(s->window);
return FALSE;
}
/*
* Report the window's position, for terminal reports.
*/
void get_window_pos(void *frontend, int *x, int *y)
{
Session *s = frontend;
Rect rect;
#if TARGET_API_MAC_CARBON
GetPortBounds(GetWindowPort(s->window), &rect);
#else
rect = s->window->portRect;
#endif
*x = rect.left;
*y = rect.top;
}
/*
* Report the window's pixel size, for terminal reports.
*/
void get_window_pixels(void *frontend, int *x, int *y)
{
Session *s = frontend;
Rect rect;
#if TARGET_API_MAC_CARBON
GetPortBounds(GetWindowPort(s->window), &rect);
#else
rect = s->window->portRect;
#endif
*x = rect.right - rect.left;
*y = rect.bottom - rect.top;
}
/*
* Return the window or icon title.
*/
char *get_window_title(void *frontend, int icon)
{
Session *s = frontend;
Str255 ptitle;
static char title[256];
GetWTitle(s->window, ptitle);
p2cstrcpy(title, ptitle);
return title;
}
/*
* real_palette_set(): This does the actual palette-changing work on behalf
* of palette_set(). Does _not_ call ActivatePalette() in case the caller
* is doing a batch of updates.
*/
static void real_palette_set(Session *s, int n, int r, int g, int b)
{
RGBColor col;
if (!HAVE_COLOR_QD())
return;
col.red = r * 0x0101;
col.green = g * 0x0101;
col.blue = b * 0x0101;
SetEntryColor(s->palette, n, &col);
}
/*
* Set the logical palette. Called by the terminal emulator.
*/
void palette_set(void *frontend, int n, int r, int g, int b)
{
Session *s = 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, 21
};
if (!HAVE_COLOR_QD())
return;
real_palette_set(s, first[n], r, g, b);
if (first[n] == 18)
real_palette_set(s, first[n]+1, r, g, b);
if (first[n] == DEFAULT_BG)
mac_adjustwinbg(s);
ActivatePalette(s->window);
}
/*
* Reset to the default palette
*/
void palette_reset(void *frontend)
{
Session *s = frontend;
/* This maps colour indices in cfg to those used in our palette. */
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
};
int i;
if (!HAVE_COLOR_QD())
return;
assert(lenof(ww) == NCOLOURS);
for (i = 0; i < NCOLOURS; i++) {
real_palette_set(s, i,
s->cfg.colours[ww[i]][0],
s->cfg.colours[ww[i]][1],
s->cfg.colours[ww[i]][2]);
}
mac_adjustwinbg(s);
ActivatePalette(s->window);
/* Palette Manager will generate update events as required. */
}
/*
* Scroll the screen. (`lines' is +ve for scrolling forward, -ve
* for backward.)
*/
void do_scroll(Context ctx, int topline, int botline, int lines)
{
Session *s = ctx;
Rect r;
RgnHandle scrollrgn = NewRgn();
RgnHandle movedupdate = NewRgn();
RgnHandle update = NewRgn();
Point g2l = { 0, 0 };
SetPort((GrafPtr)GetWindowPort(s->window));
/*
* Work out the part of the update region that will scrolled by
* this operation.
*/
if (lines > 0)
SetRectRgn(scrollrgn, 0, (topline + lines) * s->font_height,
s->term->cols * s->font_width,
(botline + 1) * s->font_height);
else
SetRectRgn(scrollrgn, 0, topline * s->font_height,
s->term->cols * s->font_width,
(botline - lines + 1) * s->font_height);
#if TARGET_API_MAC_CARBON
GetWindowRegion(s->window, kWindowUpdateRgn, movedupdate);
#else
GetWindowUpdateRgn(s->window, movedupdate);
#endif
GlobalToLocal(&g2l);
OffsetRgn(movedupdate, g2l.h, g2l.v); /* Convert to local co-ords. */
SectRgn(scrollrgn, movedupdate, movedupdate); /* Clip scrolled section. */
#if TARGET_API_MAC_CARBON
ValidWindowRgn(s->window, movedupdate);
#else
ValidRgn(movedupdate);
#endif
OffsetRgn(movedupdate, 0, -lines * s->font_height); /* Scroll it. */
PenNormal();
if (HAVE_COLOR_QD())
PmBackColor(DEFAULT_BG);
else
BackColor(blackColor); /* XXX make configurable */
SetRect(&r, 0, topline * s->font_height,
s->term->cols * s->font_width, (botline + 1) * s->font_height);
ScrollRect(&r, 0, - lines * s->font_height, update);
#if TARGET_API_MAC_CARBON
InvalWindowRgn(s->window, update);
InvalWindowRgn(s->window, movedupdate);
#else
InvalRgn(update);
InvalRgn(movedupdate);
#endif
DisposeRgn(scrollrgn);
DisposeRgn(movedupdate);
DisposeRgn(update);
}
/* Dummy routine, only required in plink. */
void ldisc_update(void *frontend, int echo, int edit)
{
}
/*
* Mac PuTTY doesn't support printing yet.
*/
printer_job *printer_start_job(char *printer)
{
return NULL;
}
void printer_job_data(printer_job *pj, void *data, int len)
{
}
void printer_finish_job(printer_job *pj)
{
}
void frontend_keypress(void *handle)
{
/*
* Keypress termination in non-Close-On-Exit mode is not
* currently supported in PuTTY proper, because the window
* always has a perfectly good Close button anyway. So we do
* nothing here.
*/
return;
}
/*
* Ask whether to wipe a session log file before writing to it.
* Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
*/
int askappend(void *frontend, Filename filename)
{
/* FIXME: not implemented yet. */
return 2;
}
int from_backend(void *frontend, int is_stderr, const char *data, int len)
{
Session *s = frontend;
return term_data(s->term, is_stderr, data, len);
}
/*
* Emacs magic:
* Local Variables:
* c-file-style: "simon"
* End:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -