Rationalise access to, and content of, backends[] array.
[u/mdw/putty] / mac / macterm.c
index 28898e6..4a75a0c 100644 (file)
@@ -87,6 +87,8 @@ static void mac_drawgrowicon(Session *s);
 static pascal void mac_growtermdraghook(void);
 static pascal void mac_scrolltracker(ControlHandle, short);
 static pascal void do_text_for_device(short, short, GDHandle, long);
+static void do_text_internal(Context, int, int, wchar_t *, int,
+                            unsigned long, int);
 static void text_click(Session *, EventRecord *);
 static void mac_activateterm(WindowPtr, EventRecord *);
 static void mac_adjusttermcursor(WindowPtr, Point, RgnHandle);
@@ -113,12 +115,7 @@ void mac_startsession(Session *s)
      * Select protocol. This is farmed out into a table in a
      * separate file to enable an ssh-free variant.
      */
-    s->back = NULL;
-    for (i = 0; backends[i].backend != NULL; i++)
-       if (backends[i].protocol == s->cfg.protocol) {
-           s->back = backends[i].backend;
-           break;
-       }
+    s->back = backend_from_proto(s->cfg.protocol);
     if (s->back == NULL)
        fatalbox("Unsupported protocol number found");
 
@@ -305,18 +302,6 @@ static pascal OSStatus uni_to_font_fallback(UniChar *ucp,
 }
 
 /*
- * Called every time round the event loop.
- */
-void mac_pollterm(void)
-{
-    Session *s;
-
-    for (s = sesslist; s != NULL; s = s->next) {
-       term_update(s->term);
-    }
-}
-
-/*
  * To be called whenever the window size changes.
  * rows and cols should be desired values.
  * It's assumed the terminal emulator will be informed, and will set rows
@@ -605,7 +590,7 @@ static void text_click(Session *s, EventRecord *event)
     lastwhen = TickCount();
 }
 
-void write_clip(void *cookie, wchar_t *data, int len, int must_deselect)
+void write_clip(void *cookie, wchar_t *data, int *attr, int len, int must_deselect)
 {
 #if !TARGET_API_MAC_CARBON
     Session *s = cookie;
@@ -1022,14 +1007,26 @@ static pascal void mac_growtermdraghook(void)
 
 void mac_closeterm(WindowPtr window)
 {
+    int alertret;
     Session *s = mac_windowsession(window);
 
-    /* XXX warn on close */
+    if (s->cfg.warn_on_close && !s->session_closed) {
+       ParamText("\pAre you sure you want to close this session?",
+                 NULL, NULL, NULL);
+       alertret=CautionAlert(wQuestion, NULL);
+       if (alertret == 2) {
+           /* Cancel */
+           return;
+       }
+    }
+
     HideWindow(s->window);
     *s->prev = s->next;
     s->next->prev = s->prev;
-    ldisc_free(s->ldisc);
-    s->back->free(s->backhandle);
+    if (s->ldisc)
+       ldisc_free(s->ldisc);
+    if (s->back)
+       s->back->free(s->backhandle);
     log_free(s->logctx);
     if (s->uni_to_font != NULL)
        DisposeUnicodeToTextInfo(&s->uni_to_font);
@@ -1143,8 +1140,8 @@ struct do_text_args {
  *
  * x and y are text row and column (zero-based)
  */
-void do_text(Context ctx, int x, int y, wchar_t *text, int len,
-            unsigned long attr, int lattr)
+static void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
+                     unsigned long attr, int lattr)
 {
     Session *s = ctx;
     int style;
@@ -1162,11 +1159,6 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
 
     assert(len <= 1024);
 
-    /* SGT, 2004-10-14: I don't know how to support combining characters
-     * on the Mac. Hopefully the first person to fail this assertion will
-     * know how to do it better than me... */
-    assert(!(attr & TATTR_COMBINING));
-
     SetPort((GrafPtr)GetWindowPort(s->window));
 
     fontwidth = s->font_width;
@@ -1271,6 +1263,24 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
 #endif
 }
 
+/*
+ * Wrapper that handles combining characters.
+ */
+void do_text(Context ctx, int x, int y, wchar_t *text, int len,
+            unsigned long attr, int lattr)
+{
+    if (attr & TATTR_COMBINING) {
+       unsigned long a = 0;
+       attr &= ~TATTR_COMBINING;
+       while (len--) {
+           do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
+           text++;
+           a = TATTR_COMBINING;
+       }
+    } else
+       do_text_internal(ctx, x, y, text, len, attr, lattr);
+}
+
 static pascal void do_text_for_device(short depth, short devflags,
                                      GDHandle device, long cookie)
 {
@@ -1325,7 +1335,8 @@ static pascal void do_text_for_device(short depth, short devflags,
        }
     }
 
-    EraseRect(&a->textrect);
+    if (!(a->attr & TATTR_COMBINING))
+       EraseRect(&a->textrect);
     switch (a->lattr & LATTR_MODE) {
       case LATTR_NORM:
       case LATTR_WIDE:
@@ -1472,7 +1483,7 @@ void sys_cursor(void *frontend, int x, int y)
  * 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)
 {
     if (mode != BELL_VISUAL)
        SysBeep(30);
@@ -1512,6 +1523,14 @@ void set_title(void *frontend, char *title)
 }
 
 /*
+ * Used by backend to indicate busy-ness
+ */
+void set_busy_status(void *frontend, int status)
+{
+    /* FIXME do something */
+}
+
+/*
  * set or clear the "raw mouse message" mode
  */
 void set_raw_mouse_mode(void *frontend, int activate)
@@ -1821,6 +1840,12 @@ void ldisc_update(void *frontend, int echo, int edit)
 {
 }
 
+char *get_ttymode(void *frontend, const char *mode)
+{
+    Session *s = frontend;
+    return term_get_ttymode(s->term, mode);
+}
+
 /*
  * Mac PuTTY doesn't support printing yet.
  */
@@ -1853,7 +1878,8 @@ void frontend_keypress(void *handle)
  * 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)
+int askappend(void *frontend, Filename filename,
+             void (*callback)(void *ctx, int result), void *ctx)
 {
 
     /* FIXME: not implemented yet. */
@@ -1867,6 +1893,12 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len)
     return term_data(s->term, is_stderr, data, len);
 }
 
+int get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
+{
+    Session *s = p->frontend;
+    return term_get_userpass_input(s->term, p, in, inlen);
+}
+
 /*
  * Emacs magic:
  * Local Variables: