2012-06-02 12:44:37 -07:00
/*
2013-01-13 10:57:24 -08:00
* Copyright 2011 - 2013 Branimir Karadzic . All rights reserved .
2012-06-02 12:44:37 -07:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
2013-08-07 21:45:56 -07:00
# include "entry.h"
2012-06-02 12:44:37 -07:00
# if BX_PLATFORM_LINUX
2013-01-17 22:38:13 -08:00
# define XK_MISCELLANY
# define XK_LATIN1
# include <X11/keysymdef.h>
2013-01-13 15:35:06 -08:00
# undef None
2013-08-07 23:11:20 -07:00
# include <bgfxplatform.h>
2013-01-17 22:38:13 -08:00
# include "entry_p.h"
2013-08-07 23:11:20 -07:00
2013-08-07 23:03:09 -07:00
# include <bx/thread.h>
# include <bx/os.h>
# include <string.h> // memset
2013-01-13 11:20:56 -08:00
2013-01-13 15:35:06 -08:00
# define DEFAULT_WIDTH 1280
# define DEFAULT_HEIGHT 720
2013-01-13 11:20:56 -08:00
namespace entry
{
2013-01-17 22:38:13 -08:00
static uint8_t s_translateKey [ 512 ] ;
static void initTranslateKey ( uint16_t _xk , Key : : Enum _key )
{
_xk + = 256 ;
2013-08-06 21:04:28 -07:00
BX_CHECK ( _xk < BX_COUNTOF ( s_translateKey ) , " Out of bounds %d. " , _xk ) ;
2013-01-17 22:38:13 -08:00
s_translateKey [ _xk & 0x1ff ] = ( uint8_t ) _key ;
}
Key : : Enum fromXk ( uint16_t _xk )
{
_xk + = 256 ;
return 512 > _xk ? ( Key : : Enum ) s_translateKey [ _xk ] : Key : : None ;
}
2013-01-13 15:35:06 -08:00
struct MainThreadEntry
{
int m_argc ;
char * * m_argv ;
2013-01-18 21:12:04 -08:00
static int32_t threadFunc ( void * _userData ) ;
2013-01-13 15:35:06 -08:00
} ;
struct Context
{
2013-01-17 22:38:13 -08:00
Context ( )
2013-01-20 20:44:33 -08:00
: m_modifiers ( Modifier : : None )
, m_exit ( false )
2013-01-17 22:38:13 -08:00
{
memset ( s_translateKey , 0 , sizeof ( s_translateKey ) ) ;
2013-01-17 23:22:38 -08:00
initTranslateKey ( XK_Escape , Key : : Esc ) ;
initTranslateKey ( XK_Return , Key : : Return ) ;
initTranslateKey ( XK_Tab , Key : : Tab ) ;
initTranslateKey ( XK_BackSpace , Key : : Backspace ) ;
initTranslateKey ( XK_space , Key : : Space ) ;
initTranslateKey ( XK_Up , Key : : Up ) ;
initTranslateKey ( XK_Down , Key : : Down ) ;
initTranslateKey ( XK_Left , Key : : Left ) ;
initTranslateKey ( XK_Right , Key : : Right ) ;
initTranslateKey ( XK_Page_Up , Key : : PageUp ) ;
initTranslateKey ( XK_Page_Down , Key : : PageUp ) ;
initTranslateKey ( XK_Home , Key : : Home ) ;
initTranslateKey ( XK_KP_End , Key : : End ) ;
initTranslateKey ( XK_Print , Key : : Print ) ;
initTranslateKey ( XK_equal , Key : : Plus ) ;
initTranslateKey ( XK_minus , Key : : Minus ) ;
initTranslateKey ( XK_F1 , Key : : F1 ) ;
initTranslateKey ( XK_F2 , Key : : F2 ) ;
initTranslateKey ( XK_F3 , Key : : F3 ) ;
initTranslateKey ( XK_F4 , Key : : F4 ) ;
initTranslateKey ( XK_F5 , Key : : F5 ) ;
initTranslateKey ( XK_F6 , Key : : F6 ) ;
initTranslateKey ( XK_F7 , Key : : F7 ) ;
initTranslateKey ( XK_F8 , Key : : F8 ) ;
initTranslateKey ( XK_F9 , Key : : F9 ) ;
initTranslateKey ( XK_F10 , Key : : F10 ) ;
initTranslateKey ( XK_F11 , Key : : F11 ) ;
initTranslateKey ( XK_F12 , Key : : F12 ) ;
initTranslateKey ( XK_KP_Insert , Key : : NumPad0 ) ;
initTranslateKey ( XK_KP_End , Key : : NumPad1 ) ;
initTranslateKey ( XK_KP_Down , Key : : NumPad2 ) ;
2013-01-17 22:38:13 -08:00
initTranslateKey ( XK_KP_Page_Down , Key : : NumPad3 ) ;
2013-01-17 23:22:38 -08:00
initTranslateKey ( XK_KP_Left , Key : : NumPad4 ) ;
initTranslateKey ( XK_KP_Begin , Key : : NumPad5 ) ;
initTranslateKey ( XK_KP_Right , Key : : NumPad6 ) ;
initTranslateKey ( XK_KP_Home , Key : : NumPad7 ) ;
initTranslateKey ( XK_KP_Up , Key : : NumPad8 ) ;
initTranslateKey ( XK_KP_Page_Up , Key : : NumPad9 ) ;
initTranslateKey ( ' 0 ' , Key : : Key0 ) ;
initTranslateKey ( ' 1 ' , Key : : Key1 ) ;
initTranslateKey ( ' 2 ' , Key : : Key2 ) ;
initTranslateKey ( ' 3 ' , Key : : Key3 ) ;
initTranslateKey ( ' 4 ' , Key : : Key4 ) ;
initTranslateKey ( ' 5 ' , Key : : Key5 ) ;
initTranslateKey ( ' 6 ' , Key : : Key6 ) ;
initTranslateKey ( ' 7 ' , Key : : Key7 ) ;
initTranslateKey ( ' 8 ' , Key : : Key8 ) ;
initTranslateKey ( ' 9 ' , Key : : Key9 ) ;
initTranslateKey ( ' a ' , Key : : KeyA ) ;
initTranslateKey ( ' b ' , Key : : KeyB ) ;
initTranslateKey ( ' c ' , Key : : KeyC ) ;
initTranslateKey ( ' d ' , Key : : KeyD ) ;
initTranslateKey ( ' e ' , Key : : KeyE ) ;
initTranslateKey ( ' f ' , Key : : KeyF ) ;
initTranslateKey ( ' g ' , Key : : KeyG ) ;
initTranslateKey ( ' h ' , Key : : KeyH ) ;
initTranslateKey ( ' i ' , Key : : KeyI ) ;
initTranslateKey ( ' j ' , Key : : KeyJ ) ;
initTranslateKey ( ' k ' , Key : : KeyK ) ;
initTranslateKey ( ' l ' , Key : : KeyL ) ;
initTranslateKey ( ' m ' , Key : : KeyM ) ;
initTranslateKey ( ' n ' , Key : : KeyN ) ;
initTranslateKey ( ' o ' , Key : : KeyO ) ;
initTranslateKey ( ' p ' , Key : : KeyP ) ;
initTranslateKey ( ' q ' , Key : : KeyQ ) ;
initTranslateKey ( ' r ' , Key : : KeyR ) ;
initTranslateKey ( ' s ' , Key : : KeyS ) ;
initTranslateKey ( ' t ' , Key : : KeyT ) ;
initTranslateKey ( ' u ' , Key : : KeyU ) ;
initTranslateKey ( ' v ' , Key : : KeyV ) ;
initTranslateKey ( ' w ' , Key : : KeyW ) ;
initTranslateKey ( ' x ' , Key : : KeyX ) ;
initTranslateKey ( ' y ' , Key : : KeyY ) ;
initTranslateKey ( ' z ' , Key : : KeyZ ) ;
2013-01-17 22:38:13 -08:00
}
2013-01-13 15:35:06 -08:00
int32_t run ( int _argc , char * * _argv )
{
2013-01-17 22:38:13 -08:00
XInitThreads ( ) ;
2013-01-13 15:35:06 -08:00
m_display = XOpenDisplay ( 0 ) ;
int32_t screen = DefaultScreen ( m_display ) ;
int32_t depth = DefaultDepth ( m_display , screen ) ;
Visual * visual = DefaultVisual ( m_display , screen ) ;
Window root = RootWindow ( m_display , screen ) ;
XSetWindowAttributes windowAttrs ;
2013-01-18 21:12:04 -08:00
memset ( & windowAttrs , 0 , sizeof ( windowAttrs ) ) ;
2013-01-13 15:35:06 -08:00
windowAttrs . background_pixmap = 0 ;
windowAttrs . border_pixel = 0 ;
2013-01-18 21:12:04 -08:00
windowAttrs . event_mask = 0
| ButtonPressMask
| ButtonReleaseMask
| ExposureMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| ResizeRedirectMask
| StructureNotifyMask
;
2013-01-13 15:35:06 -08:00
m_window = XCreateWindow ( m_display
, root
, 0 , 0
, DEFAULT_WIDTH , DEFAULT_HEIGHT , 0 , depth
, InputOutput
, visual
2013-01-18 21:12:04 -08:00
, CWBorderPixel | CWEventMask
2013-01-13 15:35:06 -08:00
, & windowAttrs
) ;
2013-01-18 21:12:04 -08:00
XMapWindow ( m_display , m_window ) ;
2013-01-17 22:38:13 -08:00
XStoreName ( m_display , m_window , " BGFX " ) ;
2013-01-13 15:35:06 -08:00
bgfx : : x11SetDisplayWindow ( m_display , m_window ) ;
MainThreadEntry mte ;
mte . m_argc = _argc ;
mte . m_argv = _argv ;
bx : : Thread thread ;
thread . init ( mte . threadFunc , & mte ) ;
2013-01-17 22:38:13 -08:00
while ( ! m_exit )
{
if ( XPending ( m_display ) )
{
XEvent event ;
XNextEvent ( m_display , & event ) ;
switch ( event . type )
{
case Expose :
break ;
case ConfigureNotify :
break ;
case ButtonPress :
case ButtonRelease :
2013-01-18 21:12:04 -08:00
{
2013-01-20 20:44:33 -08:00
const XButtonEvent & xbutton = event . xbutton ;
2013-01-18 21:12:04 -08:00
MouseButton : : Enum mb ;
2013-01-20 20:44:33 -08:00
switch ( xbutton . button )
2013-01-18 21:12:04 -08:00
{
case Button1 : mb = MouseButton : : Left ; break ;
case Button2 : mb = MouseButton : : Middle ; break ;
case Button3 : mb = MouseButton : : Right ; break ;
default : mb = MouseButton : : None ; break ;
}
if ( MouseButton : : None ! = mb )
{
2013-01-20 20:44:33 -08:00
m_eventQueue . postMouseEvent ( xbutton . x
, xbutton . y
2013-01-18 21:12:04 -08:00
, mb
, event . type = = ButtonPress
) ;
}
}
2013-01-17 22:38:13 -08:00
break ;
case MotionNotify :
2013-01-18 21:12:04 -08:00
{
2013-01-20 20:44:33 -08:00
const XMotionEvent & xmotion = event . xmotion ;
m_eventQueue . postMouseEvent ( xmotion . x
, xmotion . y
2013-01-18 21:12:04 -08:00
) ;
}
2013-01-17 22:38:13 -08:00
break ;
case KeyPress :
case KeyRelease :
{
2013-01-20 20:44:33 -08:00
XKeyEvent & xkey = event . xkey ;
KeySym keysym = XLookupKeysym ( & xkey , 0 ) ;
switch ( keysym )
2013-01-17 22:38:13 -08:00
{
2013-01-20 20:44:33 -08:00
case XK_Meta_L : setModifier ( Modifier : : LeftMeta , KeyPress = = event . type ) ; break ;
case XK_Meta_R : setModifier ( Modifier : : RightMeta , KeyPress = = event . type ) ; break ;
case XK_Control_L : setModifier ( Modifier : : LeftCtrl , KeyPress = = event . type ) ; break ;
case XK_Control_R : setModifier ( Modifier : : RightCtrl , KeyPress = = event . type ) ; break ;
case XK_Shift_L : setModifier ( Modifier : : LeftShift , KeyPress = = event . type ) ; break ;
case XK_Shift_R : setModifier ( Modifier : : RightShift , KeyPress = = event . type ) ; break ;
case XK_Alt_L : setModifier ( Modifier : : LeftAlt , KeyPress = = event . type ) ; break ;
case XK_Alt_R : setModifier ( Modifier : : RightAlt , KeyPress = = event . type ) ; break ;
default :
{
Key : : Enum key = fromXk ( keysym ) ;
if ( Key : : None ! = key )
{
m_eventQueue . postKeyEvent ( key , m_modifiers , KeyPress = = event . type ) ;
}
}
break ;
2013-01-17 22:38:13 -08:00
}
}
break ;
2013-01-18 21:12:04 -08:00
case ResizeRequest :
{
2013-01-20 20:44:33 -08:00
const XResizeRequestEvent & xresize = event . xresizerequest ;
XResizeWindow ( m_display , m_window , xresize . width , xresize . height ) ;
2013-01-18 21:12:04 -08:00
}
break ;
2013-01-17 22:38:13 -08:00
}
}
}
2013-01-13 15:35:06 -08:00
thread . shutdown ( ) ;
2013-01-18 21:12:04 -08:00
XUnmapWindow ( m_display , m_window ) ;
XDestroyWindow ( m_display , m_window ) ;
2013-01-13 15:35:06 -08:00
return EXIT_SUCCESS ;
}
2013-01-20 20:44:33 -08:00
void setModifier ( Modifier : : Enum _modifier , bool _set )
{
m_modifiers & = ~ _modifier ;
m_modifiers | = _set ? _modifier : 0 ;
}
uint8_t m_modifiers ;
2013-01-13 15:35:06 -08:00
Display * m_display ;
Window m_window ;
2013-01-17 22:38:13 -08:00
bool m_exit ;
EventQueue m_eventQueue ;
2013-01-13 15:35:06 -08:00
} ;
static Context s_ctx ;
2013-01-18 21:12:04 -08:00
int32_t MainThreadEntry : : threadFunc ( void * _userData )
{
MainThreadEntry * self = ( MainThreadEntry * ) _userData ;
2013-08-07 21:45:56 -07:00
int32_t result = main ( self - > m_argc , self - > m_argv ) ;
2013-01-18 21:12:04 -08:00
s_ctx . m_exit = true ;
return result ;
}
2013-01-16 22:44:51 -08:00
const Event * poll ( )
2013-01-13 11:20:56 -08:00
{
2013-01-17 22:38:13 -08:00
return s_ctx . m_eventQueue . poll ( ) ;
2013-01-16 22:44:51 -08:00
}
void release ( const Event * _event )
{
2013-01-17 22:38:13 -08:00
s_ctx . m_eventQueue . release ( _event ) ;
2013-01-16 22:44:51 -08:00
}
2013-01-17 22:38:13 -08:00
void setWindowSize ( uint32_t _width , uint32_t _height )
{
2013-01-18 21:12:04 -08:00
XResizeRequestEvent ev ;
ev . type = ResizeRequest ;
ev . serial = 0 ;
ev . send_event = true ;
ev . display = s_ctx . m_display ;
ev . window = s_ctx . m_window ;
ev . width = ( int ) _width ;
ev . height = ( int ) _height ;
XSendEvent ( s_ctx . m_display , s_ctx . m_window , false , ResizeRedirectMask , ( XEvent * ) & ev ) ;
2013-01-16 22:44:51 -08:00
}
void toggleWindowFrame ( )
2013-01-17 22:38:13 -08:00
{
2013-01-13 11:20:56 -08:00
}
2013-01-19 00:22:25 -08:00
void setMouseLock ( bool _lock )
{
}
2013-01-13 11:20:56 -08:00
} // namespace entry
2012-06-02 12:44:37 -07:00
int main ( int _argc , char * * _argv )
{
2013-01-13 15:35:06 -08:00
using namespace entry ;
return s_ctx . run ( _argc , _argv ) ;
2012-06-02 12:44:37 -07:00
}
# endif // BX_PLATFORM_LINUX