2 * Copyright 2001 Eric Pouech
3 * Copyright 2020 Jacek Caban for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(console
);
31 #define WM_UPDATE_CONFIG (WM_USER + 1)
42 HDC mem_dc
; /* memory DC holding the bitmap below */
43 HBITMAP bitmap
; /* bitmap of display window content */
44 HFONT font
; /* font used for rendering, usually fixed */
45 HMENU popup_menu
; /* popup menu triggered by right mouse click */
46 HBITMAP cursor_bitmap
; /* bitmap used for the caret */
47 BOOL in_selection
; /* an area is being selected */
48 COORD selection_start
; /* selection coordinates */
50 unsigned int ui_charset
; /* default UI charset */
51 WCHAR
*config_key
; /* config registry key name */
52 LONG ext_leading
; /* external leading for font */
54 BOOL quick_edit
; /* whether mouse ops are sent to app or used for content selection */
55 unsigned int menu_mask
; /* MK_CONTROL MK_SHIFT mask to drive submenu opening */
56 COORD win_pos
; /* position (in cells) of visible part of screen buffer in window */
57 unsigned int win_width
; /* size (in cells) of visible part of window (width & height) */
58 unsigned int win_height
;
59 unsigned int cursor_size
; /* in % of cell height */
60 int cursor_visible
; /* cursor visibility */
61 unsigned int sb_width
; /* active screen buffer width */
62 unsigned int sb_height
; /* active screen buffer height */
63 COORD cursor_pos
; /* cursor position */
65 RECT update
; /* screen buffer update rect */
66 enum update_state update_state
; /* update state */
71 DWORD color_map
[16]; /* console color table */
72 unsigned int cell_width
; /* width in pixels of a character */
73 unsigned int cell_height
; /* height in pixels of a character */
74 unsigned int cursor_size
; /* in % of cell height */
75 int cursor_visible
; /* cursor visibility */
76 unsigned int attr
; /* default fill attributes (screen colors) */
77 unsigned int popup_attr
; /* pop-up color attributes */
78 unsigned int history_size
; /* number of commands in history buffer */
79 unsigned int history_mode
; /* flag if commands are not stored twice in buffer */
80 unsigned int insert_mode
; /* TRUE to insert text at the cursor location; FALSE to overwrite it */
81 unsigned int menu_mask
; /* MK_CONTROL MK_SHIFT mask to drive submenu opening */
82 unsigned int quick_edit
; /* whether mouse ops are sent to app or used for content selection */
83 unsigned int sb_width
; /* active screen buffer width */
84 unsigned int sb_height
; /* active screen buffer height */
85 unsigned int win_width
; /* size (in cells) of visible part of window (width & height) */
86 unsigned int win_height
;
87 COORD win_pos
; /* position (in cells) of visible part of screen buffer in window */
88 unsigned int edition_mode
; /* edition mode flavor while line editing */
89 unsigned int font_pitch_family
;
90 unsigned int font_weight
;
91 WCHAR face_name
[LF_FACESIZE
];
94 static const char *debugstr_config( const struct console_config
*config
)
96 return wine_dbg_sprintf( "cell=(%u,%u) cursor=(%d,%d) attr=%02x pop-up=%02x font=%s/%u/%u "
97 "hist=%u/%d flags=%c%c msk=%08x sb=(%u,%u) win=(%u,%u)x(%u,%u) edit=%u",
98 config
->cell_width
, config
->cell_height
, config
->cursor_size
,
99 config
->cursor_visible
, config
->attr
, config
->popup_attr
,
100 wine_dbgstr_w(config
->face_name
), config
->font_pitch_family
,
101 config
->font_weight
, config
->history_size
,
102 config
->history_mode
? 1 : 2,
103 config
->insert_mode
? 'I' : 'i',
104 config
->quick_edit
? 'Q' : 'q',
105 config
->menu_mask
, config
->sb_width
, config
->sb_height
,
106 config
->win_pos
.X
, config
->win_pos
.Y
, config
->win_width
,
107 config
->win_height
, config
->edition_mode
);
110 static const char *debugstr_logfont( const LOGFONTW
*lf
, unsigned int ft
)
112 return wine_dbg_sprintf( "%s%s%s%s lfHeight=%ld lfWidth=%ld lfEscapement=%ld "
113 "lfOrientation=%ld lfWeight=%ld lfItalic=%u lfUnderline=%u "
114 "lfStrikeOut=%u lfCharSet=%u lfPitchAndFamily=%u lfFaceName=%s",
115 (ft
& RASTER_FONTTYPE
) ? "raster" : "",
116 (ft
& TRUETYPE_FONTTYPE
) ? "truetype" : "",
117 ((ft
& (RASTER_FONTTYPE
|TRUETYPE_FONTTYPE
)) == 0) ? "vector" : "",
118 (ft
& DEVICE_FONTTYPE
) ? "|device" : "",
119 lf
->lfHeight
, lf
->lfWidth
, lf
->lfEscapement
, lf
->lfOrientation
,
120 lf
->lfWeight
, lf
->lfItalic
, lf
->lfUnderline
, lf
->lfStrikeOut
,
121 lf
->lfCharSet
, lf
->lfPitchAndFamily
, wine_dbgstr_w( lf
->lfFaceName
));
124 static const char *debugstr_textmetric( const TEXTMETRICW
*tm
, unsigned int ft
)
126 return wine_dbg_sprintf( "%s%s%s%s tmHeight=%ld tmAscent=%ld tmDescent=%ld "
127 "tmAveCharWidth=%ld tmMaxCharWidth=%ld tmWeight=%ld "
128 "tmPitchAndFamily=%u tmCharSet=%u",
129 (ft
& RASTER_FONTTYPE
) ? "raster" : "",
130 (ft
& TRUETYPE_FONTTYPE
) ? "truetype" : "",
131 ((ft
& (RASTER_FONTTYPE
|TRUETYPE_FONTTYPE
)) == 0) ? "vector" : "",
132 (ft
& DEVICE_FONTTYPE
) ? "|device" : "",
133 tm
->tmHeight
, tm
->tmAscent
, tm
->tmDescent
, tm
->tmAveCharWidth
,
134 tm
->tmMaxCharWidth
, tm
->tmWeight
, tm
->tmPitchAndFamily
,
138 /* read the basic configuration from any console key or subkey */
139 static void load_registry_key( HKEY key
, struct console_config
*config
)
141 DWORD type
, count
, val
, i
;
142 WCHAR color_name
[13];
144 for (i
= 0; i
< ARRAY_SIZE(config
->color_map
); i
++)
146 wsprintfW( color_name
, L
"ColorTable%02d", i
);
148 if (!RegQueryValueExW( key
, color_name
, 0, &type
, (BYTE
*)&val
, &count
))
149 config
->color_map
[i
] = val
;
153 if (!RegQueryValueExW( key
, L
"CursorSize", 0, &type
, (BYTE
*)&val
, &count
))
154 config
->cursor_size
= val
;
157 if (!RegQueryValueExW( key
, L
"CursorVisible", 0, &type
, (BYTE
*)&val
, &count
))
158 config
->cursor_visible
= val
;
161 if (!RegQueryValueExW( key
, L
"EditionMode", 0, &type
, (BYTE
*)&val
, &count
))
162 config
->edition_mode
= val
;
164 count
= sizeof(config
->face_name
);
165 RegQueryValueExW( key
, L
"FaceName", 0, &type
, (BYTE
*)&config
->face_name
, &count
);
168 if (!RegQueryValueExW( key
, L
"FontFamily", 0, &type
, (BYTE
*)&val
, &count
) ||
169 !RegQueryValueExW( key
, L
"FontPitchFamily", 0, &type
, (BYTE
*)&val
, &count
))
170 config
->font_pitch_family
= val
;
173 if (!RegQueryValueExW( key
, L
"FontSize", 0, &type
, (BYTE
*)&val
, &count
))
175 int height
= HIWORD(val
);
176 int width
= LOWORD(val
);
177 /* A value of zero reflects the default settings */
178 if (height
) config
->cell_height
= MulDiv( height
, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI
);
179 if (width
) config
->cell_width
= MulDiv( width
, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI
);
183 if (!RegQueryValueExW( key
, L
"FontWeight", 0, &type
, (BYTE
*)&val
, &count
))
184 config
->font_weight
= val
;
187 if (!RegQueryValueExW( key
, L
"HistoryBufferSize", 0, &type
, (BYTE
*)&val
, &count
))
188 config
->history_size
= val
;
191 if (!RegQueryValueExW( key
, L
"HistoryNoDup", 0, &type
, (BYTE
*)&val
, &count
))
192 config
->history_mode
= val
;
195 if (!RegQueryValueExW( key
, L
"wszInsertMode", 0, &type
, (BYTE
*)&val
, &count
))
196 config
->insert_mode
= val
;
199 if (!RegQueryValueExW( key
, L
"MenuMask", 0, &type
, (BYTE
*)&val
, &count
))
200 config
->menu_mask
= val
;
203 if (!RegQueryValueExW( key
, L
"PopupColors", 0, &type
, (BYTE
*)&val
, &count
))
204 config
->popup_attr
= val
;
207 if (!RegQueryValueExW( key
, L
"QuickEdit", 0, &type
, (BYTE
*)&val
, &count
))
208 config
->quick_edit
= val
;
211 if (!RegQueryValueExW( key
, L
"ScreenBufferSize", 0, &type
, (BYTE
*)&val
, &count
))
213 config
->sb_height
= HIWORD(val
);
214 config
->sb_width
= LOWORD(val
);
218 if (!RegQueryValueExW( key
, L
"ScreenColors", 0, &type
, (BYTE
*)&val
, &count
))
222 if (!RegQueryValueExW( key
, L
"WindowSize", 0, &type
, (BYTE
*)&val
, &count
))
224 config
->win_height
= HIWORD(val
);
225 config
->win_width
= LOWORD(val
);
229 /* load config from registry */
230 static void load_config( const WCHAR
*key_name
, struct console_config
*config
)
232 static const COLORREF color_map
[] =
234 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x80), RGB(0x00, 0x80, 0x00), RGB(0x00, 0x80, 0x80),
235 RGB(0x80, 0x00, 0x00), RGB(0x80, 0x00, 0x80), RGB(0x80, 0x80, 0x00), RGB(0xC0, 0xC0, 0xC0),
236 RGB(0x80, 0x80, 0x80), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xFF),
237 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xFF)
242 TRACE( "Loading default console settings\n" );
244 memcpy( config
->color_map
, color_map
, sizeof(color_map
) );
245 memset( config
->face_name
, 0, sizeof(config
->face_name
) );
246 config
->cursor_size
= 25;
247 config
->cursor_visible
= 1;
248 config
->font_pitch_family
= FIXED_PITCH
| FF_DONTCARE
;
249 config
->cell_height
= MulDiv( 16, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI
);
250 config
->cell_width
= MulDiv( 8, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI
);
251 config
->font_weight
= FW_NORMAL
;
253 config
->history_size
= 50;
254 config
->history_mode
= 0;
255 config
->insert_mode
= 1;
256 config
->menu_mask
= 0;
257 config
->popup_attr
= 0xF5;
258 config
->quick_edit
= 0;
259 config
->sb_height
= 150;
260 config
->sb_width
= 80;
261 config
->attr
= 0x000F;
262 config
->win_height
= 25;
263 config
->win_width
= 80;
264 config
->win_pos
.X
= 0;
265 config
->win_pos
.Y
= 0;
266 config
->edition_mode
= 0;
268 /* Load default console settings */
269 if (!RegOpenKeyW( HKEY_CURRENT_USER
, L
"Console", &key
))
271 load_registry_key( key
, config
);
273 /* Load app-specific console settings (if any) */
274 if (key_name
&& !RegOpenKeyW( key
, key_name
, &app_key
))
276 TRACE( "Loading %s console settings\n", wine_dbgstr_w(key_name
) );
277 load_registry_key( app_key
, config
);
278 RegCloseKey( app_key
);
282 TRACE( "%s\n", debugstr_config( config
));
285 static void save_registry_key( HKEY key
, const struct console_config
*config
, BOOL save_all
)
287 struct console_config default_config
;
288 DWORD val
, width
, height
, i
;
289 WCHAR color_name
[13];
291 TRACE( "%s\n", debugstr_config( config
));
294 load_config( NULL
, &default_config
);
296 for (i
= 0; i
< ARRAY_SIZE(config
->color_map
); i
++)
298 if (save_all
|| config
->color_map
[i
] != default_config
.color_map
[i
])
300 wsprintfW( color_name
, L
"ColorTable%02d", i
);
301 val
= config
->color_map
[i
];
302 RegSetValueExW( key
, color_name
, 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
306 if (save_all
|| config
->cursor_size
!= default_config
.cursor_size
)
308 val
= config
->cursor_size
;
309 RegSetValueExW( key
, L
"CursorSize", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
312 if (save_all
|| config
->cursor_visible
!= default_config
.cursor_visible
)
314 val
= config
->cursor_visible
;
315 RegSetValueExW( key
, L
"CursorVisible", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
318 if (save_all
|| config
->edition_mode
!= default_config
.edition_mode
)
320 val
= config
->edition_mode
;
321 RegSetValueExW( key
, L
"EditionMode", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
324 if (save_all
|| lstrcmpW( config
->face_name
, default_config
.face_name
))
326 RegSetValueExW( key
, L
"FaceName", 0, REG_SZ
, (BYTE
*)&config
->face_name
,
327 (lstrlenW(config
->face_name
) + 1) * sizeof(WCHAR
) );
330 if (save_all
|| config
->font_pitch_family
!= default_config
.font_pitch_family
)
332 val
= config
->font_pitch_family
;
333 RegSetValueExW( key
, L
"FontFamily", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
336 if (save_all
|| config
->cell_height
!= default_config
.cell_height
||
337 config
->cell_width
!= default_config
.cell_width
)
339 width
= MulDiv( config
->cell_width
, USER_DEFAULT_SCREEN_DPI
, GetDpiForSystem() );
340 height
= MulDiv( config
->cell_height
, USER_DEFAULT_SCREEN_DPI
, GetDpiForSystem() );
341 val
= MAKELONG( width
, height
);
343 RegSetValueExW( key
, L
"FontSize", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
346 if (save_all
|| config
->font_weight
!= default_config
.font_weight
)
348 val
= config
->font_weight
;
349 RegSetValueExW( key
, L
"FontWeight", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
352 if (save_all
|| config
->history_size
!= default_config
.history_size
)
354 val
= config
->history_size
;
355 RegSetValueExW( key
, L
"HistoryBufferSize", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
358 if (save_all
|| config
->history_mode
!= default_config
.history_mode
)
360 val
= config
->history_mode
;
361 RegSetValueExW( key
, L
"HistoryNoDup", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
364 if (save_all
|| config
->insert_mode
!= default_config
.insert_mode
)
366 val
= config
->insert_mode
;
367 RegSetValueExW( key
, L
"InsertMode", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
370 if (save_all
|| config
->menu_mask
!= default_config
.menu_mask
)
372 val
= config
->menu_mask
;
373 RegSetValueExW( key
, L
"MenuMask", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
376 if (save_all
|| config
->popup_attr
!= default_config
.popup_attr
)
378 val
= config
->popup_attr
;
379 RegSetValueExW( key
, L
"PopupColors", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
382 if (save_all
|| config
->quick_edit
!= default_config
.quick_edit
)
384 val
= config
->quick_edit
;
385 RegSetValueExW( key
, L
"QuickEdit", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
388 if (save_all
|| config
->sb_width
!= default_config
.sb_width
||
389 config
->sb_height
!= default_config
.sb_height
)
391 val
= MAKELONG(config
->sb_width
, config
->sb_height
);
392 RegSetValueExW( key
, L
"ScreenBufferSize", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
395 if (save_all
|| config
->attr
!= default_config
.attr
)
398 RegSetValueExW( key
, L
"ScreenColors", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
401 if (save_all
|| config
->win_width
!= default_config
.win_width
||
402 config
->win_height
!= default_config
.win_height
)
404 val
= MAKELONG( config
->win_width
, config
->win_height
);
405 RegSetValueExW( key
, L
"WindowSize", 0, REG_DWORD
, (BYTE
*)&val
, sizeof(val
) );
409 static void save_config( const WCHAR
*key_name
, const struct console_config
*config
)
413 TRACE( "Saving %s console settings\n", key_name
? debugstr_w( key_name
) : "default" );
415 if (RegCreateKeyW( HKEY_CURRENT_USER
, L
"Console", &key
))
417 ERR("Can't open registry for saving\n");
423 if (RegCreateKeyW( key
, key_name
, &app_key
))
425 ERR("Can't open registry for saving\n");
429 save_registry_key( app_key
, config
, FALSE
);
430 RegCloseKey( app_key
);
433 else save_registry_key( key
, config
, TRUE
);
437 /* fill memory DC with current cells values */
438 static void fill_mem_dc( struct console
*console
, const RECT
*update
)
440 unsigned int i
, j
, k
;
449 if (!console
->window
->font
|| !console
->window
->bitmap
)
452 if (!(line
= malloc( (update
->right
- update
->left
+ 1) * sizeof(WCHAR
))) ) return;
453 dx
= malloc( (update
->right
- update
->left
+ 1) * sizeof(*dx
) );
455 old_font
= SelectObject( console
->window
->mem_dc
, console
->window
->font
);
456 for (j
= update
->top
; j
<= update
->bottom
; j
++)
458 cell
= &console
->active
->data
[j
* console
->active
->width
];
459 for (i
= update
->left
; i
<= update
->right
; i
++)
462 SetBkColor( console
->window
->mem_dc
, console
->active
->color_map
[(attr
>> 4) & 0x0F] );
463 SetTextColor( console
->window
->mem_dc
, console
->active
->color_map
[attr
& 0x0F] );
464 for (k
= i
; k
<= update
->right
&& cell
[k
].attr
== attr
; k
++)
466 line
[k
- i
] = cell
[k
].ch
;
467 dx
[k
- i
] = console
->active
->font
.width
;
469 ExtTextOutW( console
->window
->mem_dc
, i
* console
->active
->font
.width
,
470 j
* console
->active
->font
.height
, 0, NULL
, line
, k
- i
, dx
);
471 if (console
->window
->ext_leading
&&
472 (brush
= CreateSolidBrush( console
->active
->color_map
[(attr
>> 4) & 0x0F] )))
474 r
.left
= i
* console
->active
->font
.width
;
475 r
.top
= (j
+ 1) * console
->active
->font
.height
- console
->window
->ext_leading
;
476 r
.right
= k
* console
->active
->font
.width
;
477 r
.bottom
= (j
+ 1) * console
->active
->font
.height
;
478 FillRect( console
->window
->mem_dc
, &r
, brush
);
479 DeleteObject( brush
);
484 SelectObject( console
->window
->mem_dc
, old_font
);
489 /* set a new position for the cursor */
490 static void update_window_cursor( struct console
*console
)
492 if (!console
->active
->cursor_visible
|| console
->win
!= GetFocus()) return;
494 SetCaretPos( (get_bounded_cursor_x( console
->active
) - console
->active
->win
.left
) * console
->active
->font
.width
,
495 (console
->active
->cursor_y
- console
->active
->win
.top
) * console
->active
->font
.height
);
496 ShowCaret( console
->win
);
499 /* sets a new shape for the cursor */
500 static void shape_cursor( struct console
*console
)
502 int size
= console
->active
->cursor_size
;
504 if (console
->active
->cursor_visible
&& console
->win
== GetFocus()) DestroyCaret();
505 if (console
->window
->cursor_bitmap
) DeleteObject( console
->window
->cursor_bitmap
);
506 console
->window
->cursor_bitmap
= NULL
;
507 console
->window
->cursor_visible
= FALSE
;
511 int w16b
; /* number of bytes per row, aligned on word size */
515 w16b
= ((console
->active
->font
.width
+ 15) & ~15) / 8;
516 ptr
= calloc( w16b
, console
->active
->font
.height
);
518 nbl
= max( (console
->active
->font
.height
* size
) / 100, 1 );
519 for (j
= console
->active
->font
.height
- nbl
; j
< console
->active
->font
.height
; j
++)
521 for (i
= 0; i
< console
->active
->font
.width
; i
++)
523 ptr
[w16b
* j
+ (i
/ 8)] |= 0x80 >> (i
& 7);
526 console
->window
->cursor_bitmap
= CreateBitmap( console
->active
->font
.width
,
527 console
->active
->font
.height
, 1, 1, ptr
);
532 static void update_window( struct console
*console
)
534 unsigned int win_width
, win_height
;
535 BOOL update_all
= FALSE
;
539 console
->window
->update_state
= UPDATE_BUSY
;
541 if (console
->window
->sb_width
!= console
->active
->width
||
542 console
->window
->sb_height
!= console
->active
->height
||
543 (!console
->window
->bitmap
&& IsWindowVisible( console
->win
)))
545 console
->window
->sb_width
= console
->active
->width
;
546 console
->window
->sb_height
= console
->active
->height
;
548 if (console
->active
->width
&& console
->active
->height
&& console
->window
->font
)
554 if (!(dc
= GetDC( console
->win
))) return;
556 bitmap
= CreateCompatibleBitmap( dc
,
557 console
->active
->width
* console
->active
->font
.width
,
558 console
->active
->height
* console
->active
->font
.height
);
559 ReleaseDC( console
->win
, dc
);
560 SelectObject( console
->window
->mem_dc
, bitmap
);
562 if (console
->window
->bitmap
) DeleteObject( console
->window
->bitmap
);
563 console
->window
->bitmap
= bitmap
;
564 SetRect( &r
, 0, 0, console
->active
->width
- 1, console
->active
->height
- 1 );
565 fill_mem_dc( console
, &r
);
568 empty_update_rect( console
->active
, &console
->window
->update
);
572 /* compute window size from desired client size */
573 win_width
= console
->active
->win
.right
- console
->active
->win
.left
+ 1;
574 win_height
= console
->active
->win
.bottom
- console
->active
->win
.top
+ 1;
576 if (update_all
|| win_width
!= console
->window
->win_width
||
577 win_height
!= console
->window
->win_height
)
579 console
->window
->win_width
= win_width
;
580 console
->window
->win_height
= win_height
;
583 r
.right
= win_width
* console
->active
->font
.width
;
584 r
.bottom
= win_height
* console
->active
->font
.height
;
585 AdjustWindowRect( &r
, GetWindowLongW( console
->win
, GWL_STYLE
), FALSE
);
588 if (console
->active
->width
> win_width
)
590 dy
= GetSystemMetrics( SM_CYHSCROLL
);
591 SetScrollRange( console
->win
, SB_HORZ
, 0, console
->active
->width
- win_width
, FALSE
);
592 SetScrollPos( console
->win
, SB_VERT
, console
->active
->win
.top
, FALSE
);
593 ShowScrollBar( console
->win
, SB_HORZ
, TRUE
);
597 ShowScrollBar( console
->win
, SB_HORZ
, FALSE
);
600 if (console
->active
->height
> win_height
)
602 dx
= GetSystemMetrics( SM_CXVSCROLL
);
603 SetScrollRange( console
->win
, SB_VERT
, 0, console
->active
->height
- win_height
, FALSE
);
604 SetScrollPos( console
->win
, SB_VERT
, console
->active
->win
.top
, FALSE
);
605 ShowScrollBar( console
->win
, SB_VERT
, TRUE
);
608 ShowScrollBar( console
->win
, SB_VERT
, FALSE
);
610 dx
+= r
.right
- r
.left
;
611 dy
+= r
.bottom
- r
.top
;
612 SetWindowPos( console
->win
, 0, 0, 0, dx
, dy
, SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
614 SystemParametersInfoW( SPI_GETWORKAREA
, 0, &r
, 0 );
615 console
->active
->max_width
= (r
.right
- r
.left
) / console
->active
->font
.width
;
616 console
->active
->max_height
= (r
.bottom
- r
.top
- GetSystemMetrics( SM_CYCAPTION
)) /
617 console
->active
->font
.height
;
619 InvalidateRect( console
->win
, NULL
, FALSE
);
620 UpdateWindow( console
->win
);
623 else if (console
->active
->win
.left
!= console
->window
->win_pos
.X
||
624 console
->active
->win
.top
!= console
->window
->win_pos
.Y
)
626 ScrollWindow( console
->win
,
627 (console
->window
->win_pos
.X
- console
->active
->win
.left
) * console
->active
->font
.width
,
628 (console
->window
->win_pos
.Y
- console
->active
->win
.top
) * console
->active
->font
.height
,
630 SetScrollPos( console
->win
, SB_HORZ
, console
->active
->win
.left
, TRUE
);
631 SetScrollPos( console
->win
, SB_VERT
, console
->active
->win
.top
, TRUE
);
632 InvalidateRect( console
->win
, NULL
, FALSE
);
635 console
->window
->win_pos
.X
= console
->active
->win
.left
;
636 console
->window
->win_pos
.Y
= console
->active
->win
.top
;
638 if (console
->window
->update
.top
<= console
->window
->update
.bottom
&&
639 console
->window
->update
.left
<= console
->window
->update
.right
)
641 RECT
*update
= &console
->window
->update
;
642 r
.left
= (update
->left
- console
->active
->win
.left
) * console
->active
->font
.width
;
643 r
.right
= (update
->right
- console
->active
->win
.left
+ 1) * console
->active
->font
.width
;
644 r
.top
= (update
->top
- console
->active
->win
.top
) * console
->active
->font
.height
;
645 r
.bottom
= (update
->bottom
- console
->active
->win
.top
+ 1) * console
->active
->font
.height
;
646 fill_mem_dc( console
, update
);
647 empty_update_rect( console
->active
, &console
->window
->update
);
648 InvalidateRect( console
->win
, &r
, FALSE
);
649 UpdateWindow( console
->win
);
652 if (update_all
|| console
->active
->cursor_size
!= console
->window
->cursor_size
)
654 console
->window
->cursor_size
= console
->active
->cursor_size
;
655 shape_cursor( console
);
658 if (console
->active
->cursor_visible
!= console
->window
->cursor_visible
)
660 console
->window
->cursor_visible
= console
->active
->cursor_visible
;
661 if (console
->win
== GetFocus())
663 if (console
->window
->cursor_visible
)
665 CreateCaret( console
->win
, console
->window
->cursor_bitmap
,
666 console
->active
->font
.width
, console
->active
->font
.height
);
667 update_window_cursor( console
);
674 if (update_all
|| get_bounded_cursor_x( console
->active
) != console
->window
->cursor_pos
.X
||
675 console
->active
->cursor_y
!= console
->window
->cursor_pos
.Y
)
677 console
->window
->cursor_pos
.X
= get_bounded_cursor_x( console
->active
);
678 console
->window
->cursor_pos
.Y
= console
->active
->cursor_y
;
679 update_window_cursor( console
);
682 console
->window
->update_state
= UPDATE_NONE
;
685 /* get the relevant information from the font described in lf and store them in config */
686 static HFONT
select_font_config( struct console_config
*config
, unsigned int cp
, HWND hwnd
,
689 HFONT font
, old_font
;
694 if (!(dc
= GetDC( hwnd
))) return NULL
;
695 if (!(font
= CreateFontIndirectW( lf
)))
697 ReleaseDC( hwnd
, dc
);
701 old_font
= SelectObject( dc
, font
);
702 GetTextMetricsW( dc
, &tm
);
703 SelectObject( dc
, old_font
);
704 ReleaseDC( hwnd
, dc
);
706 config
->cell_width
= tm
.tmAveCharWidth
;
707 config
->cell_height
= tm
.tmHeight
+ tm
.tmExternalLeading
;
708 config
->font_weight
= tm
.tmWeight
;
709 lstrcpyW( config
->face_name
, lf
->lfFaceName
);
711 /* FIXME: use maximum width for DBCS codepages since some chars take two cells */
712 if (GetCPInfo( cp
, &cpinfo
) && cpinfo
.MaxCharSize
== 2)
713 config
->cell_width
= tm
.tmMaxCharWidth
;
718 static void fill_logfont( LOGFONTW
*lf
, const WCHAR
*face_name
, size_t face_name_size
,
719 unsigned int height
, unsigned int weight
)
721 lf
->lfHeight
= height
;
723 lf
->lfEscapement
= 0;
724 lf
->lfOrientation
= 0;
725 lf
->lfWeight
= weight
;
726 lf
->lfItalic
= FALSE
;
727 lf
->lfUnderline
= FALSE
;
728 lf
->lfStrikeOut
= FALSE
;
729 lf
->lfCharSet
= DEFAULT_CHARSET
;
730 lf
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
731 lf
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
732 lf
->lfQuality
= DEFAULT_QUALITY
;
733 lf
->lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
734 face_name_size
= min( face_name_size
, sizeof(lf
->lfFaceName
) - sizeof(WCHAR
) );
735 memcpy( lf
->lfFaceName
, face_name
, face_name_size
);
736 lf
->lfFaceName
[face_name_size
/ sizeof(WCHAR
)] = 0;
739 static BOOL
set_console_font( struct console
*console
, const LOGFONTW
*logfont
)
741 struct font_info
*font_info
= &console
->active
->font
;
742 HFONT font
, old_font
;
744 WCHAR face_name
[LF_FACESIZE
];
748 TRACE( "%s\n", debugstr_logfont( logfont
, 0 ));
750 if (console
->window
->font
&& logfont
->lfHeight
== console
->active
->font
.height
&&
751 logfont
->lfWeight
== console
->active
->font
.weight
&&
752 !logfont
->lfItalic
&& !logfont
->lfUnderline
&& !logfont
->lfStrikeOut
&&
753 console
->active
->font
.face_len
== wcslen( logfont
->lfFaceName
) &&
754 !memcmp( logfont
->lfFaceName
, console
->active
->font
.face_name
,
755 console
->active
->font
.face_len
* sizeof(WCHAR
) ))
757 TRACE( "equal to current\n" );
761 if (!(dc
= GetDC( console
->win
))) return FALSE
;
762 if (!(font
= CreateFontIndirectW( logfont
)))
764 ReleaseDC( console
->win
, dc
);
768 old_font
= SelectObject( dc
, font
);
769 GetTextMetricsW( dc
, &tm
);
770 font_info
->face_len
= GetTextFaceW( dc
, ARRAY_SIZE(face_name
), face_name
) - 1;
771 SelectObject( dc
, old_font
);
772 ReleaseDC( console
->win
, dc
);
774 font_info
->width
= tm
.tmAveCharWidth
;
775 font_info
->height
= tm
.tmHeight
+ tm
.tmExternalLeading
;
776 font_info
->pitch_family
= tm
.tmPitchAndFamily
;
777 font_info
->weight
= tm
.tmWeight
;
779 free( font_info
->face_name
);
780 font_info
->face_name
= malloc( font_info
->face_len
* sizeof(WCHAR
) );
781 memcpy( font_info
->face_name
, face_name
, font_info
->face_len
* sizeof(WCHAR
) );
783 /* FIXME: use maximum width for DBCS codepages since some chars take two cells */
784 if (GetCPInfo( console
->output_cp
, &cpinfo
) && cpinfo
.MaxCharSize
== 2)
785 font_info
->width
= tm
.tmMaxCharWidth
;
787 if (console
->window
->font
) DeleteObject( console
->window
->font
);
788 console
->window
->font
= font
;
789 console
->window
->ext_leading
= tm
.tmExternalLeading
;
791 if (console
->window
->bitmap
)
793 DeleteObject(console
->window
->bitmap
);
794 console
->window
->bitmap
= NULL
;
801 struct console
*console
;
803 unsigned int font_height
;
804 unsigned int font_width
;
808 /* check if the font described in tm is usable as a font for the renderer */
809 static BOOL
validate_font_metric( struct console
*console
, const TEXTMETRICW
*tm
,
810 DWORD type
, int pass
)
812 switch (pass
) /* we get increasingly lenient in later passes */
815 if (type
& RASTER_FONTTYPE
) return FALSE
;
818 if (type
& RASTER_FONTTYPE
)
820 if (tm
->tmMaxCharWidth
* (console
->active
->win
.right
- console
->active
->win
.left
+ 1)
821 >= GetSystemMetrics(SM_CXSCREEN
))
823 if (tm
->tmHeight
* (console
->active
->win
.bottom
- console
->active
->win
.top
+ 1)
824 >= GetSystemMetrics(SM_CYSCREEN
))
829 if (tm
->tmCharSet
!= DEFAULT_CHARSET
&& tm
->tmCharSet
!= console
->window
->ui_charset
)
833 if (tm
->tmItalic
|| tm
->tmUnderlined
|| tm
->tmStruckOut
) return FALSE
;
839 /* check if the font family described in lf is usable as a font for the renderer */
840 static BOOL
validate_font( struct console
*console
, const LOGFONTW
*lf
, int pass
)
842 switch (pass
) /* we get increasingly lenient in later passes */
847 if (lf
->lfCharSet
!= DEFAULT_CHARSET
&& lf
->lfCharSet
!= console
->window
->ui_charset
)
851 if ((lf
->lfPitchAndFamily
& 3) != FIXED_PITCH
) return FALSE
;
854 if (lf
->lfFaceName
[0] == '@') return FALSE
;
860 static int CALLBACK
enum_first_font_proc( const LOGFONTW
*lf
, const TEXTMETRICW
*tm
,
861 DWORD font_type
, LPARAM lparam
)
863 struct font_chooser
*fc
= (struct font_chooser
*)lparam
;
866 if (font_type
!= TRUETYPE_FONTTYPE
) return 1;
868 TRACE( "%s\n", debugstr_logfont( lf
, font_type
));
870 if (!validate_font( fc
->console
, lf
, fc
->pass
))
873 TRACE( "%s\n", debugstr_textmetric( tm
, font_type
));
875 if (!validate_font_metric( fc
->console
, tm
, font_type
, fc
->pass
))
878 /* set default font size */
880 mlf
.lfHeight
= fc
->font_height
;
881 mlf
.lfWidth
= fc
->font_width
;
883 if (!set_console_font( fc
->console
, &mlf
))
891 static void set_first_font( struct console
*console
, struct console_config
*config
)
894 struct font_chooser fc
;
896 TRACE("Looking for a suitable console font\n");
898 memset( &lf
, 0, sizeof(lf
) );
899 lf
.lfCharSet
= DEFAULT_CHARSET
;
900 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_MODERN
;
902 fc
.console
= console
;
903 fc
.font_height
= config
->cell_height
;
904 fc
.font_width
= config
->cell_width
;
907 for (fc
.pass
= 0; fc
.pass
<= 5; fc
.pass
++)
909 EnumFontFamiliesExW( console
->window
->mem_dc
, &lf
, enum_first_font_proc
, (LPARAM
)&fc
, 0);
914 ERR("Unable to find a valid console font\n");
916 /* Update active configuration */
917 config
->cell_width
= console
->active
->font
.width
;
918 config
->cell_height
= console
->active
->font
.height
;
919 config
->font_pitch_family
= console
->active
->font
.pitch_family
;
920 memcpy( config
->face_name
, console
->active
->font
.face_name
,
921 console
->active
->font
.face_len
* sizeof(WCHAR
) );
922 config
->face_name
[console
->active
->font
.face_len
] = 0;
924 /* Save default console configuration to the registry */
925 save_config( NULL
, config
);
928 /* Sets the font specified in the LOGFONT as the new console font */
929 void update_console_font( struct console
*console
, const WCHAR
*face_name
, size_t face_name_size
,
930 unsigned int height
, unsigned int weight
)
934 if (!console
->window
) return;
936 fill_logfont( &lf
, face_name
, face_name_size
, height
, weight
);
938 set_console_font( console
, &lf
);
941 /* get a cell from a relative coordinate in window (takes into account the scrolling) */
942 static COORD
get_cell( struct console
*console
, LPARAM lparam
)
945 c
.X
= console
->active
->win
.left
+ (short)LOWORD(lparam
) / console
->active
->font
.width
;
946 c
.Y
= console
->active
->win
.top
+ (short)HIWORD(lparam
) / console
->active
->font
.height
;
950 /* get the console bit mask equivalent to the VK_ status in key state */
951 static DWORD
get_ctrl_state( BYTE
*key_state
)
953 unsigned int ret
= 0;
955 GetKeyboardState(key_state
);
956 if (key_state
[VK_SHIFT
] & 0x80) ret
|= SHIFT_PRESSED
;
957 if (key_state
[VK_LCONTROL
] & 0x80) ret
|= LEFT_CTRL_PRESSED
;
958 if (key_state
[VK_RCONTROL
] & 0x80) ret
|= RIGHT_CTRL_PRESSED
;
959 if (key_state
[VK_LMENU
] & 0x80) ret
|= LEFT_ALT_PRESSED
;
960 if (key_state
[VK_RMENU
] & 0x80) ret
|= RIGHT_ALT_PRESSED
;
961 if (key_state
[VK_CAPITAL
] & 0x01) ret
|= CAPSLOCK_ON
;
962 if (key_state
[VK_NUMLOCK
] & 0x01) ret
|= NUMLOCK_ON
;
963 if (key_state
[VK_SCROLL
] & 0x01) ret
|= SCROLLLOCK_ON
;
968 /* get the selection rectangle */
969 static void get_selection_rect( struct console
*console
, RECT
*r
)
971 r
->left
= (min(console
->window
->selection_start
.X
, console
->window
->selection_end
.X
) -
972 console
->active
->win
.left
) * console
->active
->font
.width
;
973 r
->top
= (min(console
->window
->selection_start
.Y
, console
->window
->selection_end
.Y
) -
974 console
->active
->win
.top
) * console
->active
->font
.height
;
975 r
->right
= (max(console
->window
->selection_start
.X
, console
->window
->selection_end
.X
) + 1 -
976 console
->active
->win
.left
) * console
->active
->font
.width
;
977 r
->bottom
= (max(console
->window
->selection_start
.Y
, console
->window
->selection_end
.Y
) + 1 -
978 console
->active
->win
.top
) * console
->active
->font
.height
;
981 static void update_selection( struct console
*console
, HDC ref_dc
)
986 get_selection_rect( console
, &r
);
987 dc
= ref_dc
? ref_dc
: GetDC( console
->win
);
990 if (console
->win
== GetFocus() && console
->active
->cursor_visible
)
991 HideCaret( console
->win
);
992 InvertRect( dc
, &r
);
994 ReleaseDC( console
->win
, dc
);
995 if (console
->win
== GetFocus() && console
->active
->cursor_visible
)
996 ShowCaret( console
->win
);
999 static void move_selection( struct console
*console
, COORD c1
, COORD c2
)
1004 if (c1
.X
< 0 || c1
.X
>= console
->active
->width
||
1005 c2
.X
< 0 || c2
.X
>= console
->active
->width
||
1006 c1
.Y
< 0 || c1
.Y
>= console
->active
->height
||
1007 c2
.Y
< 0 || c2
.Y
>= console
->active
->height
)
1010 get_selection_rect( console
, &r
);
1011 dc
= GetDC( console
->win
);
1014 if (console
->win
== GetFocus() && console
->active
->cursor_visible
)
1015 HideCaret( console
->win
);
1016 InvertRect( dc
, &r
);
1018 console
->window
->selection_start
= c1
;
1019 console
->window
->selection_end
= c2
;
1022 get_selection_rect( console
, &r
);
1023 InvertRect( dc
, &r
);
1024 ReleaseDC( console
->win
, dc
);
1025 if (console
->win
== GetFocus() && console
->active
->cursor_visible
)
1026 ShowCaret( console
->win
);
1030 /* copies the current selection into the clipboard */
1031 static void copy_selection( struct console
*console
)
1037 w
= abs( console
->window
->selection_start
.X
- console
->window
->selection_end
.X
) + 1;
1038 h
= abs( console
->window
->selection_start
.Y
- console
->window
->selection_end
.Y
) + 1;
1040 if (!OpenClipboard( console
->win
)) return;
1043 mem
= GlobalAlloc( GMEM_MOVEABLE
, (w
+ 1) * h
* sizeof(WCHAR
) );
1044 if (mem
&& (p
= buf
= GlobalLock( mem
)))
1049 c
.X
= min( console
->window
->selection_start
.X
, console
->window
->selection_end
.X
);
1050 c
.Y
= min( console
->window
->selection_start
.Y
, console
->window
->selection_end
.Y
);
1052 for (y
= c
.Y
; y
< c
.Y
+ h
; y
++)
1056 for (x
= c
.X
; x
< c
.X
+ w
; x
++)
1057 p
[x
- c
.X
] = console
->active
->data
[y
* console
->active
->width
+ x
].ch
;
1059 /* strip spaces from the end of the line */
1061 while (end
> p
&& *(end
- 1) == ' ')
1063 *end
= (y
< c
.Y
+ h
- 1) ? '\n' : '\0';
1067 TRACE( "%s\n", debugstr_w( buf
));
1068 if (p
- buf
!= (w
+ 1) * h
)
1071 new_mem
= GlobalReAlloc( mem
, (p
- buf
) * sizeof(WCHAR
), GMEM_MOVEABLE
);
1072 if (new_mem
) mem
= new_mem
;
1074 GlobalUnlock( mem
);
1075 SetClipboardData( CF_UNICODETEXT
, mem
);
1080 static void paste_clipboard( struct console
*console
)
1085 if (!OpenClipboard( console
->win
)) return;
1086 h
= GetClipboardData( CF_UNICODETEXT
);
1087 if (h
&& (ptr
= GlobalLock( h
)))
1089 unsigned int i
, len
= GlobalSize(h
) / sizeof(WCHAR
);
1093 ir
[0].EventType
= KEY_EVENT
;
1094 ir
[0].Event
.KeyEvent
.wRepeatCount
= 0;
1095 ir
[0].Event
.KeyEvent
.dwControlKeyState
= 0;
1096 ir
[0].Event
.KeyEvent
.bKeyDown
= TRUE
;
1098 /* generate the corresponding input records */
1099 for (i
= 0; i
< len
; i
++)
1101 /* FIXME: the modifying keys are not generated (shift, ctrl...) */
1102 sh
= VkKeyScanW( ptr
[i
] );
1103 ir
[0].Event
.KeyEvent
.wVirtualKeyCode
= LOBYTE(sh
);
1104 ir
[0].Event
.KeyEvent
.wVirtualScanCode
= MapVirtualKeyW( LOBYTE(sh
), 0 );
1105 ir
[0].Event
.KeyEvent
.uChar
.UnicodeChar
= ptr
[i
];
1108 ir
[1].Event
.KeyEvent
.bKeyDown
= FALSE
;
1110 write_console_input( console
, ir
, 2, i
== len
- 1 );
1118 /* handle keys while selecting an area */
1119 static void handle_selection_key( struct console
*console
, BOOL down
, WPARAM wparam
, LPARAM lparam
)
1121 BYTE key_state
[256];
1126 state
= get_ctrl_state( key_state
) & ~(CAPSLOCK_ON
|NUMLOCK_ON
|SCROLLLOCK_ON
);
1134 console
->window
->in_selection
= FALSE
;
1135 update_selection( console
, 0 );
1136 copy_selection( console
);
1139 c1
= console
->window
->selection_start
;
1140 c2
= console
->window
->selection_end
;
1142 move_selection( console
, c1
, c2
);
1145 c1
= console
->window
->selection_start
;
1146 c2
= console
->window
->selection_end
;
1148 move_selection( console
, c1
, c2
);
1151 c1
= console
->window
->selection_start
;
1152 c2
= console
->window
->selection_end
;
1154 move_selection( console
, c1
, c2
);
1157 c1
= console
->window
->selection_start
;
1158 c2
= console
->window
->selection_end
;
1160 move_selection( console
, c1
, c2
);
1168 c1
= console
->window
->selection_start
;
1169 c2
= console
->window
->selection_end
;
1171 move_selection( console
, c1
, c2
);
1174 c1
= console
->window
->selection_start
;
1175 c2
= console
->window
->selection_end
;
1177 move_selection( console
, c1
, c2
);
1180 c1
= console
->window
->selection_start
;
1181 c2
= console
->window
->selection_end
;
1183 move_selection( console
, c1
, c2
);
1186 c1
= console
->window
->selection_start
;
1187 c2
= console
->window
->selection_end
;
1189 move_selection( console
, c1
, c2
);
1195 if (wparam
< VK_SPACE
) /* Shift, Alt, Ctrl, Num Lock etc. */
1198 update_selection( console
, 0 );
1199 console
->window
->in_selection
= FALSE
;
1202 /* generate input_record from windows WM_KEYUP/WM_KEYDOWN messages */
1203 static void record_key_input( struct console
*console
, BOOL down
, WPARAM wparam
, LPARAM lparam
)
1205 static WCHAR last
; /* keep last char seen as feed for key up message */
1206 BYTE key_state
[256];
1210 ir
.EventType
= KEY_EVENT
;
1211 ir
.Event
.KeyEvent
.bKeyDown
= down
;
1212 ir
.Event
.KeyEvent
.wRepeatCount
= LOWORD(lparam
);
1213 ir
.Event
.KeyEvent
.wVirtualKeyCode
= wparam
;
1214 ir
.Event
.KeyEvent
.wVirtualScanCode
= HIWORD(lparam
) & 0xFF;
1215 ir
.Event
.KeyEvent
.uChar
.UnicodeChar
= 0;
1216 ir
.Event
.KeyEvent
.dwControlKeyState
= get_ctrl_state( key_state
);
1217 if (lparam
& (1u << 24)) ir
.Event
.KeyEvent
.dwControlKeyState
|= ENHANCED_KEY
;
1221 switch (ToUnicode(wparam
, HIWORD(lparam
), key_state
, buf
, 2, 0))
1224 /* FIXME: should generate two events */
1234 ir
.Event
.KeyEvent
.uChar
.UnicodeChar
= last
;
1235 if (!down
) last
= 0; /* FIXME: buggy HACK */
1237 write_console_input( console
, &ir
, 1, TRUE
);
1240 /* generate input_record from WM_CHAR message. */
1241 static void record_char_input( struct console
*console
, WCHAR ch
, LPARAM lparam
)
1244 SHORT sh
= VkKeyScanW( ch
);
1246 if (sh
== ~0) return;
1247 ir
.EventType
= KEY_EVENT
;
1248 ir
.Event
.KeyEvent
.bKeyDown
= TRUE
;
1249 ir
.Event
.KeyEvent
.wRepeatCount
= 0;
1250 ir
.Event
.KeyEvent
.wVirtualKeyCode
= LOBYTE(sh
);
1251 ir
.Event
.KeyEvent
.wVirtualScanCode
= MapVirtualKeyW( LOBYTE(sh
), 0 );
1252 ir
.Event
.KeyEvent
.uChar
.UnicodeChar
= ch
;
1253 ir
.Event
.KeyEvent
.dwControlKeyState
= 0;
1254 if (lparam
& (1u << 24)) ir
.Event
.KeyEvent
.dwControlKeyState
|= ENHANCED_KEY
;
1256 write_console_input( console
, &ir
, 1, TRUE
);
1259 static void record_mouse_input( struct console
*console
, COORD c
, WPARAM wparam
, DWORD event
)
1261 BYTE key_state
[256];
1264 /* MOUSE_EVENTs shouldn't be sent unless ENABLE_MOUSE_INPUT is active */
1265 if (!(console
->mode
& ENABLE_MOUSE_INPUT
)) return;
1267 ir
.EventType
= MOUSE_EVENT
;
1268 ir
.Event
.MouseEvent
.dwMousePosition
= c
;
1269 ir
.Event
.MouseEvent
.dwButtonState
= 0;
1270 if (wparam
& MK_LBUTTON
) ir
.Event
.MouseEvent
.dwButtonState
|= FROM_LEFT_1ST_BUTTON_PRESSED
;
1271 if (wparam
& MK_MBUTTON
) ir
.Event
.MouseEvent
.dwButtonState
|= FROM_LEFT_2ND_BUTTON_PRESSED
;
1272 if (wparam
& MK_RBUTTON
) ir
.Event
.MouseEvent
.dwButtonState
|= RIGHTMOST_BUTTON_PRESSED
;
1273 if (wparam
& MK_CONTROL
) ir
.Event
.MouseEvent
.dwButtonState
|= LEFT_CTRL_PRESSED
;
1274 if (wparam
& MK_SHIFT
) ir
.Event
.MouseEvent
.dwButtonState
|= SHIFT_PRESSED
;
1275 if (event
== MOUSE_WHEELED
) ir
.Event
.MouseEvent
.dwButtonState
|= wparam
& 0xFFFF0000;
1276 ir
.Event
.MouseEvent
.dwControlKeyState
= get_ctrl_state( key_state
);
1277 ir
.Event
.MouseEvent
.dwEventFlags
= event
;
1279 write_console_input( console
, &ir
, 1, TRUE
);
1284 struct console
*console
;
1285 struct console_config config
;
1286 HWND dialog
; /* handle to active propsheet */
1289 /* dialog proc for the option property sheet */
1290 static INT_PTR WINAPI
option_dialog_proc( HWND dialog
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1292 struct dialog_info
*di
;
1298 di
= (struct dialog_info
*)((PROPSHEETPAGEA
*)lparam
)->lParam
;
1299 di
->dialog
= dialog
;
1300 SetWindowLongPtrW( dialog
, DWLP_USER
, (LONG_PTR
)di
);
1302 SendMessageW( GetDlgItem( dialog
, IDC_OPT_HIST_SIZE_UD
), UDM_SETRANGE
, 0, MAKELPARAM(500, 0) );
1304 if (di
->config
.cursor_size
<= 25) idc
= IDC_OPT_CURSOR_SMALL
;
1305 else if (di
->config
.cursor_size
<= 50) idc
= IDC_OPT_CURSOR_MEDIUM
;
1306 else idc
= IDC_OPT_CURSOR_LARGE
;
1308 SendDlgItemMessageW( dialog
, idc
, BM_SETCHECK
, BST_CHECKED
, 0 );
1309 SetDlgItemInt( dialog
, IDC_OPT_HIST_SIZE
, di
->config
.history_size
, FALSE
);
1310 SendDlgItemMessageW( dialog
, IDC_OPT_HIST_NODOUBLE
, BM_SETCHECK
,
1311 (di
->config
.history_mode
) ? BST_CHECKED
: BST_UNCHECKED
, 0 );
1312 SendDlgItemMessageW( dialog
, IDC_OPT_INSERT_MODE
, BM_SETCHECK
,
1313 (di
->config
.insert_mode
) ? BST_CHECKED
: BST_UNCHECKED
, 0 );
1314 SendDlgItemMessageW( dialog
, IDC_OPT_CONF_CTRL
, BM_SETCHECK
,
1315 (di
->config
.menu_mask
& MK_CONTROL
) ? BST_CHECKED
: BST_UNCHECKED
, 0 );
1316 SendDlgItemMessageW( dialog
, IDC_OPT_CONF_SHIFT
, BM_SETCHECK
,
1317 (di
->config
.menu_mask
& MK_SHIFT
) ? BST_CHECKED
: BST_UNCHECKED
, 0 );
1318 SendDlgItemMessageW( dialog
, IDC_OPT_QUICK_EDIT
, BM_SETCHECK
,
1319 (di
->config
.quick_edit
) ? BST_CHECKED
: BST_UNCHECKED
, 0 );
1320 return FALSE
; /* because we set the focus */
1327 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
1331 di
= (struct dialog_info
*)GetWindowLongPtrW( dialog
, DWLP_USER
);
1333 switch (nmhdr
->code
)
1336 /* needed in propsheet to keep properly the selected radio button
1337 * otherwise, the focus would be set to the first tab stop in the
1338 * propsheet, which would always activate the first radio button
1340 if (IsDlgButtonChecked( dialog
, IDC_OPT_CURSOR_SMALL
) == BST_CHECKED
)
1341 idc
= IDC_OPT_CURSOR_SMALL
;
1342 else if (IsDlgButtonChecked( dialog
, IDC_OPT_CURSOR_MEDIUM
) == BST_CHECKED
)
1343 idc
= IDC_OPT_CURSOR_MEDIUM
;
1345 idc
= IDC_OPT_CURSOR_LARGE
;
1346 PostMessageW( dialog
, WM_NEXTDLGCTL
, (WPARAM
)GetDlgItem( dialog
, idc
), TRUE
);
1347 di
->dialog
= dialog
;
1350 if (IsDlgButtonChecked( dialog
, IDC_OPT_CURSOR_SMALL
) == BST_CHECKED
) val
= 25;
1351 else if (IsDlgButtonChecked( dialog
, IDC_OPT_CURSOR_MEDIUM
) == BST_CHECKED
) val
= 50;
1353 di
->config
.cursor_size
= val
;
1355 val
= GetDlgItemInt( dialog
, IDC_OPT_HIST_SIZE
, &done
, FALSE
);
1356 if (done
) di
->config
.history_size
= val
;
1358 val
= (IsDlgButtonChecked( dialog
, IDC_OPT_HIST_NODOUBLE
) & BST_CHECKED
) != 0;
1359 di
->config
.history_mode
= val
;
1361 val
= (IsDlgButtonChecked( dialog
, IDC_OPT_INSERT_MODE
) & BST_CHECKED
) != 0;
1362 di
->config
.insert_mode
= val
;
1365 if (IsDlgButtonChecked( dialog
, IDC_OPT_CONF_CTRL
) & BST_CHECKED
) val
|= MK_CONTROL
;
1366 if (IsDlgButtonChecked( dialog
, IDC_OPT_CONF_SHIFT
) & BST_CHECKED
) val
|= MK_SHIFT
;
1367 di
->config
.menu_mask
= val
;
1369 val
= (IsDlgButtonChecked( dialog
, IDC_OPT_QUICK_EDIT
) & BST_CHECKED
) != 0;
1370 di
->config
.quick_edit
= val
;
1372 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
1385 static COLORREF
get_color( struct dialog_info
*di
, unsigned int idc
)
1389 index
= GetWindowLongW(GetDlgItem( di
->dialog
, idc
), 0);
1390 return di
->config
.color_map
[index
];
1393 /* window proc for font previewer in font property sheet */
1394 static LRESULT WINAPI
font_preview_proc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1399 SetWindowLongPtrW( hwnd
, 0, 0 );
1403 return GetWindowLongPtrW( hwnd
, 0 );
1406 SetWindowLongPtrW( hwnd
, 0, wparam
);
1409 InvalidateRect( hwnd
, NULL
, TRUE
);
1410 UpdateWindow( hwnd
);
1416 HFONT font
= (HFONT
)GetWindowLongPtrW( hwnd
, 0 );
1417 if (font
) DeleteObject( font
);
1423 struct dialog_info
*di
;
1424 HFONT font
, old_font
;
1427 di
= (struct dialog_info
*)GetWindowLongPtrW( GetParent( hwnd
), DWLP_USER
);
1428 BeginPaint( hwnd
, &ps
);
1430 font
= (HFONT
)GetWindowLongPtrW( hwnd
, 0 );
1433 static const WCHAR ascii
[] = L
"ASCII: abcXYZ";
1438 old_font
= SelectObject( ps
.hdc
, font
);
1439 bkcolor
= get_color( di
, IDC_FNT_COLOR_BK
);
1440 FillRect( ps
.hdc
, &ps
.rcPaint
, CreateSolidBrush( bkcolor
));
1441 SetBkColor( ps
.hdc
, bkcolor
);
1442 SetTextColor( ps
.hdc
, get_color( di
, IDC_FNT_COLOR_FG
));
1443 len
= LoadStringW( GetModuleHandleW(NULL
), IDS_FNT_PREVIEW
, buf
, ARRAY_SIZE(buf
) );
1444 if (len
) TextOutW( ps
.hdc
, 0, 0, buf
, len
);
1445 TextOutW( ps
.hdc
, 0, di
->config
.cell_height
, ascii
, ARRAY_SIZE(ascii
) - 1 );
1446 SelectObject( ps
.hdc
, old_font
);
1448 EndPaint( hwnd
, &ps
);
1453 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1458 /* window proc for color previewer */
1459 static LRESULT WINAPI
color_preview_proc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1465 struct dialog_info
*di
;
1471 BeginPaint( hwnd
, &ps
);
1472 GetClientRect( hwnd
, &client
);
1473 step
= client
.right
/ 8;
1475 di
= (struct dialog_info
*)GetWindowLongPtrW( GetParent(hwnd
), DWLP_USER
);
1477 for (i
= 0; i
< 16; i
++)
1479 r
.top
= (i
/ 8) * (client
.bottom
/ 2);
1480 r
.bottom
= r
.top
+ client
.bottom
/ 2;
1481 r
.left
= (i
& 7) * step
;
1482 r
.right
= r
.left
+ step
;
1483 brush
= CreateSolidBrush( di
->config
.color_map
[i
] );
1484 FillRect( ps
.hdc
, &r
, brush
);
1485 DeleteObject( brush
);
1486 if (GetWindowLongW( hwnd
, 0 ) == i
)
1491 old_pen
= SelectObject( ps
.hdc
, GetStockObject( WHITE_PEN
));
1492 r
.right
--; r
.bottom
--;
1495 MoveToEx( ps
.hdc
, r
.left
, r
.bottom
, NULL
);
1496 LineTo( ps
.hdc
, r
.left
, r
.top
);
1497 LineTo( ps
.hdc
, r
.right
, r
.top
);
1498 SelectObject( ps
.hdc
, GetStockObject( BLACK_PEN
));
1499 LineTo( ps
.hdc
, r
.right
, r
.bottom
);
1500 LineTo( ps
.hdc
, r
.left
, r
.bottom
);
1501 if (--i
== 0) break;
1502 r
.left
++; r
.top
++; r
.right
--; r
.bottom
--;
1503 SelectObject( ps
.hdc
, GetStockObject( WHITE_PEN
));
1505 SelectObject( ps
.hdc
, old_pen
);
1508 EndPaint( hwnd
, &ps
);
1512 case WM_LBUTTONDOWN
:
1517 GetClientRect( hwnd
, &client
);
1518 step
= client
.right
/ 8;
1519 i
= (HIWORD(lparam
) >= client
.bottom
/ 2) ? 8 : 0;
1520 i
+= LOWORD(lparam
) / step
;
1521 SetWindowLongW( hwnd
, 0, i
);
1522 InvalidateRect( GetDlgItem( GetParent( hwnd
), IDC_FNT_PREVIEW
), NULL
, FALSE
);
1523 InvalidateRect( hwnd
, NULL
, FALSE
);
1528 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1533 static BOOL
select_font( struct dialog_info
*di
)
1535 int font_idx
, size_idx
;
1536 WCHAR face_name
[LF_FACESIZE
], height_buf
[4];
1538 unsigned int font_height
;
1540 HFONT font
, old_font
;
1545 font_idx
= SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_FONT
, LB_GETCURSEL
, 0, 0 );
1546 size_idx
= SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_SIZE
, LB_GETCURSEL
, 0, 0 );
1548 if (font_idx
< 0 || size_idx
< 0)
1551 len
= SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_FONT
, LB_GETTEXT
, font_idx
, (LPARAM
)&face_name
);
1552 SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_SIZE
, LB_GETTEXT
, size_idx
, (LPARAM
)&height_buf
);
1553 font_height
= _wtoi( height_buf
);
1555 fill_logfont( &lf
, face_name
, len
* sizeof(WCHAR
), font_height
, FW_NORMAL
);
1556 font
= select_font_config( &di
->config
, di
->console
->output_cp
, di
->console
->win
, &lf
);
1557 if (!font
) return FALSE
;
1559 if (di
->config
.cell_height
!= font_height
)
1560 TRACE( "mismatched heights (%u<>%u)\n", di
->config
.cell_height
, font_height
);
1562 old_font
= (HFONT
)SendDlgItemMessageW( di
->dialog
, IDC_FNT_PREVIEW
, WM_GETFONT
, 0, 0 );
1563 SendDlgItemMessageW( di
->dialog
, IDC_FNT_PREVIEW
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1564 if (old_font
) DeleteObject( old_font
);
1566 LoadStringW( GetModuleHandleW(NULL
), IDS_FNT_DISPLAY
, fmt
, ARRAY_SIZE(fmt
) );
1567 args
[0] = di
->config
.cell_width
;
1568 args
[1] = di
->config
.cell_height
;
1569 FormatMessageW( FORMAT_MESSAGE_FROM_STRING
|FORMAT_MESSAGE_ARGUMENT_ARRAY
,
1570 fmt
, 0, 0, buf
, ARRAY_SIZE(buf
), (va_list *)args
);
1572 SendDlgItemMessageW( di
->dialog
, IDC_FNT_FONT_INFO
, WM_SETTEXT
, 0, (LPARAM
)buf
);
1576 static BOOL
fill_list_size( struct dialog_info
*di
, BOOL init
)
1580 static const int sizes
[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
1581 unsigned int i
, idx
= 4;
1584 for (i
= 0; i
< ARRAY_SIZE(sizes
); i
++)
1586 wsprintfW( buf
, L
"%u", sizes
[i
] );
1587 SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_SIZE
, LB_INSERTSTRING
, -1, (LPARAM
)buf
);
1589 if (di
->config
.cell_height
== sizes
[i
]) idx
= i
;
1592 SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_SIZE
, LB_SETCURSEL
, idx
, 0 );
1600 static int CALLBACK
enum_list_font_proc( const LOGFONTW
*lf
, const TEXTMETRICW
*tm
,
1601 DWORD font_type
, LPARAM lparam
)
1603 struct dialog_info
*di
= (struct dialog_info
*)lparam
;
1605 if (font_type
!= TRUETYPE_FONTTYPE
) return 1;
1607 TRACE( "%s\n", debugstr_logfont( lf
, font_type
));
1609 if (validate_font( di
->console
, lf
, 0 ))
1610 SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_FONT
, LB_ADDSTRING
, 0, (LPARAM
)lf
->lfFaceName
);
1615 static BOOL
fill_list_font( struct dialog_info
*di
)
1619 memset( &lf
, 0, sizeof(lf
) );
1620 lf
.lfCharSet
= DEFAULT_CHARSET
;
1621 lf
.lfFaceName
[0] = 0;
1622 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_MODERN
;
1624 EnumFontFamiliesExW( di
->console
->window
->mem_dc
, &lf
, enum_list_font_proc
, (LPARAM
)di
, 0 );
1626 if (SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_FONT
, LB_SELECTSTRING
,
1627 -1, (LPARAM
)di
->config
.face_name
) == LB_ERR
)
1628 SendDlgItemMessageW( di
->dialog
, IDC_FNT_LIST_FONT
, LB_SETCURSEL
, 0, 0 );
1630 fill_list_size( di
, TRUE
);
1635 /* dialog proc for the font property sheet */
1636 static INT_PTR WINAPI
font_dialog_proc( HWND dialog
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1638 struct dialog_info
*di
;
1643 di
= (struct dialog_info
*)((PROPSHEETPAGEA
*)lparam
)->lParam
;
1644 di
->dialog
= dialog
;
1645 SetWindowLongPtrW( dialog
, DWLP_USER
, (DWORD_PTR
)di
);
1646 /* use default system font until user-selected font is applied */
1647 SendDlgItemMessageW( dialog
, IDC_FNT_PREVIEW
, WM_SETFONT
, 0, 0 );
1648 fill_list_font( di
);
1649 SetWindowLongW( GetDlgItem( dialog
, IDC_FNT_COLOR_BK
), 0, (di
->config
.attr
>> 4) & 0x0F );
1650 SetWindowLongW( GetDlgItem( dialog
, IDC_FNT_COLOR_FG
), 0, di
->config
.attr
& 0x0F );
1654 di
= (struct dialog_info
*)GetWindowLongPtrW( dialog
, DWLP_USER
);
1655 switch (LOWORD(wparam
))
1657 case IDC_FNT_LIST_FONT
:
1658 if (HIWORD(wparam
) == LBN_SELCHANGE
)
1659 fill_list_size( di
, FALSE
);
1661 case IDC_FNT_LIST_SIZE
:
1662 if (HIWORD(wparam
) == LBN_SELCHANGE
)
1670 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
1673 di
= (struct dialog_info
*)GetWindowLongPtrW( dialog
, DWLP_USER
);
1674 switch (nmhdr
->code
)
1677 di
->dialog
= dialog
;
1680 val
= (GetWindowLongW( GetDlgItem( dialog
, IDC_FNT_COLOR_BK
), 0 ) << 4) |
1681 GetWindowLongW( GetDlgItem( dialog
, IDC_FNT_COLOR_FG
), 0 );
1682 di
->config
.attr
= val
;
1683 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
1696 /* dialog proc for the config property sheet */
1697 static INT_PTR WINAPI
config_dialog_proc( HWND dialog
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1699 struct dialog_info
*di
;
1705 di
= (struct dialog_info
*)((PROPSHEETPAGEA
*)lparam
)->lParam
;
1706 di
->dialog
= dialog
;
1708 SetWindowLongPtrW( dialog
, DWLP_USER
, (DWORD_PTR
)di
);
1709 SetDlgItemInt( dialog
, IDC_CNF_SB_WIDTH
, di
->config
.sb_width
, FALSE
);
1710 SetDlgItemInt( dialog
, IDC_CNF_SB_HEIGHT
, di
->config
.sb_height
, FALSE
);
1711 SetDlgItemInt( dialog
, IDC_CNF_WIN_WIDTH
, di
->config
.win_width
, FALSE
);
1712 SetDlgItemInt( dialog
, IDC_CNF_WIN_HEIGHT
, di
->config
.win_height
, FALSE
);
1714 SendMessageW( GetDlgItem(dialog
, IDC_CNF_WIN_HEIGHT_UD
), UDM_SETRANGE
, 0, MAKELPARAM(max_ud
, 0));
1715 SendMessageW( GetDlgItem(dialog
, IDC_CNF_WIN_WIDTH_UD
), UDM_SETRANGE
, 0, MAKELPARAM(max_ud
, 0));
1716 SendMessageW( GetDlgItem(dialog
, IDC_CNF_SB_HEIGHT_UD
), UDM_SETRANGE
, 0, MAKELPARAM(max_ud
, 0));
1717 SendMessageW( GetDlgItem(dialog
, IDC_CNF_SB_WIDTH_UD
), UDM_SETRANGE
, 0, MAKELPARAM(max_ud
, 0));
1719 SendDlgItemMessageW( dialog
, IDC_CNF_CLOSE_EXIT
, BM_SETCHECK
, BST_CHECKED
, 0 );
1721 SendDlgItemMessageW( dialog
, IDC_CNF_EDITION_MODE
, CB_ADDSTRING
, 0, (LPARAM
)L
"Win32" );
1722 SendDlgItemMessageW( dialog
, IDC_CNF_EDITION_MODE
, CB_ADDSTRING
, 0, (LPARAM
)L
"Emacs" );
1723 SendDlgItemMessageW( dialog
, IDC_CNF_EDITION_MODE
, CB_SETCURSEL
, di
->config
.edition_mode
, 0 );
1728 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
1729 int win_w
, win_h
, sb_w
, sb_h
;
1732 di
= (struct dialog_info
*)GetWindowLongPtrW( dialog
, DWLP_USER
);
1733 switch (nmhdr
->code
)
1736 di
->dialog
= dialog
;
1739 sb_w
= GetDlgItemInt( dialog
, IDC_CNF_SB_WIDTH
, &st1
, FALSE
);
1740 sb_h
= GetDlgItemInt( dialog
, IDC_CNF_SB_HEIGHT
, &st2
, FALSE
);
1743 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_INVALID
);
1746 win_w
= GetDlgItemInt( dialog
, IDC_CNF_WIN_WIDTH
, &st1
, FALSE
);
1747 win_h
= GetDlgItemInt( dialog
, IDC_CNF_WIN_HEIGHT
, &st2
, FALSE
);
1750 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_INVALID
);
1753 if (win_w
> sb_w
|| win_h
> sb_h
)
1758 LoadStringW( GetModuleHandleW(NULL
), IDS_DLG_TIT_ERROR
, cap
, ARRAY_SIZE(cap
) );
1759 LoadStringW( GetModuleHandleW(NULL
), IDS_DLG_ERR_SBWINSIZE
, txt
, ARRAY_SIZE(txt
) );
1761 MessageBoxW( dialog
, txt
, cap
, MB_OK
);
1762 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_INVALID
);
1765 di
->config
.win_width
= win_w
;
1766 di
->config
.win_height
= win_h
;
1767 di
->config
.sb_width
= sb_w
;
1768 di
->config
.sb_height
= sb_h
;
1770 di
->config
.edition_mode
= SendDlgItemMessageW( dialog
, IDC_CNF_EDITION_MODE
,
1771 CB_GETCURSEL
, 0, 0 );
1772 SetWindowLongPtrW( dialog
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
1785 static void apply_config( struct console
*console
, const struct console_config
*config
)
1787 if (console
->active
->width
!= config
->sb_width
|| console
->active
->height
!= config
->sb_height
)
1788 change_screen_buffer_size( console
->active
, config
->sb_width
, config
->sb_height
);
1790 console
->window
->menu_mask
= config
->menu_mask
;
1791 console
->window
->quick_edit
= config
->quick_edit
;
1793 console
->edition_mode
= config
->edition_mode
;
1794 console
->history_mode
= config
->history_mode
;
1796 if (console
->history_size
!= config
->history_size
)
1798 struct history_line
**mem
= NULL
;
1801 if (config
->history_size
&& (mem
= malloc( config
->history_size
* sizeof(*mem
) )))
1803 memset( mem
, 0, config
->history_size
* sizeof(*mem
) );
1805 delta
= (console
->history_index
> config
->history_size
)
1806 ? (console
->history_index
- config
->history_size
) : 0;
1808 for (i
= delta
; i
< console
->history_index
; i
++)
1810 mem
[i
- delta
] = console
->history
[i
];
1811 console
->history
[i
] = NULL
;
1813 console
->history_index
-= delta
;
1815 for (i
= 0; i
< console
->history_size
; i
++)
1816 free( console
->history
[i
] );
1817 free( console
->history
);
1818 console
->history
= mem
;
1819 console
->history_size
= config
->history_size
;
1823 if (config
->insert_mode
)
1824 console
->mode
|= ENABLE_INSERT_MODE
|ENABLE_EXTENDED_FLAGS
;
1826 console
->mode
&= ~ENABLE_INSERT_MODE
;
1828 console
->active
->cursor_size
= config
->cursor_size
;
1829 console
->active
->cursor_visible
= config
->cursor_visible
;
1830 console
->active
->attr
= config
->attr
;
1831 console
->active
->popup_attr
= config
->popup_attr
;
1832 console
->active
->win
.left
= config
->win_pos
.X
;
1833 console
->active
->win
.top
= config
->win_pos
.Y
;
1834 console
->active
->win
.right
= config
->win_pos
.X
+ config
->win_width
- 1;
1835 console
->active
->win
.bottom
= config
->win_pos
.Y
+ config
->win_height
- 1;
1836 memcpy( console
->active
->color_map
, config
->color_map
, sizeof(config
->color_map
) );
1838 if (console
->active
->font
.width
!= config
->cell_width
||
1839 console
->active
->font
.height
!= config
->cell_height
||
1840 console
->active
->font
.weight
!= config
->font_weight
||
1841 console
->active
->font
.pitch_family
!= config
->font_pitch_family
||
1842 console
->active
->font
.face_len
!= wcslen( config
->face_name
) ||
1843 memcmp( console
->active
->font
.face_name
, config
->face_name
,
1844 console
->active
->font
.face_len
* sizeof(WCHAR
) ))
1846 update_console_font( console
, config
->face_name
, wcslen(config
->face_name
) * sizeof(WCHAR
),
1847 config
->cell_height
, config
->font_weight
);
1850 update_window( console
);
1852 notify_screen_buffer_size( console
->active
);
1855 static void current_config( struct console
*console
, struct console_config
*config
)
1859 config
->menu_mask
= console
->window
->menu_mask
;
1860 config
->quick_edit
= console
->window
->quick_edit
;
1862 config
->edition_mode
= console
->edition_mode
;
1863 config
->history_mode
= console
->history_mode
;
1864 config
->history_size
= console
->history_size
;
1866 config
->insert_mode
= (console
->mode
& (ENABLE_INSERT_MODE
|ENABLE_EXTENDED_FLAGS
)) ==
1867 (ENABLE_INSERT_MODE
|ENABLE_EXTENDED_FLAGS
);
1869 config
->cursor_size
= console
->active
->cursor_size
;
1870 config
->cursor_visible
= console
->active
->cursor_visible
;
1871 config
->attr
= console
->active
->attr
;
1872 config
->popup_attr
= console
->active
->popup_attr
;
1873 memcpy( config
->color_map
, console
->active
->color_map
, sizeof(config
->color_map
) );
1875 config
->cell_width
= console
->active
->font
.width
;
1876 config
->cell_height
= console
->active
->font
.height
;
1877 config
->font_weight
= console
->active
->font
.weight
;
1878 config
->font_pitch_family
= console
->active
->font
.pitch_family
;
1879 len
= min( ARRAY_SIZE(config
->face_name
) - 1, console
->active
->font
.face_len
);
1880 if (len
) memcpy( config
->face_name
, console
->active
->font
.face_name
, len
* sizeof(WCHAR
) );
1881 config
->face_name
[len
] = 0;
1883 config
->sb_width
= console
->active
->width
;
1884 config
->sb_height
= console
->active
->height
;
1886 config
->win_width
= console
->active
->win
.right
- console
->active
->win
.left
+ 1;
1887 config
->win_height
= console
->active
->win
.bottom
- console
->active
->win
.top
+ 1;
1888 config
->win_pos
.X
= console
->active
->win
.left
;
1889 config
->win_pos
.Y
= console
->active
->win
.top
;
1892 /* run the dialog box to set up the console options */
1893 static BOOL
config_dialog( struct console
*console
, BOOL current
)
1895 struct console_config prev_config
;
1896 struct dialog_info di
;
1897 PROPSHEETHEADERW header
;
1898 HPROPSHEETPAGE pages
[3];
1903 InitCommonControls();
1905 memset( &di
, 0, sizeof(di
) );
1906 di
.console
= console
;
1909 current_config( console
, &di
.config
);
1911 load_config( NULL
, &di
.config
);
1913 prev_config
= di
.config
;
1916 wndclass
.lpfnWndProc
= font_preview_proc
;
1917 wndclass
.cbClsExtra
= 0;
1918 wndclass
.cbWndExtra
= sizeof(HFONT
);
1919 wndclass
.hInstance
= GetModuleHandleW( NULL
);
1921 wndclass
.hCursor
= LoadCursorW( 0, (const WCHAR
*)IDC_ARROW
);
1922 wndclass
.hbrBackground
= GetStockObject( BLACK_BRUSH
);
1923 wndclass
.lpszMenuName
= NULL
;
1924 wndclass
.lpszClassName
= L
"WineConFontPreview";
1925 RegisterClassW( &wndclass
);
1928 wndclass
.lpfnWndProc
= color_preview_proc
;
1929 wndclass
.cbClsExtra
= 0;
1930 wndclass
.cbWndExtra
= sizeof(DWORD
);
1931 wndclass
.hInstance
= GetModuleHandleW( NULL
);
1933 wndclass
.hCursor
= LoadCursorW( 0, (const WCHAR
*)IDC_ARROW
);
1934 wndclass
.hbrBackground
= GetStockObject( BLACK_BRUSH
);
1935 wndclass
.lpszMenuName
= NULL
;
1936 wndclass
.lpszClassName
= L
"WineConColorPreview";
1937 RegisterClassW( &wndclass
);
1939 memset( &psp
, 0, sizeof(psp
) );
1940 psp
.dwSize
= sizeof(psp
);
1942 psp
.hInstance
= wndclass
.hInstance
;
1943 psp
.lParam
= (LPARAM
)&di
;
1945 psp
.pszTemplate
= MAKEINTRESOURCEW(IDD_OPTION
);
1946 psp
.pfnDlgProc
= option_dialog_proc
;
1947 pages
[0] = CreatePropertySheetPageW( &psp
);
1949 psp
.pszTemplate
= MAKEINTRESOURCEW(IDD_FONT
);
1950 psp
.pfnDlgProc
= font_dialog_proc
;
1951 pages
[1] = CreatePropertySheetPageW( &psp
);
1953 psp
.pszTemplate
= MAKEINTRESOURCEW(IDD_CONFIG
);
1954 psp
.pfnDlgProc
= config_dialog_proc
;
1955 pages
[2] = CreatePropertySheetPageW( &psp
);
1957 memset( &header
, 0, sizeof(header
) );
1958 header
.dwSize
= sizeof(header
);
1960 if (!LoadStringW( GetModuleHandleW( NULL
),
1961 current
? IDS_DLG_TIT_CURRENT
: IDS_DLG_TIT_DEFAULT
,
1962 buff
, ARRAY_SIZE(buff
) ))
1963 wcscpy( buff
, L
"Setup" );
1965 header
.pszCaption
= buff
;
1967 header
.hwndParent
= console
->win
;
1968 header
.phpage
= pages
;
1969 header
.dwFlags
= PSH_NOAPPLYNOW
;
1970 if (PropertySheetW( &header
) < 1)
1973 if (!memcmp( &prev_config
, &di
.config
, sizeof(prev_config
) ))
1976 TRACE( "%s\n", debugstr_config(&di
.config
) );
1980 apply_config( console
, &di
.config
);
1981 update_window( di
.console
);
1984 save_config( current
? console
->window
->config_key
: NULL
, &di
.config
);
1989 static void resize_window( struct console
*console
, int width
, int height
)
1991 struct console_config config
;
1993 current_config( console
, &config
);
1994 config
.win_width
= width
;
1995 config
.win_height
= height
;
1997 /* auto size screen-buffer if it's now smaller than window */
1998 if (config
.sb_width
< config
.win_width
)
1999 config
.sb_width
= config
.win_width
;
2000 if (config
.sb_height
< config
.win_height
)
2001 config
.sb_height
= config
.win_height
;
2003 /* and reset window pos so that we don't display outside of the screen-buffer */
2004 if (config
.win_pos
.X
+ config
.win_width
> config
.sb_width
)
2005 config
.win_pos
.X
= config
.sb_width
- config
.win_width
;
2006 if (config
.win_pos
.Y
+ config
.win_height
> config
.sb_height
)
2007 config
.win_pos
.Y
= config
.sb_height
- config
.win_height
;
2009 apply_config( console
, &config
);
2012 /* grays / ungrays the menu items according to their state */
2013 static void set_menu_details( struct console
*console
, HMENU menu
)
2015 EnableMenuItem( menu
, IDS_COPY
, MF_BYCOMMAND
|
2016 (console
->window
->in_selection
? MF_ENABLED
: MF_GRAYED
) );
2017 EnableMenuItem( menu
, IDS_PASTE
, MF_BYCOMMAND
|
2018 (IsClipboardFormatAvailable(CF_UNICODETEXT
) ? MF_ENABLED
: MF_GRAYED
) );
2019 EnableMenuItem( menu
, IDS_SCROLL
, MF_BYCOMMAND
| MF_GRAYED
);
2020 EnableMenuItem( menu
, IDS_SEARCH
, MF_BYCOMMAND
| MF_GRAYED
);
2023 static BOOL
fill_menu( HMENU menu
, BOOL sep
)
2025 HINSTANCE module
= GetModuleHandleW( NULL
);
2029 if (!menu
) return FALSE
;
2031 sub_menu
= CreateMenu();
2032 if (!sub_menu
) return FALSE
;
2034 LoadStringW( module
, IDS_MARK
, buff
, ARRAY_SIZE(buff
) );
2035 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_MARK
, buff
);
2036 LoadStringW( module
, IDS_COPY
, buff
, ARRAY_SIZE(buff
) );
2037 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_COPY
, buff
);
2038 LoadStringW( module
, IDS_PASTE
, buff
, ARRAY_SIZE(buff
) );
2039 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_PASTE
, buff
);
2040 LoadStringW( module
, IDS_SELECTALL
, buff
, ARRAY_SIZE(buff
) );
2041 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_SELECTALL
, buff
);
2042 LoadStringW( module
, IDS_SCROLL
, buff
, ARRAY_SIZE(buff
) );
2043 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_SCROLL
, buff
);
2044 LoadStringW( module
, IDS_SEARCH
, buff
, ARRAY_SIZE(buff
) );
2045 InsertMenuW( sub_menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_SEARCH
, buff
);
2047 if (sep
) InsertMenuW( menu
, -1, MF_BYPOSITION
|MF_SEPARATOR
, 0, NULL
);
2048 LoadStringW( module
, IDS_EDIT
, buff
, ARRAY_SIZE(buff
) );
2049 InsertMenuW( menu
, -1, MF_BYPOSITION
|MF_STRING
|MF_POPUP
, (UINT_PTR
)sub_menu
, buff
);
2050 LoadStringW( module
, IDS_DEFAULT
, buff
, ARRAY_SIZE(buff
) );
2051 InsertMenuW( menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_DEFAULT
, buff
);
2052 LoadStringW( module
, IDS_PROPERTIES
, buff
, ARRAY_SIZE(buff
) );
2053 InsertMenuW( menu
, -1, MF_BYPOSITION
|MF_STRING
, IDS_PROPERTIES
, buff
);
2058 static LRESULT
window_create( HWND hwnd
, const CREATESTRUCTW
*create
)
2060 struct console
*console
= create
->lpCreateParams
;
2063 TRACE( "%p\n", hwnd
);
2065 SetWindowLongPtrW( hwnd
, 0, (DWORD_PTR
)console
);
2066 console
->win
= hwnd
;
2068 if (console
->window
)
2070 sys_menu
= GetSystemMenu( hwnd
, FALSE
);
2071 if (!sys_menu
) return 0;
2072 console
->window
->popup_menu
= CreatePopupMenu();
2073 if (!console
->window
->popup_menu
) return 0;
2075 fill_menu( sys_menu
, TRUE
);
2076 fill_menu( console
->window
->popup_menu
, FALSE
);
2078 console
->window
->mem_dc
= CreateCompatibleDC( 0 );
2083 static LRESULT WINAPI
window_proc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
2085 struct console
*console
= (struct console
*)GetWindowLongPtrW( hwnd
, 0 );
2090 return window_create( hwnd
, (const CREATESTRUCTW
*)lparam
);
2093 console
->win
= NULL
;
2094 PostQuitMessage( 0 );
2098 case WM_UPDATE_CONFIG
:
2099 if (console
->window
&& console
->window
->update_state
== UPDATE_PENDING
)
2100 update_window( console
);
2107 if (!console
->window
) break;
2109 BeginPaint( console
->win
, &ps
);
2110 BitBlt( ps
.hdc
, 0, 0,
2111 (console
->active
->win
.right
- console
->active
->win
.left
+ 1) * console
->active
->font
.width
,
2112 (console
->active
->win
.bottom
- console
->active
->win
.top
+ 1) * console
->active
->font
.height
,
2113 console
->window
->mem_dc
,
2114 console
->active
->win
.left
* console
->active
->font
.width
,
2115 console
->active
->win
.top
* console
->active
->font
.height
,
2117 if (console
->window
->in_selection
) update_selection( console
, ps
.hdc
);
2118 EndPaint( console
->win
, &ps
);
2123 if (!console
->window
) break;
2125 update_window( console
);
2128 if (console
->window
->bitmap
) DeleteObject( console
->window
->bitmap
);
2129 console
->window
->bitmap
= NULL
;
2135 if (console
->window
&& console
->window
->in_selection
)
2136 handle_selection_key( console
, msg
== WM_KEYDOWN
, wparam
, lparam
);
2138 record_key_input( console
, msg
== WM_KEYDOWN
, wparam
, lparam
);
2143 record_key_input( console
, msg
== WM_SYSKEYDOWN
, wparam
, lparam
);
2147 if (console
->window
&& console
->window
->in_selection
)
2148 handle_selection_key( console
, TRUE
, LOBYTE( VkKeyScanW( (WCHAR
)wparam
) ), lparam
);
2150 record_char_input( console
, (WCHAR
)wparam
, lparam
);
2153 case WM_LBUTTONDOWN
:
2154 if (console
->window
&& (console
->window
->quick_edit
|| console
->window
->in_selection
))
2156 if (console
->window
->in_selection
)
2157 update_selection( console
, 0 );
2159 if (console
->window
->quick_edit
&& console
->window
->in_selection
)
2161 console
->window
->in_selection
= FALSE
;
2165 console
->window
->selection_end
= get_cell( console
, lparam
);
2166 console
->window
->selection_start
= console
->window
->selection_end
;
2167 SetCapture( console
->win
);
2168 update_selection( console
, 0 );
2169 console
->window
->in_selection
= TRUE
;
2174 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, 0 );
2179 if (console
->window
&& (console
->window
->quick_edit
|| console
->window
->in_selection
))
2181 if (GetCapture() == console
->win
&& console
->window
->in_selection
&&
2182 (wparam
& MK_LBUTTON
))
2184 move_selection( console
, console
->window
->selection_start
,
2185 get_cell(console
, lparam
) );
2190 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, MOUSE_MOVED
);
2195 if (console
->window
&& (console
->window
->quick_edit
|| console
->window
->in_selection
))
2197 if (GetCapture() == console
->win
&& console
->window
->in_selection
)
2199 move_selection( console
, console
->window
->selection_start
,
2200 get_cell(console
, lparam
) );
2206 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, 0 );
2210 case WM_RBUTTONDOWN
:
2211 if (console
->window
&& (wparam
& (MK_CONTROL
|MK_SHIFT
)) == console
->window
->menu_mask
)
2214 pt
.x
= (short)LOWORD(lparam
);
2215 pt
.y
= (short)HIWORD(lparam
);
2216 ClientToScreen( hwnd
, &pt
);
2217 set_menu_details( console
, console
->window
->popup_menu
);
2218 TrackPopupMenu( console
->window
->popup_menu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_RIGHTBUTTON
,
2219 pt
.x
, pt
.y
, 0, hwnd
, NULL
);
2223 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, 0 );
2228 /* no need to track for rbutton up when opening the popup... the event will be
2229 * swallowed by TrackPopupMenu */
2230 case WM_MBUTTONDOWN
:
2232 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, 0 );
2235 case WM_LBUTTONDBLCLK
:
2236 case WM_MBUTTONDBLCLK
:
2237 case WM_RBUTTONDBLCLK
:
2238 record_mouse_input( console
, get_cell(console
, lparam
), wparam
, DOUBLE_CLICK
);
2242 if (console
->window
&& console
->active
->cursor_visible
)
2244 CreateCaret( console
->win
, console
->window
->cursor_bitmap
,
2245 console
->active
->font
.width
, console
->active
->font
.height
);
2246 update_window_cursor( console
);
2251 if (console
->window
&& console
->active
->cursor_visible
)
2256 if (console
->window
&& console
->window
->update_state
!= UPDATE_BUSY
)
2257 resize_window( console
,
2258 max( LOWORD(lparam
) / console
->active
->font
.width
, 20 ),
2259 max( HIWORD(lparam
) / console
->active
->font
.height
, 20 ));
2264 int win_width
= console
->active
->win
.right
- console
->active
->win
.left
+ 1;
2265 int x
= console
->active
->win
.left
;
2267 if (!console
->window
) break;
2268 switch (LOWORD(wparam
))
2270 case SB_PAGEUP
: x
-= 8; break;
2271 case SB_PAGEDOWN
: x
+= 8; break;
2272 case SB_LINEUP
: x
--; break;
2273 case SB_LINEDOWN
: x
++; break;
2274 case SB_THUMBTRACK
: x
= HIWORD(wparam
); break;
2277 x
= min( max( x
, 0 ), console
->active
->width
- win_width
);
2278 if (x
!= console
->active
->win
.left
)
2280 console
->active
->win
.left
= x
;
2281 console
->active
->win
.right
= x
+ win_width
- 1;
2282 update_window( console
);
2288 if (console
->active
->height
<= console
->active
->win
.bottom
- console
->active
->win
.top
+ 1)
2290 record_mouse_input(console
, get_cell(console
, lparam
), wparam
, MOUSE_WHEELED
);
2293 /* else fallthrough */
2296 int win_height
= console
->active
->win
.bottom
- console
->active
->win
.top
+ 1;
2297 int y
= console
->active
->win
.top
;
2299 if (!console
->window
) break;
2301 if (msg
== WM_MOUSEWHEEL
)
2303 UINT scroll_lines
= 3;
2304 SystemParametersInfoW( SPI_GETWHEELSCROLLLINES
, 0, &scroll_lines
, 0 );
2305 scroll_lines
*= -GET_WHEEL_DELTA_WPARAM(wparam
) / WHEEL_DELTA
;
2310 switch (LOWORD(wparam
))
2312 case SB_PAGEUP
: y
-= 8; break;
2313 case SB_PAGEDOWN
: y
+= 8; break;
2314 case SB_LINEUP
: y
--; break;
2315 case SB_LINEDOWN
: y
++; break;
2316 case SB_THUMBTRACK
: y
= HIWORD(wparam
); break;
2321 y
= min( max( y
, 0 ), console
->active
->height
- win_height
);
2322 if (y
!= console
->active
->win
.top
)
2324 console
->active
->win
.top
= y
;
2325 console
->active
->win
.bottom
= y
+ win_height
- 1;
2326 update_window( console
);
2332 if (!console
->window
) break;
2336 config_dialog( console
, FALSE
);
2338 case IDS_PROPERTIES
:
2339 config_dialog( console
, TRUE
);
2342 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
2347 if (!console
->window
) break;
2351 config_dialog( console
, FALSE
);
2353 case IDS_PROPERTIES
:
2354 config_dialog( console
, TRUE
);
2357 console
->window
->selection_start
.X
= console
->window
->selection_start
.Y
= 0;
2358 console
->window
->selection_end
.X
= console
->window
->selection_end
.Y
= 0;
2359 update_selection( console
, 0 );
2360 console
->window
->in_selection
= TRUE
;
2363 if (console
->window
->in_selection
)
2365 console
->window
->in_selection
= FALSE
;
2366 update_selection( console
, 0 );
2367 copy_selection( console
);
2371 paste_clipboard( console
);
2374 console
->window
->selection_start
.X
= console
->window
->selection_start
.Y
= 0;
2375 console
->window
->selection_end
.X
= console
->active
->width
- 1;
2376 console
->window
->selection_end
.Y
= console
->active
->height
- 1;
2377 update_selection( console
, 0 );
2378 console
->window
->in_selection
= TRUE
;
2382 FIXME( "Unhandled yet command: %Ix\n", wparam
);
2385 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
2389 case WM_INITMENUPOPUP
:
2390 if (!console
->window
|| !HIWORD(lparam
)) return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
2391 set_menu_details( console
, GetSystemMenu(console
->win
, FALSE
) );
2395 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
2401 void update_window_config( struct console
*console
, BOOL delay
)
2403 const int delay_timeout
= 50;
2405 if (!console
->window
|| console
->window
->update_state
!= UPDATE_NONE
) return;
2406 console
->window
->update_state
= UPDATE_PENDING
;
2408 SetTimer( console
->win
, 1, delay_timeout
, NULL
);
2410 PostMessageW( console
->win
, WM_UPDATE_CONFIG
, 0, 0 );
2413 void update_window_region( struct console
*console
, const RECT
*update
)
2415 RECT
*window_rect
= &console
->window
->update
;
2416 window_rect
->left
= min( window_rect
->left
, update
->left
);
2417 window_rect
->top
= min( window_rect
->top
, update
->top
);
2418 window_rect
->right
= max( window_rect
->right
, update
->right
);
2419 window_rect
->bottom
= max( window_rect
->bottom
, update
->bottom
);
2420 update_window_config( console
, TRUE
);
2423 BOOL
init_window( struct console
*console
)
2425 struct console_config config
;
2430 static struct console_window console_window
;
2432 console
->window
= &console_window
;
2433 if (!TranslateCharsetInfo( (DWORD
*)(INT_PTR
)GetACP(), &ci
, TCI_SRCCODEPAGE
))
2436 console
->window
->ui_charset
= ci
.ciCharset
;
2438 GetStartupInfoW(&si
);
2441 size_t i
, title_len
= wcslen( si
.lpTitle
);
2442 if (!(console
->window
->config_key
= malloc( (title_len
+ 1) * sizeof(WCHAR
) )))
2444 for (i
= 0; i
< title_len
; i
++)
2445 console
->window
->config_key
[i
] = si
.lpTitle
[i
] == '\\' ? '_' : si
.lpTitle
[i
];
2446 console
->window
->config_key
[title_len
] = 0;
2449 load_config( console
->window
->config_key
, &config
);
2450 if (si
.dwFlags
& STARTF_USECOUNTCHARS
)
2452 config
.sb_width
= si
.dwXCountChars
;
2453 config
.sb_height
= si
.dwYCountChars
;
2455 if (si
.dwFlags
& STARTF_USEFILLATTRIBUTE
)
2456 config
.attr
= si
.dwFillAttribute
;
2458 wndclass
.style
= CS_DBLCLKS
;
2459 wndclass
.lpfnWndProc
= window_proc
;
2460 wndclass
.cbClsExtra
= 0;
2461 wndclass
.cbWndExtra
= sizeof(DWORD_PTR
);
2462 wndclass
.hInstance
= GetModuleHandleW(NULL
);
2463 wndclass
.hIcon
= LoadIconW( 0, (const WCHAR
*)IDI_WINLOGO
);
2464 wndclass
.hCursor
= LoadCursorW( 0, (const WCHAR
*)IDC_ARROW
);
2465 wndclass
.hbrBackground
= GetStockObject( BLACK_BRUSH
);
2466 wndclass
.lpszMenuName
= NULL
;
2467 wndclass
.lpszClassName
= L
"WineConsoleClass";
2468 RegisterClassW(&wndclass
);
2470 if (!CreateWindowW( wndclass
.lpszClassName
, NULL
,
2471 WS_OVERLAPPED
|WS_CAPTION
|WS_SYSMENU
|WS_THICKFRAME
|WS_MINIMIZEBOX
|
2472 WS_MAXIMIZEBOX
|WS_HSCROLL
|WS_VSCROLL
, CW_USEDEFAULT
, CW_USEDEFAULT
,
2473 0, 0, 0, 0, wndclass
.hInstance
, console
))
2476 if (!config
.face_name
[0])
2477 set_first_font( console
, &config
);
2479 apply_config( console
, &config
);
2483 void init_message_window( struct console
*console
)
2487 wndclass
.style
= CS_DBLCLKS
;
2488 wndclass
.lpfnWndProc
= window_proc
;
2489 wndclass
.cbClsExtra
= 0;
2490 wndclass
.cbWndExtra
= sizeof(DWORD_PTR
);
2491 wndclass
.hInstance
= GetModuleHandleW( NULL
);
2493 wndclass
.hCursor
= 0;
2494 wndclass
.hbrBackground
= GetStockObject( BLACK_BRUSH
);
2495 wndclass
.lpszMenuName
= NULL
;
2496 wndclass
.lpszClassName
= L
"WineConsoleClass";
2497 RegisterClassW(&wndclass
);
2499 CreateWindowW( wndclass
.lpszClassName
, NULL
,
2500 WS_OVERLAPPED
|WS_CAPTION
|WS_SYSMENU
|WS_THICKFRAME
|WS_MINIMIZEBOX
|
2501 WS_MAXIMIZEBOX
|WS_HSCROLL
|WS_VSCROLL
, CW_USEDEFAULT
, CW_USEDEFAULT
,
2502 0, 0, HWND_MESSAGE
, 0, wndclass
.hInstance
, console
);