diff --git a/CNFG.h b/CNFG.h index 6a1e627..e68ba70 100644 --- a/CNFG.h +++ b/CNFG.h @@ -137,6 +137,10 @@ int HandleDestroy(); // Return nonzero if you want to cancel destroy. void HandleWindowTermination(); #endif +// Only implemented in Windows and X11 drivers +void HandleScancode( int scancode, int bDown ); +void HandleChar( int character ); + //Internal function for resizing rasterizer for rasterizer-mode. void CNFGInternalResize( short x, short y ); //don't call this. diff --git a/CNFGWinDriver.c b/CNFGWinDriver.c index 7994e60..30da310 100644 --- a/CNFGWinDriver.c +++ b/CNFGWinDriver.c @@ -342,9 +342,12 @@ int CNFGHandleInput() case WM_MBUTTONUP: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 3, 0 ); break; case WM_KEYDOWN: case WM_KEYUP: + HandleScancode( (msg.lParam >> 16) & 0xFF, msg.message==WM_KEYDOWN); + if (msg.lParam & 0x01000000) HandleKey( (int) msg.wParam + 0x7C , (msg.message==WM_KEYDOWN) ); else HandleKey( (int) msg.wParam, (msg.message==WM_KEYDOWN) ); break; + case WM_CHAR: HandleChar( (int) msg.wParam ); break; case WM_MOUSEWHEEL: { POINT p = { 0 }; diff --git a/CNFGXDriver.c b/CNFGXDriver.c index 935b7fe..24fcc2a 100644 --- a/CNFGXDriver.c +++ b/CNFGXDriver.c @@ -99,6 +99,9 @@ void CNFGGLXSetup( ) int CNFGX11ForceNoDecoration; XImage *xi; +XIM CNFGXIM = NULL; +XIC CNFGXIC = NULL; + int g_x_global_key_state; int g_x_global_shift_key; @@ -221,6 +224,9 @@ static void InternalLinkScreenAndGo( const char * WindowName ) if( !CNFGWindowInvisible ) XMapWindow(CNFGDisplay, CNFGWindow); + CNFGXIM = XOpenIM(CNFGDisplay, NULL, wm_res_name, wm_res_class); + CNFGXIC = XCreateIC(CNFGXIM, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); + #ifdef CNFG_HAS_XSHAPE if( prepare_xshape ) { @@ -327,6 +333,9 @@ void CNFGTearDown() if ( CNFGGC ) XFreeGC( CNFGDisplay, CNFGGC ); if ( CNFGWindowGC ) XFreeGC( CNFGDisplay, CNFGWindowGC ); if ( CNFGDisplay ) XCloseDisplay( CNFGDisplay ); + if ( CNFGXIC ) XDestroyIC( CNFGXIC ); + if ( CNFGXIM ) XCloseIM( CNFGXIM ); + #ifdef CNFGOGL if ( CNFGGLXFBConfigs ) XFree( CNFGGLXFBConfigs ); CNFGGLXFBConfigs = NULL; @@ -435,7 +444,18 @@ int CNFGHandleInput() case KeyPress: g_x_global_key_state = report.xkey.state; g_x_global_shift_key = XLookupKeysym(&report.xkey, 1); - HandleKey( XLookupKeysym(&report.xkey, 0), bKeyDirection ); + + KeySym sym = XLookupKeysym(&report.xkey, 0); + HandleKey( sym, bKeyDirection ); + + HandleScancode( report.xkey.keycode, bKeyDirection ); + + // Chars should ONLY be handled on Key Press + if (report.type == KeyPress) { + char buf[8] = {0}; + if (Xutf8LookupString(CNFGXIC, &report.xkey, buf, 8, NULL, NULL)) HandleChar( *((int*)buf) ); + } + break; case ButtonRelease: bKeyDirection = 0; diff --git a/README.md b/README.md index 0e357b1..217a440 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ is as follows: #include "rawdraw_sf.h" void HandleKey( int keycode, int bDown ) { } +void HandleScancode( int scancode, int bDown ) { } +void HandleChar( int character ) { } void HandleButton( int x, int y, int button, int bDown ) { } void HandleMotion( int x, int y, int mask ) { } int HandleDestroy() { return 0; } diff --git a/ogltest.c b/ogltest.c index 3ae8f5d..d60fdbf 100644 --- a/ogltest.c +++ b/ogltest.c @@ -9,6 +9,16 @@ void HandleKey( int keycode, int bDown ) printf( "Key: %d %d\n", keycode, bDown ); } +void HandleScancode( int scancode, int bDown ) +{ + printf( "Scancode: %d -> %d\n", scancode, bDown ); +} + +void HandleChar( int character ) +{ + printf( "Char: %c\n", character ); +} + void HandleButton( int x, int y, int button, int bDown ) { } diff --git a/osdtest.c b/osdtest.c index dda9761..0b2efcd 100644 --- a/osdtest.c +++ b/osdtest.c @@ -15,6 +15,16 @@ void HandleKey( int keycode, int bDown ) printf( "Key: %d -> %d\n", keycode, bDown ); } +void HandleScancode( int scancode, int bDown ) +{ + printf( "Scancode: %d -> %d\n", scancode, bDown ); +} + +void HandleChar( int character ) +{ + printf( "Char: %c\n", character ); +} + void HandleButton( int x, int y, int button, int bDown ) { printf( "Button: %d,%d (%d) -> %d\n", x, y, button, bDown ); diff --git a/rawdraw.c b/rawdraw.c index ee2ed65..ca85761 100644 --- a/rawdraw.c +++ b/rawdraw.c @@ -7,7 +7,7 @@ #define CNFG3D #define CNFG_IMPLEMENTATION -#define CNFGOGL +//#define CNFGOGL //#define CNFGRASTERIZER //#define CNFG_WINDOWS_DISABLE_BATCH @@ -22,6 +22,16 @@ void HandleKey( int keycode, int bDown ) printf( "Key: %d -> %d\n", keycode, bDown ); } +void HandleScancode( int scancode, int bDown ) +{ + printf( "Scancode: %d -> %d\n", scancode, bDown ); +} + +void HandleChar( int character ) +{ + printf( "Char: %c\n", character ); +} + void HandleButton( int x, int y, int button, int bDown ) { printf( "Button: %d,%d (%d) -> %d\n", x, y, button, bDown ); diff --git a/rawdraw_sf.h b/rawdraw_sf.h index bc49e9b..3a60454 100644 --- a/rawdraw_sf.h +++ b/rawdraw_sf.h @@ -1,5 +1,5 @@ //This file was automatically generated by Makefile at https://github.com/cntools/rawdraw -//Generated from files git hash d8e1b42a3d436a9e04cc7549ff3eb2861e38242b on Thu Apr 11 05:17:30 PM PDT 2024 (This is not the git hash of this file) +//Generated from files git hash 907aeeb011b451ac72f9c07689eaa15803eda779 on Mon Apr 15 07:11:21 PM EDT 2024 (This is not the git hash of this file) // Copyright 2010-2021 <>< CNLohr, et. al. (Several other authors, many but not all mentioned) // Licensed under the MIT/x11 or NewBSD License you choose. // @@ -139,6 +139,10 @@ int HandleDestroy(); // Return nonzero if you want to cancel destroy. void HandleWindowTermination(); #endif +// Only implemented in Windows and X11 drivers +void HandleScancode( int scancode, int bDown ); +void HandleChar( int character ); + //Internal function for resizing rasterizer for rasterizer-mode. void CNFGInternalResize( short x, short y ); //don't call this. @@ -4032,9 +4036,12 @@ int CNFGHandleInput() case WM_MBUTTONUP: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 3, 0 ); break; case WM_KEYDOWN: case WM_KEYUP: + HandleScancode( (msg.lParam >> 16) & 0xFF, msg.message==WM_KEYDOWN); + if (msg.lParam & 0x01000000) HandleKey( (int) msg.wParam + 0x7C , (msg.message==WM_KEYDOWN) ); else HandleKey( (int) msg.wParam, (msg.message==WM_KEYDOWN) ); break; + case WM_CHAR: HandleChar( (int) msg.wParam ); break; case WM_MOUSEWHEEL: { POINT p = { 0 }; @@ -5608,6 +5615,9 @@ void CNFGGLXSetup( ) int CNFGX11ForceNoDecoration; XImage *xi; +XIM CNFGXIM = NULL; +XIC CNFGXIC = NULL; + int g_x_global_key_state; int g_x_global_shift_key; @@ -5730,6 +5740,9 @@ static void InternalLinkScreenAndGo( const char * WindowName ) if( !CNFGWindowInvisible ) XMapWindow(CNFGDisplay, CNFGWindow); + CNFGXIM = XOpenIM(CNFGDisplay, NULL, wm_res_name, wm_res_class); + CNFGXIC = XCreateIC(CNFGXIM, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); + #ifdef CNFG_HAS_XSHAPE if( prepare_xshape ) { @@ -5836,6 +5849,9 @@ void CNFGTearDown() if ( CNFGGC ) XFreeGC( CNFGDisplay, CNFGGC ); if ( CNFGWindowGC ) XFreeGC( CNFGDisplay, CNFGWindowGC ); if ( CNFGDisplay ) XCloseDisplay( CNFGDisplay ); + if ( CNFGXIC ) XDestroyIC( CNFGXIC ); + if ( CNFGXIM ) XCloseIM( CNFGXIM ); + #ifdef CNFGOGL if ( CNFGGLXFBConfigs ) XFree( CNFGGLXFBConfigs ); CNFGGLXFBConfigs = NULL; @@ -5944,7 +5960,18 @@ int CNFGHandleInput() case KeyPress: g_x_global_key_state = report.xkey.state; g_x_global_shift_key = XLookupKeysym(&report.xkey, 1); - HandleKey( XLookupKeysym(&report.xkey, 0), bKeyDirection ); + + KeySym sym = XLookupKeysym(&report.xkey, 0); + HandleKey( sym, bKeyDirection ); + + HandleScancode( report.xkey.keycode, bKeyDirection ); + + // Chars should ONLY be handled on Key Press + if (report.type == KeyPress) { + char buf[8] = {0}; + if (Xutf8LookupString(CNFGXIC, &report.xkey, buf, 8, NULL, NULL)) HandleChar( *((int*)buf) ); + } + break; case ButtonRelease: bKeyDirection = 0; diff --git a/simple.c b/simple.c index f5d8e05..abfc372 100644 --- a/simple.c +++ b/simple.c @@ -7,6 +7,8 @@ #include "CNFG.h" void HandleKey( int keycode, int bDown ) { } +void HandleScancode( int scancode, int bDown ) { } +void HandleChar( int character ) { } void HandleButton( int x, int y, int button, int bDown ) { } void HandleMotion( int x, int y, int mask ) { } int HandleDestroy() { return 0; }