diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 969ab99df..6018735cf 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -20,17 +20,7 @@ #endif #if defined(SUPPORT_X11) - #include - #include - #include - - #if !defined(GLES) - #include - #include - #endif - - #include - map x11_keymap; + #include "linux-dist/x11.h" #endif #if defined(USES_HOMEDIR) @@ -48,25 +38,9 @@ #ifdef TARGET_PANDORA #include #include - #include - #define WINDOW_WIDTH 800 -#else - #define WINDOW_WIDTH 640 + #include #endif -#define WINDOW_HEIGHT 480 -void* x11_win = 0; -void* x11_disp = 0; - -void* libPvr_GetRenderTarget() -{ - return x11_win; -} - -void* libPvr_GetRenderSurface() -{ - return x11_disp; -} int msgboxf(const wchar* text, unsigned int type, ...) { @@ -82,6 +56,19 @@ int msgboxf(const wchar* text, unsigned int type, ...) return MBX_OK; } +void* x11_win = 0; +void* x11_disp = 0; + +void* libPvr_GetRenderTarget() +{ + return x11_win; +} + +void* libPvr_GetRenderSurface() +{ + return x11_disp; +} + u16 kcode[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; @@ -159,35 +146,14 @@ void SetupInput() free(joystick_device); } #endif + + #if defined(SUPPORT_X11) + input_x11_init(); + #endif } extern bool KillTex; -#ifdef TARGET_PANDORA - static Cursor CreateNullCursor(Display *display, Window root) - { - Pixmap cursormask; - XGCValues xgc; - GC gc; - XColor dummycolour; - Cursor cursor; - - cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); - xgc.function = GXclear; - gc = XCreateGC(display, cursormask, GCFunction, &xgc); - XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); - dummycolour.pixel = 0; - dummycolour.red = 0; - dummycolour.flags = 04; - cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0); - XFreePixmap(display,cursormask); - XFreeGC(display,gc); - return cursor; - } -#endif - -int x11_dc_buttons = 0xFFFF; - void UpdateInputState(u32 port) { #if defined(TARGET_EMSCRIPTEN) @@ -206,235 +172,22 @@ void UpdateInputState(u32 port) void os_DoEvents() { #if defined(SUPPORT_X11) - if (x11_win) - { - //Handle X11 - XEvent e; - - if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e)) - { - switch(e.type) - { - case KeyPress: - case KeyRelease: - { - int dc_key = x11_keymap[e.xkey.keycode]; - - if (e.type == KeyPress) - { - kcode[0] &= ~dc_key; - } - else - { - kcode[0] |= dc_key; - } - - //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); - } - break; - - - { - printf("KEYRELEASE\n"); - } - break; - - } - } - } + input_x11_handle(); #endif } void os_SetWindowText(const char * text) { - if (0==x11_win || 0==x11_disp || 1) - { - printf("%s\n",text); - } + printf("%s\n",text); #if defined(SUPPORT_X11) - else if (x11_win) - { - XChangeProperty((Display*)x11_disp, (Window)x11_win, - XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME, - XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING, - 8, PropModeReplace, (const unsigned char *)text, strlen(text)); - } + x11_window_set_text(text); #endif } - -void* x11_glc; - -int ndcid=0; void os_CreateWindow() { #if defined(SUPPORT_X11) - if (cfgLoadInt("pvr", "nox11", 0) == 0) - { - XInitThreads(); - // X11 variables - Window x11Window = 0; - Display* x11Display = 0; - long x11Screen = 0; - XVisualInfo* x11Visual = 0; - Colormap x11Colormap = 0; - - /* - Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output - */ - Window sRootWindow; - XSetWindowAttributes sWA; - unsigned int ui32Mask; - int i32Depth; - - // Initializes the display and screen - x11Display = XOpenDisplay(0); - if (!x11Display && !(x11Display = XOpenDisplay(":0"))) - { - printf("Error: Unable to open X display\n"); - return; - } - x11Screen = XDefaultScreen(x11Display); - - // Gets the window parameters - sRootWindow = RootWindow(x11Display, x11Screen); - - int depth = CopyFromParent; - - #if !defined(GLES) - // Get a matching FB config - static int visual_attribs[] = - { - GLX_X_RENDERABLE , True, - GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, - GLX_RENDER_TYPE , GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, - GLX_RED_SIZE , 8, - GLX_GREEN_SIZE , 8, - GLX_BLUE_SIZE , 8, - GLX_ALPHA_SIZE , 8, - GLX_DEPTH_SIZE , 24, - GLX_STENCIL_SIZE , 8, - GLX_DOUBLEBUFFER , True, - //GLX_SAMPLE_BUFFERS , 1, - //GLX_SAMPLES , 4, - None - }; - - int glx_major, glx_minor; - - // FBConfigs were added in GLX version 1.3. - if (!glXQueryVersion(x11Display, &glx_major, &glx_minor) || - ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) - { - printf("Invalid GLX version"); - exit(1); - } - - int fbcount; - GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); - if (!fbc) - { - printf("Failed to retrieve a framebuffer config\n"); - exit(1); - } - printf("Found %d matching FB configs.\n", fbcount); - - GLXFBConfig bestFbc = fbc[0]; - XFree(fbc); - - // Get a visual - XVisualInfo *vi = glXGetVisualFromFBConfig(x11Display, bestFbc); - printf("Chosen visual ID = 0x%x\n", vi->visualid); - - - depth = vi->depth; - x11Visual = vi; - - x11Colormap = XCreateColormap(x11Display, RootWindow(x11Display, x11Screen), vi->visual, AllocNone); - #else - i32Depth = DefaultDepth(x11Display, x11Screen); - x11Visual = new XVisualInfo; - XMatchVisualInfo(x11Display, x11Screen, i32Depth, TrueColor, x11Visual); - if (!x11Visual) - { - printf("Error: Unable to acquire visual\n"); - return; - } - x11Colormap = XCreateColormap(x11Display, sRootWindow, x11Visual->visual, AllocNone); - #endif - - sWA.colormap = x11Colormap; - - // Add to these for handling other events - sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; - ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; - - #ifdef TARGET_PANDORA - int width = 800; - int height = 480; - #else - int width = cfgLoadInt("x11", "width", WINDOW_WIDTH); - int height = cfgLoadInt("x11", "height", WINDOW_HEIGHT); - #endif - - if (width == -1) - { - width = XDisplayWidth(x11Display, x11Screen); - height = XDisplayHeight(x11Display, x11Screen); - } - - // Creates the X11 window - x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, - 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA); - - #ifdef TARGET_PANDORA - // fullscreen - Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); - Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); - XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); - - XMapRaised(x11Display, x11Window); - #else - XMapWindow(x11Display, x11Window); - - #if !defined(GLES) - #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 - #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 - typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); - - glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; - glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); - verify(glXCreateContextAttribsARB != 0); - int context_attribs[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - None - }; - - x11_glc = glXCreateContextAttribsARB(x11Display, bestFbc, 0, True, context_attribs); - XSync(x11Display, False); - - if (!x11_glc) - { - die("Failed to create GL3.1 context\n"); - } - #endif - #endif - - XFlush(x11Display); - - //(EGLNativeDisplayType)x11Display; - x11_disp = (void*)x11Display; - x11_win = (void*)x11Window; - } - else - { - printf("Not creating X11 window ..\n"); - } + x11_window_create(); #endif } @@ -507,17 +260,7 @@ void dc_run(); gl_term(); } - // close XWindow - if (x11_win) - { - XDestroyWindow(x11_disp, x11_win); - x11_win = 0; - } - if (x11_disp) - { - XCloseDisplay(x11_disp); - x11_disp = 0; - } + x11_window_destroy(): // finish cleaning if (sig_num!=0) @@ -554,26 +297,6 @@ int main(int argc, wchar* argv[]) SetHomeDir(home); printf("Home dir is: %s\n", GetPath("/").c_str()); - #if defined(SUPPORT_X11) - x11_keymap[113] = DC_DPAD_LEFT; - x11_keymap[114] = DC_DPAD_RIGHT; - - x11_keymap[111] = DC_DPAD_UP; - x11_keymap[116] = DC_DPAD_DOWN; - - x11_keymap[53] = DC_BTN_X; - x11_keymap[54] = DC_BTN_B; - x11_keymap[55] = DC_BTN_A; - - /* - //TODO: Fix sliders - x11_keymap[38] = DPad_Down; - x11_keymap[39] = DPad_Down; - */ - - x11_keymap[36] = DC_BTN_START; - #endif - common_linux_setup(); settings.profile.run_counts=0; diff --git a/core/linux-dist/main.h b/core/linux-dist/main.h index 124280623..f9e9c3db8 100644 --- a/core/linux-dist/main.h +++ b/core/linux-dist/main.h @@ -1,10 +1,14 @@ #pragma once +#include "types.h" extern u16 kcode[4]; extern u32 vks[4]; extern u8 rt[4], lt[4]; extern s8 joyx[4], joyy[4]; +extern void* x11_win; +extern void* x11_disp; + enum DreamcastController { DC_BTN_C = 1, diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp new file mode 100644 index 000000000..1c77db124 --- /dev/null +++ b/core/linux-dist/x11.cpp @@ -0,0 +1,308 @@ +#if defined(SUPPORT_X11) +#include +#include +#include +#include + +#if !defined(GLES) + #include + #include +#endif + +#include "types.h" +#include "cfg/cfg.h" +#include "linux-dist/x11.h" +#include "linux-dist/main.h" + +#if defined(TARGET_PANDORA) + #define WINDOW_WIDTH 800 +#else + #define WINDOW_WIDTH 640 +#endif +#define WINDOW_HEIGHT 480 + +map x11_keymap; +int x11_dc_buttons = 0xFFFF; + +int ndcid = 0; +void* x11_glc; + +#ifdef TARGET_PANDORA + static Cursor CreateNullCursor(Display *display, Window root) + { + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; + } +#endif + +void input_x11_handle() { + if (x11_win) + { + //Handle X11 + XEvent e; + + if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e)) + { + switch(e.type) + { + case KeyPress: + case KeyRelease: + { + int dc_key = x11_keymap[e.xkey.keycode]; + + if (e.type == KeyPress) + { + kcode[0] &= ~dc_key; + } + else + { + kcode[0] |= dc_key; + } + + //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); + } + break; + + + { + printf("KEYRELEASE\n"); + } + break; + + } + } + } +} + +void input_x11_init() +{ + x11_keymap[113] = DC_DPAD_LEFT; + x11_keymap[114] = DC_DPAD_RIGHT; + + x11_keymap[111] = DC_DPAD_UP; + x11_keymap[116] = DC_DPAD_DOWN; + + x11_keymap[53] = DC_BTN_X; + x11_keymap[54] = DC_BTN_B; + x11_keymap[55] = DC_BTN_A; + + /* + //TODO: Fix sliders + x11_keymap[38] = DPad_Down; + x11_keymap[39] = DPad_Down; + */ + + x11_keymap[36] = DC_BTN_START; +} + +void x11_window_create() +{ + if (cfgLoadInt("pvr", "nox11", 0) == 0) + { + XInitThreads(); + // X11 variables + Window x11Window = 0; + Display* x11Display = 0; + long x11Screen = 0; + XVisualInfo* x11Visual = 0; + Colormap x11Colormap = 0; + + /* + Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output + */ + Window sRootWindow; + XSetWindowAttributes sWA; + unsigned int ui32Mask; + int i32Depth; + + // Initializes the display and screen + x11Display = XOpenDisplay(0); + if (!x11Display && !(x11Display = XOpenDisplay(":0"))) + { + printf("Error: Unable to open X display\n"); + return; + } + x11Screen = XDefaultScreen(x11Display); + + // Gets the window parameters + sRootWindow = RootWindow(x11Display, x11Screen); + + int depth = CopyFromParent; + + #if !defined(GLES) + // Get a matching FB config + static int visual_attribs[] = + { + GLX_X_RENDERABLE , True, + GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, + GLX_RENDER_TYPE , GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, + GLX_RED_SIZE , 8, + GLX_GREEN_SIZE , 8, + GLX_BLUE_SIZE , 8, + GLX_ALPHA_SIZE , 8, + GLX_DEPTH_SIZE , 24, + GLX_STENCIL_SIZE , 8, + GLX_DOUBLEBUFFER , True, + //GLX_SAMPLE_BUFFERS , 1, + //GLX_SAMPLES , 4, + None + }; + + int glx_major, glx_minor; + + // FBConfigs were added in GLX version 1.3. + if (!glXQueryVersion(x11Display, &glx_major, &glx_minor) || + ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) + { + printf("Invalid GLX version"); + exit(1); + } + + int fbcount; + GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); + if (!fbc) + { + printf("Failed to retrieve a framebuffer config\n"); + exit(1); + } + printf("Found %d matching FB configs.\n", fbcount); + + GLXFBConfig bestFbc = fbc[0]; + XFree(fbc); + + // Get a visual + XVisualInfo *vi = glXGetVisualFromFBConfig(x11Display, bestFbc); + printf("Chosen visual ID = 0x%x\n", vi->visualid); + + + depth = vi->depth; + x11Visual = vi; + + x11Colormap = XCreateColormap(x11Display, RootWindow(x11Display, x11Screen), vi->visual, AllocNone); + #else + i32Depth = DefaultDepth(x11Display, x11Screen); + x11Visual = new XVisualInfo; + XMatchVisualInfo(x11Display, x11Screen, i32Depth, TrueColor, x11Visual); + if (!x11Visual) + { + printf("Error: Unable to acquire visual\n"); + return; + } + x11Colormap = XCreateColormap(x11Display, sRootWindow, x11Visual->visual, AllocNone); + #endif + + sWA.colormap = x11Colormap; + + // Add to these for handling other events + sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; + ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; + + #ifdef TARGET_PANDORA + int width = 800; + int height = 480; + #else + int width = cfgLoadInt("x11", "width", WINDOW_WIDTH); + int height = cfgLoadInt("x11", "height", WINDOW_HEIGHT); + #endif + + if (width == -1) + { + width = XDisplayWidth(x11Display, x11Screen); + height = XDisplayHeight(x11Display, x11Screen); + } + + // Creates the X11 window + x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, + 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA); + + #ifdef TARGET_PANDORA + // fullscreen + Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); + Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); + XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); + + XMapRaised(x11Display, x11Window); + #else + XMapWindow(x11Display, x11Window); + + #if !defined(GLES) + #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); + verify(glXCreateContextAttribsARB != 0); + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + }; + + x11_glc = glXCreateContextAttribsARB(x11Display, bestFbc, 0, True, context_attribs); + XSync(x11Display, False); + + if (!x11_glc) + { + die("Failed to create GL3.1 context\n"); + } + #endif + #endif + + XFlush(x11Display); + + //(EGLNativeDisplayType)x11Display; + x11_disp = (void*)x11Display; + x11_win = (void*)x11Window; + } + else + { + printf("Not creating X11 window ..\n"); + } +} + +void x11_window_set_text(const char* text) +{ + if (x11_win) + { + XChangeProperty((Display*)x11_disp, (Window)x11_win, + XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME, + XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING, + 8, PropModeReplace, (const unsigned char *)text, strlen(text)); + } +} + +void x11_window_destroy() +{ + // close XWindow + if (x11_win) + { + XDestroyWindow(x11_disp, x11_win); + x11_win = 0; + } + if (x11_disp) + { + XCloseDisplay(x11_disp); + x11_disp = 0; + } +} +#endif \ No newline at end of file diff --git a/core/linux-dist/x11.h b/core/linux-dist/x11.h new file mode 100644 index 000000000..d4b60da70 --- /dev/null +++ b/core/linux-dist/x11.h @@ -0,0 +1,7 @@ +#pragma once + +extern void* x11_glc; +extern void input_x11_init(); +extern void input_x11_handle(); +extern void x11_window_create(); +extern void x11_window_set_text(const char* text); \ No newline at end of file