/*
 * Copyright 2024, ttcoder
 * All rights reserved. Distributed under the terms of the MIT license.
 */
#ifndef _GeInput_H
#define _GeInput_H


// genode/base.lib.a
#include <input_session/connection.h>

// libbe.so
class BWindow;
#include <interface/Point.h>  // member
#include <interface/Size.h>  // member
#include "_WindowNitpickerPriv.h"  // Wm


namespace hog {
	class InputBridger;
	//class Wm;
	
	namespace conv_input {
		int HaikuKey_for_GeKey(
			const	Input::Keycode genode_scancode,
					int32 & changed_disambiguated_modifier
			);
		int ModifiedKey_for_RawBeKey(
			int raw_be_key,
			int virtualized_modifiers
			);
	}
}


class hog::InputBridger
{
public:
		InputBridger( BWindow & win );
		~InputBridger();
		
	//static int input_server_( void * data );
		void eventLoop();
		
		void handleInput();
		void handleDisplayMode();


private:  // Code

		void handleOneEvent(
			const Input::Event & ev
			);
		BMessage mouseDown( int32 button );
		BMessage mouseUp( int32 button );
		BMessage keyDownOrUp(
			const Input::Keycode genode_key,
			const bool latch_down );
		
	static int forwarding_to_pthread( void * bridger_uncast );


private:  // Data

		// Tx -- for pushing to PostMessage() and access to ServerWindow()
		BWindow & ourWin;
		
		// State --
		// double-click detection state
		bigtime_t latestClick;  // last time any button (left, right, etc) was pressed down, in support of mouseDown()
		// current state, previously in struct "MouseState":
		BPoint curScreenWhere;
		int32  curButtons;
		
		// distinct thread, to separate Genode-context and LibC-context code,
		// communicating through a mutex'ed FIFO:
		//
		thread_id threadId;
		Genode::Entrypoint localEp;  // Genode thread dedicated to the sigh
		// Rx -- let Genode push events to us
		Genode::Signal_handler<InputBridger>
			inputHandler;
		Genode::Signal_handler<InputBridger>
			dispModeHandler;
		
		// shared between our <ep> Genode-thread and <forwarder> pthread
		//
		Genode::Blockade greenlightForwarder;
		Genode::Mutex mutexFwd;
		
		struct EvItem : public Genode::Fifo<EvItem>::Element
		{
			EvItem( const Input::Event & ev )
			: event( ev )  // copy ctor seems to work fine
			{
			}
			
			Input::Event  event;
		};
		Genode::Fifo< EvItem > eventsToForward;
		
		BSize newMode; //_d_: Framebuffer::Mode  newMode;
		bool tearDownThread;  // set to <true> to signal function forwarding_to_pthread() to end its thread
		
#ifdef HAS_MICRO_WINDOW_MANAGER
		Wm winManager;
#endif  // ~HAS_MICRO_WINDOW_MANAGER
};



#endif // _GeInput_H

