linux-dist: Move most x11 related code into a separate file

This commit is contained in:
Jan Holthuis 2015-08-15 05:50:08 +02:00
parent 729ded83f6
commit 1843fc3fe4
4 changed files with 343 additions and 301 deletions

View File

@ -20,17 +20,7 @@
#endif
#if defined(SUPPORT_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#if !defined(GLES)
#include <GL/gl.h>
#include <GL/glx.h>
#endif
#include <map>
map<int, int> x11_keymap;
#include "linux-dist/x11.h"
#endif
#if defined(USES_HOMEDIR)
@ -48,25 +38,9 @@
#ifdef TARGET_PANDORA
#include <signal.h>
#include <execinfo.h>
#include <sys/soundcard.h>
#define WINDOW_WIDTH 800
#else
#define WINDOW_WIDTH 640
#include <sys/soundcard.h>
#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;

View File

@ -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,

308
core/linux-dist/x11.cpp Normal file
View File

@ -0,0 +1,308 @@
#if defined(SUPPORT_X11)
#include <map>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#if !defined(GLES)
#include <GL/gl.h>
#include <GL/glx.h>
#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<int, int> 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

7
core/linux-dist/x11.h Normal file
View File

@ -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);