]> code.delx.au - gnu-emacs/blobdiff - src/w32term.c
*** empty log message ***
[gnu-emacs] / src / w32term.c
index 294059aa77bbb598df55eaaba7df7394f016903a..0422257f2d6a547e009dfc79fb6ee72271551d12 100644 (file)
@@ -1,12 +1,13 @@
 /* Implementation of GUI terminal on the Microsoft W32 API.
-   Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
+                 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+                 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -91,6 +92,10 @@ static Lisp_Object last_window;
    (Not yet supported, see TODO in x_draw_glyph_string.)  */
 int x_use_underline_position_properties;
 
+/* Non-zero means to draw the underline at the same place as the descent line.  */
+
+int x_underline_at_descent_line;
+
 extern unsigned int msh_mousewheel;
 
 extern void free_frame_menubar ();
@@ -1587,7 +1592,10 @@ x_draw_glyph_string_foreground (s)
        {
          /* For overstriking (to simulate bold-face), draw the
             characters again shifted to the right by one pixel.  */
+         int old_BkMode = SetBkMode (s->hdc, TRANSPARENT);
          w32_text_out (s, x + 1, s->ybase - boff, s->char2b, s->nchars);
+         if (old_BkMode && old_BkMode != TRANSPARENT)
+           SetBkMode (s->hdc, old_BkMode);
        }
     }
   if (s->font && s->font->hfont)
@@ -2418,7 +2426,9 @@ x_draw_stretch_glyph_string (s)
       int background_width = s->background_width;
       int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
 
-      if (x < left_x)
+      /* Don't draw into left margin, fringe or scrollbar area
+         except for header line and mode line.  */
+      if (x < left_x && !s->row->mode_line_p)
        {
          background_width -= left_x - x;
          x = left_x;
@@ -2507,21 +2517,27 @@ x_draw_glyph_string (s)
           && (s->font->bdf || !s->font->tm.tmUnderlined))
         {
           unsigned long h = 1;
-          unsigned long dy = s->height - h;
+          unsigned long dy = 0;
 
-         /* TODO: Use font information for positioning and thickness
-            of underline.  See OUTLINETEXTMETRIC, and xterm.c.
-            Note: If you make this work, don't forget to change the
-            doc string of x-use-underline-position-properties below.  */
+          if (x_underline_at_descent_line)
+            dy = s->height - h;
+          else
+            {
+              /* TODO: Use font information for positioning and thickness of
+                 underline.  See OUTLINETEXTMETRIC, and xterm.c.  Note: If
+                 you make this work, don't forget to change the doc string of
+                 x-use-underline-position-properties below.  */
+              dy = s->height - h;
+            }
           if (s->face->underline_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             s->y + dy, s->width, 1);
+                             s->y + dy, s->background_width, 1);
             }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
-                             s->y + dy, s->width, 1);
+                             s->y + dy, s->background_width, 1);
             }
         }
 
@@ -2533,12 +2549,12 @@ x_draw_glyph_string (s)
           if (s->face->overline_color_defaulted_p)
         {
           w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                         s->y + dy, s->width, h);
+                         s->y + dy, s->background_width, h);
         }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
-                             s->y + dy, s->width, h);
+                             s->y + dy, s->background_width, h);
             }
         }
 
@@ -3458,25 +3474,51 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
      int portion, position, whole;
 {
   Window w = SCROLL_BAR_W32_WINDOW (bar);
-  double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+  /* We use the whole scroll-bar height in the calculations below, to
+     avoid strange effects like scrolling backwards when just clicking
+     on the handle (without moving it).  */
+  double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height))
+                 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
   int sb_page, sb_pos;
   BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
   SCROLLINFO si;
 
+  /* We used to change the nPage setting while dragging the handle,
+     but that had very strange effects (such as scrolling backwards
+     while dragging downwards).
+
+     Now, we don't change the nPage setting while dragging unless we
+     get near to the end of the buffer, in which case we often have to
+     resize the handle to "go all the way".  */
+
+  if (draggingp)
+    {
+      int near_bottom_p;
+      BLOCK_INPUT;
+      si.cbSize = sizeof (si);
+      si.fMask = SIF_POS | SIF_PAGE;
+      GetScrollInfo(w, SB_CTL, &si);
+      near_bottom_p = si.nPos + si.nPage >= range;
+      UNBLOCK_INPUT;
+      if (!near_bottom_p)
+       return;
+    }
+
   if (whole)
     {
       /* Position scroll bar at rock bottom if the bottom of the
          buffer is visible. This avoids shinking the thumb away
          to nothing if it is held at the bottom of the buffer.  */
-      if (position + portion >= whole)
-        {
-          sb_page = range * (whole - position) / whole
-            + VERTICAL_SCROLL_BAR_MIN_HANDLE;
-          sb_pos = range;
-        }
-
-      sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
-      sb_pos = position * range / whole;
+      if (position + portion >= whole && !draggingp)
+       {
+         sb_page = range * (whole - position) / whole;
+         sb_pos = range;
+       }
+      else
+       {
+         sb_pos = position * range / whole;
+         sb_page = (min (portion, (whole - position)) * range) / whole;
+       }
     }
   else
     {
@@ -3484,19 +3526,16 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
       sb_pos = 0;
     }
 
+  sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
+
   BLOCK_INPUT;
 
   si.cbSize = sizeof (si);
-  /* Only update page size if currently dragging, to reduce
-     flicker effects.  */
-  if (draggingp)
-    si.fMask = SIF_PAGE;
-  else
-    si.fMask = SIF_PAGE | SIF_POS;
+  si.fMask = SIF_PAGE | SIF_POS;
   si.nPage = sb_page;
   si.nPos = sb_pos;
 
-  SetScrollInfo (w, SB_CTL, &si, !draggingp);
+  SetScrollInfo (w, SB_CTL, &si, TRUE);
 
   UNBLOCK_INPUT;
 }
@@ -4286,7 +4325,7 @@ w32_read_socket (sd, expected, hold_quit)
          if (f)
            {
              /* Generate SELECT_WINDOW_EVENTs when needed.  */
-             if (mouse_autoselect_window)
+             if (!NILP (Vmouse_autoselect_window))
                {
                  Lisp_Object window;
                  int x = LOWORD (msg.msg.lParam);
@@ -4297,7 +4336,7 @@ w32_read_socket (sd, expected, hold_quit)
                  /* Window will be selected only when it is not
                     selected now and last mouse movement event was
                     not in it.  Minibuffer window will be selected
-                    iff it is active.  */
+                    only when it is active.  */
                  if (WINDOWP(window)
                      && !EQ (window, last_window)
                      && !EQ (window, selected_window))
@@ -4424,7 +4463,7 @@ w32_read_socket (sd, expected, hold_quit)
                /* Ignore any mouse motion that happened before this
                   event; any subsequent mouse-movement Emacs events
                   should reflect only motion after the
-                  ButtonPress.  */
+                  ButtonPress.  */
                f->mouse_moved = 0;
              }
            last_mouse_frame = f;
@@ -6267,7 +6306,7 @@ x_delete_display (dpyinfo)
 \f
 /* Set up use of W32.  */
 
-DWORD w32_msg_worker ();
+DWORD WINAPI w32_msg_worker (void * arg);
 
 void
 x_flush (struct frame * f)
@@ -6372,8 +6411,8 @@ w32_initialize ()
     PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
 
     hWindowsThread = CreateThread (NULL, 0,
-                              (LPTHREAD_START_ROUTINE) w32_msg_worker,
-                              0, 0, &dwWindowsThreadId);
+                                   w32_msg_worker,
+                                   0, 0, &dwWindowsThreadId);
 
     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
   }
@@ -6501,13 +6540,21 @@ the cursor have no effect.  */);
   DEFVAR_BOOL ("x-use-underline-position-properties",
               &x_use_underline_position_properties,
      doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-nil means ignore them.  If you encounter fonts with bogus
+A value of nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.
 
 NOTE: Not supported on MS-Windows yet.  */);
   x_use_underline_position_properties = 0;
 
+  DEFVAR_BOOL ("x-underline-at-descent-line",
+              &x_underline_at_descent_line,
+     doc: /* *Non-nil means to draw the underline at the same place as the descent line.
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level.  The default value is nil.  */);
+  x_underline_at_descent_line = 0;
+
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
   Vx_toolkit_scroll_bars = Qt;