]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - macterm.c
Correct handling of keypad enter in normal keypad mode.
[PuTTY.git] / macterm.c
index fd0e1f330aedb541d01a28a1fc36eb95a192ab0d..555b2363367d68a8fc1f4f8dc4a56b4bf3e8cc98 100644 (file)
--- a/macterm.c
+++ b/macterm.c
@@ -1,5 +1,6 @@
-/* $Id: macterm.c,v 1.1.2.26 1999/03/18 00:04:34 ben Exp $ */
+/* $Id: macterm.c,v 1.1.2.31 1999/03/28 15:27:03 ben Exp $ */
 /*
+ * Copyright (c) 1999 Simon Tatham
  * Copyright (c) 1999 Ben Harris
  * All rights reserved.
  *
@@ -41,6 +42,7 @@
 #include <QuickdrawText.h>
 #include <Resources.h>
 #include <Scrap.h>
+#include <Script.h>
 #include <Sound.h>
 #include <ToolUtils.h>
 
@@ -70,6 +72,7 @@
 struct mac_session {
     short              fontnum;
     int                        font_ascent;
+    int                        font_leading;
     WindowPtr          window;
     PaletteHandle      palette;
     ControlHandle      scrollbar;
@@ -87,7 +90,7 @@ static pascal void mac_set_attr_mask(short, short, GDHandle, long);
 static int mac_keytrans(struct mac_session *, EventRecord *, unsigned char *);
 static void text_click(struct mac_session *, EventRecord *);
 
-#ifdef USES_ROUTINE_DESCRIPTORS
+#if TARGET_RT_MAC_CFM
 static RoutineDescriptor mac_scrolltracker_upp =
     BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo,
                             (ProcPtr)mac_scrolltracker);
@@ -97,11 +100,11 @@ static RoutineDescriptor do_text_for_device_upp =
 static RoutineDescriptor mac_set_attr_mask_upp =
     BUILD_ROUTINE_DESCRIPTOR(uppDeviceLoopDrawingProcInfo,
                             (ProcPtr)mac_set_attr_mask);
-#else /* not USES_ROUTINE_DESCRIPTORS */
+#else /* not TARGET_RT_MAC_CFM */
 #define mac_scrolltracker_upp  mac_scrolltracker
 #define do_text_for_device_upp do_text_for_device
 #define mac_set_attr_mask_upp  mac_set_attr_mask
-#endif /* not USES_ROUTINE_DESCRIPTORS */
+#endif /* not TARGET_RT_MAC_CFM */
 
 /*
  * Temporary hack till I get the terminal emulator supporting multiple
@@ -142,13 +145,12 @@ static void display_resource(unsigned long type, short id) {
 
 void mac_newsession(void) {
     struct mac_session *s;
-    int i;
     UInt32 starttime;
     char msg[128];
 
     /* This should obviously be initialised by other means */
     mac_loadconfig(&cfg);
-    back = &loop_backend;
+    back = &hexdump_backend;
     s = smalloc(sizeof(*s));
     memset(s, 0, sizeof(*s));
     onlysession = s;
@@ -187,9 +189,10 @@ static void mac_initfont(struct mac_session *s) {
     TextFace(cfg.fontisbold ? bold : 0);
     TextSize(cfg.fontheight);
     GetFontInfo(&fi);
-    font_width = fi.widMax;
-    font_height = fi.ascent + fi.descent + fi.leading;
+    font_width = CharWidth('W'); /* Well, it's what NCSA uses. */
     s->font_ascent = fi.ascent;
+    s->font_leading = fi.leading;
+    font_height = s->font_ascent + fi.descent + s->font_leading;
     mac_adjustsize(s, rows, cols);
 }
 
@@ -223,20 +226,57 @@ static void mac_initpalette(struct mac_session *s) {
 }
 
 /*
- * I don't think this is (a) safe or (b) a good way to do this.
+ * Set the background colour of the window correctly.  Should be
+ * called whenever the default background changes.
  */
 static void mac_adjustwinbg(struct mac_session *s) {
 
-    if (s->wctab == NULL)
-       s->wctab = (WCTabHandle)NewHandle(sizeof(**s->wctab));
-    if (s->wctab == NULL)
-       return; /* do without */
-    (*s->wctab)->wCSeed = 0;
-    (*s->wctab)->wCReserved = 0;
-    (*s->wctab)->ctSize = 0;
-    (*s->wctab)->ctTable[0].value = wContentColor;
-    (*s->wctab)->ctTable[0].rgb = (*s->palette)->pmInfo[DEFAULT_BG].ciRGB;
-    SetWinColor(s->window, s->wctab);
+#if 0 /* XXX doesn't link (at least for 68k) */
+    if (mac_gestalts.windattr & gestaltWindowMgrPresent)
+       SetWindowContentColor(s->window,
+                             &(*s->palette)->pmInfo[DEFAULT_BG].ciRGB);
+    else
+#endif
+    {
+       if (s->wctab == NULL)
+           s->wctab = (WCTabHandle)NewHandle(sizeof(**s->wctab));
+       if (s->wctab == NULL)
+           return; /* do without */
+       (*s->wctab)->wCSeed = 0;
+       (*s->wctab)->wCReserved = 0;
+       (*s->wctab)->ctSize = 0;
+       (*s->wctab)->ctTable[0].value = wContentColor;
+       (*s->wctab)->ctTable[0].rgb = (*s->palette)->pmInfo[DEFAULT_BG].ciRGB;
+       SetWinColor(s->window, s->wctab);
+    }
+}
+
+/*
+ * Set the cursor shape correctly
+ */
+void mac_adjusttermcursor(WindowPtr window, Point mouse, RgnHandle cursrgn) {
+    struct mac_session *s;
+    ControlHandle control;
+    short part;
+    int x, y;
+
+    SetPort(window);
+    s = (struct mac_session *)GetWRefCon(window);
+    GlobalToLocal(&mouse);
+    part = FindControl(mouse, window, &control);
+    if (control == s->scrollbar) {
+       SetCursor(&qd.arrow);
+       RectRgn(cursrgn, &(*s->scrollbar)->contrlRect);
+       SectRgn(cursrgn, window->visRgn, cursrgn);
+    } else {
+       x = mouse.h / font_width;
+       y = mouse.v / font_height;
+       SetCursor(*GetCursor(iBeamCursor));
+       /* Ask for shape changes if we leave this character cell. */
+       SetRectRgn(cursrgn, x * font_width, y * font_height,
+                  (x + 1) * font_width, (y + 1) * font_height);
+       SectRgn(cursrgn, window->visRgn, cursrgn);
+    }
 }
 
 /*
@@ -370,10 +410,12 @@ void get_clip(void **p, int *lenp) {
        h = NULL;
     } else
        if (GetScrap(NULL, 'TEXT', &offset) > 0) {
-           h = NewEmptyHandle();
+           h = NewHandle(0);
            *lenp = GetScrap(h, 'TEXT', &offset);
            HLock(h);
            *p = *h;
+           if (*p == NULL || *lenp <= 0)
+               fatalbox("Empty scrap");
        } else {
            *p = NULL;
            *lenp = 0;
@@ -400,7 +442,6 @@ static pascal void mac_scrolltracker(ControlHandle control, short part) {
     }
 }
 
-#define K_SPACE        0x3100
 #define K_BS   0x3300
 #define K_F1   0x7a00
 #define K_F2   0x7800
@@ -414,6 +455,9 @@ static pascal void mac_scrolltracker(ControlHandle control, short part) {
 #define K_F10  0x6d00
 #define K_F11  0x6700
 #define K_F12  0x6f00
+#define K_F13  0x6900
+#define K_F14  0x6b00
+#define K_F15  0x7100
 #define K_INSERT 0x7200
 #define K_HOME 0x7300
 #define K_PRIOR        0x7400
@@ -447,15 +491,31 @@ void mac_keyterm(WindowPtr window, EventRecord *event) {
     unsigned char buf[20];
     int len;
     struct mac_session *s;
-    int i;
 
     s = (struct mac_session *)GetWRefCon(window);
     len = mac_keytrans(s, event, buf);
     back->send((char *)buf, len);
-    term_out();
-    term_update();
 }
 
+static UInt32 mac_rekey(EventModifiers newmodifiers, UInt32 oldmessage) {
+    UInt32 transresult, state;
+    Ptr kchr;
+
+    state = 0;
+    kchr = (Ptr)GetScriptManagerVariable(smKCHRCache);
+    transresult = KeyTranslate(kchr,
+                              (oldmessage & keyCodeMask) >> 8 |
+                              newmodifiers & 0xff00,
+                              &state);
+    /*
+     * KeyTranslate returns two character codes.  We only worry about
+     * one.  Yes, this is slightly bogus, but it makes life less
+     * painful.
+     */
+    return oldmessage & ~charCodeMask | transresult & 0xff;
+}
+
+
 static int mac_keytrans(struct mac_session *s, EventRecord *event,
                        unsigned char *output) {
     unsigned char *p = output;
@@ -463,6 +523,14 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event,
 
     /* No meta key yet -- that'll be rather fun. */
 
+    /* Check if the meta "key" was held down */
+
+    if ((event->modifiers & cfg.meta_modifiers) == cfg.meta_modifiers) {
+       *p++ = '\033';
+       event->modifiers &= ~cfg.meta_modifiers;
+       event->message = mac_rekey(event->modifiers, event->message);
+    }
+
     /* Keys that we handle locally */
     if (event->modifiers & shiftKey) {
        switch (event->message & keyCodeMask) {
@@ -579,6 +647,9 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event,
       case K_LEFT:
        p += sprintf((char *)p, app_cursor_keys ? "\x1BOD" : "\x1B[D");
        return p - output;
+      case KP_ENTER:
+       *p++ = 0x0d;
+       return p - output;
       case K_BS:
        *p++ = (cfg.bksp_is_delete ? 0x7f : 0x08);
        return p - output;
@@ -632,8 +703,8 @@ void mac_updateterm(WindowPtr window) {
               (*window->visRgn)->rgnBBox.right,
               (*window->visRgn)->rgnBBox.bottom);
     /* Restore default colours in case the Window Manager uses them */
-    PmForeColor(16);
-    PmBackColor(18);
+    PmForeColor(DEFAULT_FG);
+    PmBackColor(DEFAULT_BG);
     if (FrontWindow() != window)
        EraseRect(&(*s->scrollbar)->contrlRect);
     UpdateControls(window, window->visRgn);
@@ -658,6 +729,7 @@ static void mac_drawgrowicon(struct mac_session *s) {
 struct do_text_args {
     struct mac_session *s;
     Rect textrect;
+    Rect leadrect;
     char *text;
     int len;
     unsigned long attr;
@@ -671,8 +743,6 @@ struct do_text_args {
 void do_text(struct mac_session *s, int x, int y, char *text, int len,
             unsigned long attr) {
     int style = 0;
-    int bgcolour, fgcolour;
-    RGBColor rgbfore, rgbback;
     struct do_text_args a;
     RgnHandle textrgn;
 
@@ -690,6 +760,12 @@ void do_text(struct mac_session *s, int x, int y, char *text, int len,
     a.text = text;
     a.len = len;
     a.attr = attr;
+    if (s->font_leading > 0)
+       SetRect(&a.leadrect,
+               a.textrect.left, a.textrect.bottom - s->font_leading,
+               a.textrect.right, a.textrect.bottom);
+    else
+       SetRect(&a.leadrect, 0, 0, 0, 0);
     SetPort(s->window);
     TextFont(s->fontnum);
     if (cfg.fontisbold || (attr & ATTR_BOLD) && !cfg.bold_colour)
@@ -755,6 +831,10 @@ static pascal void do_text_for_device(short depth, short devflags,
        break;
     }
 
+    if (a->attr & ATTR_REVERSE)
+       PaintRect(&a->leadrect);
+    else
+       EraseRect(&a->leadrect);
     MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent);
     DrawText(a->text, 0, a->len);
 
@@ -935,3 +1015,4 @@ void do_scroll(int topline, int botline, int lines) {
  * c-file-style: "simon"
  * End:
  */
+