Mercurial > hg > xemacs-beta
annotate src/redisplay-msw.c @ 5176:8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
-------------------- ChangeLog entries follow: --------------------
etc/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* dbxrc.in:
Rename objects.c -> fontcolor.c.
lisp/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* dumped-lisp.el (preloaded-file-list):
* font.el (font-tty-find-closest-color):
* fontcolor.el:
* fontcolor.el (ws-object-property-1): Removed.
* fontcolor.el (fontcolor-property-1): New.
* fontcolor.el (font-name):
* fontcolor.el (font-ascent):
* fontcolor.el (font-descent):
* fontcolor.el (font-width):
* fontcolor.el (font-height):
* fontcolor.el (font-proportional-p):
* fontcolor.el (font-properties):
* fontcolor.el (font-truename):
* fontcolor.el (color-name):
* fontcolor.el (color-rgb-components):
* x-faces.el:
Rename objects.el -> fontcolor.el.
lwlib/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* lwlib-colors.h:
objects*.h -> fontcolor*.h.
man/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* internals/internals.texi (A Summary of the Various XEmacs Modules):
* internals/internals.texi (Modules for other Display-Related Lisp Objects):
objects*.[ch] -> fontcolor*.[ch].
nt/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* xemacs.dsp:
* xemacs.mak:
* xemacs.mak (OPT_OBJS):
objects*.[ch] -> fontcolor*.[ch].
src/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* EmacsFrame.c:
* Makefile.in.in (x_objs):
* Makefile.in.in (mswindows_objs):
* Makefile.in.in (tty_objs):
* Makefile.in.in (gtk_objs):
* Makefile.in.in (objs):
* console-tty.h:
* console-x-impl.h:
* console-x-impl.h (struct x_device):
* console-x.h:
* console-xlike-inc.h:
* depend:
* device-gtk.c:
* device-msw.c:
* device-x.c:
* device-x.c (x_init_device):
* device-x.c (x_finish_init_device):
* device.c:
* devslots.h (MARKED_SLOT):
* emacs.c (main_1):
* event-Xt.c:
* event-gtk.c:
* event-msw.c:
* faces.c:
* font-mgr.c:
* fontcolor-gtk-impl.h:
* fontcolor-gtk.c:
* fontcolor-gtk.c (syms_of_fontcolor_gtk):
* fontcolor-gtk.c (console_type_create_fontcolor_gtk):
* fontcolor-gtk.c (vars_of_fontcolor_gtk):
* fontcolor-gtk.h:
* fontcolor-impl.h:
* fontcolor-msw-impl.h:
* fontcolor-msw.c:
* fontcolor-msw.c (syms_of_fontcolor_mswindows):
* fontcolor-msw.c (console_type_create_fontcolor_mswindows):
* fontcolor-msw.c (reinit_vars_of_fontcolor_mswindows):
* fontcolor-msw.c (vars_of_fontcolor_mswindows):
* fontcolor-msw.h:
* fontcolor-msw.h (mswindows_color_to_string):
* fontcolor-tty-impl.h:
* fontcolor-tty.c:
* fontcolor-tty.c (syms_of_fontcolor_tty):
* fontcolor-tty.c (console_type_create_fontcolor_tty):
* fontcolor-tty.c (vars_of_fontcolor_tty):
* fontcolor-tty.h:
* fontcolor-x-impl.h:
* fontcolor-x.c:
* fontcolor-x.c (syms_of_fontcolor_x):
* fontcolor-x.c (console_type_create_fontcolor_x):
* fontcolor-x.c (vars_of_fontcolor_x):
* fontcolor-x.c (Xatoms_of_fontcolor_x):
* fontcolor-x.h:
* fontcolor.c:
* fontcolor.c (syms_of_fontcolor):
* fontcolor.c (specifier_type_create_fontcolor):
* fontcolor.c (reinit_specifier_type_create_fontcolor):
* fontcolor.c (reinit_vars_of_fontcolor):
* fontcolor.c (vars_of_fontcolor):
* fontcolor.h:
* fontcolor.h (set_face_boolean_attached_to):
* frame-gtk.c:
* frame-x.c:
* glyphs-eimage.c:
* glyphs-gtk.c:
* glyphs-msw.c:
* glyphs-widget.c:
* glyphs-x.c:
* glyphs.c:
* gtk-glue.c:
* gtk-glue.c (xemacs_type_register):
* gtk-xemacs.c:
* inline.c:
* intl-win32.c:
* lisp.h:
* lrecord.h:
* mule-charset.c:
* native-gtk-toolbar.c:
* redisplay-msw.c:
* redisplay-tty.c:
* redisplay.c:
* select-x.c:
* select.c:
* symsinit.h:
* toolbar-msw.c:
* toolbar-msw.c (TOOLBAR_ITEM_ID_BITS):
* toolbar-x.c:
* ui-gtk.c:
* window.c:
Rename objects*.[ch] -> fontcolor*.[ch]. Fix up all references to
the old files (e.g. in #include statements, Makefiles,
functions like syms_of_objects_x(), etc.).
tests/ChangeLog addition:
2010-02-22 Ben Wing <ben@xemacs.org>
* reproduce-crashes.el (8):
objects*.[ch] -> fontcolor*.[ch].
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 22 Feb 2010 06:49:30 -0600 |
parents | d4f666cda5e6 |
children | 97eb4942aec8 |
rev | line source |
---|---|
428 | 1 /* mswindows output and frame manipulation routines. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1994 Lucid, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5046 | 5 Copyright (C) 2001, 2002, 2003, 2010 Ben Wing. |
428 | 6 |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* Synched up with: Not in FSF. */ | |
25 | |
771 | 26 /* I think this file is essentially Mule-ized, but I'm not sure! |
27 Could stand a good once-over. Unicode support is trash, of course. */ | |
28 | |
428 | 29 /* Authorship: |
30 | |
31 Chuck Thompson | |
32 Lots of work done by Ben Wing for Mule | |
442 | 33 |
34 Partially rewritten for mswindows by Jonathan Harris, November 1997 | |
35 for 21.0. */ | |
428 | 36 |
37 #include <config.h> | |
38 #include "lisp.h" | |
39 | |
40 #include "buffer.h" | |
800 | 41 #include "charset.h" |
428 | 42 #include "debug.h" |
872 | 43 #include "device-impl.h" |
428 | 44 #include "events.h" |
45 #include "faces.h" | |
872 | 46 #include "frame-impl.h" |
428 | 47 #include "gutter.h" |
48 #include "redisplay.h" | |
49 #include "sysdep.h" | |
872 | 50 #include "window-impl.h" |
800 | 51 |
872 | 52 #include "console-msw-impl.h" |
800 | 53 #include "glyphs-msw.h" |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5046
diff
changeset
|
54 #include "fontcolor-msw-impl.h" |
428 | 55 |
56 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 | |
57 | |
58 /* | |
59 * Random forward declarations | |
60 */ | |
440 | 61 static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
62 Lisp_Object bg_pmap); | |
63 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, | |
64 int under, int strike); | |
428 | 65 static void mswindows_output_vertical_divider (struct window *w, int clear); |
66 static void mswindows_output_dibitmap (struct frame *f, | |
440 | 67 Lisp_Image_Instance *p, |
771 | 68 struct display_box *db, |
69 struct display_glyph_area *dga); | |
428 | 70 |
71 typedef struct textual_run | |
72 { | |
771 | 73 Lisp_Object charset; /* charset of this run */ |
74 WCHAR *ptr; /* pointer to Unicode chars in this run */ | |
75 int nchars; /* number of internal characters in this run */ | |
76 int nwchars; /* number of Unicode chars in this run */ | |
428 | 77 } textual_run; |
78 | |
771 | 79 /* Separate out the text in STR into a series of textual runs of a |
80 particular charset. Returns the number of runs actually used. | |
81 Returns the textual runs (STATICALLY ALLOCATED!) in RUN_STORAGE_PTR. */ | |
428 | 82 |
83 static int | |
771 | 84 separate_textual_runs (textual_run **run_storage_ptr, |
867 | 85 const Ichar *str, Charcount len) |
428 | 86 { |
771 | 87 static WCHAR *ext_storage; |
88 static int ext_storage_size; /* in WCHARS! */ | |
89 static textual_run *run_storage; | |
90 static int run_storage_size; | |
428 | 91 int runs_so_far = 0; |
771 | 92 int runbegin = 0; |
93 int total_nchars = 0; | |
428 | 94 int i; |
771 | 95 Lisp_Object prev_charset; |
428 | 96 |
771 | 97 if (len == 0) |
98 return 0; | |
99 | |
867 | 100 prev_charset = ichar_charset (str[0]); |
428 | 101 |
771 | 102 for (i = 1; i <= len; i++) |
103 { | |
867 | 104 if (i == len || !EQ (ichar_charset (str[i]), prev_charset)) |
428 | 105 { |
771 | 106 int j; |
867 | 107 Ibyte *int_storage = |
108 alloca_ibytes (MAX_ICHAR_LEN * (i - runbegin)); | |
771 | 109 int int_storage_ptr = 0; |
110 Extbyte *alloca_ext_storage; | |
111 int nchars; | |
428 | 112 |
771 | 113 int_storage_ptr = 0; |
114 for (j = runbegin; j < i; j++) | |
115 int_storage_ptr += | |
867 | 116 set_itext_ichar (int_storage + int_storage_ptr, str[j]); |
771 | 117 TO_EXTERNAL_FORMAT (DATA, (int_storage, int_storage_ptr), |
118 ALLOCA, (alloca_ext_storage, nchars), | |
119 Qmswindows_unicode); | |
120 nchars /= sizeof (WCHAR); /* Tricky ... */ | |
121 DO_REALLOC (ext_storage, ext_storage_size, total_nchars + nchars, | |
122 WCHAR); | |
123 memcpy (ext_storage + total_nchars, alloca_ext_storage, | |
124 nchars * sizeof (WCHAR)); | |
125 DO_REALLOC (run_storage, run_storage_size, runs_so_far + 1, | |
126 textual_run); | |
127 run_storage[runs_so_far].ptr = ext_storage + total_nchars; | |
128 run_storage[runs_so_far].charset = prev_charset; | |
129 run_storage[runs_so_far].nwchars = nchars; | |
130 run_storage[runs_so_far].nchars = i - runbegin; | |
131 total_nchars += nchars; | |
428 | 132 runs_so_far++; |
771 | 133 runbegin = i; |
134 if (i < len) | |
867 | 135 prev_charset = ichar_charset (str[i]); |
428 | 136 } |
137 } | |
138 | |
771 | 139 *run_storage_ptr = run_storage; |
428 | 140 return runs_so_far; |
141 } | |
142 | |
143 | |
144 static int | |
145 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, | |
146 textual_run *run) | |
147 { | |
148 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); | |
149 SIZE size; | |
150 | |
4476
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
151 /* The X11 code doesn't have to do this explicitly, because there we trust |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
152 the font instance to know whether it's actually proportional or not, |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
153 and we use the zero width that is stored in the monospace null font |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
154 instance. */ |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
155 if (EQ (Vthe_null_font_instance, font_inst)) |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
156 { |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
157 return 0; |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
158 } |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
159 |
2367 | 160 #if 0 /* #### not the way of ikeyama's ws */ |
428 | 161 if (!fi->proportional_p || !hdc) |
771 | 162 { |
163 if (XCHARSET_DIMENSION (run->charset) == 2) | |
164 /* Don't trust FONT_INSTANCE_WIDTH. Asian fonts have both of | |
165 one and two column characters. */ | |
166 goto the_hard_way; | |
167 else | |
168 return fi->width * run->nchars; | |
169 } | |
428 | 170 else |
171 { | |
771 | 172 the_hard_way: |
173 #endif | |
440 | 174 mswindows_set_dc_font (hdc, font_inst, |
175 cachel->underline, cachel->strikethru); | |
771 | 176 GetTextExtentPoint32W (hdc, run->ptr, run->nwchars, &size); |
177 return size.cx; | |
2367 | 178 #if 0 /* #### not the way of ikeyama's ws */ |
428 | 179 } |
771 | 180 #endif |
428 | 181 } |
182 | |
440 | 183 /* |
184 * Given F, retrieve device context. F can be a display frame, or | |
442 | 185 * a print job. For a print job, page is also started when printer's |
186 * device context is first time requested. | |
440 | 187 */ |
188 static HDC | |
442 | 189 get_frame_dc (struct frame *f, int start_page_p) |
440 | 190 { |
191 if (FRAME_MSWINDOWS_P (f)) | |
192 return FRAME_MSWINDOWS_DC (f); | |
193 else | |
442 | 194 { |
195 if (start_page_p && !FRAME_MSPRINTER_PAGE_STARTED (f)) | |
196 msprinter_start_page (f); | |
197 return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); | |
198 } | |
440 | 199 } |
200 | |
201 /* | |
202 * Given F, retrieve compatible device context. F can be a display | |
203 * frame, or a print job. | |
204 */ | |
205 static HDC | |
206 get_frame_compdc (struct frame *f) | |
207 { | |
442 | 208 struct device *d = XDEVICE (FRAME_DEVICE (f)); |
209 if (DEVICE_MSWINDOWS_P (d)) | |
210 return DEVICE_MSWINDOWS_HCDC (d); | |
440 | 211 else |
442 | 212 return DEVICE_MSPRINTER_HCDC (d); |
440 | 213 } |
428 | 214 |
215 /***************************************************************************** | |
216 mswindows_update_dc | |
217 | |
218 Given a number of parameters munge the DC so it has those properties. | |
219 ****************************************************************************/ | |
220 static void | |
440 | 221 mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
2286 | 222 Lisp_Object UNUSED (bg_pmap)) |
428 | 223 { |
224 if (!NILP (fg)) | |
225 { | |
226 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR | |
227 (XCOLOR_INSTANCE (fg))); | |
228 } | |
440 | 229 |
428 | 230 if (!NILP (bg)) |
231 { | |
232 SetBkMode (hdc, OPAQUE); | |
233 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); | |
234 } | |
235 else | |
236 { | |
237 SetBkMode (hdc, TRANSPARENT); | |
238 } | |
239 } | |
240 | |
771 | 241 static void |
242 mswindows_set_dc_font (HDC hdc, Lisp_Object font, int under, int strike) | |
428 | 243 { |
771 | 244 SelectObject (hdc, mswindows_get_hfont (XFONT_INSTANCE (font), |
245 under, strike)); | |
428 | 246 } |
247 | |
248 /***************************************************************************** | |
249 mswindows_output_hline | |
250 | |
251 Output a horizontal line in the foreground of its face. | |
252 ****************************************************************************/ | |
253 static void | |
2286 | 254 mswindows_output_hline (struct window *UNUSED (w), |
255 struct display_line *UNUSED (dl), | |
256 struct rune *UNUSED (rb)) | |
771 | 257 { /* #### Implement me */ |
428 | 258 } |
259 | |
260 | |
261 /***************************************************************************** | |
262 mswindows_output_blank | |
263 | |
264 Output a blank by clearing the area it covers in the background color | |
265 of its face. | |
266 ****************************************************************************/ | |
267 static void | |
268 mswindows_output_blank (struct window *w, struct display_line *dl, | |
269 struct rune *rb, int start_pixpos) | |
270 { | |
271 struct frame *f = XFRAME (w->frame); | |
442 | 272 HDC hdc = get_frame_dc (f, 1); |
428 | 273 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), |
274 rb->xpos+rb->width, | |
275 DISPLAY_LINE_YEND (dl) }; | |
276 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); | |
277 | |
278 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); | |
279 | |
280 /* Unmap all subwindows in the area we are going to blank. */ | |
281 redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl), | |
282 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
283 | |
284 if (!IMAGE_INSTANCEP (bg_pmap) | |
285 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | |
286 bg_pmap = Qnil; | |
287 | |
288 if (!NILP(bg_pmap)) | |
289 { | |
290 struct display_box db; | |
291 struct display_glyph_area dga; | |
292 redisplay_calculate_display_boxes (dl, rb->xpos, | |
293 /*rb->object.dglyph.xoffset*/ 0, | |
819 | 294 /*rb->object.dglyph.yoffset*/ 0, |
428 | 295 start_pixpos, rb->width, |
296 &db, &dga); | |
297 /* blank the background in the appropriate color */ | |
440 | 298 mswindows_update_dc (hdc, cachel->foreground, |
428 | 299 cachel->background, Qnil); |
300 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, | |
301 0, 0, 0, TRUE); | |
302 } | |
303 else | |
304 { | |
440 | 305 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); |
771 | 306 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 307 } |
308 } | |
309 | |
310 | |
311 /***************************************************************************** | |
312 mswindows_output_cursor | |
313 | |
314 Draw a normal or end-of-line cursor. The end-of-line cursor is | |
315 narrower than the normal cursor. | |
316 ****************************************************************************/ | |
317 static void | |
318 mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, | |
867 | 319 int width, face_index findex, Ichar ch, int image_p) |
428 | 320 { |
321 struct frame *f = XFRAME (w->frame); | |
322 struct device *d = XDEVICE (f->device); | |
323 Lisp_Object font = Qnil; | |
324 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | |
442 | 325 HDC hdc = get_frame_dc (f, 1); |
647 | 326 int local_face_index = 0; |
771 | 327 textual_run *run; |
328 int nruns = 0; | |
428 | 329 RECT rect = { xpos, |
330 DISPLAY_LINE_YPOS (dl), | |
331 xpos + width, | |
332 DISPLAY_LINE_YEND (dl) }; | |
333 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, | |
334 WINDOW_BUFFER (w)); | |
335 int bar_p = image_p || !NILP (bar); | |
336 int cursor_p = !NILP (w->text_cursor_visible_p); | |
337 int real_char_p = ch != 0; | |
338 | |
339 /* Unmap all subwindows in the area we are going to blank. */ | |
340 redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), | |
341 width, DISPLAY_LINE_HEIGHT (dl)); | |
342 | |
343 if (real_char_p) | |
344 { | |
345 /* Use the font from the underlying character */ | |
771 | 346 struct face_cachel *font_cachel = WINDOW_FACE_CACHEL (w, findex); |
347 nruns = separate_textual_runs (&run, &ch, 1); | |
348 font = FACE_CACHEL_FONT (font_cachel, run->charset); | |
349 mswindows_set_dc_font (hdc, font, | |
350 font_cachel->underline, font_cachel->strikethru); | |
428 | 351 } |
352 | |
353 if (!image_p) | |
354 { | |
355 struct face_cachel *color_cachel; | |
356 | |
357 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar | |
358 or when we need to erase the cursor. Output nothing at eol if bar | |
359 cursor */ | |
440 | 360 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
428 | 361 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? |
440 | 362 findex : local_face_index)); |
363 mswindows_update_dc (hdc, color_cachel->foreground, | |
428 | 364 color_cachel->background, Qnil); |
771 | 365 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, |
366 nruns ? run->ptr : NULL, nruns ? run->nwchars : 0, NULL); | |
428 | 367 } |
368 | |
369 if (!cursor_p) | |
370 return; | |
371 | |
372 if (focus && bar_p) | |
373 { | |
771 | 374 struct face_cachel *cursor_cachel; |
428 | 375 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); |
440 | 376 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
771 | 377 cursor_cachel = WINDOW_FACE_CACHEL (w, local_face_index); |
378 mswindows_update_dc (hdc, Qnil, cursor_cachel->background, Qnil); | |
379 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); | |
428 | 380 } |
381 else if (!focus) | |
382 { | |
771 | 383 struct face_cachel *cursor_cachel; |
384 | |
428 | 385 /* Now have real character drawn in its own color. We deflate |
386 the rectangle so character cell will be bounded by the | |
387 previously drawn cursor shape */ | |
388 InflateRect (&rect, -1, -1); | |
771 | 389 local_face_index = get_builtin_face_cache_index (w, Vdefault_face); |
390 cursor_cachel = | |
391 WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index)); | |
392 mswindows_update_dc (hdc, | |
393 cursor_cachel->foreground, | |
394 cursor_cachel->background, Qnil); | |
395 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, | |
396 &rect, nruns ? run->ptr : NULL, nruns ? run->nwchars : 0, | |
397 NULL); | |
398 } | |
428 | 399 |
771 | 400 #ifdef MULE |
401 if (DEVICE_MSWINDOWS_P (d) && | |
402 (FRAME_MSWINDOWS_CURSOR_X (f) != xpos | |
403 || FRAME_MSWINDOWS_CURSOR_Y (f) != DISPLAY_LINE_YPOS (dl) | |
404 || FRAME_MSWINDOWS_CURSOR_FINDEX (f) != findex)) | |
405 { | |
406 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f); | |
407 HIMC himc = ImmGetContext (hwnd); | |
408 | |
409 FRAME_MSWINDOWS_CURSOR_X (f) = xpos; | |
410 FRAME_MSWINDOWS_CURSOR_Y (f) = DISPLAY_LINE_YPOS (dl); | |
411 FRAME_MSWINDOWS_CURSOR_FINDEX (f) = findex; | |
412 | |
413 /* If the composition window is active, reset position of the | |
414 composition window. */ | |
415 if (qxeImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0)) | |
416 mswindows_start_ime_composition (f); | |
417 | |
418 ImmReleaseContext (hwnd, himc); | |
428 | 419 } |
771 | 420 #endif /* MULE */ |
428 | 421 } |
422 | |
423 | |
424 /***************************************************************************** | |
425 mswindows_output_string | |
426 | |
427 Given a string and a starting position, output that string in the | |
428 given face. | |
429 Correctly handles multiple charsets in the string. | |
430 | |
431 The meaning of the parameters is something like this: | |
432 | |
433 W Window that the text is to be displayed in. | |
434 DL Display line that this text is on. The values in the | |
435 structure are used to determine the vertical position and | |
436 clipping range of the text. | |
867 | 437 BUF Dynamic array of Ichars specifying what is actually to be |
428 | 438 drawn. |
439 XPOS X position in pixels where the text should start being drawn. | |
440 XOFFSET Number of pixels to be chopped off the left side of the | |
441 text. The effect is as if the text were shifted to the | |
442 left this many pixels and clipped at XPOS. | |
443 CLIP_START Clip everything left of this X position. | |
444 WIDTH Clip everything right of XPOS + WIDTH. | |
445 FINDEX Index for the face cache element describing how to display | |
446 the text. | |
447 ****************************************************************************/ | |
440 | 448 static void |
428 | 449 mswindows_output_string (struct window *w, struct display_line *dl, |
2286 | 450 Ichar_dynarr *buf, int xpos, int xoffset, |
451 int clip_start, int width, face_index findex, | |
452 int UNUSED (cursor), int UNUSED (cursor_start), | |
453 int UNUSED (cursor_width), int UNUSED (cursor_height)) | |
428 | 454 { |
455 struct frame *f = XFRAME (w->frame); | |
456 /* struct device *d = XDEVICE (f->device);*/ | |
457 Lisp_Object window; | |
442 | 458 HDC hdc = get_frame_dc (f, 1); |
428 | 459 int clip_end; |
460 Lisp_Object bg_pmap; | |
771 | 461 textual_run *runs; |
428 | 462 int nruns; |
463 int i, height; | |
464 RECT rect; | |
465 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); | |
466 | |
793 | 467 window = wrap_window (w); |
428 | 468 |
469 #if 0 /* #### FIXME? */ | |
470 /* We can't work out the width before we've set the font in the DC */ | |
471 if (width < 0) | |
4967 | 472 width = mswindows_text_width (w, cachel, Dynarr_begin (buf), |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
473 Dynarr_length (buf)); |
428 | 474 #else |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
475 assert (width >= 0); |
428 | 476 #endif |
477 | |
478 /* Regularize the variables passed in. */ | |
479 if (clip_start < xpos) | |
480 clip_start = xpos; | |
481 clip_end = xpos + width; | |
482 if (clip_start >= clip_end) | |
483 /* It's all clipped out. */ | |
484 return; | |
485 | |
486 xpos -= xoffset; | |
487 | |
488 /* sort out the destination rectangle */ | |
489 height = DISPLAY_LINE_HEIGHT (dl); | |
490 rect.left = clip_start; | |
491 rect.top = DISPLAY_LINE_YPOS (dl); | |
492 rect.right = clip_end; | |
493 rect.bottom = rect.top + height; | |
494 | |
495 /* make sure the area we are about to display is subwindow free. */ | |
496 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
497 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
498 | |
499 /* output the background pixmap if there is one */ | |
500 bg_pmap = cachel->background_pixmap; | |
501 if (!IMAGE_INSTANCEP (bg_pmap) | |
502 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | |
503 bg_pmap = Qnil; | |
504 | |
505 if (!NILP(bg_pmap)) | |
506 { | |
507 struct display_box db; | |
508 struct display_glyph_area dga; | |
819 | 509 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, 0, |
428 | 510 clip_start, width, &db, &dga); |
511 /* blank the background in the appropriate color */ | |
440 | 512 mswindows_update_dc (hdc, |
513 cachel->foreground, cachel->background, Qnil); | |
428 | 514 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, |
515 0, 0, 0, TRUE); | |
516 /* output pixmap calls this so we have to recall to get correct | |
517 references */ | |
518 cachel = WINDOW_FACE_CACHEL (w, findex); | |
519 } | |
520 | |
4967 | 521 nruns = separate_textual_runs (&runs, Dynarr_begin (buf), |
428 | 522 Dynarr_length (buf)); |
523 | |
524 for (i = 0; i < nruns; i++) | |
525 { | |
526 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | |
440 | 527 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |
428 | 528 int this_width; |
529 | |
530 if (EQ (font, Vthe_null_font_instance)) | |
531 continue; | |
532 | |
440 | 533 mswindows_update_dc (hdc, cachel->foreground, |
428 | 534 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); |
440 | 535 mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru); |
428 | 536 |
537 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); | |
538 | |
539 /* cope with fonts taller than lines */ | |
540 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) | |
541 { | |
542 int clear_start = max (xpos, clip_start); | |
543 int clear_end = min (xpos + this_width, clip_end); | |
544 | |
545 { | |
546 redisplay_clear_region (window, findex, clear_start, | |
547 DISPLAY_LINE_YPOS (dl), | |
548 clear_end - clear_start, | |
549 height); | |
550 /* output pixmap calls this so we have to recall to get correct | |
551 references */ | |
552 cachel = WINDOW_FACE_CACHEL (w, findex); | |
553 } | |
554 } | |
555 | |
771 | 556 ExtTextOutW (hdc, xpos, dl->ypos, |
557 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, | |
558 &rect, runs[i].ptr, runs[i].nwchars, NULL); | |
428 | 559 |
560 xpos += this_width; | |
561 } | |
562 } | |
563 | |
564 static void | |
440 | 565 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, |
771 | 566 struct display_box *db, |
567 struct display_glyph_area *dga) | |
428 | 568 { |
442 | 569 HDC hdc = get_frame_dc (f, 1); |
440 | 570 HDC hcompdc = get_frame_compdc (f); |
428 | 571 HGDIOBJ old=NULL; |
442 | 572 const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p); |
573 const int real_y = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (p); | |
574 const int surface_x = IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
575 const int surface_y = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
428 | 576 |
442 | 577 /* first blit the mask */ |
428 | 578 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) |
579 { | |
442 | 580 RGBQUAD bg; |
581 COLORREF bgcolor; | |
428 | 582 |
440 | 583 old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p)); |
428 | 584 |
442 | 585 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_MONO_PIXMAP) |
586 { | |
587 COLORREF fgcolor; | |
588 RGBQUAD fg; | |
589 | |
590 fgcolor = GetTextColor (hdc); | |
591 fg.rgbBlue = GetBValue (fgcolor); | |
592 fg.rgbRed = GetRValue (fgcolor); | |
593 fg.rgbGreen = GetGValue (fgcolor); | |
594 fg.rgbReserved = 0; | |
595 SetDIBColorTable (hcompdc, 0, 1, &fg); | |
596 } | |
428 | 597 |
442 | 598 bgcolor = GetBkColor (hdc); |
599 bg.rgbBlue = GetBValue (bgcolor); | |
600 bg.rgbRed = GetRValue (bgcolor); | |
601 bg.rgbGreen = GetGValue (bgcolor); | |
602 bg.rgbReserved = 0; | |
603 SetDIBColorTable (hcompdc, 1, 1, &bg); | |
604 | |
605 StretchBlt (hdc, | |
606 db->xpos, db->ypos, | |
607 dga->width, dga->height, | |
608 hcompdc, | |
609 MulDiv (dga->xoffset, real_x, surface_x), | |
610 MulDiv (dga->yoffset, real_y, surface_y), | |
611 MulDiv (dga->width, real_x, surface_x), | |
612 MulDiv (dga->height, real_y, surface_y), | |
613 SRCCOPY); | |
428 | 614 |
440 | 615 SelectObject (hcompdc, old); |
428 | 616 } |
617 | |
442 | 618 /* Now blit the bitmap itself, or one of its slices. */ |
440 | 619 old = SelectObject (hcompdc, |
428 | 620 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE |
621 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); | |
622 | |
442 | 623 StretchBlt (hdc, |
624 db->xpos, db->ypos, | |
625 dga->width, dga->height, | |
626 hcompdc, | |
627 MulDiv (dga->xoffset, real_x, surface_x), | |
628 MulDiv (dga->yoffset, real_y, surface_y), | |
629 MulDiv (dga->width, real_x, surface_x), | |
630 MulDiv (dga->height, real_y, surface_y), | |
631 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); | |
428 | 632 |
440 | 633 SelectObject (hcompdc, old); |
428 | 634 } |
635 | |
636 /* X gc's have this nice property that setting the bg pixmap will | |
637 * output it offset relative to the window. Windows doesn't have this | |
638 * feature so we have to emulate this by outputting multiple pixmaps. | |
639 * This is only used for background pixmaps. Normal pixmaps are | |
640 * outputted once and are scrollable */ | |
641 static void | |
642 mswindows_output_dibitmap_region (struct frame *f, | |
440 | 643 Lisp_Image_Instance *p, |
428 | 644 struct display_box *db, |
645 struct display_glyph_area *dga) | |
646 { | |
647 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; | |
648 struct display_glyph_area xdga | |
649 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), | |
650 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; | |
651 int pxoffset = 0, pyoffset = 0; | |
652 | |
653 if (dga) | |
654 { | |
655 xdga.width = dga->width; | |
656 xdga.height = dga->height; | |
657 } | |
658 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) | |
659 return; | |
660 | |
661 /* when doing a bg pixmap do a partial pixmap first so that we | |
662 blt whole pixmaps thereafter */ | |
663 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - | |
664 db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
665 | |
666 while (xdga.height > 0) | |
667 { | |
668 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), | |
669 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - | |
670 db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
671 pxoffset = 0; | |
672 while (xdga.width > 0) | |
673 { | |
674 xdb.xpos = db->xpos + pxoffset; | |
675 xdb.ypos = db->ypos + pyoffset; | |
676 /* do we need to offset the pixmap vertically? this is necessary | |
677 for background pixmaps. */ | |
678 xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
679 xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
680 /* the width is handled by mswindows_output_pixmap_region */ | |
681 mswindows_output_dibitmap (f, p, &xdb, &xdga); | |
682 pxoffset += xdga.width; | |
683 xdga.width = min ((db->width - pxoffset), | |
684 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
685 } | |
686 pyoffset += xdga.height; | |
687 xdga.height = min ((db->height - pyoffset), | |
688 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
689 } | |
690 } | |
691 | |
692 /* Output a pixmap at the desired location. | |
693 DB normalized display_box. | |
694 DGA normalized display_glyph_area. */ | |
695 static void | |
696 mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, | |
2286 | 697 struct display_box *db, |
698 struct display_glyph_area *dga, face_index findex, | |
699 int UNUSED (cursor_start), int UNUSED (cursor_width), | |
700 int UNUSED (cursor_height), int bg_pixmap) | |
428 | 701 { |
702 struct frame *f = XFRAME (w->frame); | |
442 | 703 HDC hdc = get_frame_dc (f, 1); |
428 | 704 |
440 | 705 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
428 | 706 |
707 /* Output the pixmap. Have to do this as many times as is required | |
708 to fill the given area */ | |
440 | 709 mswindows_update_dc (hdc, |
428 | 710 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), |
711 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); | |
712 | |
713 if (bg_pixmap) | |
714 mswindows_output_dibitmap_region (f, p, db, dga); | |
715 else | |
716 mswindows_output_dibitmap (f, p, db, dga); | |
717 } | |
718 | |
719 #ifdef HAVE_SCROLLBARS | |
720 /* | |
721 * This function paints window's deadbox, a rectangle between window | |
722 * borders and two short edges of both scrollbars. | |
723 * | |
724 * Function checks whether deadbox intersects with the rectangle pointed | |
725 * to by PRC, and paints only the intersection | |
726 */ | |
727 static void | |
1318 | 728 mswindows_redisplay_deadbox (struct window *w, int x, int y, int width, |
729 int height) | |
428 | 730 { |
1318 | 731 RECT rc = { x, y, x + width, y + height }; |
428 | 732 int sbh = window_scrollbar_height (w); |
733 int sbw = window_scrollbar_width (w); | |
734 RECT rect_dead, rect_paint; | |
735 if (sbh == 0 || sbw == 0) | |
736 return; | |
737 | |
738 if (!NILP (w->scrollbar_on_left_p)) | |
739 rect_dead.left = WINDOW_LEFT (w); | |
740 else | |
741 rect_dead.left = WINDOW_TEXT_RIGHT (w); | |
742 rect_dead.right = rect_dead.left + sbw; | |
743 | |
744 if (!NILP (w->scrollbar_on_top_p)) | |
745 rect_dead.top = WINDOW_TOP (w); | |
746 else | |
747 rect_dead.top = WINDOW_TEXT_BOTTOM (w); | |
748 rect_dead.bottom = rect_dead.top + sbh; | |
749 | |
1318 | 750 if (IntersectRect (&rect_paint, &rect_dead, &rc)) |
428 | 751 { |
752 struct frame *f = XFRAME (WINDOW_FRAME (w)); | |
442 | 753 FillRect (get_frame_dc (f, 1), &rect_paint, |
428 | 754 (HBRUSH) (COLOR_BTNFACE+1)); |
755 } | |
756 } | |
757 | |
758 #endif /* HAVE_SCROLLBARS */ | |
759 | |
760 /***************************************************************************** | |
761 mswindows_bevel_area | |
762 | |
763 Draw a 3d border around the specified area on window W. | |
764 ****************************************************************************/ | |
765 static void | |
766 mswindows_bevel_area (struct window *w, face_index findex, int x, int y, | |
767 int width, int height, int thickness, | |
768 int edges, enum edge_style style) | |
769 { | |
770 struct frame *f = XFRAME (w->frame); | |
771 UINT edge; | |
772 UINT border = 0; | |
773 | |
774 if (style == EDGE_ETCHED_IN) | |
775 edge = EDGE_ETCHED; | |
776 else if (style == EDGE_ETCHED_OUT) | |
777 edge = EDGE_BUMP; | |
778 else if (style == EDGE_BEVEL_IN) | |
779 { | |
780 if (thickness == 1) | |
781 edge = BDR_SUNKENINNER; | |
782 else | |
783 edge = EDGE_SUNKEN; | |
784 } | |
785 else /* EDGE_BEVEL_OUT */ | |
786 { | |
787 if (thickness == 1) | |
788 edge = BDR_RAISEDINNER; | |
789 else | |
790 edge = EDGE_RAISED; | |
791 } | |
792 | |
793 if (edges & EDGE_TOP) | |
794 border |= BF_TOP; | |
795 if (edges & EDGE_LEFT) | |
796 border |= BF_LEFT; | |
797 if (edges & EDGE_BOTTOM) | |
798 border |= BF_BOTTOM; | |
799 if (edges & EDGE_RIGHT) | |
800 border |= BF_RIGHT; | |
801 | |
802 { | |
803 RECT rect = { x, y, x + width, y + height }; | |
804 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | |
442 | 805 HDC hdc = get_frame_dc (f, 1); |
428 | 806 |
440 | 807 mswindows_update_dc (hdc, Qnil, color, Qnil); |
808 DrawEdge (hdc, &rect, edge, border); | |
428 | 809 } |
810 } | |
811 | |
812 | |
813 /***************************************************************************** | |
814 Display methods | |
815 *****************************************************************************/ | |
816 | |
817 /***************************************************************************** | |
818 mswindows_divider_height | |
819 | |
820 Return the height of the horizontal divider. | |
821 ****************************************************************************/ | |
822 static int | |
823 mswindows_divider_height (void) | |
824 { | |
825 return 1; /* XXX Copied from redisplay-X.c. What is this? */ | |
826 } | |
827 | |
828 /***************************************************************************** | |
829 mswindows_eol_cursor_width | |
830 | |
831 Return the width of the end-of-line cursor. | |
832 ****************************************************************************/ | |
833 static int | |
834 mswindows_eol_cursor_width (void) | |
835 { | |
836 return MSWINDOWS_EOL_CURSOR_WIDTH; | |
837 } | |
838 | |
839 /***************************************************************************** | |
442 | 840 mswindows_frame_output_begin |
428 | 841 |
842 Perform any necessary initialization prior to an update. | |
843 ****************************************************************************/ | |
844 static void | |
2286 | 845 mswindows_frame_output_begin (struct frame *UNUSED (f)) |
428 | 846 { |
847 } | |
848 | |
849 /***************************************************************************** | |
442 | 850 mswindows_frame_output_end |
428 | 851 |
852 Perform any necessary flushing of queues when an update has completed. | |
853 ****************************************************************************/ | |
854 static void | |
2286 | 855 mswindows_frame_output_end (struct frame * |
856 #ifdef DEFER_WINDOW_POS | |
857 f | |
858 #else | |
859 UNUSED (f) | |
860 #endif | |
861 ) | |
442 | 862 { |
863 #ifdef DEFER_WINDOW_POS | |
864 HDWP hdwp = FRAME_MSWINDOWS_DATA (f)->hdwp; | |
865 | |
866 if (hdwp != 0) | |
867 { | |
868 EndDeferWindowPos (hdwp); | |
869 FRAME_MSWINDOWS_DATA (f)->hdwp = 0; | |
870 } | |
871 #endif | |
872 GdiFlush(); | |
873 } | |
874 | |
875 /* Printer version is more lightweight. */ | |
876 static void | |
2286 | 877 msprinter_frame_output_end (struct frame *UNUSED (f)) |
428 | 878 { |
879 GdiFlush(); | |
880 } | |
881 | |
882 static int | |
883 mswindows_flash (struct device *d) | |
884 { | |
885 struct frame *f = device_selected_frame (d); | |
442 | 886 HDC hdc = get_frame_dc (f, 1); |
428 | 887 RECT rc; |
888 | |
889 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); | |
440 | 890 InvertRect (hdc, &rc); |
428 | 891 GdiFlush (); |
892 Sleep (25); | |
440 | 893 InvertRect (hdc, &rc); |
428 | 894 |
895 return 1; | |
896 } | |
897 | |
898 static void | |
2286 | 899 mswindows_ring_bell (struct device *UNUSED (d), int UNUSED (volume), |
900 int UNUSED (pitch), int UNUSED (duration)) | |
428 | 901 { |
902 /* Beep does not work at all, anyways! -kkm */ | |
903 MessageBeep (MB_OK); | |
904 } | |
905 | |
906 /***************************************************************************** | |
907 mswindows_output_display_block | |
908 | |
909 Given a display line, a block number for that start line, output all | |
910 runes between start and end in the specified display block. | |
911 Ripped off with minimal thought from the corresponding X routine. | |
912 ****************************************************************************/ | |
913 static void | |
771 | 914 mswindows_output_display_block (struct window *w, struct display_line *dl, |
915 int block, int start, int end, | |
916 int start_pixpos, int cursor_start, | |
917 int cursor_width, int cursor_height) | |
428 | 918 { |
919 struct frame *f = XFRAME (w->frame); | |
3479 | 920 Ichar_dynarr *buf; |
428 | 921 Lisp_Object window; |
922 | |
923 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | |
924 rune_dynarr *rba = db->runes; | |
925 struct rune *rb; | |
926 | |
927 int elt = start; | |
928 face_index findex; | |
929 int xpos, width; | |
930 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when | |
931 MULE is not defined */ | |
793 | 932 window = wrap_window (w); |
428 | 933 rb = Dynarr_atp (rba, start); |
934 | |
935 if (!rb) | |
936 /* Nothing to do so don't do anything. */ | |
937 return; | |
938 | |
939 findex = rb->findex; | |
940 xpos = rb->xpos; | |
941 width = 0; | |
942 if (rb->type == RUNE_CHAR) | |
867 | 943 charset = ichar_charset (rb->object.chr.ch); |
428 | 944 |
945 if (end < 0) | |
946 end = Dynarr_length (rba); | |
3479 | 947 buf = Dynarr_new (Ichar); |
428 | 948 |
949 while (elt < end) | |
950 { | |
951 rb = Dynarr_atp (rba, elt); | |
952 | |
953 if (rb->findex == findex && rb->type == RUNE_CHAR | |
954 && rb->object.chr.ch != '\n' && rb->cursor_type != CURSOR_ON | |
867 | 955 && EQ (charset, ichar_charset (rb->object.chr.ch))) |
428 | 956 { |
957 Dynarr_add (buf, rb->object.chr.ch); | |
958 width += rb->width; | |
959 elt++; | |
960 } | |
961 else | |
962 { | |
963 if (Dynarr_length (buf)) | |
964 { | |
771 | 965 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, |
966 width, findex, 0, 0, 0, 0); | |
428 | 967 xpos = rb->xpos; |
968 width = 0; | |
969 } | |
970 Dynarr_reset (buf); | |
971 width = 0; | |
972 | |
973 if (rb->type == RUNE_CHAR) | |
974 { | |
975 findex = rb->findex; | |
976 xpos = rb->xpos; | |
867 | 977 charset = ichar_charset (rb->object.chr.ch); |
428 | 978 |
979 if (rb->cursor_type == CURSOR_ON) | |
980 { | |
981 if (rb->object.chr.ch == '\n') | |
982 { | |
983 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
984 findex, 0, 0); | |
985 } | |
986 else | |
987 { | |
988 Dynarr_add (buf, rb->object.chr.ch); | |
989 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
990 findex, rb->object.chr.ch, 0); | |
991 Dynarr_reset (buf); | |
992 } | |
993 | |
994 xpos += rb->width; | |
995 elt++; | |
996 } | |
997 else if (rb->object.chr.ch == '\n') | |
998 { | |
999 /* Clear in case a cursor was formerly here. */ | |
1000 redisplay_clear_region (window, findex, xpos, | |
1001 DISPLAY_LINE_YPOS (dl), | |
1002 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
1003 elt++; | |
1004 } | |
1005 } | |
1006 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | |
1007 { | |
1008 if (rb->type == RUNE_BLANK) | |
1009 mswindows_output_blank (w, dl, rb, start_pixpos); | |
1010 else | |
1011 { | |
1012 /* #### Our flagging of when we need to redraw the | |
1013 modeline shadows sucks. Since RUNE_HLINE is only used | |
1014 by the modeline at the moment it is a good bet | |
1015 that if it gets redrawn then we should also | |
1016 redraw the shadows. This won't be true forever. | |
1017 We borrow the shadow_thickness_changed flag for | |
1018 now. */ | |
1019 w->shadow_thickness_changed = 1; | |
1020 mswindows_output_hline (w, dl, rb); | |
1021 } | |
1022 | |
1023 if (rb->cursor_type == CURSOR_ON) | |
1024 mswindows_output_cursor (w, dl, xpos, cursor_width, rb->findex, 0, 0); | |
1025 | |
1026 elt++; | |
1027 if (elt < end) | |
1028 { | |
1029 rb = Dynarr_atp (rba, elt); | |
1030 | |
1031 findex = rb->findex; | |
1032 xpos = rb->xpos; | |
1033 } | |
1034 } | |
1035 else if (rb->type == RUNE_DGLYPH) | |
1036 { | |
1037 Lisp_Object instance; | |
440 | 1038 struct display_box dbox; |
428 | 1039 struct display_glyph_area dga; |
442 | 1040 |
428 | 1041 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, |
819 | 1042 rb->object.dglyph.yoffset, |
1043 start_pixpos, rb->width, &dbox, &dga); | |
428 | 1044 |
793 | 1045 window = wrap_window (w); |
428 | 1046 instance = glyph_image_instance (rb->object.dglyph.glyph, |
793 | 1047 window, ERROR_ME_DEBUG_WARN, 1); |
428 | 1048 findex = rb->findex; |
1049 | |
1050 if (IMAGE_INSTANCEP (instance)) | |
442 | 1051 { |
1052 switch (XIMAGE_INSTANCE_TYPE (instance)) | |
428 | 1053 { |
442 | 1054 case IMAGE_MONO_PIXMAP: |
1055 case IMAGE_COLOR_PIXMAP: | |
1056 redisplay_output_pixmap (w, instance, &dbox, &dga, findex, | |
1057 cursor_start, cursor_width, | |
1058 cursor_height, 0); | |
428 | 1059 if (rb->cursor_type == CURSOR_ON) |
1060 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
442 | 1061 findex, 0, 1); |
1062 break; | |
1063 | |
1064 case IMAGE_WIDGET: | |
1065 if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance), | |
1066 Qlayout)) | |
1067 { | |
1068 redisplay_output_layout (window, instance, &dbox, &dga, findex, | |
1069 cursor_start, cursor_width, | |
1070 cursor_height); | |
1071 if (rb->cursor_type == CURSOR_ON) | |
1072 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1073 findex, 0, 1); | |
1074 break; | |
1075 } | |
1076 case IMAGE_SUBWINDOW: | |
1077 redisplay_output_subwindow (w, instance, &dbox, &dga, findex, | |
1078 cursor_start, cursor_width, | |
1079 cursor_height); | |
1080 if (rb->cursor_type == CURSOR_ON) | |
1081 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1082 findex, 0, 1); | |
1083 break; | |
1084 | |
1085 case IMAGE_NOTHING: | |
1086 /* nothing is as nothing does */ | |
1087 break; | |
428 | 1088 |
442 | 1089 case IMAGE_TEXT: |
1090 case IMAGE_POINTER: | |
1091 default: | |
2500 | 1092 ABORT (); |
442 | 1093 } |
1094 IMAGE_INSTANCE_OPTIMIZE_OUTPUT | |
1095 (XIMAGE_INSTANCE (instance)) = 0; | |
1096 } | |
428 | 1097 xpos += rb->width; |
1098 elt++; | |
1099 } | |
1100 else | |
2500 | 1101 ABORT (); |
428 | 1102 } |
1103 } | |
1104 | |
1105 if (Dynarr_length (buf)) | |
1106 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, | |
1107 0, 0, 0, 0); | |
1108 | |
1109 if (dl->modeline | |
1110 && !EQ (Qzero, w->modeline_shadow_thickness) | |
1111 && (f->clear | |
1112 || f->windows_structure_changed | |
1113 || w->shadow_thickness_changed)) | |
1114 bevel_modeline (w, dl); | |
1115 | |
1116 Dynarr_free (buf); | |
1117 } | |
1118 | |
1119 | |
1120 /***************************************************************************** | |
1121 mswindows_output_vertical_divider | |
1122 | |
1123 Draw a vertical divider down the right side of the given window. | |
1124 ****************************************************************************/ | |
1125 static void | |
2286 | 1126 mswindows_output_vertical_divider (struct window *w, int UNUSED (clear_unused)) |
428 | 1127 { |
1128 struct frame *f = XFRAME (w->frame); | |
442 | 1129 HDC hdc = get_frame_dc (f, 1); |
428 | 1130 RECT rect; |
1131 int spacing = XINT (w->vertical_divider_spacing); | |
1132 int shadow = XINT (w->vertical_divider_shadow_thickness); | |
1133 int abs_shadow = abs (shadow); | |
1134 int line_width = XINT (w->vertical_divider_line_width); | |
1135 int div_left = WINDOW_RIGHT (w) - window_divider_width (w); | |
442 | 1136 int y1 = WINDOW_TOP (w); |
1137 int y2 = WINDOW_BOTTOM (w); | |
428 | 1138 |
1139 /* Clear left and right spacing areas */ | |
1140 if (spacing) | |
1141 { | |
1142 rect.top = y1; | |
1143 rect.bottom = y2; | |
440 | 1144 mswindows_update_dc (hdc, Qnil, |
428 | 1145 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); |
1146 rect.right = WINDOW_RIGHT (w); | |
1147 rect.left = rect.right - spacing; | |
771 | 1148 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1149 rect.left = div_left; |
1150 rect.right = div_left + spacing; | |
771 | 1151 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1152 } |
1153 | |
1154 /* Clear divider face */ | |
1155 rect.top = y1 + abs_shadow; | |
1156 rect.bottom = y2 - abs_shadow; | |
1157 rect.left = div_left + spacing + abs_shadow; | |
1158 rect.right = rect.left + line_width; | |
1159 if (rect.left < rect.right) | |
1160 { | |
1161 face_index div_face | |
1162 = get_builtin_face_cache_index (w, Vvertical_divider_face); | |
440 | 1163 mswindows_update_dc (hdc, Qnil, |
428 | 1164 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); |
771 | 1165 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1166 } |
1167 | |
1168 /* Draw a shadow around the divider */ | |
1169 if (shadow != 0) | |
1170 { | |
1171 /* #### This will be fixed to support arbitrary thickness */ | |
1172 InflateRect (&rect, abs_shadow, abs_shadow); | |
440 | 1173 DrawEdge (hdc, &rect, |
428 | 1174 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); |
1175 } | |
1176 } | |
1177 | |
1178 /**************************************************************************** | |
1179 mswindows_text_width | |
1180 | |
1181 Given a string and a face, return the string's length in pixels when | |
1182 displayed in the font associated with the face. | |
1183 ****************************************************************************/ | |
1184 static int | |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
1185 mswindows_text_width (struct window *w, struct face_cachel *cachel, |
867 | 1186 const Ichar *str, Charcount len) |
428 | 1187 { |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
1188 struct frame *f = WINDOW_XFRAME (w); |
442 | 1189 HDC hdc = get_frame_dc (f, 0); |
428 | 1190 int width_so_far = 0; |
771 | 1191 textual_run *runs; |
428 | 1192 int nruns; |
1193 int i; | |
1194 | |
771 | 1195 nruns = separate_textual_runs (&runs, str, len); |
428 | 1196 |
1197 for (i = 0; i < nruns; i++) | |
771 | 1198 width_so_far += mswindows_text_width_single_run (hdc, cachel, runs + i); |
428 | 1199 |
1200 return width_so_far; | |
1201 } | |
1202 | |
1203 | |
1204 /**************************************************************************** | |
1205 mswindows_clear_region | |
1206 | |
1207 Clear the area in the box defined by the given parameters using the | |
1208 given face. | |
1209 ****************************************************************************/ | |
1210 static void | |
5046 | 1211 mswindows_clear_region (Lisp_Object USED_IF_SCROLLBARS (locale), |
2286 | 1212 struct device *UNUSED (d), struct frame *f, |
1213 face_index UNUSED (findex), int x, int y, | |
1214 int width, int height, Lisp_Object fcolor, | |
1215 Lisp_Object bcolor, Lisp_Object background_pixmap) | |
428 | 1216 { |
1217 RECT rect = { x, y, x+width, y+height }; | |
442 | 1218 HDC hdc = get_frame_dc (f, 1); |
428 | 1219 |
1220 if (!NILP (background_pixmap)) | |
1221 { | |
1222 struct display_box db = { x, y, width, height }; | |
440 | 1223 mswindows_update_dc (hdc, |
1224 fcolor, bcolor, background_pixmap); | |
428 | 1225 mswindows_output_dibitmap_region |
1226 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); | |
1227 } | |
1228 else | |
1229 { | |
440 | 1230 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); |
771 | 1231 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1232 } |
1233 | |
1234 #ifdef HAVE_SCROLLBARS | |
1235 if (WINDOWP (locale)) | |
1318 | 1236 mswindows_redisplay_deadbox (XWINDOW (locale), x, y, width, height); |
428 | 1237 #endif |
1238 } | |
1239 | |
1318 | 1240 /* #### Implement me! */ |
428 | 1241 static void |
2286 | 1242 mswindows_clear_frame (struct frame *UNUSED (f)) |
428 | 1243 { |
1318 | 1244 GdiFlush (); |
428 | 1245 } |
1246 | |
1247 | |
1248 /************************************************************************/ | |
1249 /* initialization */ | |
1250 /************************************************************************/ | |
1251 | |
1252 void | |
1253 console_type_create_redisplay_mswindows (void) | |
1254 { | |
440 | 1255 /* redisplay methods - display*/ |
428 | 1256 CONSOLE_HAS_METHOD (mswindows, text_width); |
1257 CONSOLE_HAS_METHOD (mswindows, output_display_block); | |
1258 CONSOLE_HAS_METHOD (mswindows, divider_height); | |
1259 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); | |
1260 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); | |
1261 CONSOLE_HAS_METHOD (mswindows, clear_region); | |
1262 CONSOLE_HAS_METHOD (mswindows, clear_frame); | |
442 | 1263 CONSOLE_HAS_METHOD (mswindows, frame_output_begin); |
1264 CONSOLE_HAS_METHOD (mswindows, frame_output_end); | |
428 | 1265 CONSOLE_HAS_METHOD (mswindows, flash); |
1266 CONSOLE_HAS_METHOD (mswindows, ring_bell); | |
1267 CONSOLE_HAS_METHOD (mswindows, bevel_area); | |
1268 CONSOLE_HAS_METHOD (mswindows, output_string); | |
1269 CONSOLE_HAS_METHOD (mswindows, output_pixmap); | |
1318 | 1270 #ifdef HAVE_SCROLLBARS |
1271 CONSOLE_HAS_METHOD (mswindows, redisplay_deadbox); | |
1272 #endif | |
440 | 1273 |
1274 /* redisplay methods - printer */ | |
442 | 1275 CONSOLE_HAS_METHOD (msprinter, frame_output_end); |
440 | 1276 CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width); |
1277 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block); | |
1278 CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height); | |
1279 CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width); | |
1280 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider); | |
1281 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region); | |
1282 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame); | |
442 | 1283 CONSOLE_INHERITS_METHOD (msprinter, mswindows, frame_output_begin); |
440 | 1284 CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area); |
1285 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string); | |
1286 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap); | |
428 | 1287 } |