Skip to content

Commit

Permalink
rtlib: win32/win64: MULTIKEY() on consoles track console focus
Browse files Browse the repository at this point in the history
- MULTIKEY(): remove the 'FindWindow' logic for console windows
- use fb_ConsoleProcessEvents() to handle FOCUS_EVENT and
  track if the console has focus
- previously GetForegroundWindow() and FindWindow() was
  used to try determine if the console has focus,
  but this won't work in a program having a window that
  manages multiple consoles (win 10+)
  • Loading branch information
jayrm committed Jan 6, 2024
1 parent db67992 commit dfab9a8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 56 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -52,6 +52,7 @@ Version 1.20.0
- rtlib: internal fb_LeftSelf( s, 0 ) was failing to reduce the string to a length of zero.
- fbc: 64-bit builds of fbc didn't recognise UTF32-BE encoded source files
- sf.net #659: Keep the stack 16-byte aligned on linux-x86, android-x86 and darwin-x86 to comply with ABI; fixes crashes when external libraries use SSE
- rtlib: win32/win64: MULTIKEY() on consoles track console focus, remove the 'FindWindow' logic for console windows and handle FOCUS_EVENT message to track focus (adeyblue)


Version 1.10.2
Expand Down
1 change: 1 addition & 0 deletions src/rtlib/win32/fb_private_console.h
Expand Up @@ -42,6 +42,7 @@ void fb_hConsoleResetHandles( void );
int fb_ConsoleGetRawX( void );
int fb_ConsoleGetRawY( void );
HANDLE fb_hConsoleCreateBuffer( void );
int fb_ConsoleHasFocus( void );

#define __fb_in_handle fb_hConsoleGetHandle( TRUE )
#define __fb_out_handle fb_hConsoleGetHandle( FALSE )
Expand Down
13 changes: 11 additions & 2 deletions src/rtlib/win32/io_input.c
Expand Up @@ -10,6 +10,7 @@ static size_t key_head = 0, key_tail = 0;
static INPUT_RECORD input_events[KEY_BUFFER_LEN];
static unsigned key_scratch_pad = 0;
static int key_buffer_changed = FALSE;
static int console_has_focus = TRUE;

typedef struct _FB_KEY_CODES {
unsigned short value_normal;
Expand Down Expand Up @@ -383,10 +384,15 @@ static void fb_hInitControlHandler( void )
FB_UNLOCK();
}

int fb_ConsoleHasFocus( void )
{
return console_has_focus;
}

int fb_ConsoleProcessEvents( void )
{
int got_event = FALSE;
INPUT_RECORD ir;
INPUT_RECORD ir;
DWORD dwRead;

fb_hInitControlHandler();
Expand Down Expand Up @@ -418,14 +424,17 @@ int fb_ConsoleProcessEvents( void )
got_event = TRUE;
}
break;
case FOCUS_EVENT:
console_has_focus = ir.Event.FocusEvent.bSetFocus;
break;
}

FB_UNLOCK();
}

} while( dwRead != 0 );

return got_event;
return got_event;
}

/** Translates an ASCII character, Virtual scan code and Virtual key code to
Expand Down
62 changes: 8 additions & 54 deletions src/rtlib/win32/io_multikey.c
Expand Up @@ -2,6 +2,7 @@

#include "../fb.h"
#include <windows.h>
#include "fb_private_console.h"

const unsigned char __fb_keytable[][3] = {
{ SC_ESCAPE, VK_ESCAPE, 0 }, { SC_1, '1', 0 },
Expand Down Expand Up @@ -51,24 +52,6 @@ const unsigned char __fb_keytable[][3] = {
{ 0, 0, 0 }
};

static HWND find_window(void)
{
TCHAR old_title[MAX_PATH];
TCHAR title[MAX_PATH];
static HWND hwnd = NULL;

if (hwnd)
return hwnd;

if (GetConsoleTitle(old_title, MAX_PATH)) {
sprintf(title, "_fb_console_title %f", fb_Timer());
SetConsoleTitle(title);
hwnd = FindWindow(NULL, title);
SetConsoleTitle(old_title);
}
return hwnd;
}

int fb_hVirtualToScancode(int vkey)
{
int i;
Expand All @@ -79,46 +62,17 @@ int fb_hVirtualToScancode(int vkey)
return 0;
}

#if 0
/* !!!TODO!!! need a way to find out if console is foreground in windows terminal */
static int maybeDoFindWindow()
{
static int inited = FB_FALSE;
static int do_find = FB_FALSE;
if( !inited )
{
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
if( ((info.dwMajorVersion << 8) | info.dwMinorVersion) <= 0x600 ) {
do_find = FB_TRUE;
}
inited = FB_TRUE;
}
return do_find;
}
#endif

int fb_ConsoleMultikey( int scancode )
{
int i;
fb_ConsoleProcessEvents();

#if 1
/* !!!FIXME!!! this doesn't seem to work under windows terminal */
if ( find_window() != GetForegroundWindow() )
return FB_FALSE;
#else
/* !!!TODO!!! need a way to find out if console is foreground in windows terminal */
if( maybeDoFindWindow() )
{
if ( find_window() != GetForegroundWindow() )
return FB_FALSE;
}
#endif
if(fb_ConsoleHasFocus()) {
int i;

for( i = 0; __fb_keytable[i][0]; i++ ) {
if( __fb_keytable[i][0] == scancode ) {
return ((GetAsyncKeyState(__fb_keytable[i][1]) | GetAsyncKeyState(__fb_keytable[i][2])) & 0x8000) ? FB_TRUE : FB_FALSE;
for( i = 0; __fb_keytable[i][0]; i++ ) {
if( __fb_keytable[i][0] == scancode ) {
return ((GetAsyncKeyState(__fb_keytable[i][1]) | GetAsyncKeyState(__fb_keytable[i][2])) & 0x8000) ? FB_TRUE : FB_FALSE;
}
}
}
return FB_FALSE;
Expand Down

0 comments on commit dfab9a8

Please sign in to comment.