Yet more global-removal. The static variables in logging.c are now
[u/mdw/putty] / terminal.c
index d0a09a3..738c754 100644 (file)
@@ -148,12 +148,14 @@ static void power_on(Terminal *term)
            term->tabs[i] = (i % 8 == 0 ? TRUE : FALSE);
     }
     term->alt_om = term->dec_om = cfg.dec_om;
-    term->alt_wnext = term->wrapnext = term->alt_ins = term->insert = FALSE;
+    term->alt_ins = term->insert = FALSE;
+    term->alt_wnext = term->wrapnext = term->save_wnext = FALSE;
     term->alt_wrap = term->wrap = cfg.wrap_mode;
-    term->alt_cset = term->cset = 0;
-    term->alt_utf = term->utf = 0;
-    term->alt_sco_acs = term->sco_acs = 0;
-    term->cset_attr[0] = term->cset_attr[1] = ATTR_ASCII;
+    term->alt_cset = term->cset = term->save_cset = 0;
+    term->alt_utf = term->utf = term->save_utf = 0;
+    term->utf_state = 0;
+    term->alt_sco_acs = term->sco_acs = term->save_sco_acs = 0;
+    term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = ATTR_ASCII;
     term->rvideo = 0;
     term->in_vbell = FALSE;
     term->cursor_on = 1;
@@ -186,7 +188,7 @@ static void power_on(Terminal *term)
 void term_update(Terminal *term)
 {
     Context ctx;
-    ctx = get_ctx();
+    ctx = get_ctx(term->frontend);
     if (ctx) {
        int need_sbar_update = term->seen_disp_event;
        if (term->seen_disp_event && cfg.scroll_on_disp) {
@@ -197,7 +199,7 @@ void term_update(Terminal *term)
        if (need_sbar_update)
            update_sbar(term);
        do_paint(term, ctx, TRUE);
-       sys_cursor(term->curs.x, term->curs.y - term->disptop);
+       sys_cursor(term->frontend, term->curs.x, term->curs.y - term->disptop);
        free_ctx(ctx);
     }
 }
@@ -239,7 +241,8 @@ void term_seen_key_event(Terminal *term)
 void term_pwron(Terminal *term)
 {
     power_on(term);
-    ldisc_send(NULL, 0, 0);           /* cause ldisc to notice changes */
+    if (term->ldisc)                  /* cause ldisc to notice changes */
+       ldisc_send(term->ldisc, NULL, 0, 0);
     fix_cpos;
     term->disptop = 0;
     deselect(term);
@@ -258,7 +261,7 @@ void term_reconfig(Terminal *term)
        swap_screen(term, 0, FALSE, FALSE);
     if (cfg.no_mouse_rep) {
        term->xterm_mouse = 0;
-       set_raw_mouse_mode(0);
+       set_raw_mouse_mode(term->frontend, 0);
     }
     if (cfg.no_remote_charset) {
        term->cset_attr[0] = term->cset_attr[1] = ATTR_ASCII;
@@ -286,7 +289,7 @@ void term_clrsb(Terminal *term)
 /*
  * Initialise the terminal.
  */
-Terminal *term_init(void)
+Terminal *term_init(void *frontend)
 {
     Terminal *term;
 
@@ -295,6 +298,8 @@ Terminal *term_init(void)
      * that need it.
      */
     term = smalloc(sizeof(Terminal));
+    term->frontend = frontend;
+    term->logctx = NULL;
     term->compatibility_level = TM_PUTTY;
     strcpy(term->id_string, "\033[?6c");
     term->last_blink = term->last_tblink = 0;
@@ -302,6 +307,18 @@ Terminal *term_init(void)
     term->last_paste = 0;
     bufchain_init(&term->inbuf);
     bufchain_init(&term->printer_buf);
+    term->printing = term->only_printing = FALSE;
+    term->print_job = NULL;
+    term->vt52_mode = FALSE;
+    term->cr_lf_return = FALSE;
+    term->seen_disp_event = FALSE;
+    term->xterm_mouse = term->mouse_is_down = FALSE;
+    term->reset_132 = FALSE;
+    term->blinker = term->tblinker = 0;
+    term->has_focus = 1;
+    term->repeat_off = FALSE;
+    term->termstate = TOPLEVEL;
+    term->selstate = NO_SELECTION;
 
     term->screen = term->alt_screen = term->scrollback = NULL;
     term->disptop = 0;
@@ -314,6 +331,8 @@ Terminal *term_init(void)
     term->nbeeps = 0;
     term->lastbeep = FALSE;
     term->beep_overloaded = FALSE;
+    term->resize_fn = NULL;
+    term->resize_ctx = NULL;
 
     return term;
 }
@@ -441,7 +460,22 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
 
     update_sbar(term);
     term_update(term);
-    back->size();
+    if (term->resize_fn)
+       term->resize_fn(term->resize_ctx, term->cols, term->rows);
+}
+
+/*
+ * Hand a function and context pointer to the terminal which it can
+ * use to notify a back end of resizes.
+ */
+void term_provide_resize_fn(Terminal *term,
+                           void (*resize_fn)(void *, int, int),
+                           void *resize_ctx)
+{
+    term->resize_fn = resize_fn;
+    term->resize_ctx = resize_ctx;
+    if (term->cols > 0 && term->rows > 0)
+       resize_fn(resize_ctx, term->cols, term->rows);
 }
 
 /*
@@ -526,7 +560,8 @@ static void update_sbar(Terminal *term)
 
     nscroll = count234(term->scrollback);
 
-    set_sbar(nscroll + term->rows, nscroll + term->disptop, term->rows);
+    set_sbar(term->frontend, nscroll + term->rows,
+            nscroll + term->disptop, term->rows);
 }
 
 /*
@@ -841,7 +876,7 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
          case 3:                      /* 80/132 columns */
            deselect(term);
            if (!cfg.no_remote_resize)
-               request_resize(state ? 132 : 80, term->rows);
+               request_resize(term->frontend, state ? 132 : 80, term->rows);
            term->reset_132 = state;
            break;
          case 5:                      /* reverse video */
@@ -884,7 +919,8 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
            break;
          case 10:                     /* set local edit mode */
            term->term_editing = state;
-           ldisc_send(NULL, 0, 0);    /* cause ldisc to notice changes */
+           if (term->ldisc)           /* cause ldisc to notice changes */
+               ldisc_send(term->ldisc, NULL, 0, 0);
            break;
          case 25:                     /* enable/disable cursor */
            compatibility2(OTHER, VT220);
@@ -899,11 +935,11 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
            break;
          case 1000:                   /* xterm mouse 1 */
            term->xterm_mouse = state ? 1 : 0;
-           set_raw_mouse_mode(state);
+           set_raw_mouse_mode(term->frontend, state);
            break;
          case 1002:                   /* xterm mouse 2 */
            term->xterm_mouse = state ? 2 : 0;
-           set_raw_mouse_mode(state);
+           set_raw_mouse_mode(term->frontend, state);
            break;
          case 1047:                   /* alternate screen */
            compatibility(OTHER);
@@ -934,7 +970,8 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
            break;
          case 12:                     /* set echo mode */
            term->term_echoing = !state;
-           ldisc_send(NULL, 0, 0);    /* cause ldisc to notice changes */
+           if (term->ldisc)           /* cause ldisc to notice changes */
+               ldisc_send(term->ldisc, NULL, 0, 0);
            break;
          case 20:                     /* Return sends ... */
            term->cr_lf_return = state;
@@ -960,14 +997,14 @@ static void do_osc(Terminal *term)
          case 0:
          case 1:
            if (!cfg.no_remote_wintitle)
-               set_icon(term->osc_string);
+               set_icon(term->frontend, term->osc_string);
            if (term->esc_args[0] == 1)
                break;
            /* fall through: parameter 0 means set both */
          case 2:
          case 21:
            if (!cfg.no_remote_wintitle)
-               set_title(term->osc_string);
+               set_title(term->frontend, term->osc_string);
            break;
        }
     }
@@ -1053,8 +1090,8 @@ void term_out(Terminal *term)
             * Optionally log the session traffic to a file. Useful for
             * debugging and possibly also useful for actual logging.
             */
-           if (cfg.logtype == LGTYP_DEBUG)
-               logtraffic((unsigned char) c, LGTYP_DEBUG);
+           if (cfg.logtype == LGTYP_DEBUG && term->logctx)
+               logtraffic(term->logctx, (unsigned char) c, LGTYP_DEBUG);
        } else {
            c = unget;
            unget = -1;
@@ -1257,7 +1294,7 @@ void term_out(Terminal *term)
                 * An xterm returns "xterm" (5 characters)
                 */
                compatibility(ANSIMIN);
-               {
+               if (term->ldisc) {
                    char abuf[256], *s, *d;
                    int state = 0;
                    for (s = cfg.answerback, d = abuf; *s; s++) {
@@ -1275,7 +1312,8 @@ void term_out(Terminal *term)
                        } else
                            *d++ = *s;
                    }
-                   lpage_send(DEFAULT_CODEPAGE, abuf, d - abuf, 0);
+                   lpage_send(term->ldisc, DEFAULT_CODEPAGE,
+                              abuf, d - abuf, 0);
                }
                break;
              case '\007':
@@ -1339,7 +1377,7 @@ void term_out(Terminal *term)
                            term->vbell_startpoint = ticks;
                            term_update(term);
                        } else
-                           beep(cfg.beep);
+                           beep(term->frontend, cfg.beep);
                    }
                    term->disptop = 0;
                }
@@ -1380,7 +1418,8 @@ void term_out(Terminal *term)
                fix_cpos;
                term->seen_disp_event = TRUE;
                term->paste_hold = 0;
-               logtraffic((unsigned char) c, LGTYP_ASCII);
+               if (term->logctx)
+                   logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
                break;
              case '\014':
                if (has_compat(SCOANSI)) {
@@ -1404,7 +1443,8 @@ void term_out(Terminal *term)
                term->wrapnext = FALSE;
                term->seen_disp_event = 1;
                term->paste_hold = 0;
-               logtraffic((unsigned char) c, LGTYP_ASCII);
+               if (term->logctx)
+                   logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
                break;
              case '\t':
                {
@@ -1452,8 +1492,9 @@ void term_out(Terminal *term)
                    incpos(cursplus);
                    check_selection(term, term->curs, cursplus);
                }
-               if ((c & CSET_MASK) == ATTR_ASCII || (c & CSET_MASK) == 0)
-                   logtraffic((unsigned char) c, LGTYP_ASCII);
+               if (((c & CSET_MASK) == ATTR_ASCII || (c & CSET_MASK) == 0) &&
+                   term->logctx)
+                   logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
                {
                    extern int wcwidth(wchar_t ucs);
                    int width = 0;
@@ -1586,15 +1627,18 @@ void term_out(Terminal *term)
                    break;
                  case 'Z':            /* terminal type query */
                    compatibility(VT100);
-                   ldisc_send(term->id_string, strlen(term->id_string), 0);
+                   if (term->ldisc)
+                       ldisc_send(term->ldisc, term->id_string,
+                                  strlen(term->id_string), 0);
                    break;
                  case 'c':            /* restore power-on settings */
                    compatibility(VT100);
                    power_on(term);
-                   ldisc_send(NULL, 0, 0);/* cause ldisc to notice changes */
+                   if (term->ldisc)   /* cause ldisc to notice changes */
+                       ldisc_send(term->ldisc, NULL, 0, 0);
                    if (term->reset_132) {
                        if (!cfg.no_remote_resize)
-                           request_resize(80, term->rows);
+                           request_resize(term->frontend, 80, term->rows);
                        term->reset_132 = 0;
                    }
                    fix_cpos;
@@ -1752,7 +1796,8 @@ void term_out(Terminal *term)
                        compatibility(OTHER);
                        /* this reports xterm version 136 so that VIM can
                           use the drag messages from the mouse reporting */
-                       ldisc_send("\033[>0;136;0c", 11, 0);
+                       if (term->ldisc)
+                           ldisc_send(term->ldisc, "\033[>0;136;0c", 11, 0);
                        break;
                      case 'a':       /* move right N cols */
                        compatibility(ANSI);
@@ -1854,17 +1899,20 @@ void term_out(Terminal *term)
                      case 'c':       /* terminal type query */
                        compatibility(VT100);
                        /* This is the response for a VT102 */
-                       ldisc_send(term->id_string,
-                                  strlen(term->id_string), 0);
+                       if (term->ldisc)
+                           ldisc_send(term->ldisc, term->id_string,
+                                      strlen(term->id_string), 0);
                        break;
                      case 'n':       /* cursor position query */
-                       if (term->esc_args[0] == 6) {
-                           char buf[32];
-                           sprintf(buf, "\033[%d;%dR", term->curs.y + 1,
-                                   term->curs.x + 1);
-                           ldisc_send(buf, strlen(buf), 0);
-                       } else if (term->esc_args[0] == 5) {
-                           ldisc_send("\033[0n", 4, 0);
+                       if (term->ldisc) {
+                           if (term->esc_args[0] == 6) {
+                               char buf[32];
+                               sprintf(buf, "\033[%d;%dR", term->curs.y + 1,
+                                       term->curs.x + 1);
+                               ldisc_send(term->ldisc, buf, strlen(buf), 0);
+                           } else if (term->esc_args[0] == 5) {
+                               ldisc_send(term->ldisc, "\033[0n", 4, 0);
+                           }
                        }
                        break;
                      case 'h':       /* toggle modes to high */
@@ -2092,7 +2140,7 @@ void term_out(Terminal *term)
                                term->esc_args[0] >= 24)) {
                            compatibility(VT340TEXT);
                            if (!cfg.no_remote_resize)
-                               request_resize(term->cols,
+                               request_resize(term->frontend, term->cols,
                                               def(term->esc_args[0], 24));
                            deselect(term);
                        } else if (term->esc_nargs >= 1 &&
@@ -2104,15 +2152,16 @@ void term_out(Terminal *term)
                                int x, y, len;
                                char buf[80], *p;
                              case 1:
-                               set_iconic(FALSE);
+                               set_iconic(term->frontend, FALSE);
                                break;
                              case 2:
-                               set_iconic(TRUE);
+                               set_iconic(term->frontend, TRUE);
                                break;
                              case 3:
                                if (term->esc_nargs >= 3) {
                                    if (!cfg.no_remote_resize)
-                                       move_window(def(term->esc_args[1], 0),
+                                       move_window(term->frontend,
+                                                   def(term->esc_args[1], 0),
                                                    def(term->esc_args[2], 0));
                                }
                                break;
@@ -2123,44 +2172,56 @@ void term_out(Terminal *term)
                                 * manage it. */
                                break;
                              case 5:
-                               set_zorder(TRUE);   /* move to top */
+                               /* move to top */
+                               set_zorder(term->frontend, TRUE);
                                break;
                              case 6:
-                               set_zorder(FALSE);  /* move to bottom */
+                               /* move to bottom */
+                               set_zorder(term->frontend, FALSE);
                                break;
                              case 7:
-                               refresh_window();
+                               refresh_window(term->frontend);
                                break;
                              case 8:
                                if (term->esc_nargs >= 3) {
                                    if (!cfg.no_remote_resize)
-                                       request_resize(def(term->esc_args[2], cfg.width),
+                                       request_resize(term->frontend,
+                                                      def(term->esc_args[2], cfg.width),
                                                       def(term->esc_args[1], cfg.height));
                                }
                                break;
                              case 9:
                                if (term->esc_nargs >= 2)
-                                   set_zoomed(term->esc_args[1] ?
+                                   set_zoomed(term->frontend,
+                                              term->esc_args[1] ?
                                               TRUE : FALSE);
                                break;
                              case 11:
-                               ldisc_send(is_iconic() ? "\033[1t" : "\033[2t",
-                                          4, 0);
+                               if (term->ldisc)
+                                   ldisc_send(term->ldisc,
+                                              is_iconic(term->frontend) ?
+                                              "\033[1t" : "\033[2t", 4, 0);
                                break;
                              case 13:
-                               get_window_pos(&x, &y);
-                               len = sprintf(buf, "\033[3;%d;%dt", x, y);
-                               ldisc_send(buf, len, 0);
+                               if (term->ldisc) {
+                                   get_window_pos(term->frontend, &x, &y);
+                                   len = sprintf(buf, "\033[3;%d;%dt", x, y);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
                                break;
                              case 14:
-                               get_window_pixels(&x, &y);
-                               len = sprintf(buf, "\033[4;%d;%dt", x, y);
-                               ldisc_send(buf, len, 0);
+                               if (term->ldisc) {
+                                   get_window_pixels(term->frontend, &x, &y);
+                                   len = sprintf(buf, "\033[4;%d;%dt", x, y);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
                                break;
                              case 18:
-                               len = sprintf(buf, "\033[8;%d;%dt",
-                                             term->rows, term->cols);
-                               ldisc_send(buf, len, 0);
+                               if (term->ldisc) {
+                                   len = sprintf(buf, "\033[8;%d;%dt",
+                                                 term->rows, term->cols);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
                                break;
                              case 19:
                                /*
@@ -2180,18 +2241,22 @@ void term_out(Terminal *term)
                                 */
                                break;
                              case 20:
-                               p = get_window_title(TRUE);
-                               len = strlen(p);
-                               ldisc_send("\033]L", 3, 0);
-                               ldisc_send(p, len, 0);
-                               ldisc_send("\033\\", 2, 0);
+                               if (term->ldisc) {
+                                   p = get_window_title(term->frontend, TRUE);
+                                   len = strlen(p);
+                                   ldisc_send(term->ldisc, "\033]L", 3, 0);
+                                   ldisc_send(term->ldisc, p, len, 0);
+                                   ldisc_send(term->ldisc, "\033\\", 2, 0);
+                               }
                                break;
                              case 21:
-                               p = get_window_title(FALSE);
-                               len = strlen(p);
-                               ldisc_send("\033]l", 3, 0);
-                               ldisc_send(p, len, 0);
-                               ldisc_send("\033\\", 2, 0);
+                               if (term->ldisc) {
+                                   p = get_window_title(term->frontend,FALSE);
+                                   len = strlen(p);
+                                   ldisc_send(term->ldisc, "\033]l", 3, 0);
+                                   ldisc_send(term->ldisc, p, len, 0);
+                                   ldisc_send(term->ldisc, "\033\\", 2, 0);
+                               }
                                break;
                            }
                        }
@@ -2221,7 +2286,7 @@ void term_out(Terminal *term)
                        compatibility(VT420);
                        if (term->esc_nargs == 1 && term->esc_args[0] > 0) {
                            if (!cfg.no_remote_resize)
-                               request_resize(term->cols,
+                               request_resize(term->frontend, term->cols,
                                               def(term->esc_args[0],
                                                   cfg.height));
                            deselect(term);
@@ -2235,7 +2300,8 @@ void term_out(Terminal *term)
                        compatibility(VT340TEXT);
                        if (term->esc_nargs <= 1) {
                            if (!cfg.no_remote_resize)
-                               request_resize(def(term->esc_args[0],
+                               request_resize(term->frontend,
+                                              def(term->esc_args[0],
                                                   cfg.width), term->rows);
                            deselect(term);
                        }
@@ -2259,13 +2325,13 @@ void term_out(Terminal *term)
                        break;
                      case 'x':       /* report terminal characteristics */
                        compatibility(VT100);
-                       {
+                       if (term->ldisc) {
                            char buf[32];
                            int i = def(term->esc_args[0], 0);
                            if (i == 0 || i == 1) {
                                strcpy(buf, "\033[2;1;1;112;112;1;0x");
                                buf[2] += i;
-                               ldisc_send(buf, 20, 0);
+                               ldisc_send(term->ldisc, buf, 20, 0);
                            }
                        }
                        break;
@@ -2387,7 +2453,7 @@ void term_out(Terminal *term)
                    term->osc_strlen = 0;
                    break;
                  case 'R':            /* Linux palette reset */
-                   palette_reset();
+                   palette_reset(term->frontend);
                    term_invalidate(term);
                    term->termstate = TOPLEVEL;
                    break;
@@ -2466,7 +2532,7 @@ void term_out(Terminal *term)
                    }
                    term->osc_string[term->osc_strlen++] = val;
                    if (term->osc_strlen >= 7) {
-                       palette_set(term->osc_string[0],
+                       palette_set(term->frontend, term->osc_string[0],
                                    term->osc_string[1] * 16 + term->osc_string[2],
                                    term->osc_string[3] * 16 + term->osc_string[4],
                                    term->osc_string[5] * 16 + term->osc_string[6]);
@@ -2589,7 +2655,8 @@ void term_out(Terminal *term)
                    term->termstate = VT52_Y1;
                    break;
                  case 'Z':
-                   ldisc_send("\033/Z", 3, 0);
+                   if (term->ldisc)
+                       ldisc_send(term->ldisc, "\033/Z", 3, 0);
                    break;
                  case '=':
                    term->app_keypad_keys = TRUE;
@@ -2887,12 +2954,15 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
                    tattr |= ATTR_WIDE;
 
            /* Video reversing things */
-           if (term->seltype == LEXICOGRAPHIC)
-               selected = (posle(term->selstart, scrpos) &&
-                           poslt(scrpos, term->selend));
-           else
-               selected = (posPle(term->selstart, scrpos) &&
-                           posPlt(scrpos, term->selend));
+           if (term->selstate == DRAGGING || term->selstate == SELECTED) {
+               if (term->seltype == LEXICOGRAPHIC)
+                   selected = (posle(term->selstart, scrpos) &&
+                               poslt(scrpos, term->selend));
+               else
+                   selected = (posPle(term->selstart, scrpos) &&
+                               posPlt(scrpos, term->selend));
+           } else
+               selected = FALSE;
            tattr = (tattr ^ rv
                     ^ (selected ? ATTR_REVERSE : 0));
 
@@ -3228,7 +3298,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect)
     wblen++;
     *wbptr++ = 0;
 #endif
-    write_clip(workbuf, wblen, FALSE); /* transfer to clipboard */
+    write_clip(term->frontend, workbuf, wblen, FALSE); /* transfer to clipbd */
     if (buflen > 0)                   /* indicates we allocated this buffer */
        sfree(workbuf);
 }
@@ -3247,9 +3317,10 @@ void term_copyall(Terminal *term)
  */
 static int wordtype(Terminal *term, int uc)
 {
-    static struct {
+    struct ucsword {
        int start, end, ctype;
-    } *wptr, ucs_words[] = {
+    };
+    static const struct ucsword ucs_words[] = {
        {
        128, 160, 0}, {
        161, 191, 1}, {
@@ -3313,6 +3384,7 @@ static int wordtype(Terminal *term, int uc)
        {
        0, 0, 0}
     };
+    const struct ucsword *wptr;
 
     uc &= (CSET_MASK | CHAR_MASK);
 
@@ -3455,7 +3527,7 @@ void term_do_paste(Terminal *term)
     wchar_t *data;
     int len;
 
-    get_clip(&data, &len);
+    get_clip(term->frontend, &data, &len);
     if (data && len > 0) {
         wchar_t *p, *q;
 
@@ -3490,14 +3562,15 @@ void term_do_paste(Terminal *term)
 
         /* Assume a small paste will be OK in one go. */
         if (term->paste_len < 256) {
-            luni_send(term->paste_buffer, term->paste_len, 0);
+            if (term->ldisc)
+               luni_send(term->ldisc, term->paste_buffer, term->paste_len, 0);
             if (term->paste_buffer)
                 sfree(term->paste_buffer);
             term->paste_buffer = 0;
             term->paste_pos = term->paste_hold = term->paste_len = 0;
         }
     }
-    get_clip(NULL, NULL);
+    get_clip(term->frontend, NULL, NULL);
 }
 
 void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y,
@@ -3539,56 +3612,58 @@ void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y,
     if (raw_mouse) {
        int encstate = 0, r, c;
        char abuf[16];
-       static int is_down = 0;
 
-       switch (b) {
-         case MBT_LEFT:
-           encstate = 0x20;           /* left button down */
-           break;
-         case MBT_MIDDLE:
-           encstate = 0x21;
-           break;
-         case MBT_RIGHT:
-           encstate = 0x22;
-           break;
-         case MBT_WHEEL_UP:
-           encstate = 0x60;
-           break;
-         case MBT_WHEEL_DOWN:
-           encstate = 0x61;
-           break;
-         default: break;              /* placate gcc warning about enum use */
-       }
-       switch (a) {
-         case MA_DRAG:
-           if (term->xterm_mouse == 1)
-               return;
-           encstate += 0x20;
-           break;
-         case MA_RELEASE:
-           encstate = 0x23;
-           is_down = 0;
-           break;
-         case MA_CLICK:
-           if (is_down == b)
-               return;
-           is_down = b;
-           break;
-         default: break;              /* placate gcc warning about enum use */
+       if (term->ldisc) {
+
+           switch (b) {
+             case MBT_LEFT:
+               encstate = 0x20;               /* left button down */
+               break;
+             case MBT_MIDDLE:
+               encstate = 0x21;
+               break;
+             case MBT_RIGHT:
+               encstate = 0x22;
+               break;
+             case MBT_WHEEL_UP:
+               encstate = 0x60;
+               break;
+             case MBT_WHEEL_DOWN:
+               encstate = 0x61;
+               break;
+             default: break;          /* placate gcc warning about enum use */
+           }
+           switch (a) {
+             case MA_DRAG:
+               if (term->xterm_mouse == 1)
+                   return;
+               encstate += 0x20;
+               break;
+             case MA_RELEASE:
+               encstate = 0x23;
+               term->mouse_is_down = 0;
+               break;
+             case MA_CLICK:
+               if (term->mouse_is_down == b)
+                   return;
+               term->mouse_is_down = b;
+               break;
+             default: break;          /* placate gcc warning about enum use */
+           }
+           if (shift)
+               encstate += 0x04;
+           if (ctrl)
+               encstate += 0x10;
+           r = y + 33;
+           c = x + 33;
+
+           sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
+           ldisc_send(term->ldisc, abuf, 6, 0);
        }
-       if (shift)
-           encstate += 0x04;
-       if (ctrl)
-           encstate += 0x10;
-       r = y + 33;
-       c = x + 33;
-
-       sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
-       ldisc_send(abuf, 6, 0);
        return;
     }
 
-    b = translate_button(b);
+    b = translate_button(term->frontend, b);
 
     /*
      * Set the selection type (rectangular or normal) at the start
@@ -3699,7 +3774,7 @@ void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y,
                   || a == MA_2CLK || a == MA_3CLK
 #endif
                   )) {
-       request_paste();
+       request_paste(term->frontend);
     }
 
     term_update(term);
@@ -3710,7 +3785,7 @@ void term_nopaste(Terminal *term)
     if (term->paste_len == 0)
        return;
     sfree(term->paste_buffer);
-    term->paste_buffer = 0;
+    term->paste_buffer = NULL;
     term->paste_len = 0;
 }
 
@@ -3741,7 +3816,8 @@ void term_paste(Terminal *term)
            if (term->paste_buffer[term->paste_pos + n++] == '\r')
                break;
        }
-       luni_send(term->paste_buffer + term->paste_pos, n, 0);
+       if (term->ldisc)
+           luni_send(term->ldisc, term->paste_buffer + term->paste_pos, n, 0);
        term->paste_pos += n;
 
        if (term->paste_pos < term->paste_len) {
@@ -3807,3 +3883,8 @@ int from_backend(void *vterm, int is_stderr, char *data, int len)
      */
     return 0;
 }
+
+void term_provide_logctx(Terminal *term, void *logctx)
+{
+    term->logctx = logctx;
+}