2 * osxwin.m: code to manage a session window in Mac OS X PuTTY.
5 #import <Cocoa/Cocoa.h>
10 /* Colours come in two flavours: configurable, and xterm-extended. */
11 #define NCFGCOLOURS (lenof(((Config *)0)->colours))
12 #define NEXTCOLOURS 240 /* 216 colour-cube plus 24 shades of grey */
13 #define NALLCOLOURS (NCFGCOLOURS + NEXTCOLOURS)
16 * The key component of the per-session data is the SessionWindow
17 * class. A pointer to this is used as the frontend handle, to be
18 * passed to all the platform-independent subsystems that require
22 @interface TerminalView : NSImageView
28 NSColor *colours[NALLCOLOURS];
29 float fw, fasc, fdesc, fh;
31 - (void)drawStartFinish:(BOOL)start;
32 - (void)setColour:(int)n r:(float)r g:(float)g b:(float)b;
33 - (void)doText:(wchar_t *)text len:(int)len x:(int)x y:(int)y
34 attr:(unsigned long)attr lattr:(int)lattr;
37 @implementation TerminalView
42 - (id)initWithTerminal:(Terminal *)aTerm config:(Config)aCfg
46 self = [self initWithFrame:NSMakeRect(0,0,100,100)];
52 * Initialise the fonts we're going to use.
54 * FIXME: for the moment I'm sticking with exactly one default font.
56 font = [NSFont userFixedPitchFontOfSize:0];
59 * Now determine the size of the primary font.
61 * FIXME: If we have multiple fonts, we may need to set fasc
62 * and fdesc to the _maximum_ asc and desc out of all the
63 * fonts, _before_ adding them together to get fh.
65 fw = [font widthOfString:@"A"];
66 fasc = [font ascender];
67 fdesc = -[font descender];
69 fh = (int)fh + (fh > (int)fh); /* round up, ickily */
72 * Use this to figure out the size of the terminal view.
78 * And set our size and subimage.
80 image = [[NSImage alloc] initWithSize:NSMakeSize(w,h)];
81 [image setFlipped:YES];
82 [self setImage:image];
83 [self setFrame:NSMakeRect(0,0,w,h)];
85 term_invalidate(term);
89 - (void)drawStartFinish:(BOOL)start
96 - (void)doText:(wchar_t *)text len:(int)len x:(int)x y:(int)y
97 attr:(unsigned long)attr lattr:(int)lattr
99 int nfg, nbg, rlen, widefactor;
100 float ox, oy, tw, th;
101 NSDictionary *attrdict;
103 /* FIXME: TATTR_COMBINING */
105 nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
106 nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
107 if (attr & ATTR_REVERSE) {
112 if (cfg.bold_colour && (attr & ATTR_BOLD)) {
113 if (nfg < 16) nfg |= 8;
114 else if (nfg >= 256) nfg |= 1;
116 if (cfg.bold_colour && (attr & ATTR_BLINK)) {
117 if (nbg < 16) nbg |= 8;
118 else if (nbg >= 256) nbg |= 1;
120 if (attr & TATTR_ACTCURS) {
125 if (attr & ATTR_WIDE) {
127 /* FIXME: what do we actually have to do about wide characters? */
132 /* FIXME: ATTR_BOLD without cfg.bold_colour */
134 if ((lattr & LATTR_MODE) != LATTR_NORM) {
138 if (x + len*2*widefactor > term->cols)
139 len = (term->cols-x)/2/widefactor;/* trim to LH half */
144 /* FIXME: how do we actually implement double-{width,height} lattrs? */
148 tw = rlen * widefactor * fw;
152 * Set the clipping rectangle.
154 [[NSGraphicsContext currentContext] saveGraphicsState];
155 [NSBezierPath clipRect:NSMakeRect(ox, oy, tw, th)];
157 attrdict = [NSDictionary dictionaryWithObjectsAndKeys:
158 colours[nfg], NSForegroundColorAttributeName,
159 colours[nbg], NSBackgroundColorAttributeName,
160 font, NSFontAttributeName, nil];
163 * Create an NSString and draw it.
165 * Annoyingly, although our input is wchar_t which is four
166 * bytes wide on OS X and terminal.c supports 32-bit Unicode,
167 * we must convert into the two-byte type `unichar' to store in
168 * NSString, so we lose display capability for extra-BMP stuff
176 utext = snewn(len, unichar);
177 for (i = 0; i < len; i++)
178 utext[i] = (text[i] >= 0x10000 ? 0xFFFD : text[i]);
180 string = [NSString stringWithCharacters:utext length:len];
181 [string drawAtPoint:NSMakePoint(ox, oy) withAttributes:attrdict];
187 * Restore the graphics state from before the clipRect: call.
189 [[NSGraphicsContext currentContext] restoreGraphicsState];
192 * And flag this area as needing display.
194 [self setNeedsDisplayInRect:NSMakeRect(ox, oy, tw, th)];
197 - (void)setColour:(int)n r:(float)r g:(float)g b:(float)b
199 assert(n >= 0 && n < lenof(colours));
200 colours[n] = [[NSColor colorWithDeviceRed:r green:g blue:b alpha:1.0]
205 @implementation SessionWindow
206 - (id)initWithConfig:(Config)aCfg
208 NSRect rect = { {0,0}, {0,0} };
210 cfg = aCfg; /* structure copy */
212 init_ucs(&ucsdata, cfg.line_codepage, cfg.utf8_override,
213 CS_UTF8, cfg.vtmode);
214 term = term_init(&cfg, &ucsdata, self);
215 logctx = log_init(self, &cfg);
216 term_provide_logctx(term, logctx);
217 term_size(term, cfg.height, cfg.width, cfg.savelines);
219 termview = [[[TerminalView alloc] initWithTerminal:term config:cfg]
223 * Now work out the size of the window.
225 rect = [termview frame];
226 rect.origin = NSMakePoint(0,0);
227 rect.size.width += 2 * cfg.window_border;
228 rect.size.height += 2 * cfg.window_border;
236 for (i = 0; backends[i].backend != NULL; i++)
237 if (backends[i].protocol == cfg.protocol) {
238 back = backends[i].backend;
245 char *realhost = NULL;
246 error = back->init(self, &backhandle, &cfg, cfg.host, cfg.port,
247 &realhost, cfg.tcp_nodelay, cfg.tcp_keepalives);
249 fatalbox("%s\n", error); /* FIXME: connection_fatal at worst */
253 sfree(realhost); /* FIXME: do something with this */
257 * Create a line discipline. (This must be done after creating
258 * the terminal _and_ the backend, since it needs to be passed
261 ldisc = ldisc_create(&cfg, term, back, backhandle, self);
264 * FIXME: Set up a scrollbar.
267 self = [super initWithContentRect:rect
268 styleMask:(NSTitledWindowMask | NSMiniaturizableWindowMask |
269 NSClosableWindowMask)
270 backing:NSBackingStoreBuffered
272 [self setTitle:@"PuTTY"];
274 [self setIgnoresMouseEvents:NO];
277 * Put the terminal view in the window.
279 rect = [termview frame];
280 rect.origin = NSMakePoint(cfg.window_border, cfg.window_border);
281 [termview setFrame:rect];
282 [[self contentView] addSubview:termview];
285 * Set up the colour palette.
290 * FIXME: Only the _first_ document window should be centred.
291 * The subsequent ones should appear down and to the right of
292 * it, probably using the cascade function provided by Cocoa.
293 * Also we're apparently required by the HIG to remember and
294 * reuse previous positions of windows, although I'm not sure
295 * how that works if the user opens more than one of the same
298 [self center]; /* :-) */
306 * FIXME: Here we must deallocate all sorts of stuff: the
307 * terminal, the backend, the ldisc, the logctx, you name it.
313 - (void)drawStartFinish:(BOOL)start
315 [termview drawStartFinish:start];
318 - (void)setColour:(int)n r:(float)r g:(float)g b:(float)b
320 [termview setColour:n r:r g:g b:b];
323 - (void)doText:(wchar_t *)text len:(int)len x:(int)x y:(int)y
324 attr:(unsigned long)attr lattr:(int)lattr
326 /* Pass this straight on to the TerminalView. */
327 [termview doText:text len:len x:x y:y attr:attr lattr:lattr];
335 - (void)keyDown:(NSEvent *)ev
337 NSString *s = [ev characters];
339 int n = [s length], c = [s characterAtIndex:0], m = [ev modifierFlags];
340 int cm = [[ev charactersIgnoringModifiers] characterAtIndex:0];
343 int use_coutput = FALSE, special = FALSE, start, end;
345 printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
348 * FIXME: Alt+numberpad codes.
352 * Shift and Ctrl with PageUp/PageDown for scrollback.
354 if (n == 1 && c == NSPageUpFunctionKey && (m & NSShiftKeyMask)) {
355 term_scroll(term, 0, -term->rows/2);
358 if (n == 1 && c == NSPageUpFunctionKey && (m & NSControlKeyMask)) {
359 term_scroll(term, 0, -1);
362 if (n == 1 && c == NSPageDownFunctionKey && (m & NSShiftKeyMask)) {
363 term_scroll(term, 0, +term->rows/2);
366 if (n == 1 && c == NSPageDownFunctionKey && (m & NSControlKeyMask)) {
367 term_scroll(term, 0, +1);
372 * FIXME: Shift-Ins for paste? Or is that not Maccy enough?
376 * FIXME: Alt (Option? Command?) prefix in general.
378 * (Note that Alt-Shift-thing will work just by looking at
379 * charactersIgnoringModifiers; but Alt-Ctrl-thing will need
380 * processing properly, and Alt-as-in-Option won't happen at
383 * (Note also that we need to be able to override menu key
384 * equivalents before this is particularly useful.)
390 * Ctrl-` is the same as Ctrl-\, unless we already have a
393 if ((m & NSControlKeyMask) && n == 1 && cm == '`' && c == '`') {
398 /* We handle Return ourselves, because it needs to be flagged as
399 * special to ldisc. */
400 if (n == 1 && c == '\015') {
407 /* Control-Shift-Space is 160 (ISO8859 nonbreaking space) */
408 if (n == 1 && (m & NSControlKeyMask) && (m & NSShiftKeyMask) &&
414 /* Control-2, Control-Space and Control-@ are all NUL. */
415 if ((m & NSControlKeyMask) && n == 1 &&
416 (cm == '2' || cm == '@' || cm == ' ') && c == cm) {
421 /* We don't let MacOS tell us what Backspace is! We know better. */
422 if (cm == 0x7F && !(m & NSShiftKeyMask)) {
423 coutput[1] = cfg.bksp_is_delete ? '\x7F' : '\x08';
425 use_coutput = special = TRUE;
427 /* For Shift Backspace, do opposite of what is configured. */
428 if (cm == 0x7F && (m & NSShiftKeyMask)) {
429 coutput[1] = cfg.bksp_is_delete ? '\x08' : '\x7F';
431 use_coutput = special = TRUE;
434 /* Shift-Tab is ESC [ Z. Oddly, this combination generates ^Y by
435 * default on MacOS! */
436 if (cm == 0x19 && (m & NSShiftKeyMask) && !(m & NSControlKeyMask)) {
438 output[end++] = '\033';
444 * NetHack keypad mode.
446 if (cfg.nethack_keypad && (m & NSNumericPadKeyMask)) {
447 wchar_t *keys = NULL;
449 case '1': keys = L"bB"; break;
450 case '2': keys = L"jJ"; break;
451 case '3': keys = L"nN"; break;
452 case '4': keys = L"hH"; break;
453 case '5': keys = L".."; break;
454 case '6': keys = L"lL"; break;
455 case '7': keys = L"yY"; break;
456 case '8': keys = L"kK"; break;
457 case '9': keys = L"uU"; break;
461 if (m & NSShiftKeyMask)
470 * Application keypad mode.
472 if (term->app_keypad_keys && !cfg.no_applic_k &&
473 (m & NSNumericPadKeyMask)) {
476 case NSClearLineFunctionKey: xkey = 'P'; break;
477 case '=': xkey = 'Q'; break;
478 case '/': xkey = 'R'; break;
479 case '*': xkey = 'S'; break;
481 * FIXME: keypad - and + need to be mapped to ESC O l
482 * and ESC O k, or ESC O l and ESC O m, depending on
483 * xterm function key mode, and I can't remember which
486 case '\003': xkey = 'M'; break;
487 case '0': xkey = 'p'; break;
488 case '1': xkey = 'q'; break;
489 case '2': xkey = 'r'; break;
490 case '3': xkey = 's'; break;
491 case '4': xkey = 't'; break;
492 case '5': xkey = 'u'; break;
493 case '6': xkey = 'v'; break;
494 case '7': xkey = 'w'; break;
495 case '8': xkey = 'x'; break;
496 case '9': xkey = 'y'; break;
497 case '.': xkey = 'n'; break;
500 if (term->vt52_mode) {
501 if (xkey >= 'P' && xkey <= 'S') {
502 output[end++] = '\033';
503 output[end++] = xkey;
505 output[end++] = '\033';
507 output[end++] = xkey;
510 output[end++] = '\033';
512 output[end++] = xkey;
519 * Next, all the keys that do tilde codes. (ESC '[' nn '~',
520 * for integer decimal nn.)
522 * We also deal with the weird ones here. Linux VCs replace F1
523 * to F5 by ESC [ [ A to ESC [ [ E. rxvt doesn't do _that_, but
524 * does replace Home and End (1~ and 4~) by ESC [ H and ESC O w
530 case NSF1FunctionKey:
531 code = (m & NSShiftKeyMask ? 23 : 11);
533 case NSF2FunctionKey:
534 code = (m & NSShiftKeyMask ? 24 : 12);
536 case NSF3FunctionKey:
537 code = (m & NSShiftKeyMask ? 25 : 13);
539 case NSF4FunctionKey:
540 code = (m & NSShiftKeyMask ? 26 : 14);
542 case NSF5FunctionKey:
543 code = (m & NSShiftKeyMask ? 28 : 15);
545 case NSF6FunctionKey:
546 code = (m & NSShiftKeyMask ? 29 : 17);
548 case NSF7FunctionKey:
549 code = (m & NSShiftKeyMask ? 31 : 18);
551 case NSF8FunctionKey:
552 code = (m & NSShiftKeyMask ? 32 : 19);
554 case NSF9FunctionKey:
555 code = (m & NSShiftKeyMask ? 33 : 20);
557 case NSF10FunctionKey:
558 code = (m & NSShiftKeyMask ? 34 : 21);
560 case NSF11FunctionKey:
563 case NSF12FunctionKey:
566 case NSF13FunctionKey:
569 case NSF14FunctionKey:
572 case NSF15FunctionKey:
575 case NSF16FunctionKey:
578 case NSF17FunctionKey:
581 case NSF18FunctionKey:
584 case NSF19FunctionKey:
587 case NSF20FunctionKey:
591 if (!(m & NSControlKeyMask)) switch (cm) {
592 case NSHomeFunctionKey:
596 case GDK_Insert: case GDK_KP_Insert:
600 case NSDeleteFunctionKey:
603 case NSEndFunctionKey:
606 case NSPageUpFunctionKey:
609 case NSPageDownFunctionKey:
613 /* Reorder edit keys to physical order */
614 if (cfg.funky_type == FUNKY_VT400 && code <= 6)
615 code = "\0\2\1\4\5\3\6"[code];
617 if (term->vt52_mode && code > 0 && code <= 6) {
618 output[end++] = '\033';
619 output[end++] = " HLMEIG"[code];
623 if (cfg.funky_type == FUNKY_SCO && /* SCO function keys */
624 code >= 11 && code <= 34) {
625 char codes[] = "MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@[\\]^_`{";
628 case NSF1FunctionKey: index = 0; break;
629 case NSF2FunctionKey: index = 1; break;
630 case NSF3FunctionKey: index = 2; break;
631 case NSF4FunctionKey: index = 3; break;
632 case NSF5FunctionKey: index = 4; break;
633 case NSF6FunctionKey: index = 5; break;
634 case NSF7FunctionKey: index = 6; break;
635 case NSF8FunctionKey: index = 7; break;
636 case NSF9FunctionKey: index = 8; break;
637 case NSF10FunctionKey: index = 9; break;
638 case NSF11FunctionKey: index = 10; break;
639 case NSF12FunctionKey: index = 11; break;
641 if (m & NSShiftKeyMask) index += 12;
642 if (m & NSControlKeyMask) index += 24;
643 output[end++] = '\033';
645 output[end++] = codes[index];
648 if (cfg.funky_type == FUNKY_SCO && /* SCO small keypad */
649 code >= 1 && code <= 6) {
650 char codes[] = "HL.FIG";
655 output[end++] = '\033';
657 output[end++] = codes[code-1];
661 if ((term->vt52_mode || cfg.funky_type == FUNKY_VT100P) &&
662 code >= 11 && code <= 24) {
668 if (term->vt52_mode) {
669 output[end++] = '\033';
670 output[end++] = code + 'P' - 11 - offt;
672 output[end++] = '\033';
674 output[end++] = code + 'P' - 11 - offt;
678 if (cfg.funky_type == FUNKY_LINUX && code >= 11 && code <= 15) {
679 output[end++] = '\033';
682 output[end++] = code + 'A' - 11;
685 if (cfg.funky_type == FUNKY_XTERM && code >= 11 && code <= 14) {
686 if (term->vt52_mode) {
687 output[end++] = '\033';
688 output[end++] = code + 'P' - 11;
690 output[end++] = '\033';
692 output[end++] = code + 'P' - 11;
696 if (cfg.rxvt_homeend && (code == 1 || code == 4)) {
698 output[end++] = '\033';
702 output[end++] = '\033';
710 sprintf(buf, "\x1B[%d~", code);
711 for (i = 0; buf[i]; i++)
712 output[end++] = buf[i];
718 * Cursor keys. (This includes the numberpad cursor keys,
719 * if we haven't already done them due to app keypad mode.)
724 case NSUpArrowFunctionKey: xkey = 'A'; break;
725 case NSDownArrowFunctionKey: xkey = 'B'; break;
726 case NSRightArrowFunctionKey: xkey = 'C'; break;
727 case NSLeftArrowFunctionKey: xkey = 'D'; break;
731 * The arrow keys normally do ESC [ A and so on. In
732 * app cursor keys mode they do ESC O A instead.
733 * Ctrl toggles the two modes.
735 if (term->vt52_mode) {
736 output[end++] = '\033';
737 output[end++] = xkey;
738 } else if (!term->app_cursor_keys ^ !(m & NSControlKeyMask)) {
739 output[end++] = '\033';
741 output[end++] = xkey;
743 output[end++] = '\033';
745 output[end++] = xkey;
754 * Failing everything else, send the exact Unicode we got from
758 if (n > lenof(output)-start)
759 n = lenof(output)-start; /* _shouldn't_ happen! */
760 for (i = 0; i < n; i++) {
761 output[i+start] = [s characterAtIndex:i];
768 assert(end < lenof(coutput));
770 ldisc_send(ldisc, coutput+start, -2, TRUE);
772 luni_send(ldisc, output+start, end-start, TRUE);
776 - (int)fromBackend:(const char *)data len:(int)len isStderr:(int)is_stderr
778 return term_data(term, is_stderr, data, len);
783 int from_backend(void *frontend, int is_stderr, const char *data, int len)
785 SessionWindow *win = (SessionWindow *)frontend;
786 return [win fromBackend:data len:len isStderr:is_stderr];
789 void frontend_keypress(void *handle)
794 void connection_fatal(void *frontend, char *p, ...)
796 //SessionWindow *win = (SessionWindow *)frontend;
797 /* FIXME: proper OS X GUI stuff */
799 fprintf(stderr, "FATAL ERROR: ");
801 vfprintf(stderr, p, ap);
807 void notify_remote_exit(void *frontend)
809 //SessionWindow *win = (SessionWindow *)frontend;
813 void ldisc_update(void *frontend, int echo, int edit)
815 //SessionWindow *win = (SessionWindow *)frontend;
817 * In a GUI front end, this need do nothing.
821 void update_specials_menu(void *frontend)
823 //SessionWindow *win = (SessionWindow *)frontend;
828 * This is still called when mode==BELL_VISUAL, even though the
829 * visual bell is handled entirely within terminal.c, because we
830 * may want to perform additional actions on any kind of bell (for
831 * example, taskbar flashing in Windows).
833 void beep(void *frontend, int mode)
835 //SessionWindow *win = (SessionWindow *)frontend;
836 if (mode != BELL_VISUAL)
840 int char_width(Context ctx, int uc)
843 * Under X, any fixed-width font really _is_ fixed-width.
844 * Double-width characters will be dealt with using a separate
845 * font. For the moment we can simply return 1.
850 void palette_set(void *frontend, int n, int r, int g, int b)
852 SessionWindow *win = (SessionWindow *)frontend;
858 [win setColour:n r:r/255.0 g:g/255.0 b:b/255.0];
861 * FIXME: do we need an OS X equivalent of set_window_background?
865 void palette_reset(void *frontend)
867 SessionWindow *win = (SessionWindow *)frontend;
868 Config *cfg = [win cfg];
870 /* This maps colour indices in cfg to those used in colours[]. */
871 static const int ww[] = {
872 256, 257, 258, 259, 260, 261,
873 0, 8, 1, 9, 2, 10, 3, 11,
874 4, 12, 5, 13, 6, 14, 7, 15
879 for (i = 0; i < NCFGCOLOURS; i++) {
880 [win setColour:ww[i] r:cfg->colours[i][0]/255.0
881 g:cfg->colours[i][1]/255.0 b:cfg->colours[i][2]/255.0];
884 for (i = 0; i < NEXTCOLOURS; i++) {
886 int r = i / 36, g = (i / 6) % 6, b = i % 6;
887 [win setColour:i+16 r:r/5.0 g:g/5.0 b:b/5.0];
890 float fshade = (shade + 1) / (float)(NEXTCOLOURS - 216 + 1);
891 [win setColour:i+16 r:fshade g:fshade b:fshade];
896 * FIXME: do we need an OS X equivalent of set_window_background?
900 Context get_ctx(void *frontend)
902 SessionWindow *win = (SessionWindow *)frontend;
905 * Lock the drawing focus on the image inside the TerminalView.
907 [win drawStartFinish:YES];
909 [[NSGraphicsContext currentContext] setShouldAntialias:YES];
912 * Cocoa drawing functions don't take a graphics context: that
913 * parameter is implicit. Therefore, we'll use the frontend
914 * handle itself as the context, on the grounds that it's as
915 * good a thing to use as any.
920 void free_ctx(Context ctx)
922 SessionWindow *win = (SessionWindow *)ctx;
924 [win drawStartFinish:NO];
927 void do_text(Context ctx, int x, int y, wchar_t *text, int len,
928 unsigned long attr, int lattr)
930 SessionWindow *win = (SessionWindow *)ctx;
932 [win doText:text len:len x:x y:y attr:attr lattr:lattr];
935 void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
936 unsigned long attr, int lattr)
938 SessionWindow *win = (SessionWindow *)ctx;
939 Config *cfg = [win cfg];
942 if (attr & TATTR_PASCURS) {
943 attr &= ~TATTR_PASCURS;
947 if ((attr & TATTR_ACTCURS) && cfg->cursor_type != 0) {
948 attr &= ~TATTR_ACTCURS;
953 [win doText:text len:len x:x y:y attr:attr lattr:lattr];
956 * FIXME: now draw the various cursor types (both passive and
957 * active underlines and vertical lines, plus passive blocks).
962 * Minimise or restore the window in response to a server-side
965 void set_iconic(void *frontend, int iconic)
967 //SessionWindow *win = (SessionWindow *)frontend;
972 * Move the window in response to a server-side request.
974 void move_window(void *frontend, int x, int y)
976 //SessionWindow *win = (SessionWindow *)frontend;
981 * Move the window to the top or bottom of the z-order in response
982 * to a server-side request.
984 void set_zorder(void *frontend, int top)
986 //SessionWindow *win = (SessionWindow *)frontend;
991 * Refresh the window in response to a server-side request.
993 void refresh_window(void *frontend)
995 //SessionWindow *win = (SessionWindow *)frontend;
1000 * Maximise or restore the window in response to a server-side
1003 void set_zoomed(void *frontend, int zoomed)
1005 //SessionWindow *win = (SessionWindow *)frontend;
1010 * Report whether the window is iconic, for terminal reports.
1012 int is_iconic(void *frontend)
1014 //SessionWindow *win = (SessionWindow *)frontend;
1015 return NO; /* FIXME */
1019 * Report the window's position, for terminal reports.
1021 void get_window_pos(void *frontend, int *x, int *y)
1023 //SessionWindow *win = (SessionWindow *)frontend;
1028 * Report the window's pixel size, for terminal reports.
1030 void get_window_pixels(void *frontend, int *x, int *y)
1032 //SessionWindow *win = (SessionWindow *)frontend;
1037 * Return the window or icon title.
1039 char *get_window_title(void *frontend, int icon)
1041 //SessionWindow *win = (SessionWindow *)frontend;
1042 return NULL; /* FIXME */
1045 void set_title(void *frontend, char *title)
1047 //SessionWindow *win = (SessionWindow *)frontend;
1051 void set_icon(void *frontend, char *title)
1053 //SessionWindow *win = (SessionWindow *)frontend;
1057 void set_sbar(void *frontend, int total, int start, int page)
1059 //SessionWindow *win = (SessionWindow *)frontend;
1063 void get_clip(void *frontend, wchar_t ** p, int *len)
1065 //SessionWindow *win = (SessionWindow *)frontend;
1069 void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
1071 //SessionWindow *win = (SessionWindow *)frontend;
1075 void request_paste(void *frontend)
1077 //SessionWindow *win = (SessionWindow *)frontend;
1081 void set_raw_mouse_mode(void *frontend, int activate)
1083 //SessionWindow *win = (SessionWindow *)frontend;
1087 void request_resize(void *frontend, int w, int h)
1089 //SessionWindow *win = (SessionWindow *)frontend;
1093 void sys_cursor(void *frontend, int x, int y)
1095 //SessionWindow *win = (SessionWindow *)frontend;
1097 * This is probably meaningless under OS X. FIXME: find out for
1102 void logevent(void *frontend, const char *string)
1104 //SessionWindow *win = (SessionWindow *)frontend;
1106 printf("logevent: %s\n", string);
1109 int font_dimension(void *frontend, int which)/* 0 for width, 1 for height */
1111 //SessionWindow *win = (SessionWindow *)frontend;
1112 return 1; /* FIXME */
1115 void set_busy_status(void *frontend, int status)
1118 * We need do nothing here: the OS X `application is busy'
1119 * beachball pointer appears _automatically_ when the
1120 * application isn't responding to GUI messages.