diff src/redisplay-msw.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
line wrap: on
line diff
--- a/src/redisplay-msw.c	Mon Aug 13 11:33:40 2007 +0200
+++ b/src/redisplay-msw.c	Mon Aug 13 11:35:02 2007 +0200
@@ -26,8 +26,9 @@
 
    Chuck Thompson
    Lots of work done by Ben Wing for Mule
-   Partially rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
- */
+
+   Partially rewritten for mswindows by Jonathan Harris, November 1997
+   for 21.0.  */
 
 #include <config.h>
 #include "lisp.h"
@@ -91,7 +92,7 @@
 static int
 separate_textual_runs (unsigned char *text_storage,
 		       textual_run *run_storage,
-		       CONST Emchar *str, Charcount len)
+		       const Emchar *str, Charcount len)
 {
   Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a
 					  possible valid charset when
@@ -201,15 +202,20 @@
 
 /*
  * Given F, retrieve device context. F can be a display frame, or
- * a print job.
+ * a print job. For a print job, page is also started when printer's
+ * device context is first time requested. 
  */
 static HDC
-get_frame_dc (struct frame *f)
+get_frame_dc (struct frame *f, int start_page_p)
 {
   if (FRAME_MSWINDOWS_P (f))
     return FRAME_MSWINDOWS_DC (f);
   else
-    return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
+    {
+      if (start_page_p && !FRAME_MSPRINTER_PAGE_STARTED (f))
+	msprinter_start_page (f);
+      return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
+    }
 }
 
 /*
@@ -219,10 +225,11 @@
 static HDC
 get_frame_compdc (struct frame *f)
 {
-  if (FRAME_MSWINDOWS_P (f))
-    return FRAME_MSWINDOWS_CDC (f);
+  struct device *d = XDEVICE (FRAME_DEVICE (f));
+  if (DEVICE_MSWINDOWS_P (d))
+    return DEVICE_MSWINDOWS_HCDC (d);
   else
-    return FRAME_MSPRINTER_CDC (f);
+    return DEVICE_MSPRINTER_HCDC (d);
 }
 
 /*****************************************************************************
@@ -280,7 +287,7 @@
 			struct rune *rb, int start_pixpos)
 {
   struct frame *f = XFRAME (w->frame);
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl),
 		rb->xpos+rb->width, 
 		DISPLAY_LINE_YEND (dl) };
@@ -333,7 +340,7 @@
   struct face_cachel *cachel=0;
   Lisp_Object font = Qnil;
   int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   unsigned int local_face_index=0;
   char *p_char = NULL;
   int n_char = 0;
@@ -453,7 +460,7 @@
   struct frame *f = XFRAME (w->frame);
   /* struct device *d = XDEVICE (f->device);*/
   Lisp_Object window;
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   int clip_end;
   Lisp_Object bg_pmap;
   int len = Dynarr_length (buf);
@@ -566,45 +573,69 @@
 			   struct display_box* db,
 			   struct display_glyph_area* dga)
 {
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   HDC hcompdc = get_frame_compdc (f);
   HGDIOBJ old=NULL;
-  COLORREF bgcolor = GetBkColor (hdc);
+  const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p);
+  const int real_y = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (p);
+  const int surface_x = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
+  const int surface_y = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
 
-  /* first blt the mask */
+  /* first blit the mask */
   if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
     {
-      RGBQUAD col;
-      col.rgbBlue = GetBValue (bgcolor);
-      col.rgbRed = GetRValue (bgcolor);
-      col.rgbGreen = GetGValue (bgcolor);
-      col.rgbReserved = 0;
+      RGBQUAD bg;
+      COLORREF bgcolor;
 
       old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p));
       
-      SetDIBColorTable (hcompdc, 1, 1, &col);
+      if (IMAGE_INSTANCE_TYPE (p) == IMAGE_MONO_PIXMAP)
+       {
+         COLORREF fgcolor;
+         RGBQUAD fg;
+
+         fgcolor = GetTextColor (hdc);
+         fg.rgbBlue = GetBValue (fgcolor);
+         fg.rgbRed = GetRValue (fgcolor);
+         fg.rgbGreen = GetGValue (fgcolor);
+         fg.rgbReserved = 0;
+         SetDIBColorTable (hcompdc, 0, 1, &fg);
+       }
 
-      BitBlt (hdc, 
-	      db->xpos, db->ypos,
-	      dga->width, dga->height, 
-	      hcompdc,
-	      dga->xoffset, dga->yoffset, 
-	      SRCCOPY);                  
+      bgcolor = GetBkColor (hdc);
+      bg.rgbBlue = GetBValue (bgcolor);
+      bg.rgbRed = GetRValue (bgcolor);
+      bg.rgbGreen = GetGValue (bgcolor);
+      bg.rgbReserved = 0;
+      SetDIBColorTable (hcompdc, 1, 1, &bg);
+
+      StretchBlt (hdc, 
+		  db->xpos, db->ypos,
+		  dga->width, dga->height, 
+		  hcompdc,
+		  MulDiv (dga->xoffset, real_x, surface_x),
+		  MulDiv (dga->yoffset, real_y, surface_y),
+		  MulDiv (dga->width, real_x, surface_x),
+		  MulDiv (dga->height, real_y, surface_y),
+		  SRCCOPY);                  
 
       SelectObject (hcompdc, old);
     }
   
-  /* Now blt the bitmap itself, or one of its slices. */
+  /* Now blit the bitmap itself, or one of its slices. */
   old = SelectObject (hcompdc,
 		      IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE 
 		      (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)));
 
-  BitBlt (hdc, 
-	  db->xpos, db->ypos,
-	  dga->width, dga->height,
-	  hcompdc,
-	  dga->xoffset, dga->yoffset, 
-	  IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY);
+  StretchBlt (hdc, 
+	      db->xpos, db->ypos,
+	      dga->width, dga->height,
+	      hcompdc,
+	      MulDiv (dga->xoffset, real_x, surface_x),
+	      MulDiv (dga->yoffset, real_y, surface_y),
+	      MulDiv (dga->width, real_x, surface_x),
+	      MulDiv (dga->height, real_y, surface_y),
+	      IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY);
 
   SelectObject (hcompdc, old);
 }
@@ -675,7 +706,7 @@
 			 int cursor_height, int bg_pixmap)
 {
   struct frame *f = XFRAME (w->frame);
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
 
   Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
   Lisp_Object window;
@@ -703,7 +734,7 @@
  * to by PRC, and paints only the intersection
  */
 static void
-mswindows_redisplay_deadbox_maybe (struct window *w, CONST RECT* prc)
+mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc)
 {
   int sbh = window_scrollbar_height (w);
   int sbw = window_scrollbar_width (w);
@@ -726,7 +757,7 @@
   if (IntersectRect (&rect_paint, &rect_dead, prc))
     {
       struct frame *f = XFRAME (WINDOW_FRAME (w));
-      FillRect (get_frame_dc (f), &rect_paint,
+      FillRect (get_frame_dc (f, 1), &rect_paint,
 		(HBRUSH) (COLOR_BTNFACE+1));
     }
 }
@@ -905,7 +936,7 @@
   {
     RECT rect = { x, y, x + width, y + height };
     Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
-    HDC hdc = get_frame_dc (f);
+    HDC hdc = get_frame_dc (f, 1);
 
     mswindows_update_dc (hdc, Qnil, color, Qnil);
     DrawEdge (hdc, &rect, edge, border);
@@ -940,22 +971,38 @@
 }
 
 /*****************************************************************************
- mswindows_output_begin
+ mswindows_frame_output_begin
 
  Perform any necessary initialization prior to an update.
  ****************************************************************************/
 static void
-mswindows_output_begin (struct device *d)
+mswindows_frame_output_begin (struct frame *f)
 {
 }
 
 /*****************************************************************************
- mswindows_output_end
+ mswindows_frame_output_end
 
  Perform any necessary flushing of queues when an update has completed.
  ****************************************************************************/
 static void
-mswindows_output_end (struct device *d)
+mswindows_frame_output_end (struct frame *f)
+{
+#ifdef DEFER_WINDOW_POS
+  HDWP hdwp = FRAME_MSWINDOWS_DATA (f)->hdwp;
+
+  if (hdwp != 0)
+    {
+      EndDeferWindowPos (hdwp);
+      FRAME_MSWINDOWS_DATA (f)->hdwp = 0;
+    }
+#endif
+  GdiFlush();
+}
+
+/* Printer version is more lightweight. */
+static void
+msprinter_frame_output_end (struct frame *f)
 {
   GdiFlush();
 }
@@ -964,7 +1011,7 @@
 mswindows_flash (struct device *d)
 {
   struct frame *f = device_selected_frame (d);
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   RECT rc;
 
   GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc);
@@ -1116,6 +1163,7 @@
 	      Lisp_Object instance;
 	      struct display_box dbox;
 	      struct display_glyph_area dga;
+
 	      redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
 						 start_pixpos, rb->width,
 						 &dbox, &dga);
@@ -1126,69 +1174,52 @@
 	      findex = rb->findex;
 
 	      if (IMAGE_INSTANCEP (instance))
-		switch (XIMAGE_INSTANCE_TYPE (instance))
-		  {
-		  case IMAGE_TEXT:
+		{
+		  switch (XIMAGE_INSTANCE_TYPE (instance))
 		    {
-		      /* #### This is way losing.  See the comment in
-			 add_glyph_rune(). */
-		      Lisp_Object string =
-			XIMAGE_INSTANCE_TEXT_STRING (instance);
-		      convert_bufbyte_string_into_emchar_dynarr
-			(XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
-
+		    case IMAGE_MONO_PIXMAP:
+		    case IMAGE_COLOR_PIXMAP:
+		      redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
+					       cursor_start, cursor_width,
+					       cursor_height, 0);
 		      if (rb->cursor_type == CURSOR_ON)
 			mswindows_output_cursor (w, dl, xpos, cursor_width,
-						 findex, Dynarr_at (buf, 0), 0);
-		      else /* #### redisplay-x passes -1 as the width: why ? */
-			mswindows_output_string (w, dl, buf, xpos,
-					   rb->object.dglyph.xoffset,
-					   start_pixpos, rb->width, findex,
-						 0, 0, 0, 0);
-		      Dynarr_reset (buf);
-		    }
-		    break;
-
-		  case IMAGE_MONO_PIXMAP:
-		  case IMAGE_COLOR_PIXMAP:
-		    redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
-					     cursor_start, cursor_width,
-					     cursor_height, 0);
-		    if (rb->cursor_type == CURSOR_ON)
-		      mswindows_output_cursor (w, dl, xpos, cursor_width,
-					       findex, 0, 1);
-		    break;
-
-		  case IMAGE_POINTER:
-		    abort ();
+						 findex, 0, 1);
+		      break;
+		      
+		    case IMAGE_WIDGET:
+		      if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance),
+			      Qlayout))
+			{
+			  redisplay_output_layout (window, instance, &dbox, &dga, findex,
+						   cursor_start, cursor_width,
+						   cursor_height);
+			  if (rb->cursor_type == CURSOR_ON)
+			    mswindows_output_cursor (w, dl, xpos, cursor_width,
+						     findex, 0, 1);
+			  break;
+			}
+		    case IMAGE_SUBWINDOW:
+		      redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
+						  cursor_start, cursor_width,
+						  cursor_height);
+		      if (rb->cursor_type == CURSOR_ON)
+			mswindows_output_cursor (w, dl, xpos, cursor_width,
+						 findex, 0, 1);
+		      break;
+		      
+		    case IMAGE_NOTHING:
+		      /* nothing is as nothing does */
+		      break;
 
-		  case IMAGE_SUBWINDOW:
-		  case IMAGE_WIDGET:
-		    redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
-						cursor_start, cursor_width,
-						cursor_height);
-		    if (rb->cursor_type == CURSOR_ON)
-		      mswindows_output_cursor (w, dl, xpos, cursor_width,
-					       findex, 0, 1);
-		    break;
-
-		  case IMAGE_LAYOUT:
-		    redisplay_output_layout (w, instance, &dbox, &dga, findex,
-					     cursor_start, cursor_width,
-					     cursor_height);
-		    if (rb->cursor_type == CURSOR_ON)
-		      mswindows_output_cursor (w, dl, xpos, cursor_width,
-					       findex, 0, 1);
-		    break;
-
-		  case IMAGE_NOTHING:
-		    /* nothing is as nothing does */
-		    break;
-
-		  default:
-		    abort ();
-		  }
-
+		    case IMAGE_TEXT:
+		    case IMAGE_POINTER:
+		    default:
+		      abort ();
+		    }
+		  IMAGE_INSTANCE_OPTIMIZE_OUTPUT 
+		    (XIMAGE_INSTANCE (instance)) = 0;
+		}
 	      xpos += rb->width;
 	      elt++;
 	    }
@@ -1221,15 +1252,15 @@
 mswindows_output_vertical_divider (struct window *w, int clear_unused)
 {
   struct frame *f = XFRAME (w->frame);
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
   RECT rect;
   int spacing = XINT (w->vertical_divider_spacing);
   int shadow = XINT (w->vertical_divider_shadow_thickness);
   int abs_shadow = abs (shadow);
   int line_width = XINT (w->vertical_divider_line_width);
   int div_left = WINDOW_RIGHT (w) - window_divider_width (w);
-  int y1 = WINDOW_TOP (w) + FRAME_TOP_GUTTER_BOUNDS (f);
-  int y2 = WINDOW_BOTTOM (w) + FRAME_BOTTOM_GUTTER_BOUNDS (f);
+  int y1 = WINDOW_TOP (w);
+  int y2 = WINDOW_BOTTOM (w);
 
   /* Clear left and right spacing areas */
   if (spacing)
@@ -1280,9 +1311,9 @@
  ****************************************************************************/
 static int
 mswindows_text_width (struct frame *f, struct face_cachel *cachel,
-		      CONST Emchar *str, Charcount len)
+		      const Emchar *str, Charcount len)
 {
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 0);
   int width_so_far = 0;
   unsigned char *text_storage = (unsigned char *) alloca (2 * len);
   textual_run *runs = alloca_array (textual_run, len);
@@ -1312,7 +1343,7 @@
 			Lisp_Object background_pixmap)
 {
   RECT rect = { x, y, x+width, y+height };
-  HDC hdc = get_frame_dc (f);
+  HDC hdc = get_frame_dc (f, 1);
 
   if (!NILP (background_pixmap))
     {
@@ -1359,8 +1390,8 @@
   CONSOLE_HAS_METHOD (mswindows, output_vertical_divider);
   CONSOLE_HAS_METHOD (mswindows, clear_region);
   CONSOLE_HAS_METHOD (mswindows, clear_frame);
-  CONSOLE_HAS_METHOD (mswindows, output_begin);
-  CONSOLE_HAS_METHOD (mswindows, output_end);
+  CONSOLE_HAS_METHOD (mswindows, frame_output_begin);
+  CONSOLE_HAS_METHOD (mswindows, frame_output_end);
   CONSOLE_HAS_METHOD (mswindows, flash);
   CONSOLE_HAS_METHOD (mswindows, ring_bell);
   CONSOLE_HAS_METHOD (mswindows, bevel_area);
@@ -1368,6 +1399,7 @@
   CONSOLE_HAS_METHOD (mswindows, output_pixmap);
 
   /* redisplay methods - printer */
+  CONSOLE_HAS_METHOD (msprinter, frame_output_end);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height);
@@ -1375,8 +1407,7 @@
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame);
-  CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_begin);
-  CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_end);
+  CONSOLE_INHERITS_METHOD (msprinter, mswindows, frame_output_begin);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string);
   CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap);