]> code.delx.au - gnu-emacs/blobdiff - src/msdos.c
*** empty log message ***
[gnu-emacs] / src / msdos.c
index 4a8026b4c790744549511d3802bae72034e52b72..6312d5dc2c077e796459eedfee0323cc6e947db7 100644 (file)
@@ -195,8 +195,15 @@ them.  This happens with wheeled mice on Windows 9X, for example.")
   (nbuttons)
      Lisp_Object nbuttons;
 {
+  int n;
+
   CHECK_NUMBER (nbuttons, 0);
-  mouse_setup_buttons (XINT (nbuttons));
+  n = XINT (nbuttons);
+  if (n < 2 || n > 3)
+    Fsignal (Qargs_out_of_range,
+            Fcons (build_string ("only 2 or 3 mouse buttons are supported"),
+                   Fcons (nbuttons, Qnil)));
+  mouse_setup_buttons (n);
   return Qnil;
 }
 
@@ -670,6 +677,11 @@ dos_set_window_size (rows, cols)
   *rows = ScreenRows ();
   *cols = ScreenCols ();
 
+  /* Update Emacs' notion of screen dimensions.  */
+  screen_size_X = *cols;
+  screen_size_Y = *rows;
+  screen_size = *cols * *rows;
+
 #if __DJGPP__ > 1
   /* If the dimensions changed, the mouse highlight info is invalid.  */
   if (current_rows != *rows || current_cols != *cols)
@@ -864,12 +876,13 @@ static void
 IT_set_face (int face)
 {
   struct frame *sf = SELECTED_FRAME();
-  struct face *fp = FACE_FROM_ID (sf, face);
-  unsigned long fg, bg;
+  struct face *fp  = FACE_FROM_ID (sf, face);
+  struct face *dfp = FACE_FROM_ID (sf, DEFAULT_FACE_ID);
+  unsigned long fg, bg, dflt_fg, dflt_bg;
 
   if (!fp)
     {
-      fp = FACE_FROM_ID (sf, DEFAULT_FACE_ID);
+      fp = dfp;
       /* The default face for the frame should always be realized and
         cached.  */
       if (!fp)
@@ -878,6 +891,8 @@ IT_set_face (int face)
   screen_face = face;
   fg = fp->foreground;
   bg = fp->background;
+  dflt_fg = dfp->foreground;
+  dflt_bg = dfp->background;
 
   /* Don't use invalid colors.  In particular, FACE_TTY_DEFAULT_*
      colors mean use the colors of the default face, except that if
@@ -896,14 +911,21 @@ IT_set_face (int face)
 
   /* Make sure highlighted lines really stand out, come what may.  */
   if ((highlight || fp->tty_reverse_p)
-      && (fg == FRAME_FOREGROUND_PIXEL (sf)
-         && bg == FRAME_BACKGROUND_PIXEL (sf)))
+      && (fg == dflt_fg && bg == dflt_bg))
     {
       unsigned long tem = fg;
 
       fg = bg;
       bg = tem;
     }
+  /* If the user requested inverse video, obey.  */
+  if (inverse_video)
+    {
+      unsigned long tem2 = fg;
+
+      fg = bg;
+      bg = tem2;
+    }
   if (termscript)
     fprintf (termscript, "<FACE %d%s: %d/%d[FG:%d/BG:%d]>", face,
             highlight ? "H" : "", fp->foreground, fp->background, fg, bg);
@@ -947,6 +969,9 @@ IT_write_glyphs (struct glyph *str, int str_len)
     = (NILP (current_buffer->enable_multibyte_characters)
        && unibyte_display_via_language_environment);
 
+  unsigned char conversion_buffer[256];
+  int conversion_buffer_size = sizeof conversion_buffer;
+
   if (str_len <= 0) return;
   
   screen_buf = screen_bp = alloca (str_len * 2);
@@ -982,6 +1007,9 @@ IT_write_glyphs (struct glyph *str, int str_len)
          register GLYPH g = GLYPH_FROM_CHAR_GLYPH (*str);
          int glyph_not_in_table = 0;
 
+         /* If g is negative, it means we have a multibyte character
+            in *str.  That's what GLYPH_FROM_CHAR_GLYPH returns for
+            multibyte characters.  */
          if (g < 0 || g >= tlen)
            {
              /* This glyph doesn't have an entry in Vglyph_table.  */
@@ -1017,7 +1045,7 @@ IT_write_glyphs (struct glyph *str, int str_len)
 
          /* If the face of this glyph is different from the current
             screen face, update the screen attribute byte.  */
-         cf = FAST_GLYPH_FACE (g);
+         cf = str->face_id;
          if (cf != screen_face)
            IT_set_face (cf);   /* handles invalid faces gracefully */
 
@@ -1053,7 +1081,7 @@ IT_write_glyphs (struct glyph *str, int str_len)
                 terminal_coding with Vdos_unsupported_char_glyph.  */
              if (*conversion_buffer == '?')
                {
-                 char *cbp = conversion_buffer;
+                 unsigned char *cbp = conversion_buffer;
 
                  while (cbp < conversion_buffer + enclen && *cbp == '?')
                    *cbp++ = unsupported_char;
@@ -1350,6 +1378,11 @@ fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
        }
       else if (line_start_position > 0)
        best_row = row;
+
+      /* Don't overstep the last matrix row, lest we get into the
+        never-never land... */
+      if (row->y + 1 >= yb)
+       break;
       
       ++row;
     }
@@ -1446,7 +1479,7 @@ static void
 IT_note_mouse_highlight (struct frame *f, int x, int y)
 {
   struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  int portion;
+  int portion = -1;
   Lisp_Object window;
   struct window *w;
 
@@ -1505,16 +1538,22 @@ IT_note_mouse_highlight (struct frame *f, int x, int y)
       && (XFASTINT (w->last_overlay_modified)
          == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
     {
-      int pos, i, area;
+      int pos, i;
       struct glyph_row *row;
       struct glyph *glyph;
+      int nrows = w->current_matrix->nrows;
 
       /* Find the glyph under X/Y.  */
       glyph = NULL;
-      if (y < w->current_matrix->nrows)
+      if (y >= 0 && y < nrows)
        {
          row = MATRIX_ROW (w->current_matrix, y);
-         if (row->enabled_p
+         /* Give up if some row before the one we are looking for is
+            not enabled.  */
+         for (i = 0; i <= y; i++)
+           if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
+             break;
+         if (i > y  /* all rows upto and including the one at Y are enabled */
              && row->displays_text_p
              && x <  window_box_width (w, TEXT_AREA))
            {
@@ -1571,12 +1610,13 @@ IT_note_mouse_highlight (struct frame *f, int x, int y)
           enough space for all, and try again.  */
        len = 10;
        overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-       noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL);
+       noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
        if (noverlays > len)
          {
            len = noverlays;
            overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-           noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL);
+           noverlays = overlays_at (pos,
+                                    0, &overlay_vec, &len, NULL, NULL, 0);
          }
          
        /* Sort overlays into increasing priority order.  */
@@ -1912,12 +1952,13 @@ static void
 IT_update_begin (struct frame *f)
 {
   struct display_info *display_info = FRAME_X_DISPLAY_INFO (f);
+  struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame;
   
   highlight = 0;
 
   BLOCK_INPUT;
 
-  if (f == display_info->mouse_face_mouse_frame)
+  if (f && f == mouse_face_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
       display_info->mouse_face_defer = 1;
@@ -1954,7 +1995,7 @@ IT_update_begin (struct frame *f)
            clear_mouse_face (display_info);
        }
     }
-  else if (!FRAME_LIVE_P (display_info->mouse_face_mouse_frame))
+  else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
     {
       /* If the frame with mouse highlight was deleted, invalidate the
         highlight info.  */
@@ -1985,7 +2026,7 @@ IT_frame_up_to_date (struct frame *f)
   struct window *sw;
 
   if (dpyinfo->mouse_face_deferred_gc
-      || f == dpyinfo->mouse_face_mouse_frame)
+      || (f && f == dpyinfo->mouse_face_mouse_frame))
     {
       BLOCK_INPUT;
       if (dpyinfo->mouse_face_mouse_frame)
@@ -2093,10 +2134,10 @@ x_set_menu_bar_lines (f, value, oldval)
   set_menu_bar_lines (f, value, oldval);
 }
 
-/* This was copied from xfns.c  */
+/* This was copied from xfaces.c  */
 
-Lisp_Object Qbackground_color;
-Lisp_Object Qforeground_color;
+extern Lisp_Object Qbackground_color;
+extern Lisp_Object Qforeground_color;
 Lisp_Object Qreverse;
 extern Lisp_Object Qtitle;
 
@@ -2266,17 +2307,13 @@ DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors,
      (frame)
      Lisp_Object frame;
 {
-  int reverse;
   struct frame *f;
 
   CHECK_FRAME (frame, 0);
   f= XFRAME (frame);
-  reverse = EQ (Fcdr (Fassq (intern ("reverse"), f->param_alist)), Qt);
 
-  initial_screen_colors[0]
-    = reverse ? FRAME_BACKGROUND_PIXEL (f) : FRAME_FOREGROUND_PIXEL (f);
-  initial_screen_colors[1]
-    = reverse ? FRAME_FOREGROUND_PIXEL (f) : FRAME_BACKGROUND_PIXEL (f);
+  initial_screen_colors[0] = FRAME_FOREGROUND_PIXEL (f);
+  initial_screen_colors[1] = FRAME_BACKGROUND_PIXEL (f);
 }
 
 void
@@ -2295,8 +2332,11 @@ IT_set_frame_parameters (f, alist)
   int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt);
   int was_reverse = reverse;
   int redraw = 0, fg_set = 0, bg_set = 0;
+  int need_to_reverse;
   unsigned long orig_fg;
   unsigned long orig_bg;
+  Lisp_Object frame_bg, frame_fg;
+  extern Lisp_Object Qdefault, QCforeground, QCbackground;
 
   /* If we are creating a new frame, begin with the original screen colors
      used for the initial frame.  */
@@ -2308,6 +2348,15 @@ IT_set_frame_parameters (f, alist)
     }
   orig_fg = FRAME_FOREGROUND_PIXEL (f);
   orig_bg = FRAME_BACKGROUND_PIXEL (f);
+  frame_fg = Fcdr (Fassq (Qforeground_color, f->param_alist));
+  frame_bg = Fcdr (Fassq (Qbackground_color, f->param_alist));
+  /* frame_fg and frame_bg could be nil if, for example,
+     f->param_alist is nil, e.g. if we are called from
+     Fmake_terminal_frame.  */
+  if (NILP (frame_fg))
+    frame_fg = build_string (unspecified_fg);
+  if (NILP (frame_bg))
+    frame_bg = build_string (unspecified_bg);
 
   /* Extract parm names and values into those vectors.  */
   i = 0;
@@ -2326,37 +2375,52 @@ IT_set_frame_parameters (f, alist)
 
   for (i = 0; i < j; i++)
     {
-      Lisp_Object prop = parms[i];
-      Lisp_Object val  = values[i];
+      Lisp_Object prop, val;
+
+      prop = parms[i];
+      val  = values[i];
 
       if (EQ (prop, Qreverse))
        reverse = EQ (val, Qt);
     }
-       
-  if (termscript && reverse && !was_reverse)
+
+  need_to_reverse = reverse && !was_reverse;
+  if (termscript && need_to_reverse)
     fprintf (termscript, "<INVERSE-VIDEO>\n");
 
   /* Now process the alist elements in reverse of specified order.  */
   for (i--; i >= 0; i--)
     {
-      Lisp_Object prop = parms[i];
-      Lisp_Object val  = values[i];
+      Lisp_Object prop, val;
+      Lisp_Object frame;
+
+      prop = parms[i];
+      val  = values[i];
 
       if (EQ (prop, Qforeground_color))
        {
-         unsigned long new_color = load_color (f, NULL, val, reverse
+         unsigned long new_color = load_color (f, NULL, val, need_to_reverse
                                                ? LFACE_BACKGROUND_INDEX
                                                : LFACE_FOREGROUND_INDEX);
          if (new_color !=  FACE_TTY_DEFAULT_COLOR
              && new_color != FACE_TTY_DEFAULT_FG_COLOR
              && new_color != FACE_TTY_DEFAULT_BG_COLOR)
            {
-             if (reverse)
-               /* FIXME: should the fore-/background of the default
-                  face change here as well?  */
-               FRAME_BACKGROUND_PIXEL (f) = new_color;
+             FRAME_FOREGROUND_PIXEL (f) = new_color;
+             /* Make sure the foreground of the default face for this
+                frame is changed as well.  */
+             XSETFRAME (frame, f);
+             if (need_to_reverse)
+               {
+                 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
+                                                    val, frame);
+                 prop = Qbackground_color;
+               }
              else
-               FRAME_FOREGROUND_PIXEL (f) = new_color;
+               {
+                 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
+                                                    val, frame);
+               }
              redraw = 1;
              fg_set = 1;
              if (termscript)
@@ -2365,17 +2429,28 @@ IT_set_frame_parameters (f, alist)
        }
       else if (EQ (prop, Qbackground_color))
        {
-         unsigned long new_color = load_color (f, NULL, val, reverse
+         unsigned long new_color = load_color (f, NULL, val, need_to_reverse
                                                ? LFACE_FOREGROUND_INDEX
                                                : LFACE_BACKGROUND_INDEX);
          if (new_color != FACE_TTY_DEFAULT_COLOR
              && new_color != FACE_TTY_DEFAULT_FG_COLOR
              && new_color != FACE_TTY_DEFAULT_BG_COLOR)
            {
-             if (reverse)
-               FRAME_FOREGROUND_PIXEL (f) = new_color;
+             FRAME_BACKGROUND_PIXEL (f) = new_color;
+             /* Make sure the background of the default face for this
+                frame is changed as well.  */
+             XSETFRAME (frame, f);
+             if (need_to_reverse)
+               {
+                 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
+                                                    val, frame);
+                 prop = Qforeground_color;
+               }
              else
-               FRAME_BACKGROUND_PIXEL (f) = new_color;
+               {
+                 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
+                                                    val, frame);
+               }
              redraw = 1;
              bg_set = 1;
              if (termscript)
@@ -2401,16 +2476,26 @@ IT_set_frame_parameters (f, alist)
 
   /* If they specified "reverse", but not the colors, we need to swap
      the current frame colors.  */
-  if (reverse && !was_reverse)
+  if (need_to_reverse)
     {
+      Lisp_Object frame;
+
       if (!fg_set)
        {
-         FRAME_BACKGROUND_PIXEL (f) = orig_fg;
+         XSETFRAME (frame, f);
+         Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
+                                            tty_color_name (f, orig_fg),
+                                            frame);
+         store_frame_param (f, Qbackground_color, frame_fg);
          redraw = 1;
        }
       if (!bg_set)
        {
-         FRAME_FOREGROUND_PIXEL (f) = orig_bg;
+         XSETFRAME (frame, f);
+         Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
+                                            tty_color_name (f, orig_bg),
+                                            frame);
+         store_frame_param (f, Qforeground_color, frame_bg);
          redraw = 1;
        }
     }
@@ -3066,9 +3151,6 @@ and then the scan code.")
 }
 
 /* Get a char from keyboard.  Function keys are put into the event queue.  */
-
-extern void kbd_buffer_store_event (struct input_event *);
-
 static int
 dos_rawgetc ()
 {
@@ -5227,11 +5309,7 @@ For example, if a block cursor is over a tab, it will be drawn as\n\
 wide as that tab on the display.  (No effect on MS-DOS.)");
   x_stretch_cursor_p = 0;
 
-  /* The following three are from xfns.c:  */
-  Qbackground_color = intern ("background-color");
-  staticpro (&Qbackground_color);
-  Qforeground_color = intern ("foreground-color");
-  staticpro (&Qforeground_color);
+  /* The following two are from xfns.c:  */
   Qbar = intern ("bar");
   staticpro (&Qbar);
   Qcursor_type = intern ("cursor-type");