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