]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(SYSTEM_TYPE): Use berkeley-unix.
[gnu-emacs] / src / xterm.c
index 3fd7445388216cebe94e6d177bb4c7ea34e35cdb..c17bf1fc91eddc161cff3515b3c0eba03e29d5f1 100644 (file)
@@ -31,7 +31,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "lisp.h"
 
-/* On 4.3 this loses if it comes after xterm.h.  */
+/* On 4.3 these lose if they come after xterm.h.  */
+#include <stdio.h>
 #include <signal.h>
 
 /* This may include sys/types.h, and that somehow loses
@@ -70,7 +71,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "systime.h"
 
 #include <fcntl.h>
-#include <stdio.h>
 #include <ctype.h>
 #include <errno.h>
 #include <setjmp.h>
@@ -1431,29 +1431,36 @@ unsigned int x_mouse_grabbed;
 /* Which modifier keys are on which modifier bits?
 
    With each keystroke, X returns eight bits indicating which modifier
-   keys were held down when the key was pressed.  The low three bits
-   indicate the state of the shift, shift lock, caps lock, and control
-   keys; their interpretation is fixed.  However, the interpretation
-   of the other five modifier bits depends on what keys are attached
+   keys were held down when the key was pressed.  The interpretation
+   of the top five modifier bits depends on what keys are attached
    to them.  If the Meta_L and Meta_R keysyms are on mod5, then mod5
    is the meta bit.
    
    x_meta_mod_mask is a mask containing the bits used for the meta key.
    It may have more than one bit set, if more than one modifier bit
    has meta keys on it.  Basically, if EVENT is a KeyPress event,
-   the meta key is pressed if (EVENT.state & x_meta_mod_mask) != 0.  */
-static int x_meta_mod_mask;
+   the meta key is pressed if (EVENT.state & x_meta_mod_mask) != 0.  
+
+   x_shift_lock_mask is LockMask if the XK_Shift_Lock keysym is on the
+   lock modifier bit, or zero otherwise.  Non-alphabetic keys should
+   only be affected by the lock modifier bit if XK_Shift_Lock is in
+   use; XK_Caps_Lock should only affect alphabetic keys.  With this
+   arrangement, the lock modifier should shift the character if
+   (EVENT.state & x_shift_lock_mask) != 0.  */
+static int x_meta_mod_mask, x_shift_lock_mask;
 
 /* Initialize mode_switch_bit and modifier_meaning.  */
 static void
 x_find_modifier_meanings ()
 {
-  KeyCode min_code, max_code;
+  int min_code, max_code;
   KeySym *syms;
   int syms_per_code;
   XModifierKeymap *mods;
+  int alt_mod_mask = 0;
 
   x_meta_mod_mask = 0;
+  x_shift_lock_mask = 0;
   
   XDisplayKeycodes (x_current_display, &min_code, &max_code);
   syms = XGetKeyboardMapping (x_current_display,
@@ -1461,10 +1468,8 @@ x_find_modifier_meanings ()
                              &syms_per_code);
   mods = XGetModifierMapping (x_current_display);
 
-  /* If CapsLock is on the lock modifier, then only letters should be
-     affected; since XLookupString takes care of this for us, the lock
-     modifier shouldn't set shift_modifier.  However, if ShiftLock is
-     on the lock modifier, then lock should mean shift.  */
+  /* Scan the modifier table to see which modifier bits the Meta and 
+     Alt keysyms are on.  */
   {
     int row, col;      /* The row and column in the modifier table. */
 
@@ -1480,33 +1485,50 @@ x_find_modifier_meanings ()
 
            for (code_col = 0; code_col < syms_per_code; code_col++)
              {
-               int sym = syms[(code * syms_per_code) + code_col];
+               int sym = syms[((code - min_code) * syms_per_code) + code_col];
 
-               if (sym == XK_Meta_L || sym == XK_Meta_R)
+               switch (sym)
                  {
+                 case XK_Meta_L:
+                 case XK_Meta_R:
                    x_meta_mod_mask |= (1 << row);
                    break;
+
+                 case XK_Alt_L:
+                 case XK_Alt_R:
+                   alt_mod_mask |= (1 << row);
+                   break;
+
+                 case XK_Shift_Lock:
+                   /* Ignore this if it's not on the lock modifier.  */
+                   if ((1 << row) == LockMask)
+                     x_shift_lock_mask = LockMask;
+                   break;
                  }
              }
          }
        }
   }
 
+  /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
+  if (! x_meta_mod_mask)
+    x_meta_mod_mask = alt_mod_mask;
+
   XFree ((char *) syms);
-  XFreeModifierMap (mods);
+  XFreeModifiermap (mods);
 }
 
 
 /* Convert a set of X modifier bits to the proper form for a
    struct input_event modifiers value.  */
 
-static Lisp_Object
+static unsigned int
 x_convert_modifiers (state)
      unsigned int state;
 {
-  return (  ((state & (ShiftMask | LockMask)) ? shift_modifier : 0)
-         | ((state & ControlMask)            ? ctrl_modifier  : 0)
-         | ((state & x_meta_mod_mask)        ? meta_modifier  : 0));
+  return (  ((state & (ShiftMask | x_shift_lock_mask)) ? shift_modifier : 0)
+         | ((state & ControlMask)                     ? ctrl_modifier  : 0)
+         | ((state & x_meta_mod_mask)                 ? meta_modifier  : 0));
 }
 
 extern struct frame *x_window_to_scrollbar ();
@@ -1535,7 +1557,9 @@ construct_mouse_click (result, event, f, part, prefix)
   XSET (result->code, Lisp_Int, event->button);
   result->timestamp = event->time;
   result->modifiers = (x_convert_modifiers (event->state)
-                      | (event->type == ButtonRelease ? up_modifier : 0));
+                      | (event->type == ButtonRelease
+                         ? up_modifier 
+                         : down_modifier));
 
   /* Notice if the mouse is still grabbed.  */
   if (event->type == ButtonPress)
@@ -1551,16 +1575,16 @@ construct_mouse_click (result, event, f, part, prefix)
        Vmouse_depressed = Qnil;
     }
 
-  if (part)                    /* Scrollbar event */
+  if (! NILP (part))           /* Scrollbar event */
     {
       int pos, len;
 
       pos = event->y - (f->display.x->v_scrollbar_width - 2);
-      XSET (x_mouse_x, Lisp_Int, pos);
+      x_mouse_x = pos;
       len = ((FONT_HEIGHT (f->display.x->font) * f->height)
             + f->display.x->internal_border_width
             - (2 * (f->display.x->v_scrollbar_width - 2)));
-      XSET (x_mouse_y, Lisp_Int, len);
+      x_mouse_y = len;
 
       result->kind = scrollbar_click;
       result->part = part;
@@ -1574,8 +1598,8 @@ construct_mouse_click (result, event, f, part, prefix)
 
       pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL);
       result->kind = mouse_click;
-      result->x = column;
-      result->y = row;
+      XFASTINT (result->x) = column;
+      XFASTINT (result->y) = row;
       result->frame = f;
     }
 }
@@ -1732,6 +1756,15 @@ XTmouse_position (f, x, y, time)
    sometimes don't work.  */
 static Time enter_timestamp;
 
+/* This holds the state XLookupString needs to implement dead keys
+   and other tricks known as "compose processing".  _X Window System_ 
+   says that a portable program can't use this, but Stephen Gildea assures
+   me that letting the compiler initialize it to zeros will work okay.
+
+   This must be defined outside of XTread_socket, for the same reasons
+   given for enter_timestamp, above.  */
+static XComposeStatus compose_status;
+
 /* Communication with window managers. */
 Atom Xatom_wm_protocols;
 
@@ -1756,7 +1789,7 @@ Atom Xatom_wm_window_moved;         /* When the WM moves us. */
    WAITP is nonzero if we should block until input arrives.
    EXPECTED is nonzero if the caller knows input is available.  */
 
-Lisp_Object
+int
 XTread_socket (sd, bufp, numchars, waitp, expected)
      register int sd;
      register struct input_event *bufp;
@@ -2016,7 +2049,6 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
          if (f != 0)
            {
              KeySym keysym;
-             XComposeStatus status;
              char copy_buffer[80];
              int modifiers = event.xkey.state;
 
@@ -2027,12 +2059,10 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                 just clear the meta-key flag to get the 'pure' character.  */
              event.xkey.state &= ~Mod1Mask;
 
-             /* This will have to go some day... */
-             nbytes = XLookupString (&event.xkey,
-                                     copy_buffer,
-                                     80,
-                                     &keysym,
-                                     &status);
+             /* This will have to go some day...  */
+             nbytes =
+               XLookupString (&event.xkey, copy_buffer, 80, &keysym,
+                              &compose_status);
 
              /* Strip off the vendor-specific keysym bit, and take a shot
                 at recognizing the codes.  HP servers have extra keysyms
@@ -2061,7 +2091,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 
                      if (nbytes == 1)
                        {
-                         if (modifiers & Mod1Mask)
+                         if (modifiers & x_meta_mod_mask)
                            *copy_buffer |= METABIT;
                          bufp->kind = ascii_keystroke;
                          XSET (bufp->code, Lisp_Int, *copy_buffer);
@@ -2311,7 +2341,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
            if (f)
              if (!x_focus_frame || (f == x_focus_frame))
                construct_mouse_click (&emacs_event,
-                                      &event, f, 0, 0);
+                                      &event, f, Qnil, 0);
              else
                continue;
            else
@@ -2386,10 +2416,16 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
 #endif /* ! defined (HAVE_X11) */
 
        case MappingNotify:
-         if (event.xmapping.request == MappingKeyboard)
-           /* Someone has changed the keyboard mapping - flush the
-              local cache.  */
-           XRefreshKeyboardMapping (&event.xmapping);
+         /* Someone has changed the keyboard mapping - update the
+            local cache.  */
+         switch (event.xmapping.request)
+           {
+           case MappingModifier:
+             x_find_modifier_meanings ();
+             /* This is meant to fall through.  */
+           case MappingKeyboard:
+             XRefreshKeyboardMapping (&event.xmapping);
+           }
          break;
 
        default:
@@ -3141,11 +3177,11 @@ x_calc_absolute_position (f)
 #ifdef HAVE_X11
   if (f->display.x->left_pos < 0)
     f->display.x->left_pos
-      = XINT (x_screen_width) - PIXEL_WIDTH (f) + f->display.x->left_pos;
+      = x_screen_width - PIXEL_WIDTH (f) + f->display.x->left_pos;
 
   if (f->display.x->top_pos < 0)
     f->display.x->top_pos
-      = XINT (x_screen_height) - PIXEL_HEIGHT (f) + f->display.x->top_pos;
+      = x_screen_height - PIXEL_HEIGHT (f) + f->display.x->top_pos;
 #else /* ! defined (HAVE_X11) */
   WINDOWINFO_TYPE parentinfo;