Mercurial > hg > xemacs-beta
comparison src/redisplay-msw.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | aabb7f5b1c81 |
children | 2f8bb876ab1d |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
24 | 24 |
25 /* Authorship: | 25 /* Authorship: |
26 | 26 |
27 Chuck Thompson | 27 Chuck Thompson |
28 Lots of work done by Ben Wing for Mule | 28 Lots of work done by Ben Wing for Mule |
29 Partially rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. | 29 |
30 */ | 30 Partially rewritten for mswindows by Jonathan Harris, November 1997 |
31 for 21.0. */ | |
31 | 32 |
32 #include <config.h> | 33 #include <config.h> |
33 #include "lisp.h" | 34 #include "lisp.h" |
34 | 35 |
35 #include "console-msw.h" | 36 #include "console-msw.h" |
39 #include "debug.h" | 40 #include "debug.h" |
40 #include "events.h" | 41 #include "events.h" |
41 #include "faces.h" | 42 #include "faces.h" |
42 #include "frame.h" | 43 #include "frame.h" |
43 #include "glyphs-msw.h" | 44 #include "glyphs-msw.h" |
45 #include "gutter.h" | |
44 #include "redisplay.h" | 46 #include "redisplay.h" |
45 #include "sysdep.h" | 47 #include "sysdep.h" |
46 #include "window.h" | 48 #include "window.h" |
47 | 49 |
48 #include "windows.h" | |
49 #ifdef MULE | 50 #ifdef MULE |
50 #include "mule-ccl.h" | 51 #include "mule-ccl.h" |
51 #include "mule-charset.h" | 52 #include "mule-charset.h" |
52 #endif | 53 #endif |
53 | 54 |
54 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 | 55 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 |
55 | 56 |
56 /* | 57 /* |
57 * Random forward declarations | 58 * Random forward declarations |
58 */ | 59 */ |
59 static void mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, | 60 static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
60 Lisp_Object bg, Lisp_Object bg_pmap); | 61 Lisp_Object bg_pmap); |
62 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, | |
63 int under, int strike); | |
61 static void mswindows_output_vertical_divider (struct window *w, int clear); | 64 static void mswindows_output_vertical_divider (struct window *w, int clear); |
62 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, | 65 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, |
63 int y, int width, int height); | 66 int y, int width, int height); |
64 static void mswindows_output_dibitmap (struct frame *f, | 67 static void mswindows_output_dibitmap (struct frame *f, |
65 struct Lisp_Image_Instance *p, | 68 Lisp_Image_Instance *p, |
66 int x, int y, | 69 struct display_box* db, |
67 int clip_x, int clip_y, | 70 struct display_glyph_area* dga); |
68 int clip_width, int clip_height, | |
69 int width, int height, | |
70 int pixmap_offset, | |
71 int offset_bitmap); | |
72 static void mswindows_output_pixmap (struct window *w, struct display_line *dl, | |
73 Lisp_Object image_instance, int xpos, | |
74 int xoffset, int start_pixpos, int width, | |
75 face_index findex, int cursor_start, | |
76 int cursor_width, int cursor_height, | |
77 int offset_bitmap); | |
78 | 71 |
79 typedef struct textual_run | 72 typedef struct textual_run |
80 { | 73 { |
81 Lisp_Object charset; | 74 Lisp_Object charset; |
82 unsigned char *ptr; | 75 unsigned char *ptr; |
97 Returns the number of runs actually used. */ | 90 Returns the number of runs actually used. */ |
98 | 91 |
99 static int | 92 static int |
100 separate_textual_runs (unsigned char *text_storage, | 93 separate_textual_runs (unsigned char *text_storage, |
101 textual_run *run_storage, | 94 textual_run *run_storage, |
102 CONST Emchar *str, Charcount len) | 95 const Emchar *str, Charcount len) |
103 { | 96 { |
104 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a | 97 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a |
105 possible valid charset when | 98 possible valid charset when |
106 MULE is not defined */ | 99 MULE is not defined */ |
107 int runs_so_far = 0; | 100 int runs_so_far = 0; |
163 { | 156 { |
164 char_converter.reg[0] = XCHARSET_ID (charset); | 157 char_converter.reg[0] = XCHARSET_ID (charset); |
165 char_converter.reg[1] = byte1; | 158 char_converter.reg[1] = byte1; |
166 char_converter.reg[2] = byte2; | 159 char_converter.reg[2] = byte2; |
167 char_converter.ic = 0; /* start at beginning each time */ | 160 char_converter.ic = 0; /* start at beginning each time */ |
168 ccl_driver (&char_converter, 0, 0, 0, 0); | 161 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); |
169 byte1 = char_converter.reg[1]; | 162 byte1 = char_converter.reg[1]; |
170 byte2 = char_converter.reg[2]; | 163 byte2 = char_converter.reg[2]; |
171 } | 164 } |
172 #endif | 165 #endif |
173 *text_storage++ = (unsigned char) byte1; | 166 *text_storage++ = (unsigned char) byte1; |
190 static int | 183 static int |
191 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, | 184 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, |
192 textual_run *run) | 185 textual_run *run) |
193 { | 186 { |
194 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); | 187 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); |
195 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); | 188 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); |
196 SIZE size; | 189 SIZE size; |
197 | 190 |
198 if (!fi->proportional_p || !hdc) | 191 if (!fi->proportional_p || !hdc) |
199 return (fi->width * run->len); | 192 return (fi->width * run->len); |
200 else | 193 else |
201 { | 194 { |
202 assert(run->dimension == 1); /* #### FIXME! */ | 195 assert(run->dimension == 1); /* #### FIXME! */ |
203 mswindows_update_dc (hdc, font_inst, Qnil, Qnil, Qnil); | 196 mswindows_set_dc_font (hdc, font_inst, |
197 cachel->underline, cachel->strikethru); | |
204 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size); | 198 GetTextExtentPoint32 (hdc, run->ptr, run->len, &size); |
205 return(size.cx); | 199 return(size.cx); |
206 } | 200 } |
207 } | 201 } |
208 | 202 |
203 /* | |
204 * Given F, retrieve device context. F can be a display frame, or | |
205 * a print job. | |
206 */ | |
207 INLINE HDC | |
208 get_frame_dc (struct frame *f) | |
209 { | |
210 if (FRAME_MSWINDOWS_P (f)) | |
211 return FRAME_MSWINDOWS_DC (f); | |
212 else | |
213 { | |
214 if (!FRAME_MSPRINTER_PAGE_STARTED (f)) | |
215 msprinter_start_page (f); | |
216 return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); | |
217 } | |
218 } | |
219 | |
220 /* | |
221 * Given F, retrieve compatible device context. F can be a display | |
222 * frame, or a print job. | |
223 */ | |
224 INLINE HDC | |
225 get_frame_compdc (struct frame *f) | |
226 { | |
227 if (FRAME_MSWINDOWS_P (f)) | |
228 return FRAME_MSWINDOWS_CDC (f); | |
229 else | |
230 return FRAME_MSPRINTER_CDC (f); | |
231 } | |
209 | 232 |
210 /***************************************************************************** | 233 /***************************************************************************** |
211 mswindows_update_dc | 234 mswindows_update_dc |
212 | 235 |
213 Given a number of parameters munge the DC so it has those properties. | 236 Given a number of parameters munge the DC so it has those properties. |
214 ****************************************************************************/ | 237 ****************************************************************************/ |
215 static void | 238 static void |
216 mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg, | 239 mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
217 Lisp_Object bg, Lisp_Object bg_pmap) | 240 Lisp_Object bg_pmap) |
218 { | 241 { |
219 if (!NILP (font)) | |
220 SelectObject(hdc, FONT_INSTANCE_MSWINDOWS_HFONT (XFONT_INSTANCE (font))); | |
221 | |
222 | |
223 if (!NILP (fg)) | 242 if (!NILP (fg)) |
224 { | 243 { |
225 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR | 244 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR |
226 (XCOLOR_INSTANCE (fg))); | 245 (XCOLOR_INSTANCE (fg))); |
227 } | 246 } |
247 | |
228 if (!NILP (bg)) | 248 if (!NILP (bg)) |
229 { | 249 { |
230 SetBkMode (hdc, OPAQUE); | 250 SetBkMode (hdc, OPAQUE); |
231 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); | 251 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); |
232 } | 252 } |
234 { | 254 { |
235 SetBkMode (hdc, TRANSPARENT); | 255 SetBkMode (hdc, TRANSPARENT); |
236 } | 256 } |
237 } | 257 } |
238 | 258 |
239 | 259 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, |
240 /***************************************************************************** | 260 int under, int strike) |
241 mswindows_apply_face_effects | 261 { |
242 | 262 SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font), |
243 Draw underline and strikeout as if this was X. | 263 under, strike)); |
244 #### On mswindows this really should be done as part of drawing the font. | 264 } |
245 The line width used is chosen arbitrarily from the font height. | |
246 ****************************************************************************/ | |
247 static void | |
248 mswindows_apply_face_effects (HDC hdc, struct display_line *dl, int xpos, | |
249 int width, struct Lisp_Font_Instance *fi, | |
250 struct face_cachel *cachel, | |
251 struct face_cachel *color_cachel) | |
252 { | |
253 int yclip; | |
254 HBRUSH brush, oldbrush; | |
255 RECT rect; | |
256 | |
257 brush = CreateSolidBrush (COLOR_INSTANCE_MSWINDOWS_COLOR ( | |
258 XCOLOR_INSTANCE (color_cachel->foreground))); | |
259 if (brush) | |
260 { | |
261 yclip = dl->ypos + dl->descent - dl->clip; | |
262 rect.left = xpos; | |
263 rect.right = xpos + width; | |
264 oldbrush = SelectObject (hdc, brush); | |
265 | |
266 if (cachel->underline) | |
267 { | |
268 rect.top = dl->ypos + dl->descent/2; | |
269 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1); | |
270 if (rect.bottom <= yclip) | |
271 FillRect (hdc, &rect, brush); | |
272 } | |
273 if (cachel->strikethru) | |
274 { | |
275 rect.top = dl->ypos + dl->descent - (dl->ascent + dl->descent)/2; | |
276 rect.bottom = rect.top + (fi->height >= 0x20 ? 2 : 1); | |
277 if (rect.bottom <= yclip) | |
278 FillRect (hdc, &rect, brush); | |
279 } | |
280 | |
281 SelectObject (hdc, oldbrush); | |
282 DeleteObject (brush); | |
283 } | |
284 } | |
285 | |
286 | 265 |
287 /***************************************************************************** | 266 /***************************************************************************** |
288 mswindows_output_hline | 267 mswindows_output_hline |
289 | 268 |
290 Output a horizontal line in the foreground of its face. | 269 Output a horizontal line in the foreground of its face. |
300 | 279 |
301 Output a blank by clearing the area it covers in the background color | 280 Output a blank by clearing the area it covers in the background color |
302 of its face. | 281 of its face. |
303 ****************************************************************************/ | 282 ****************************************************************************/ |
304 static void | 283 static void |
305 mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos) | 284 mswindows_output_blank (struct window *w, struct display_line *dl, |
285 struct rune *rb, int start_pixpos) | |
306 { | 286 { |
307 struct frame *f = XFRAME (w->frame); | 287 struct frame *f = XFRAME (w->frame); |
308 RECT rect = { rb->xpos, dl->ypos-dl->ascent, | 288 HDC hdc = get_frame_dc (f); |
309 rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; | 289 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), |
290 rb->xpos+rb->width, | |
291 DISPLAY_LINE_YEND (dl) }; | |
310 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); | 292 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); |
311 | 293 |
312 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); | 294 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); |
295 | |
296 /* Unmap all subwindows in the area we are going to blank. */ | |
297 redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl), | |
298 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
313 | 299 |
314 if (!IMAGE_INSTANCEP (bg_pmap) | 300 if (!IMAGE_INSTANCEP (bg_pmap) |
315 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | 301 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) |
316 bg_pmap = Qnil; | 302 bg_pmap = Qnil; |
317 | 303 |
318 if (!NILP(bg_pmap)) | 304 if (!NILP(bg_pmap)) |
319 { | 305 { |
306 struct display_box db; | |
307 struct display_glyph_area dga; | |
308 redisplay_calculate_display_boxes (dl, rb->xpos, | |
309 /*rb->object.dglyph.xoffset*/ 0, | |
310 start_pixpos, rb->width, | |
311 &db, &dga); | |
320 /* blank the background in the appropriate color */ | 312 /* blank the background in the appropriate color */ |
321 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, | 313 mswindows_update_dc (hdc, cachel->foreground, |
322 cachel->background, Qnil); | 314 cachel->background, Qnil); |
323 | 315 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, |
324 mswindows_output_pixmap (w, dl, bg_pmap, | |
325 rb->xpos, 0 /*rb->object.dglyph.xoffset*/, | |
326 start_pixpos, rb->width, rb->findex, | |
327 0, 0, 0, TRUE); | 316 0, 0, 0, TRUE); |
328 } | 317 } |
329 else | 318 else |
330 { | 319 { |
331 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, | 320 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); |
332 cachel->background, Qnil); | 321 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
333 | |
334 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | |
335 &rect, NULL, 0, NULL); | |
336 } | 322 } |
337 } | 323 } |
338 | 324 |
339 | 325 |
340 /***************************************************************************** | 326 /***************************************************************************** |
350 struct frame *f = XFRAME (w->frame); | 336 struct frame *f = XFRAME (w->frame); |
351 struct device *d = XDEVICE (f->device); | 337 struct device *d = XDEVICE (f->device); |
352 struct face_cachel *cachel=0; | 338 struct face_cachel *cachel=0; |
353 Lisp_Object font = Qnil; | 339 Lisp_Object font = Qnil; |
354 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 340 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
355 HDC hdc = FRAME_MSWINDOWS_DC (f); | 341 HDC hdc = get_frame_dc (f); |
356 unsigned int face_index=0; | 342 unsigned int local_face_index=0; |
357 char *p_char = NULL; | 343 char *p_char = NULL; |
358 int n_char = 0; | 344 int n_char = 0; |
359 RECT rect = { xpos, | 345 RECT rect = { xpos, |
360 dl->ypos - dl->ascent, | 346 DISPLAY_LINE_YPOS (dl), |
361 xpos + width, | 347 xpos + width, |
362 dl->ypos + dl->descent - dl->clip}; | 348 DISPLAY_LINE_YEND (dl) }; |
363 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, | 349 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, |
364 WINDOW_BUFFER (w)); | 350 WINDOW_BUFFER (w)); |
365 int bar_p = image_p || !NILP (bar); | 351 int bar_p = image_p || !NILP (bar); |
366 int cursor_p = !NILP (w->text_cursor_visible_p); | 352 int cursor_p = !NILP (w->text_cursor_visible_p); |
367 int real_char_p = ch != 0; | 353 int real_char_p = ch != 0; |
368 | 354 |
355 /* Unmap all subwindows in the area we are going to blank. */ | |
356 redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), | |
357 width, DISPLAY_LINE_HEIGHT (dl)); | |
358 | |
369 if (real_char_p) | 359 if (real_char_p) |
370 { | 360 { |
371 /* Use the font from the underlying character */ | 361 /* Use the font from the underlying character */ |
372 cachel = WINDOW_FACE_CACHEL (w, findex); | 362 cachel = WINDOW_FACE_CACHEL (w, findex); |
373 | 363 |
386 struct face_cachel *color_cachel; | 376 struct face_cachel *color_cachel; |
387 | 377 |
388 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar | 378 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar |
389 or when we need to erase the cursor. Output nothing at eol if bar | 379 or when we need to erase the cursor. Output nothing at eol if bar |
390 cursor */ | 380 cursor */ |
391 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); | 381 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
392 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? | 382 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? |
393 findex : face_index)); | 383 findex : local_face_index)); |
394 mswindows_update_dc (hdc, font, color_cachel->foreground, | 384 mswindows_update_dc (hdc, color_cachel->foreground, |
395 color_cachel->background, Qnil); | 385 color_cachel->background, Qnil); |
386 if (real_char_p) | |
387 mswindows_set_dc_font (hdc, font, | |
388 cachel->underline, cachel->strikethru); | |
389 | |
396 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL); | 390 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL); |
397 if (real_char_p && (cachel->underline || cachel->strikethru)) | |
398 mswindows_apply_face_effects (hdc, dl, xpos, width, | |
399 XFONT_INSTANCE (font), | |
400 cachel, color_cachel); | |
401 } | 391 } |
402 | 392 |
403 if (!cursor_p) | 393 if (!cursor_p) |
404 return; | 394 return; |
405 | 395 |
406 if (focus && bar_p) | 396 if (focus && bar_p) |
407 { | 397 { |
408 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); | 398 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); |
409 face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); | 399 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
410 cachel = WINDOW_FACE_CACHEL (w, face_index); | 400 cachel = WINDOW_FACE_CACHEL (w, local_face_index); |
411 mswindows_update_dc (hdc, Qnil, Qnil, cachel->background, Qnil); | 401 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); |
412 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); | 402 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); |
413 } | 403 } |
414 else if (!focus) | 404 else if (!focus) |
415 { | 405 { |
416 /* Now have real character drawn in its own color. We deflate | 406 /* Now have real character drawn in its own color. We deflate |
422 { | 412 { |
423 p_char = (char*) &ch; | 413 p_char = (char*) &ch; |
424 n_char = 1; | 414 n_char = 1; |
425 } | 415 } |
426 | 416 |
427 face_index = get_builtin_face_cache_index (w, Vdefault_face); | 417 local_face_index = get_builtin_face_cache_index (w, Vdefault_face); |
428 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : face_index)); | 418 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index)); |
429 mswindows_update_dc (hdc, Qnil, cachel->foreground, | 419 mswindows_update_dc (hdc, |
430 cachel->background, Qnil); | 420 cachel->foreground, cachel->background, Qnil); |
431 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, | 421 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, |
432 &rect, p_char, n_char, NULL); | 422 &rect, p_char, n_char, NULL); |
433 if (cachel->underline || cachel->strikethru) | |
434 mswindows_apply_face_effects (hdc, dl, xpos+1, width-2, | |
435 XFONT_INSTANCE (font), | |
436 cachel, cachel); | |
437 } | 423 } |
438 } | 424 } |
439 | 425 |
440 | 426 |
441 /***************************************************************************** | 427 /***************************************************************************** |
460 CLIP_START Clip everything left of this X position. | 446 CLIP_START Clip everything left of this X position. |
461 WIDTH Clip everything right of XPOS + WIDTH. | 447 WIDTH Clip everything right of XPOS + WIDTH. |
462 FINDEX Index for the face cache element describing how to display | 448 FINDEX Index for the face cache element describing how to display |
463 the text. | 449 the text. |
464 ****************************************************************************/ | 450 ****************************************************************************/ |
465 void | 451 static void |
466 mswindows_output_string (struct window *w, struct display_line *dl, | 452 mswindows_output_string (struct window *w, struct display_line *dl, |
467 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, | 453 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, |
468 int width, face_index findex) | 454 int width, face_index findex, |
455 int cursor, int cursor_start, int cursor_width, | |
456 int cursor_height) | |
469 { | 457 { |
470 struct frame *f = XFRAME (w->frame); | 458 struct frame *f = XFRAME (w->frame); |
471 /* struct device *d = XDEVICE (f->device);*/ | 459 /* struct device *d = XDEVICE (f->device);*/ |
472 Lisp_Object window; | 460 Lisp_Object window; |
473 HDC hdc = FRAME_MSWINDOWS_DC (f); | 461 HDC hdc = get_frame_dc (f); |
474 int clip_end; | 462 int clip_end; |
475 Lisp_Object bg_pmap; | 463 Lisp_Object bg_pmap; |
476 int len = Dynarr_length (buf); | 464 int len = Dynarr_length (buf); |
477 unsigned char *text_storage = (unsigned char *) alloca (2 * len); | 465 unsigned char *text_storage = (unsigned char *) alloca (2 * len); |
478 textual_run *runs = alloca_array (textual_run, len); | 466 textual_run *runs = alloca_array (textual_run, len); |
502 xpos -= xoffset; | 490 xpos -= xoffset; |
503 | 491 |
504 /* sort out the destination rectangle */ | 492 /* sort out the destination rectangle */ |
505 height = DISPLAY_LINE_HEIGHT (dl); | 493 height = DISPLAY_LINE_HEIGHT (dl); |
506 rect.left = clip_start; | 494 rect.left = clip_start; |
507 rect.top = dl->ypos - dl->ascent; | 495 rect.top = DISPLAY_LINE_YPOS (dl); |
508 rect.right = clip_end; | 496 rect.right = clip_end; |
509 rect.bottom = height + dl->ypos - dl->ascent; | 497 rect.bottom = rect.top + height; |
498 | |
499 /* make sure the area we are about to display is subwindow free. */ | |
500 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
501 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
510 | 502 |
511 /* output the background pixmap if there is one */ | 503 /* output the background pixmap if there is one */ |
512 bg_pmap = cachel->background_pixmap; | 504 bg_pmap = cachel->background_pixmap; |
513 if (!IMAGE_INSTANCEP (bg_pmap) | 505 if (!IMAGE_INSTANCEP (bg_pmap) |
514 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | 506 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) |
515 bg_pmap = Qnil; | 507 bg_pmap = Qnil; |
516 | 508 |
517 if (!NILP(bg_pmap)) | 509 if (!NILP(bg_pmap)) |
518 { | 510 { |
511 struct display_box db; | |
512 struct display_glyph_area dga; | |
513 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, | |
514 clip_start, width, &db, &dga); | |
519 /* blank the background in the appropriate color */ | 515 /* blank the background in the appropriate color */ |
520 mswindows_update_dc (hdc, Qnil, cachel->foreground, | 516 mswindows_update_dc (hdc, |
521 cachel->background, Qnil); | 517 cachel->foreground, cachel->background, Qnil); |
522 | 518 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, |
523 mswindows_output_pixmap (w, dl, bg_pmap, | |
524 xpos, xoffset, | |
525 clip_start, width, findex, | |
526 0, 0, 0, TRUE); | 519 0, 0, 0, TRUE); |
527 /* output pixmap calls this so we have to recall to get correct | 520 /* output pixmap calls this so we have to recall to get correct |
528 references */ | 521 references */ |
529 cachel = WINDOW_FACE_CACHEL (w, findex); | 522 cachel = WINDOW_FACE_CACHEL (w, findex); |
530 } | 523 } |
533 Dynarr_length (buf)); | 526 Dynarr_length (buf)); |
534 | 527 |
535 for (i = 0; i < nruns; i++) | 528 for (i = 0; i < nruns; i++) |
536 { | 529 { |
537 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | 530 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); |
538 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); | 531 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |
539 int this_width; | 532 int this_width; |
540 | 533 |
541 if (EQ (font, Vthe_null_font_instance)) | 534 if (EQ (font, Vthe_null_font_instance)) |
542 continue; | 535 continue; |
543 | 536 |
544 mswindows_update_dc (hdc, font, cachel->foreground, | 537 mswindows_update_dc (hdc, cachel->foreground, |
545 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); | 538 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); |
539 mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru); | |
546 | 540 |
547 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); | 541 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); |
548 | 542 |
549 /* cope with fonts taller than lines */ | 543 /* cope with fonts taller than lines */ |
550 if ((int) fi->height < (int) (height + dl->clip)) | 544 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) |
551 { | 545 { |
552 int clear_start = max (xpos, clip_start); | 546 int clear_start = max (xpos, clip_start); |
553 int clear_end = min (xpos + this_width, clip_end); | 547 int clear_end = min (xpos + this_width, clip_end); |
554 | 548 |
555 { | 549 { |
556 redisplay_clear_region (window, findex, clear_start, | 550 redisplay_clear_region (window, findex, clear_start, |
557 dl->ypos - dl->ascent, | 551 DISPLAY_LINE_YPOS (dl), |
558 clear_end - clear_start, | 552 clear_end - clear_start, |
559 height); | 553 height); |
560 /* output pixmap calls this so we have to recall to get correct | 554 /* output pixmap calls this so we have to recall to get correct |
561 references */ | 555 references */ |
562 cachel = WINDOW_FACE_CACHEL (w, findex); | 556 cachel = WINDOW_FACE_CACHEL (w, findex); |
566 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */ | 560 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */ |
567 ExtTextOut (hdc, xpos, dl->ypos, | 561 ExtTextOut (hdc, xpos, dl->ypos, |
568 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, | 562 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, |
569 &rect, (char *) runs[i].ptr, runs[i].len, NULL); | 563 &rect, (char *) runs[i].ptr, runs[i].len, NULL); |
570 | 564 |
571 /* #### X does underline/strikethrough here so we do the same. | |
572 On mswindows, underline/strikethrough really belongs to the font */ | |
573 if (cachel->underline || cachel->strikethru) | |
574 mswindows_apply_face_effects (hdc, dl, xpos, this_width, fi, | |
575 cachel, cachel); | |
576 xpos += this_width; | 565 xpos += this_width; |
577 } | 566 } |
578 } | 567 } |
579 | 568 |
580 static void | 569 static void |
581 mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, | 570 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, |
582 int x, int y, | 571 struct display_box* db, |
583 int clip_x, int clip_y, | 572 struct display_glyph_area* dga) |
584 int clip_width, int clip_height, | 573 { |
585 int width, int height, int pixmap_offset, | 574 HDC hdc = get_frame_dc (f); |
586 int offset_bitmap) | 575 HDC hcompdc = get_frame_compdc (f); |
587 { | |
588 HDC hdc = FRAME_MSWINDOWS_DC (f); | |
589 HGDIOBJ old=NULL; | 576 HGDIOBJ old=NULL; |
590 COLORREF bgcolor = GetBkColor (hdc); | 577 COLORREF bgcolor = GetBkColor (hdc); |
591 int need_clipping = (clip_x || clip_y); | |
592 int yoffset=0; | |
593 int xoffset=0; | |
594 | |
595 /* do we need to offset the pixmap vertically? this is necessary | |
596 for background pixmaps. */ | |
597 if (offset_bitmap) | |
598 { | |
599 yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
600 xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
601 /* the width is handled by mswindows_output_pixmap_region */ | |
602 } | |
603 | |
604 if (need_clipping) | |
605 { | |
606 } | |
607 | 578 |
608 /* first blt the mask */ | 579 /* first blt the mask */ |
609 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | 580 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) |
610 { | 581 { |
611 RGBQUAD col; | 582 RGBQUAD col; |
612 col.rgbBlue = GetBValue (bgcolor); | 583 col.rgbBlue = GetBValue (bgcolor); |
613 col.rgbRed = GetRValue (bgcolor); | 584 col.rgbRed = GetRValue (bgcolor); |
614 col.rgbGreen = GetGValue (bgcolor); | 585 col.rgbGreen = GetGValue (bgcolor); |
615 col.rgbReserved = 0; | 586 col.rgbReserved = 0; |
616 | 587 |
617 old = SelectObject (FRAME_MSWINDOWS_CDC (f), | 588 old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p)); |
618 IMAGE_INSTANCE_MSWINDOWS_MASK (p)); | |
619 | 589 |
620 SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); | 590 SetDIBColorTable (hcompdc, 1, 1, &col); |
621 | 591 |
622 BitBlt (hdc, | 592 BitBlt (hdc, |
623 x,y, | 593 db->xpos, db->ypos, |
624 width, height, | 594 dga->width, dga->height, |
625 FRAME_MSWINDOWS_CDC (f), | 595 hcompdc, |
626 xoffset,yoffset, | 596 dga->xoffset, dga->yoffset, |
627 SRCCOPY); | 597 SRCCOPY); |
628 | 598 |
629 SelectObject (FRAME_MSWINDOWS_CDC (f), old); | 599 SelectObject (hcompdc, old); |
630 } | 600 } |
631 | 601 |
632 /* now blt the bitmap itself. */ | 602 /* Now blt the bitmap itself, or one of its slices. */ |
633 old = SelectObject (FRAME_MSWINDOWS_CDC (f), | 603 old = SelectObject (hcompdc, |
634 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); | 604 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE |
605 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); | |
635 | 606 |
636 BitBlt (hdc, | 607 BitBlt (hdc, |
637 x,y, | 608 db->xpos, db->ypos, |
638 width, height, | 609 dga->width, dga->height, |
639 FRAME_MSWINDOWS_CDC (f), | 610 hcompdc, |
640 xoffset, yoffset, | 611 dga->xoffset, dga->yoffset, |
641 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); | 612 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); |
642 | 613 |
643 SelectObject (FRAME_MSWINDOWS_CDC (f),old); | 614 SelectObject (hcompdc, old); |
644 | 615 } |
645 if (need_clipping) | 616 |
646 { | 617 /* X gc's have this nice property that setting the bg pixmap will |
647 } | |
648 } | |
649 | |
650 /* | |
651 * X gc's have this nice property that setting the bg pixmap will | |
652 * output it offset relative to the window. Windows doesn't have this | 618 * output it offset relative to the window. Windows doesn't have this |
653 * feature so we have to emulate this by outputting multiple pixmaps | 619 * feature so we have to emulate this by outputting multiple pixmaps. |
654 */ | 620 * This is only used for background pixmaps. Normal pixmaps are |
621 * outputted once and are scrollable */ | |
655 static void | 622 static void |
656 mswindows_output_dibitmap_region (struct frame *f, | 623 mswindows_output_dibitmap_region (struct frame *f, |
657 struct Lisp_Image_Instance *p, | 624 Lisp_Image_Instance *p, |
658 int x, int y, | 625 struct display_box *db, |
659 int clip_x, int clip_y, | 626 struct display_glyph_area *dga) |
660 int clip_width, int clip_height, | 627 { |
661 int width, int height, int pixmap_offset, | 628 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; |
662 int offset_bitmap) | 629 struct display_glyph_area xdga |
663 { | 630 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
664 int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 631 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; |
665 int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
666 int pxoffset = 0, pyoffset = 0; | 632 int pxoffset = 0, pyoffset = 0; |
633 | |
634 if (dga) | |
635 { | |
636 xdga.width = dga->width; | |
637 xdga.height = dga->height; | |
638 } | |
639 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) | |
640 return; | |
667 | 641 |
668 /* when doing a bg pixmap do a partial pixmap first so that we | 642 /* when doing a bg pixmap do a partial pixmap first so that we |
669 blt whole pixmaps thereafter */ | 643 blt whole pixmaps thereafter */ |
670 | 644 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - |
671 if (offset_bitmap) | 645 db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); |
672 { | 646 |
673 pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - | 647 while (xdga.height > 0) |
674 y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | 648 { |
675 } | 649 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), |
676 | 650 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - |
677 while (pheight > 0) | 651 db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); |
678 { | 652 pxoffset = 0; |
679 if (offset_bitmap) | 653 while (xdga.width > 0) |
680 { | 654 { |
681 pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), | 655 xdb.xpos = db->xpos + pxoffset; |
682 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - | 656 xdb.ypos = db->ypos + pyoffset; |
683 x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 657 /* do we need to offset the pixmap vertically? this is necessary |
684 pxoffset = 0; | 658 for background pixmaps. */ |
659 xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
660 xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
661 /* the width is handled by mswindows_output_pixmap_region */ | |
662 mswindows_output_dibitmap (f, p, &xdb, &xdga); | |
663 pxoffset += xdga.width; | |
664 xdga.width = min ((db->width - pxoffset), | |
665 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
685 } | 666 } |
686 while (pwidth > 0) | 667 pyoffset += xdga.height; |
687 { | 668 xdga.height = min ((db->height - pyoffset), |
688 mswindows_output_dibitmap (f, p, | 669 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); |
689 x + pxoffset, y + pyoffset, | 670 } |
690 clip_x, clip_y, | 671 } |
691 clip_width, clip_height, | 672 |
692 pwidth, pheight, pixmap_offset, | 673 /* Output a pixmap at the desired location. |
693 offset_bitmap); | 674 DB normalized display_box. |
694 pxoffset += pwidth; | 675 DGA normalized display_glyph_area. */ |
695 pwidth = min ((width-pxoffset), | 676 static void |
696 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 677 mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, |
697 } | 678 struct display_box *db, struct display_glyph_area *dga, |
698 pyoffset += pheight; | 679 face_index findex, int cursor_start, int cursor_width, |
699 pheight = min ((height-pyoffset), | 680 int cursor_height, int bg_pixmap) |
700 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
701 } | |
702 } | |
703 | |
704 static void | |
705 mswindows_output_pixmap (struct window *w, struct display_line *dl, | |
706 Lisp_Object image_instance, int xpos, int xoffset, | |
707 int start_pixpos, int width, face_index findex, | |
708 int cursor_start, int cursor_width, int cursor_height, | |
709 int offset_bitmap) | |
710 { | 681 { |
711 struct frame *f = XFRAME (w->frame); | 682 struct frame *f = XFRAME (w->frame); |
712 HDC hdc = FRAME_MSWINDOWS_DC (f); | 683 HDC hdc = get_frame_dc (f); |
713 | 684 |
714 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 685 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
715 Lisp_Object window; | 686 Lisp_Object window; |
716 | 687 |
717 int lheight = DISPLAY_LINE_HEIGHT (dl); | |
718 int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight : | |
719 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
720 int clip_x, clip_y, clip_width, clip_height; | |
721 | |
722 /* The pixmap_offset is used to center the pixmap on lines which are | |
723 shorter than it is. This results in odd effects when scrolling | |
724 pixmaps off of the bottom. Let's try not using it. */ | |
725 #if 0 | |
726 int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; | |
727 #else | |
728 int pixmap_offset = 0; | |
729 #endif | |
730 | |
731 XSETWINDOW (window, w); | 688 XSETWINDOW (window, w); |
732 | |
733 if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) | |
734 { | |
735 if (start_pixpos > xpos && start_pixpos > xpos + width) | |
736 return; | |
737 | |
738 clip_x = xoffset; | |
739 clip_width = width; | |
740 if (start_pixpos > xpos) | |
741 { | |
742 clip_x += (start_pixpos - xpos); | |
743 clip_width -= (start_pixpos - xpos); | |
744 } | |
745 } | |
746 else | |
747 { | |
748 clip_x = 0; | |
749 clip_width = 0; | |
750 } | |
751 | |
752 /* Place markers for possible future functionality (clipping the top | |
753 half instead of the bottom half; think pixel scrolling). */ | |
754 clip_y = 0; | |
755 clip_height = pheight; | |
756 | |
757 /* Clear the area the pixmap is going into. The pixmap itself will | |
758 always take care of the full width. We don't want to clear where | |
759 it is going to go in order to avoid flicker. So, all we have to | |
760 take care of is any area above or below the pixmap. */ | |
761 /* #### We take a shortcut for now. We know that since we have | |
762 pixmap_offset hardwired to 0 that the pixmap is against the top | |
763 edge so all we have to worry about is below it. */ | |
764 /* #### Unless the pixmap has a mask in which case we have to clear | |
765 the whole damn thing since we can't yet clear just the area not | |
766 included in the mask. */ | |
767 if (((int) (dl->ypos - dl->ascent + pheight) < | |
768 (int) (dl->ypos + dl->descent - dl->clip)) | |
769 || IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | |
770 { | |
771 int clear_x, clear_y, clear_width, clear_height; | |
772 | |
773 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | |
774 { | |
775 clear_y = dl->ypos - dl->ascent; | |
776 clear_height = lheight; | |
777 } | |
778 else | |
779 { | |
780 clear_y = dl->ypos - dl->ascent + pheight; | |
781 clear_height = lheight - pheight; | |
782 } | |
783 | |
784 if (start_pixpos >= 0 && start_pixpos > xpos) | |
785 { | |
786 clear_x = start_pixpos; | |
787 clear_width = xpos + width - start_pixpos; | |
788 } | |
789 else | |
790 { | |
791 clear_x = xpos; | |
792 clear_width = width; | |
793 } | |
794 | |
795 if (!offset_bitmap) /* i.e. not a bg pixmap */ | |
796 redisplay_clear_region (window, findex, clear_x, clear_y, | |
797 clear_width, clear_height); | |
798 } | |
799 | 689 |
800 /* Output the pixmap. Have to do this as many times as is required | 690 /* Output the pixmap. Have to do this as many times as is required |
801 to fill the given area */ | 691 to fill the given area */ |
802 mswindows_update_dc (hdc, Qnil, | 692 mswindows_update_dc (hdc, |
803 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), | 693 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), |
804 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); | 694 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); |
805 | 695 |
806 mswindows_output_dibitmap_region (f, p, xpos - xoffset, | 696 if (bg_pixmap) |
807 dl->ypos - dl->ascent, | 697 mswindows_output_dibitmap_region (f, p, db, dga); |
808 clip_x, clip_y, clip_width, clip_height, | 698 else |
809 width + xoffset, pheight, pixmap_offset, | 699 mswindows_output_dibitmap (f, p, db, dga); |
810 offset_bitmap); | |
811 } | 700 } |
812 | 701 |
813 #ifdef HAVE_SCROLLBARS | 702 #ifdef HAVE_SCROLLBARS |
814 /* | 703 /* |
815 * This function paints window's deadbox, a rectangle between window | 704 * This function paints window's deadbox, a rectangle between window |
817 * | 706 * |
818 * Function checks whether deadbox intersects with the rectangle pointed | 707 * Function checks whether deadbox intersects with the rectangle pointed |
819 * to by PRC, and paints only the intersection | 708 * to by PRC, and paints only the intersection |
820 */ | 709 */ |
821 static void | 710 static void |
822 mswindows_redisplay_deadbox_maybe (struct window *w, CONST RECT* prc) | 711 mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc) |
823 { | 712 { |
824 int sbh = window_scrollbar_height (w); | 713 int sbh = window_scrollbar_height (w); |
825 int sbw = window_scrollbar_width (w); | 714 int sbw = window_scrollbar_width (w); |
826 RECT rect_dead, rect_paint; | 715 RECT rect_dead, rect_paint; |
827 if (sbh == 0 || sbw == 0) | 716 if (sbh == 0 || sbw == 0) |
840 rect_dead.bottom = rect_dead.top + sbh; | 729 rect_dead.bottom = rect_dead.top + sbh; |
841 | 730 |
842 if (IntersectRect (&rect_paint, &rect_dead, prc)) | 731 if (IntersectRect (&rect_paint, &rect_dead, prc)) |
843 { | 732 { |
844 struct frame *f = XFRAME (WINDOW_FRAME (w)); | 733 struct frame *f = XFRAME (WINDOW_FRAME (w)); |
845 FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, | 734 FillRect (get_frame_dc (f), &rect_paint, |
846 (HBRUSH) (COLOR_BTNFACE+1)); | 735 (HBRUSH) (COLOR_BTNFACE+1)); |
847 } | 736 } |
848 } | 737 } |
849 | 738 |
850 #endif /* HAVE_SCROLLBARS */ | 739 #endif /* HAVE_SCROLLBARS */ |
897 } | 786 } |
898 | 787 |
899 for (line = 0; line < Dynarr_length (cdla); line++) | 788 for (line = 0; line < Dynarr_length (cdla); line++) |
900 { | 789 { |
901 struct display_line *cdl = Dynarr_atp (cdla, line); | 790 struct display_line *cdl = Dynarr_atp (cdla, line); |
902 int top_y = cdl->ypos - cdl->ascent; | 791 |
903 int bottom_y = cdl->ypos + cdl->descent; | 792 if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) |
904 | 793 >= rect_draw.top) |
905 if (bottom_y >= rect_draw.top) | |
906 { | 794 { |
907 if (top_y > rect_draw.bottom) | 795 if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) |
908 { | 796 { |
909 if (line == 0) | 797 if (line == 0) |
910 continue; | 798 continue; |
911 else | 799 else |
912 break; | 800 break; |
963 /* #### We would rather put these off as well but there is currently | 851 /* #### We would rather put these off as well but there is currently |
964 no combination of flags which will force an unchanged toolbar to | 852 no combination of flags which will force an unchanged toolbar to |
965 redraw anyhow. */ | 853 redraw anyhow. */ |
966 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); | 854 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); |
967 #endif | 855 #endif |
856 redraw_exposed_gutters (f, x, y, width, height); | |
968 | 857 |
969 if (!f->window_face_cache_reset) | 858 if (!f->window_face_cache_reset) |
970 { | 859 { |
971 mswindows_redraw_exposed_windows (f->root_window, x, y, width, height); | 860 mswindows_redraw_exposed_windows (f->root_window, x, y, width, height); |
972 GdiFlush(); | 861 GdiFlush(); |
975 MARK_FRAME_CHANGED (f); | 864 MARK_FRAME_CHANGED (f); |
976 } | 865 } |
977 | 866 |
978 | 867 |
979 /***************************************************************************** | 868 /***************************************************************************** |
980 mswindows_bevel_modeline | 869 mswindows_bevel_area |
981 | 870 |
982 Draw a 3d border around the modeline on window W. | 871 Draw a 3d border around the specified area on window W. |
983 ****************************************************************************/ | 872 ****************************************************************************/ |
984 static void | 873 static void |
985 mswindows_bevel_modeline (struct window *w, struct display_line *dl) | 874 mswindows_bevel_area (struct window *w, face_index findex, int x, int y, |
875 int width, int height, int thickness, | |
876 int edges, enum edge_style style) | |
986 { | 877 { |
987 struct frame *f = XFRAME (w->frame); | 878 struct frame *f = XFRAME (w->frame); |
988 Lisp_Object color; | |
989 int shadow_width = MODELINE_SHADOW_THICKNESS (w); | |
990 RECT rect = { WINDOW_MODELINE_LEFT (w), | |
991 dl->ypos - dl->ascent - shadow_width, | |
992 WINDOW_MODELINE_RIGHT (w), | |
993 dl->ypos + dl->descent + shadow_width}; | |
994 UINT edge; | 879 UINT edge; |
995 | 880 UINT border = 0; |
996 color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); | 881 |
997 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); | 882 if (style == EDGE_ETCHED_IN) |
998 | 883 edge = EDGE_ETCHED; |
999 if (XINT (w->modeline_shadow_thickness) < 0) | 884 else if (style == EDGE_ETCHED_OUT) |
1000 shadow_width = -shadow_width; | 885 edge = EDGE_BUMP; |
1001 | 886 else if (style == EDGE_BEVEL_IN) |
1002 if (shadow_width < -1) | 887 { |
1003 edge = EDGE_SUNKEN; | 888 if (thickness == 1) |
1004 else if (shadow_width < 0) | 889 edge = BDR_SUNKENINNER; |
1005 edge = BDR_SUNKENINNER; | 890 else |
1006 else if (shadow_width == 1) | 891 edge = EDGE_SUNKEN; |
1007 edge = BDR_RAISEDINNER; | 892 } |
1008 else | 893 else /* EDGE_BEVEL_OUT */ |
1009 edge = EDGE_RAISED; | 894 { |
1010 | 895 if (thickness == 1) |
1011 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT); | 896 edge = BDR_RAISEDINNER; |
897 else | |
898 edge = EDGE_RAISED; | |
899 } | |
900 | |
901 if (edges & EDGE_TOP) | |
902 border |= BF_TOP; | |
903 if (edges & EDGE_LEFT) | |
904 border |= BF_LEFT; | |
905 if (edges & EDGE_BOTTOM) | |
906 border |= BF_BOTTOM; | |
907 if (edges & EDGE_RIGHT) | |
908 border |= BF_RIGHT; | |
909 | |
910 { | |
911 RECT rect = { x, y, x + width, y + height }; | |
912 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | |
913 HDC hdc = get_frame_dc (f); | |
914 | |
915 mswindows_update_dc (hdc, Qnil, color, Qnil); | |
916 DrawEdge (hdc, &rect, edge, border); | |
917 } | |
1012 } | 918 } |
1013 | 919 |
1014 | 920 |
1015 /***************************************************************************** | 921 /***************************************************************************** |
1016 Display methods | 922 Display methods |
1061 | 967 |
1062 static int | 968 static int |
1063 mswindows_flash (struct device *d) | 969 mswindows_flash (struct device *d) |
1064 { | 970 { |
1065 struct frame *f = device_selected_frame (d); | 971 struct frame *f = device_selected_frame (d); |
972 HDC hdc = get_frame_dc (f); | |
1066 RECT rc; | 973 RECT rc; |
1067 | 974 |
1068 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); | 975 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); |
1069 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); | 976 InvertRect (hdc, &rc); |
1070 GdiFlush (); | 977 GdiFlush (); |
1071 Sleep (25); | 978 Sleep (25); |
1072 InvertRect (FRAME_MSWINDOWS_DC (f), &rc); | 979 InvertRect (hdc, &rc); |
1073 | 980 |
1074 return 1; | 981 return 1; |
1075 } | 982 } |
1076 | 983 |
1077 static void | 984 static void |
1108 MULE is not defined */ | 1015 MULE is not defined */ |
1109 XSETWINDOW (window, w); | 1016 XSETWINDOW (window, w); |
1110 rb = Dynarr_atp (rba, start); | 1017 rb = Dynarr_atp (rba, start); |
1111 | 1018 |
1112 if (!rb) | 1019 if (!rb) |
1113 { | |
1114 /* Nothing to do so don't do anything. */ | 1020 /* Nothing to do so don't do anything. */ |
1115 return; | 1021 return; |
1116 } | 1022 |
1117 else | 1023 findex = rb->findex; |
1118 { | 1024 xpos = rb->xpos; |
1119 findex = rb->findex; | 1025 width = 0; |
1120 xpos = rb->xpos; | 1026 if (rb->type == RUNE_CHAR) |
1121 width = 0; | 1027 charset = CHAR_CHARSET (rb->object.chr.ch); |
1122 if (rb->type == RUNE_CHAR) | |
1123 charset = CHAR_CHARSET (rb->object.chr.ch); | |
1124 } | |
1125 | 1028 |
1126 if (end < 0) | 1029 if (end < 0) |
1127 end = Dynarr_length (rba); | 1030 end = Dynarr_length (rba); |
1128 Dynarr_reset (buf); | 1031 Dynarr_reset (buf); |
1129 | 1032 |
1142 else | 1045 else |
1143 { | 1046 { |
1144 if (Dynarr_length (buf)) | 1047 if (Dynarr_length (buf)) |
1145 { | 1048 { |
1146 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, | 1049 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, |
1147 findex); | 1050 findex, 0, 0, 0, 0); |
1148 xpos = rb->xpos; | 1051 xpos = rb->xpos; |
1149 width = 0; | 1052 width = 0; |
1150 } | 1053 } |
1151 Dynarr_reset (buf); | 1054 Dynarr_reset (buf); |
1152 width = 0; | 1055 width = 0; |
1176 elt++; | 1079 elt++; |
1177 } | 1080 } |
1178 else if (rb->object.chr.ch == '\n') | 1081 else if (rb->object.chr.ch == '\n') |
1179 { | 1082 { |
1180 /* Clear in case a cursor was formerly here. */ | 1083 /* Clear in case a cursor was formerly here. */ |
1181 int height = DISPLAY_LINE_HEIGHT (dl); | 1084 redisplay_clear_region (window, findex, xpos, |
1182 | 1085 DISPLAY_LINE_YPOS (dl), |
1183 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, | 1086 rb->width, DISPLAY_LINE_HEIGHT (dl)); |
1184 rb->width, height); | |
1185 elt++; | 1087 elt++; |
1186 } | 1088 } |
1187 } | 1089 } |
1188 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | 1090 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) |
1189 { | 1091 { |
1215 } | 1117 } |
1216 } | 1118 } |
1217 else if (rb->type == RUNE_DGLYPH) | 1119 else if (rb->type == RUNE_DGLYPH) |
1218 { | 1120 { |
1219 Lisp_Object instance; | 1121 Lisp_Object instance; |
1122 struct display_box dbox; | |
1123 struct display_glyph_area dga; | |
1124 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, | |
1125 start_pixpos, rb->width, | |
1126 &dbox, &dga); | |
1220 | 1127 |
1221 XSETWINDOW (window, w); | 1128 XSETWINDOW (window, w); |
1222 instance = glyph_image_instance (rb->object.dglyph.glyph, | 1129 instance = glyph_image_instance (rb->object.dglyph.glyph, |
1223 window, ERROR_ME_NOT, 1); | 1130 window, ERROR_ME_NOT, 1); |
1224 findex = rb->findex; | 1131 findex = rb->findex; |
1239 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1146 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1240 findex, Dynarr_at (buf, 0), 0); | 1147 findex, Dynarr_at (buf, 0), 0); |
1241 else /* #### redisplay-x passes -1 as the width: why ? */ | 1148 else /* #### redisplay-x passes -1 as the width: why ? */ |
1242 mswindows_output_string (w, dl, buf, xpos, | 1149 mswindows_output_string (w, dl, buf, xpos, |
1243 rb->object.dglyph.xoffset, | 1150 rb->object.dglyph.xoffset, |
1244 start_pixpos, rb->width, findex); | 1151 start_pixpos, rb->width, findex, |
1152 0, 0, 0, 0); | |
1245 Dynarr_reset (buf); | 1153 Dynarr_reset (buf); |
1246 } | 1154 } |
1247 break; | 1155 break; |
1248 | 1156 |
1249 case IMAGE_MONO_PIXMAP: | 1157 case IMAGE_MONO_PIXMAP: |
1250 case IMAGE_COLOR_PIXMAP: | 1158 case IMAGE_COLOR_PIXMAP: |
1251 mswindows_output_pixmap (w, dl, instance, xpos, | 1159 redisplay_output_pixmap (w, instance, &dbox, &dga, findex, |
1252 rb->object.dglyph.xoffset, start_pixpos, | 1160 cursor_start, cursor_width, |
1253 rb->width, findex, cursor_start, | 1161 cursor_height, 0); |
1254 cursor_width, cursor_height, 0); | |
1255 if (rb->cursor_type == CURSOR_ON) | 1162 if (rb->cursor_type == CURSOR_ON) |
1256 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1163 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1257 findex, 0, 1); | 1164 findex, 0, 1); |
1258 break; | 1165 break; |
1259 | 1166 |
1260 case IMAGE_POINTER: | 1167 case IMAGE_POINTER: |
1261 abort (); | 1168 abort (); |
1262 | 1169 |
1263 case IMAGE_SUBWINDOW: | 1170 case IMAGE_SUBWINDOW: |
1264 case IMAGE_WIDGET: | 1171 case IMAGE_WIDGET: |
1265 redisplay_output_subwindow (w, dl, instance, xpos, | 1172 redisplay_output_subwindow (w, instance, &dbox, &dga, findex, |
1266 rb->object.dglyph.xoffset, start_pixpos, | 1173 cursor_start, cursor_width, |
1267 rb->width, findex, cursor_start, | 1174 cursor_height); |
1268 cursor_width, cursor_height); | 1175 if (rb->cursor_type == CURSOR_ON) |
1176 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1177 findex, 0, 1); | |
1178 break; | |
1179 | |
1180 case IMAGE_LAYOUT: | |
1181 redisplay_output_layout (w, instance, &dbox, &dga, findex, | |
1182 cursor_start, cursor_width, | |
1183 cursor_height); | |
1269 if (rb->cursor_type == CURSOR_ON) | 1184 if (rb->cursor_type == CURSOR_ON) |
1270 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1185 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1271 findex, 0, 1); | 1186 findex, 0, 1); |
1272 break; | 1187 break; |
1273 | 1188 |
1286 abort (); | 1201 abort (); |
1287 } | 1202 } |
1288 } | 1203 } |
1289 | 1204 |
1290 if (Dynarr_length (buf)) | 1205 if (Dynarr_length (buf)) |
1291 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex); | 1206 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, |
1207 0, 0, 0, 0); | |
1292 | 1208 |
1293 if (dl->modeline | 1209 if (dl->modeline |
1294 && !EQ (Qzero, w->modeline_shadow_thickness) | 1210 && !EQ (Qzero, w->modeline_shadow_thickness) |
1295 && (f->clear | 1211 && (f->clear |
1296 || f->windows_structure_changed | 1212 || f->windows_structure_changed |
1297 || w->shadow_thickness_changed)) | 1213 || w->shadow_thickness_changed)) |
1298 mswindows_bevel_modeline (w, dl); | 1214 bevel_modeline (w, dl); |
1299 | 1215 |
1300 Dynarr_free (buf); | 1216 Dynarr_free (buf); |
1301 } | 1217 } |
1302 | 1218 |
1303 | 1219 |
1308 ****************************************************************************/ | 1224 ****************************************************************************/ |
1309 static void | 1225 static void |
1310 mswindows_output_vertical_divider (struct window *w, int clear_unused) | 1226 mswindows_output_vertical_divider (struct window *w, int clear_unused) |
1311 { | 1227 { |
1312 struct frame *f = XFRAME (w->frame); | 1228 struct frame *f = XFRAME (w->frame); |
1229 HDC hdc = get_frame_dc (f); | |
1313 RECT rect; | 1230 RECT rect; |
1314 int spacing = XINT (w->vertical_divider_spacing); | 1231 int spacing = XINT (w->vertical_divider_spacing); |
1315 int shadow = XINT (w->vertical_divider_shadow_thickness); | 1232 int shadow = XINT (w->vertical_divider_shadow_thickness); |
1316 int abs_shadow = abs (shadow); | 1233 int abs_shadow = abs (shadow); |
1317 int line_width = XINT (w->vertical_divider_line_width); | 1234 int line_width = XINT (w->vertical_divider_line_width); |
1318 int div_left = WINDOW_RIGHT (w) - window_divider_width (w); | 1235 int div_left = WINDOW_RIGHT (w) - window_divider_width (w); |
1236 int y1 = WINDOW_TOP (w) + FRAME_TOP_GUTTER_BOUNDS (f); | |
1237 int y2 = WINDOW_BOTTOM (w) + FRAME_BOTTOM_GUTTER_BOUNDS (f); | |
1319 | 1238 |
1320 /* Clear left and right spacing areas */ | 1239 /* Clear left and right spacing areas */ |
1321 if (spacing) | 1240 if (spacing) |
1322 { | 1241 { |
1323 rect.top = WINDOW_TOP (w); | 1242 rect.top = y1; |
1324 rect.bottom = WINDOW_BOTTOM (w); | 1243 rect.bottom = y2; |
1325 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, | 1244 mswindows_update_dc (hdc, Qnil, |
1326 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); | 1245 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); |
1327 rect.right = WINDOW_RIGHT (w); | 1246 rect.right = WINDOW_RIGHT (w); |
1328 rect.left = rect.right - spacing; | 1247 rect.left = rect.right - spacing; |
1329 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | 1248 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, |
1330 &rect, NULL, 0, NULL); | 1249 &rect, NULL, 0, NULL); |
1331 rect.left = div_left; | 1250 rect.left = div_left; |
1332 rect.right = div_left + spacing; | 1251 rect.right = div_left + spacing; |
1333 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | 1252 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, |
1334 &rect, NULL, 0, NULL); | 1253 &rect, NULL, 0, NULL); |
1335 } | 1254 } |
1336 | 1255 |
1337 /* Clear divider face */ | 1256 /* Clear divider face */ |
1338 rect.top = WINDOW_TOP (w) + abs_shadow; | 1257 rect.top = y1 + abs_shadow; |
1339 rect.bottom = WINDOW_BOTTOM (w) - abs_shadow; | 1258 rect.bottom = y2 - abs_shadow; |
1340 rect.left = div_left + spacing + abs_shadow; | 1259 rect.left = div_left + spacing + abs_shadow; |
1341 rect.right = rect.left + line_width; | 1260 rect.right = rect.left + line_width; |
1342 if (rect.left < rect.right) | 1261 if (rect.left < rect.right) |
1343 { | 1262 { |
1344 face_index div_face | 1263 face_index div_face |
1345 = get_builtin_face_cache_index (w, Vvertical_divider_face); | 1264 = get_builtin_face_cache_index (w, Vvertical_divider_face); |
1346 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, | 1265 mswindows_update_dc (hdc, Qnil, |
1347 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); | 1266 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); |
1348 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | 1267 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
1349 &rect, NULL, 0, NULL); | |
1350 } | 1268 } |
1351 | 1269 |
1352 /* Draw a shadow around the divider */ | 1270 /* Draw a shadow around the divider */ |
1353 if (shadow != 0) | 1271 if (shadow != 0) |
1354 { | 1272 { |
1355 /* #### This will be fixed to support arbitrary thickness */ | 1273 /* #### This will be fixed to support arbitrary thickness */ |
1356 InflateRect (&rect, abs_shadow, abs_shadow); | 1274 InflateRect (&rect, abs_shadow, abs_shadow); |
1357 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, | 1275 DrawEdge (hdc, &rect, |
1358 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); | 1276 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); |
1359 } | 1277 } |
1360 } | 1278 } |
1361 | 1279 |
1362 /**************************************************************************** | 1280 /**************************************************************************** |
1365 Given a string and a face, return the string's length in pixels when | 1283 Given a string and a face, return the string's length in pixels when |
1366 displayed in the font associated with the face. | 1284 displayed in the font associated with the face. |
1367 ****************************************************************************/ | 1285 ****************************************************************************/ |
1368 static int | 1286 static int |
1369 mswindows_text_width (struct frame *f, struct face_cachel *cachel, | 1287 mswindows_text_width (struct frame *f, struct face_cachel *cachel, |
1370 CONST Emchar *str, Charcount len) | 1288 const Emchar *str, Charcount len) |
1371 { | 1289 { |
1290 HDC hdc = get_frame_dc (f); | |
1372 int width_so_far = 0; | 1291 int width_so_far = 0; |
1373 unsigned char *text_storage = (unsigned char *) alloca (2 * len); | 1292 unsigned char *text_storage = (unsigned char *) alloca (2 * len); |
1374 textual_run *runs = alloca_array (textual_run, len); | 1293 textual_run *runs = alloca_array (textual_run, len); |
1375 int nruns; | 1294 int nruns; |
1376 int i; | 1295 int i; |
1377 | 1296 |
1378 nruns = separate_textual_runs (text_storage, runs, str, len); | 1297 nruns = separate_textual_runs (text_storage, runs, str, len); |
1379 | 1298 |
1380 for (i = 0; i < nruns; i++) | 1299 for (i = 0; i < nruns; i++) |
1381 width_so_far += mswindows_text_width_single_run (FRAME_MSWINDOWS_DC (f), | 1300 width_so_far += mswindows_text_width_single_run (hdc, |
1382 cachel, runs + i); | 1301 cachel, runs + i); |
1383 | 1302 |
1384 return width_so_far; | 1303 return width_so_far; |
1385 } | 1304 } |
1386 | 1305 |
1396 face_index findex, int x, int y, | 1315 face_index findex, int x, int y, |
1397 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, | 1316 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, |
1398 Lisp_Object background_pixmap) | 1317 Lisp_Object background_pixmap) |
1399 { | 1318 { |
1400 RECT rect = { x, y, x+width, y+height }; | 1319 RECT rect = { x, y, x+width, y+height }; |
1320 HDC hdc = get_frame_dc (f); | |
1401 | 1321 |
1402 if (!NILP (background_pixmap)) | 1322 if (!NILP (background_pixmap)) |
1403 { | 1323 { |
1404 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), | 1324 struct display_box db = { x, y, width, height }; |
1405 Qnil, fcolor, bcolor, background_pixmap); | 1325 mswindows_update_dc (hdc, |
1406 | 1326 fcolor, bcolor, background_pixmap); |
1407 mswindows_output_dibitmap_region | 1327 mswindows_output_dibitmap_region |
1408 ( f, XIMAGE_INSTANCE (background_pixmap), | 1328 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); |
1409 x, y, 0, 0, 0, 0, width, height, 0, TRUE); | |
1410 } | 1329 } |
1411 else | 1330 else |
1412 { | 1331 { |
1413 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil); | 1332 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); |
1414 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | 1333 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, |
1415 &rect, NULL, 0, NULL); | 1334 &rect, NULL, 0, NULL); |
1416 } | 1335 } |
1417 | 1336 |
1418 #ifdef HAVE_SCROLLBARS | 1337 #ifdef HAVE_SCROLLBARS |
1419 if (WINDOWP (locale)) | 1338 if (WINDOWP (locale)) |
1420 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); | 1339 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); |
1421 #endif | 1340 #endif |
1422 } | 1341 } |
1423 | 1342 |
1424 /***************************************************************************** | |
1425 mswindows_clear_to_window_end | |
1426 | |
1427 Clear the area between ypos1 and ypos2. Each margin area and the | |
1428 text area is handled separately since they may each have their own | |
1429 background color. | |
1430 ****************************************************************************/ | |
1431 static void | |
1432 mswindows_clear_to_window_end (struct window *w, int ypos1, int ypos2) | |
1433 { | |
1434 int height = ypos2 - ypos1; | |
1435 | |
1436 if (height) | |
1437 { | |
1438 struct frame *f = XFRAME (w->frame); | |
1439 Lisp_Object window; | |
1440 int bflag = (window_needs_vertical_divider (w) ? 0 : 1); | |
1441 layout_bounds bounds; | |
1442 | |
1443 bounds = calculate_display_line_boundaries (w, bflag); | |
1444 XSETWINDOW (window, w); | |
1445 | |
1446 if (window_is_leftmost (w)) | |
1447 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f), | |
1448 ypos1, FRAME_BORDER_WIDTH (f), height); | |
1449 | |
1450 if (bounds.left_in - bounds.left_out > 0) | |
1451 redisplay_clear_region (window, | |
1452 get_builtin_face_cache_index (w, Vleft_margin_face), | |
1453 bounds.left_out, ypos1, | |
1454 bounds.left_in - bounds.left_out, height); | |
1455 | |
1456 if (bounds.right_in - bounds.left_in > 0) | |
1457 redisplay_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1, | |
1458 bounds.right_in - bounds.left_in, height); | |
1459 | |
1460 if (bounds.right_out - bounds.right_in > 0) | |
1461 redisplay_clear_region (window, | |
1462 get_builtin_face_cache_index (w, Vright_margin_face), | |
1463 bounds.right_in, ypos1, | |
1464 bounds.right_out - bounds.right_in, height); | |
1465 | |
1466 if (window_is_rightmost (w)) | |
1467 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f), | |
1468 ypos1, FRAME_BORDER_WIDTH (f), height); | |
1469 } | |
1470 | |
1471 } | |
1472 | |
1473 | |
1474 /* XXX Implement me! */ | 1343 /* XXX Implement me! */ |
1475 static void | 1344 static void |
1476 mswindows_clear_frame (struct frame *f) | 1345 mswindows_clear_frame (struct frame *f) |
1477 { | 1346 { |
1478 GdiFlush(); | 1347 GdiFlush(); |
1485 /************************************************************************/ | 1354 /************************************************************************/ |
1486 | 1355 |
1487 void | 1356 void |
1488 console_type_create_redisplay_mswindows (void) | 1357 console_type_create_redisplay_mswindows (void) |
1489 { | 1358 { |
1490 /* redisplay methods */ | 1359 /* redisplay methods - display*/ |
1491 CONSOLE_HAS_METHOD (mswindows, text_width); | 1360 CONSOLE_HAS_METHOD (mswindows, text_width); |
1492 CONSOLE_HAS_METHOD (mswindows, output_display_block); | 1361 CONSOLE_HAS_METHOD (mswindows, output_display_block); |
1493 CONSOLE_HAS_METHOD (mswindows, divider_height); | 1362 CONSOLE_HAS_METHOD (mswindows, divider_height); |
1494 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); | 1363 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); |
1495 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); | 1364 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); |
1496 CONSOLE_HAS_METHOD (mswindows, clear_to_window_end); | |
1497 CONSOLE_HAS_METHOD (mswindows, clear_region); | 1365 CONSOLE_HAS_METHOD (mswindows, clear_region); |
1498 CONSOLE_HAS_METHOD (mswindows, clear_frame); | 1366 CONSOLE_HAS_METHOD (mswindows, clear_frame); |
1499 CONSOLE_HAS_METHOD (mswindows, output_begin); | 1367 CONSOLE_HAS_METHOD (mswindows, output_begin); |
1500 CONSOLE_HAS_METHOD (mswindows, output_end); | 1368 CONSOLE_HAS_METHOD (mswindows, output_end); |
1501 CONSOLE_HAS_METHOD (mswindows, flash); | 1369 CONSOLE_HAS_METHOD (mswindows, flash); |
1502 CONSOLE_HAS_METHOD (mswindows, ring_bell); | 1370 CONSOLE_HAS_METHOD (mswindows, ring_bell); |
1503 } | 1371 CONSOLE_HAS_METHOD (mswindows, bevel_area); |
1372 CONSOLE_HAS_METHOD (mswindows, output_string); | |
1373 CONSOLE_HAS_METHOD (mswindows, output_pixmap); | |
1374 | |
1375 /* redisplay methods - printer */ | |
1376 CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width); | |
1377 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block); | |
1378 CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height); | |
1379 CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width); | |
1380 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider); | |
1381 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region); | |
1382 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame); | |
1383 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_begin); | |
1384 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_end); | |
1385 CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area); | |
1386 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string); | |
1387 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap); | |
1388 } |