Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sokol_app.h: add custom win32 hook to handle windows events #283

Open
RicoP opened this issue Apr 22, 2020 · 2 comments
Open

sokol_app.h: add custom win32 hook to handle windows events #283

RicoP opened this issue Apr 22, 2020 · 2 comments

Comments

@RicoP
Copy link

RicoP commented Apr 22, 2020

I am using gainput (https://github.com/jkuhlmann/gainput) for input management and on windows I have to pass in all windows message manually for gainput to correctly register mouse and keyboard events

		// Update Gainput
		manager.Update();

		MSG msg;
		while (PeekMessage(&msg, hWnd,  0, 0, PM_REMOVE)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);

			// Forward any input messages to Gainput
			manager.HandleMessage(msg);
		}

unfortunately sokol_app "swallows" all win32 event messages and I have no way to stop sokol from stealing my events.

I found a workaround that makes me handle win32 events before sokol does. I have to paste the following code before the #define SOKOL_IMPL


#if defined(_WIN32)
#  ifdef WIN32_LEAN_AND_MEAN
#    undef WIN32_LEAN_AND_MEAN
#  endif
#  include <Windows.h>
   // "hook" TranslateMessage call from sokol 
   extern "C" void hook_TranslateMessage(const MSG *lpMsg);

#  define TranslateMessage(MSG) \
    hook_TranslateMessage(MSG); \
    TranslateMessage(MSG);
#endif

#define SOKOL_IMPL
#define SOKOL_GLCORE33
#include <sokol/sokol_app.h>

then in my main app I just have to implement

#ifdef _WIN32
extern "C" void hook_TranslateMessage(const MSG *msg) {
  manager.HandleMessage(*msg);
}
#endif

this works fine, but I am wondering if it is possible to add "native" event callbacks to sapp_desc to handle such cases.

Greetings!
~ Rico (Ex Bigpoint Member)

@floooh
Copy link
Owner

floooh commented Apr 24, 2020

Hi Rico :)

Hmm yeah that's a good point. I need to think of a good way to expose this type of stuff though because I can't have any Win32-types in the "public API". So basically a callback which takes a void* which would need to be cast to a MSG* in the user-provided callback.

The callback should be passed in via sapp_desc, e.g.

void my_win32_msg_callback(const void* msg) {
    const MSG* win32_msg = (const MSG*) msg;
    ...
}

sapp_desc sokol_main(int argc, char* argv[]) {
    return (sapp_desc) {
        .win32_msg_intercept_cb = my_win32_msg_callback
        ....
    };
}

There should also be a second sapp_desc callback type with a user_data pointer (same as with the init/frame/event/cleanup callbacks).

I probably won't get around implementing this for a little while because I'm still focused on the WebGPU backend, but you could provide a pull request in the meantime if you want :)

@0x1100
Copy link
Contributor

0x1100 commented Sep 21, 2020

Here is a workaround that works for my use case:

It is possible to replace the WNDPROC callback that handles events for a specific window.
I do so with the following call in init_cb().

SetWindowLongPtr((HWND)sapp_win32_get_hwnd(), GWLP_WNDPROC, (LONG_PTR)hook_sapp_win32_wndproc);

I define the function alongside the sokol_app implementation to get access to the original callback _sapp_win32_wndproc():

_SOKOL_PRIVATE LRESULT CALLBACK hook_sapp_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case ...:
            ...
        default:
            break;
    }
    return _sapp_win32_wndproc(hWnd, uMsg, wParam, lParam);
}

Now about Gainput specifically. They are using MSG structures but they seem to only use the message, wParam, and lParam members. I think you can forward the messages from a custom WNDPROC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants