[PATCH] kernelbase: Partially implement SetCurrentConsoleFontEx

Hugh McMaster hugh.mcmaster at outlook.com
Wed Feb 2 05:10:59 CST 2022


Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 dlls/kernel32/console.c         |  7 -------
 dlls/kernel32/kernel32.spec     |  2 +-
 dlls/kernel32/tests/console.c   | 30 +++++++++++++-------------
 dlls/kernelbase/console.c       | 37 +++++++++++++++++++++++++++++++++
 dlls/kernelbase/kernelbase.spec |  1 +
 include/wine/condrv.h           |  6 ++++++
 programs/conhost/conhost.c      |  9 +++++++-
 programs/conhost/conhost.h      | 14 ++++++++-----
 programs/conhost/window.c       |  5 +++--
 9 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index 80f3419cd7a..58bd18d2a5f 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -480,10 +480,3 @@ BOOL WINAPI GetConsoleFontInfo(HANDLE hConsole, BOOL maximize, DWORD numfonts, C
     SetLastError(LOWORD(E_NOTIMPL) /* win10 1709+ */);
     return FALSE;
 }
-
-BOOL WINAPI SetCurrentConsoleFontEx(HANDLE hConsole, BOOL maxwindow, CONSOLE_FONT_INFOEX *cfix)
-{
-    FIXME("(%p %d %p): stub!\n", hConsole, maxwindow, cfix);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-}
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 87fa0c39381..6e063bfaa7b 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1390,7 +1390,7 @@
 @ stdcall -import SetConsoleTitleW(wstr)
 @ stdcall -import SetConsoleWindowInfo(long long ptr)
 @ stdcall SetCriticalSectionSpinCount(ptr long) NTDLL.RtlSetCriticalSectionSpinCount
-@ stdcall SetCurrentConsoleFontEx(long long ptr)
+@ stdcall -import SetCurrentConsoleFontEx(long long ptr)
 @ stdcall -import SetCurrentDirectoryA(str)
 @ stdcall -import SetCurrentDirectoryW(wstr)
 @ stub SetDaylightFlag
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c
index e4d9d43f4c4..0943a318f6a 100644
--- a/dlls/kernel32/tests/console.c
+++ b/dlls/kernel32/tests/console.c
@@ -3576,18 +3576,18 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(NULL, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(NULL, TRUE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     CreatePipe(&pipe1, &pipe2, NULL, 0);
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(pipe1, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
     CloseHandle(pipe1);
     CloseHandle(pipe2);
 
@@ -3595,36 +3595,36 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(pipe1, TRUE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
     CloseHandle(pipe1);
     CloseHandle(pipe2);
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_input, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_input, TRUE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_output, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_output, TRUE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n", GetLastError());
 
     cfix = orig_cfix;
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(NULL, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(NULL, TRUE, &cfix);
@@ -3635,7 +3635,7 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(pipe1, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
     CloseHandle(pipe1);
     CloseHandle(pipe2);
 
@@ -3650,7 +3650,7 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_input, FALSE, &cfix);
     ok(!ret, "got %d, expected 0\n", ret);
-    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_input, TRUE, &cfix);
@@ -3659,8 +3659,8 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_output, FALSE, &cfix);
-    todo_wine ok(ret, "got %d, expected non-zero\n", ret);
-    todo_wine ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
+    ok(ret, "got %d, expected non-zero\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_output, TRUE, &cfix);
@@ -3670,8 +3670,8 @@ static void test_SetCurrentConsoleFontEx(HANDLE std_output)
     /* Restore original console font parameters */
     SetLastError(0xdeadbeef);
     ret = SetCurrentConsoleFontEx(std_output, FALSE, &orig_cfix);
-    todo_wine ok(ret, "got %d, expected non-zero\n", ret);
-    todo_wine ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
+    ok(ret, "got %d, expected non-zero\n", ret);
+    ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
 }
 
 static void test_GetConsoleFontSize(HANDLE std_output)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
index a7eeb439232..0501e140a03 100644
--- a/dlls/kernelbase/console.c
+++ b/dlls/kernelbase/console.c
@@ -1303,6 +1303,43 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleWindowInfo( HANDLE handle, BOOL absolute
 }
 
 
+/******************************************************************************
+ *	SetCurrentConsoleFontEx   (kernelbase.@)
+ */
+BOOL WINAPI SetCurrentConsoleFontEx(HANDLE hConsole, BOOL maxwindow, CONSOLE_FONT_INFOEX *cfix)
+{
+    struct condrv_output_info_params_font data;
+
+    TRACE( "(%p %d %p)\n", hConsole, maxwindow, cfix );
+
+    if (cfix->cbSize != sizeof(CONSOLE_FONT_INFOEX))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (maxwindow)
+    {
+        FIXME( "(%p %d %p): semi-stub\n", hConsole, maxwindow, cfix);
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        return FALSE;
+    }
+
+    data.params.mask = SET_CONSOLE_OUTPUT_INFO_FONT;
+
+    data.params.info.font_width  = cfix->dwFontSize.X;
+    data.params.info.font_height = cfix->dwFontSize.Y;
+    data.params.info.font_pitch_family = cfix->FontFamily;
+    data.params.info.font_weight = cfix->FontWeight;
+
+    memcpy( data.face_name, cfix->FaceName, sizeof(cfix->FaceName) );
+    data.face_name[ LF_FACESIZE - 1 ] = 0;
+
+    return console_ioctl( hConsole, IOCTL_CONDRV_SET_OUTPUT_INFO,
+                          &data, sizeof(data), NULL, 0, NULL );
+}
+
+
 /***********************************************************************
  *            ReadConsoleInputA   (kernelbase.@)
  */
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 01135d6250a..91c4909e006 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -1422,6 +1422,7 @@
 @ stdcall SetConsoleTitleW(wstr)
 @ stdcall SetConsoleWindowInfo(long long ptr)
 @ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
+@ stdcall SetCurrentConsoleFontEx(long long ptr)
 @ stdcall SetCurrentDirectoryA(str)
 @ stdcall SetCurrentDirectoryW(wstr)
 @ stdcall SetDefaultDllDirectories(long)
diff --git a/include/wine/condrv.h b/include/wine/condrv.h
index 4d2332a1ee9..605e6f2c2fe 100644
--- a/include/wine/condrv.h
+++ b/include/wine/condrv.h
@@ -148,6 +148,11 @@ struct condrv_output_info_params
     struct condrv_output_info info;   /* output info */
 };
 
+struct condrv_output_info_params_font {
+    struct condrv_output_info_params params;
+    WCHAR face_name[LF_FACESIZE];
+};
+
 #define SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM     0x0001
 #define SET_CONSOLE_OUTPUT_INFO_CURSOR_POS      0x0002
 #define SET_CONSOLE_OUTPUT_INFO_SIZE            0x0004
@@ -155,6 +160,7 @@ struct condrv_output_info_params
 #define SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW  0x0010
 #define SET_CONSOLE_OUTPUT_INFO_MAX_SIZE        0x0020
 #define SET_CONSOLE_OUTPUT_INFO_POPUP_ATTR      0x0040
+#define SET_CONSOLE_OUTPUT_INFO_FONT            0x0080
 
 /* IOCTL_CONDRV_FILL_OUTPUT params */
 struct condrv_fill_output_params
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index 78f6e345170..456f3a4889e 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -1913,6 +1913,13 @@ static NTSTATUS set_output_info( struct screen_buffer *screen_buffer,
         screen_buffer->max_width  = info->max_width;
         screen_buffer->max_height = info->max_height;
     }
+    if (params->mask & SET_CONSOLE_OUTPUT_INFO_FONT)
+    {
+        WCHAR *face_name = (WCHAR *)(params + 1);
+
+        update_console_font( screen_buffer->console, face_name,
+                             info->font_height, info->font_weight );
+    }
 
     if (is_active( screen_buffer ))
     {
@@ -2425,7 +2432,7 @@ static NTSTATUS screen_buffer_ioctl( struct screen_buffer *screen_buffer, unsign
         return get_output_info( screen_buffer, out_size );
 
     case IOCTL_CONDRV_SET_OUTPUT_INFO:
-        if (in_size != sizeof(struct condrv_output_info_params) || *out_size) return STATUS_INVALID_PARAMETER;
+        if (in_size < sizeof(struct condrv_output_info) || *out_size) return STATUS_INVALID_PARAMETER;
         return set_output_info( screen_buffer, in_data );
 
     case IOCTL_CONDRV_FILL_OUTPUT:
diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h
index 5e9b999380c..88a26f70fd0 100644
--- a/programs/conhost/conhost.h
+++ b/programs/conhost/conhost.h
@@ -130,17 +130,21 @@ struct screen_buffer
     struct wine_rb_entry   entry;               /* map entry */
 };
 
-BOOL init_window( struct console *console );
-void init_message_window( struct console *console );
-void update_window_region( struct console *console, const RECT *update );
-void update_window_config( struct console *console, BOOL delay );
-
+/* conhost.c */
 NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records,
                               unsigned int count, BOOL flush );
 
 void notify_screen_buffer_size( struct screen_buffer *screen_buffer );
 NTSTATUS change_screen_buffer_size( struct screen_buffer *screen_buffer, int new_width, int new_height );
 
+/* window.c */
+void update_console_font( struct console *console, const WCHAR *font,
+                          unsigned int height, unsigned int weight );
+BOOL init_window( struct console *console );
+void init_message_window( struct console *console );
+void update_window_region( struct console *console, const RECT *update );
+void update_window_config( struct console *console, BOOL delay );
+
 static inline void empty_update_rect( struct screen_buffer *screen_buffer, RECT *rect )
 {
     SetRect( rect, screen_buffer->width, screen_buffer->height, 0, 0 );
diff --git a/programs/conhost/window.c b/programs/conhost/window.c
index 7ad0d48effd..0d450774d23 100644
--- a/programs/conhost/window.c
+++ b/programs/conhost/window.c
@@ -705,6 +705,7 @@ static BOOL set_console_font( struct console *console, const LOGFONTW *logfont )
 
     font_info->width  = tm.tmAveCharWidth;
     font_info->height = tm.tmHeight + tm.tmExternalLeading;
+    font_info->pitch_family = tm.tmPitchAndFamily;
     font_info->weight = tm.tmWeight;
 
     free( font_info->face_name );
@@ -851,8 +852,8 @@ static int WINAPI get_first_font_enum( const LOGFONTW *lf, const TEXTMETRICW *tm
 
 
 /* sets logfont as the new font for the console */
-static void update_console_font( struct console *console, const WCHAR *font,
-                                 unsigned int height, unsigned int weight )
+void update_console_font( struct console *console, const WCHAR *font,
+                          unsigned int height, unsigned int weight )
 {
     struct font_chooser fc;
     LOGFONTW lf;
-- 
2.34.1




More information about the wine-devel mailing list