Correct an inequality sign causing the bounds check in Windows
[sgt/putty] / macosx / osxwin.m
index 8166f91..b58742d 100644 (file)
        nfg = nbg;
        nbg = t;
     }
-    if (cfg.bold_colour && (attr & ATTR_BOLD)) {
+    if ((cfg.bold_style & 2) && (attr & ATTR_BOLD)) {
        if (nfg < 16) nfg |= 8;
        else if (nfg >= 256) nfg |= 1;
     }
-    if (cfg.bold_colour && (attr & ATTR_BLINK)) {
+    if ((cfg.bold_style & 2) && (attr & ATTR_BLINK)) {
        if (nbg < 16) nbg |= 8;
        else if (nbg >= 256) nbg |= 1;
     }
        widefactor = 1;
     }
 
-    /* FIXME: ATTR_BOLD without cfg.bold_colour */
+    /* FIXME: ATTR_BOLD if cfg.bold_style & 1 */
 
     if ((lattr & LATTR_MODE) != LATTR_NORM) {
        x *= 2;
     /*
      * Set up a backend.
      */
-    {
-       int i;
+    back = backend_from_proto(cfg.protocol);
+    if (!back)
        back = &pty_backend;
-       for (i = 0; backends[i].backend != NULL; i++)
-           if (backends[i].protocol == cfg.protocol) {
-               back = backends[i].backend;
-               break;
-           }
-    }
 
     {
        const char *error;
        if (realhost)
            sfree(realhost);           /* FIXME: do something with this */
     }
+    back->provide_logctx(backhandle, logctx);
 
     /*
      * Create a line discipline. (This must be done after creating
      */
     [self center];                    /* :-) */
 
+    exited = FALSE;
+
     return self;
 }
 
      * Do so.
      */
     sfree(alert_ctx);
+    if (back)
+       back->free(backhandle);
+    if (ldisc)
+       ldisc_free(ldisc);
+    /* ldisc must be freed before term, since ldisc_free expects term
+     * still to be around. */
+    if (logctx)
+       log_free(logctx);
+    if (term)
+       term_free(term);
     [super dealloc];
 }
 
     char coutput[32];
     int use_coutput = FALSE, special = FALSE, start, end;
 
-printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
+//printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
 
     /*
      * FIXME: Alt+numberpad codes.
@@ -730,23 +737,8 @@ printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
          case NSLeftArrowFunctionKey: xkey = 'D'; break;
        }
        if (xkey) {
-           /*
-            * The arrow keys normally do ESC [ A and so on. In
-            * app cursor keys mode they do ESC O A instead.
-            * Ctrl toggles the two modes.
-            */
-           if (term->vt52_mode) {
-               output[end++] = '\033';
-               output[end++] = xkey;
-           } else if (!term->app_cursor_keys ^ !(m & NSControlKeyMask)) {
-               output[end++] = '\033';
-               output[end++] = 'O';
-               output[end++] = xkey;
-           } else {
-               output[end++] = '\033';
-               output[end++] = '[';
-               output[end++] = xkey;
-           }
+           end += format_arrow_key(output+end, term, xkey,
+                                   m & NSControlKeyMask);
            goto done;
        }
     }
@@ -781,21 +773,105 @@ printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
     return term_data(term, is_stderr, data, len);
 }
 
+- (int)fromBackendUntrusted:(const char *)data len:(int)len
+{
+    return term_data_untrusted(term, data, len);
+}
+
 - (void)startAlert:(NSAlert *)alert
     withCallback:(void (*)(void *, int))callback andCtx:(void *)ctx
 {
-    alert_callback = callback;
-    alert_ctx = ctx;                /* NB this is assumed to need freeing! */
-    [alert beginSheetModalForWindow:self modalDelegate:self
-     didEndSelector:@selector(alertSheetDidEnd:returnCode:contextInfo:)
-     contextInfo:NULL];
+    if (alert_ctx || alert_qhead) {
+       /*
+        * Queue this alert to be shown later.
+        */
+       struct alert_queue *qitem = snew(struct alert_queue);
+       qitem->next = NULL;
+       qitem->alert = alert;
+       qitem->callback = callback;
+       qitem->ctx = ctx;
+       if (alert_qtail)
+           alert_qtail->next = qitem;
+       else
+           alert_qhead = qitem;
+       alert_qtail = qitem;
+    } else {
+       alert_callback = callback;
+       alert_ctx = ctx;               /* NB this is assumed to need freeing! */
+       [alert beginSheetModalForWindow:self modalDelegate:self
+        didEndSelector:@selector(alertSheetDidEnd:returnCode:contextInfo:)
+        contextInfo:NULL];
+    }
 }
 
 - (void)alertSheetDidEnd:(NSAlert *)alert returnCode:(int)returnCode
     contextInfo:(void *)contextInfo
 {
+    [self performSelectorOnMainThread:
+     @selector(alertSheetDidFinishEnding:)
+     withObject:[NSNumber numberWithInt:returnCode]
+     waitUntilDone:NO];
+}
+
+- (void)alertSheetDidFinishEnding:(id)object
+{
+    int returnCode = [object intValue];
+
     alert_callback(alert_ctx, returnCode);   /* transfers ownership of ctx */
-    alert_ctx = NULL;
+
+    /*
+     * If there's an alert in our queue (either already or because
+     * the callback just queued it), start it.
+     */
+    if (alert_qhead) {
+       struct alert_queue *qnext;
+
+       alert_callback = alert_qhead->callback;
+       alert_ctx = alert_qhead->ctx;
+       [alert_qhead->alert beginSheetModalForWindow:self modalDelegate:self
+        didEndSelector:@selector(alertSheetDidEnd:returnCode:contextInfo:)
+        contextInfo:NULL];
+
+       qnext = alert_qhead->next;
+       sfree(alert_qhead);
+       alert_qhead = qnext;
+       if (!qnext)
+           alert_qtail = NULL;
+    } else {
+       alert_ctx = NULL;
+    }
+}
+
+- (void)notifyRemoteExit
+{
+    int exitcode;
+
+    if (!exited && (exitcode = back->exitcode(backhandle)) >= 0)
+       [self endSession:(exitcode == 0)];
+}
+
+- (void)endSession:(int)clean
+{
+    exited = TRUE;
+    if (ldisc) {
+       ldisc_free(ldisc);
+       ldisc = NULL;
+    }
+    if (back) {
+       back->free(backhandle);
+       backhandle = NULL;
+       back = NULL;
+       //FIXME: update specials menu;
+    }
+    if (cfg.close_on_exit == FORCE_ON ||
+       (cfg.close_on_exit == AUTO && clean))
+       [self close];
+    // FIXME: else show restart menu item
+}
+
+- (Terminal *)term
+{
+    return term;
 }
 
 @end
@@ -806,30 +882,31 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len)
     return [win fromBackend:data len:len isStderr:is_stderr];
 }
 
-void frontend_keypress(void *handle)
+int from_backend_untrusted(void *frontend, const char *data, int len)
 {
-    /* FIXME */
+    SessionWindow *win = (SessionWindow *)frontend;
+    return [win fromBackendUntrusted:data len:len];
 }
 
-void connection_fatal(void *frontend, char *p, ...)
+int get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
 {
-    //SessionWindow *win = (SessionWindow *)frontend;
-    /* FIXME: proper OS X GUI stuff */
-    va_list ap;
-    fprintf(stderr, "FATAL ERROR: ");
-    va_start(ap, p);
-    vfprintf(stderr, p, ap);
-    va_end(ap);
-    fputc('\n', stderr);
-    exit(1);
+    SessionWindow *win = (SessionWindow *)p->frontend;
+    Terminal *term = [win term];
+    return term_get_userpass_input(term, p, in, inlen);
 }
 
-void notify_remote_exit(void *frontend)
+void frontend_keypress(void *handle)
 {
-    //SessionWindow *win = (SessionWindow *)frontend;
     /* FIXME */
 }
 
+void notify_remote_exit(void *frontend)
+{
+    SessionWindow *win = (SessionWindow *)frontend;
+
+    [win notifyRemoteExit];
+}
+
 void ldisc_update(void *frontend, int echo, int edit)
 {
     //SessionWindow *win = (SessionWindow *)frontend;
@@ -838,6 +915,13 @@ void ldisc_update(void *frontend, int echo, int edit)
      */
 }
 
+char *get_ttymode(void *frontend, const char *mode)
+{
+    SessionWindow *win = (SessionWindow *)frontend;
+    Terminal *term = [win term];
+    return term_get_ttymode(term, mode);
+}
+
 void update_specials_menu(void *frontend)
 {
     //SessionWindow *win = (SessionWindow *)frontend;
@@ -850,7 +934,7 @@ void update_specials_menu(void *frontend)
  * may want to perform additional actions on any kind of bell (for
  * example, taskbar flashing in Windows).
  */
-void beep(void *frontend, int mode)
+void do_beep(void *frontend, int mode)
 {
     //SessionWindow *win = (SessionWindow *)frontend;
     if (mode != BELL_VISUAL)
@@ -873,7 +957,7 @@ void palette_set(void *frontend, int n, int r, int g, int b)
 
     if (n >= 16)
        n += 256 - 16;
-    if (n > NALLCOLOURS)
+    if (n >= NALLCOLOURS)
        return;
     [win setColour:n r:r/255.0 g:g/255.0 b:b/255.0];
 
@@ -904,10 +988,11 @@ void palette_reset(void *frontend)
     for (i = 0; i < NEXTCOLOURS; i++) {
        if (i < 216) {
            int r = i / 36, g = (i / 6) % 6, b = i % 6;
-           [win setColour:i+16 r:r/5.0 g:g/5.0 b:b/5.0];
+           r = r ? r*40+55 : 0; g = g ? b*40+55 : 0; b = b ? b*40+55 : 0;
+           [win setColour:i+16 r:r/255.0 g:g/255.0 b:b/255.0];
        } else {
            int shade = i - 216;
-           float fshade = (shade + 1) / (float)(NEXTCOLOURS - 216 + 1);
+           float fshade = (shade * 10 + 8) / 255.0;
            [win setColour:i+16 r:fshade g:fshade b:fshade];
        }
     }
@@ -1086,7 +1171,7 @@ void get_clip(void *frontend, wchar_t ** p, int *len)
     /* FIXME */
 }
 
-void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
+void write_clip(void *frontend, wchar_t *data, int *attr, int len, int must_deselect)
 {
     //SessionWindow *win = (SessionWindow *)frontend;
     /* FIXME */