Add initial code for raw X11 backend
This commit is contained in:
parent
b9d9d339f8
commit
e01863b80c
3 changed files with 261 additions and 0 deletions
|
@ -432,6 +432,11 @@ elseif(BACKEND_PLATFORM MATCHES "Null")
|
|||
"src/Backends/Controller/Null.cpp"
|
||||
"src/Backends/Platform/Null.cpp"
|
||||
)
|
||||
elseif(BACKEND_PLATFORM MATCHES "X11")
|
||||
target_sources(CSE2 PRIVATE
|
||||
"src/Backends/Controller/Null.cpp"
|
||||
"src/Backends/Platform/X11.cpp"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "OpenGL3")
|
||||
|
@ -458,6 +463,8 @@ elseif(BACKEND_PLATFORM MATCHES "WiiU" AND BACKEND_RENDERER MATCHES "Software")
|
|||
elseif(BACKEND_PLATFORM MATCHES "3DS" AND BACKEND_RENDERER MATCHES "3DS")
|
||||
elseif(BACKEND_PLATFORM MATCHES "3DS" AND BACKEND_RENDERER MATCHES "Software")
|
||||
target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/Software/3DS.cpp")
|
||||
elseif(BACKEND_PLATFORM MATCHES "X11" AND BACKEND_RENDERER MATCHES "Software")
|
||||
target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/Software/X11.cpp")
|
||||
elseif(BACKEND_PLATFORM MATCHES "Null" AND BACKEND_RENDERER MATCHES "Software")
|
||||
target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/Software/Null.cpp")
|
||||
else()
|
||||
|
@ -564,6 +571,10 @@ if(BACKEND_PLATFORM MATCHES "GLFW3")
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(BACKEND_PLATFORM MATCHES "X11")
|
||||
target_link_libraries(CSE2 PRIVATE "-lX11")
|
||||
endif()
|
||||
|
||||
if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2")
|
||||
if(NOT FORCE_LOCAL_LIBS)
|
||||
find_package(SDL2)
|
||||
|
|
147
src/Backends/Platform/X11.cpp
Normal file
147
src/Backends/Platform/X11.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Released under the MIT license. X11 backend by Duuqnd.
|
||||
// See LICENSE.txt for details.
|
||||
|
||||
#include "../Misc.h"
|
||||
|
||||
#include "../Rendering.h"
|
||||
#include "../../Attributes.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
static bool keyboardState[BACKEND_KEYBOARD_TOTAL];
|
||||
Display* xDisplay;
|
||||
Visual* xVisual;
|
||||
static XVisualInfo xvisinfo;
|
||||
static unsigned long startTime;
|
||||
|
||||
bool Backend_Init(void (*drag_and_drop_callback)(const char *path), void (*window_focus_callback)(bool focus)) {
|
||||
// we're ignoring the hell out of focus and drag & drop
|
||||
xDisplay = XOpenDisplay(NULL);
|
||||
//XMatchVisualInfo(xDisplay, DefaultScreen(xDisplay), 24, DirectColor, &xvisinfo);
|
||||
//xVisual = xvisinfo.visual;
|
||||
|
||||
struct timeval time; // time.tv_usec is microseconds
|
||||
gettimeofday(&time, NULL);
|
||||
startTime = (time.tv_sec * 1000) + (time.tv_usec / 1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Backend_Deinit(void) {
|
||||
XCloseDisplay(xDisplay);
|
||||
}
|
||||
|
||||
void Backend_PostWindowCreation(void) {}
|
||||
|
||||
bool Backend_GetPaths(std::string *module_path, std::string *data_path) {
|
||||
return false; // I assume this means "do it yourself, lazy"
|
||||
}
|
||||
|
||||
void Backend_HideMouse(void) {}
|
||||
|
||||
void Backend_SetWindowIcon(const unsigned char *rgb_pixels, size_t width, size_t height) {
|
||||
// Oh we'll want this for sure!
|
||||
}
|
||||
|
||||
void Backend_SetCursor(const unsigned char *rgb_pixels, size_t width, size_t height) {}
|
||||
|
||||
void Backend_EnableDragAndDrop(void) {}
|
||||
|
||||
#define DOKEY(keych, keymac) { if(keysym == keych) keyboardState[keymac] = press; }
|
||||
|
||||
static void DoKeys(KeySym keysym, bool press) {
|
||||
// X keysyms are case sensitive. Isn't it great?!
|
||||
DOKEY(XK_z, BACKEND_KEYBOARD_Z);
|
||||
DOKEY(XK_x, BACKEND_KEYBOARD_X);
|
||||
DOKEY(XK_Z, BACKEND_KEYBOARD_Z);
|
||||
DOKEY(XK_X, BACKEND_KEYBOARD_X);
|
||||
DOKEY(XK_a, BACKEND_KEYBOARD_A);
|
||||
DOKEY(XK_s, BACKEND_KEYBOARD_S);
|
||||
DOKEY(XK_A, BACKEND_KEYBOARD_A);
|
||||
DOKEY(XK_S, BACKEND_KEYBOARD_S);
|
||||
|
||||
DOKEY(XK_q, BACKEND_KEYBOARD_Q);
|
||||
DOKEY(XK_w, BACKEND_KEYBOARD_W);
|
||||
DOKEY(XK_Q, BACKEND_KEYBOARD_Q);
|
||||
DOKEY(XK_W, BACKEND_KEYBOARD_W);
|
||||
|
||||
DOKEY(XK_Escape, BACKEND_KEYBOARD_ESCAPE);
|
||||
DOKEY(XK_F1, BACKEND_KEYBOARD_F1);
|
||||
DOKEY(XK_F2, BACKEND_KEYBOARD_F2);
|
||||
|
||||
DOKEY(XK_Left, BACKEND_KEYBOARD_LEFT);
|
||||
DOKEY(XK_Right, BACKEND_KEYBOARD_RIGHT);
|
||||
DOKEY(XK_Up, BACKEND_KEYBOARD_UP);
|
||||
DOKEY(XK_Down, BACKEND_KEYBOARD_DOWN);
|
||||
}
|
||||
|
||||
bool Backend_SystemTask(bool active) {
|
||||
if(!active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XEvent e;
|
||||
while(XPending(xDisplay) > 0) {
|
||||
XNextEvent(xDisplay, &e);
|
||||
if(e.type == KeyPress) {
|
||||
KeySym keysym = XLookupKeysym((XKeyEvent*)&e, 0);
|
||||
if(keysym == XK_Insert) {
|
||||
return false;
|
||||
}
|
||||
DoKeys(keysym, true);
|
||||
}
|
||||
if(e.type == KeyRelease) {
|
||||
KeySym keysym = XLookupKeysym((XKeyEvent*)&e, 0);
|
||||
DoKeys(keysym, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Backend_GetKeyboardState(bool *out_keyboard_state) {
|
||||
memcpy(out_keyboard_state, keyboardState, sizeof(keyboardState));
|
||||
}
|
||||
|
||||
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...) {
|
||||
va_list argumentList;
|
||||
va_start(argumentList, format);
|
||||
fputs("ERROR: ", stderr);
|
||||
vfprintf(stderr, format, argumentList);
|
||||
fputc('\n', stderr);
|
||||
va_end(argumentList);
|
||||
}
|
||||
|
||||
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...) {
|
||||
va_list argumentList;
|
||||
va_start(argumentList, format);
|
||||
fputs("INFO: ", stdout);
|
||||
vfprintf(stdout, format, argumentList);
|
||||
fputc('\n', stdout);
|
||||
va_end(argumentList);
|
||||
}
|
||||
|
||||
void Backend_ShowMessageBox(const char* title, const char* message) {
|
||||
printf("ShowMessageBox: %s - %s\n", title, message);
|
||||
}
|
||||
|
||||
unsigned long Backend_GetTicks(void) {
|
||||
struct timeval time; // time.tv_usec is microseconds
|
||||
gettimeofday(&time, NULL);
|
||||
unsigned long ticktime = ((time.tv_sec * 1000) + (time.tv_usec / 1000)) - startTime;
|
||||
return ticktime;
|
||||
}
|
||||
|
||||
void Backend_Delay(unsigned int ticks) {
|
||||
usleep(ticks * 1000);
|
||||
}
|
103
src/Backends/Rendering/Window/Software/X11.cpp
Normal file
103
src/Backends/Rendering/Window/Software/X11.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "../Software.h"
|
||||
#include "../../../Misc.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
static Window window;
|
||||
static XImage* framebufferImage;
|
||||
static char* framebufferPixels;
|
||||
static int framebufferPitch;
|
||||
static char* xfriendlyFB;
|
||||
static GC gc;
|
||||
static int screenWidth;
|
||||
static int screenHeight;
|
||||
static Pixmap intermediate;
|
||||
extern Display* xDisplay;
|
||||
extern Visual* xVisual;
|
||||
|
||||
bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen_width, size_t screen_height, bool fullscreen) {
|
||||
screenWidth = screen_width;
|
||||
screenHeight = screen_height;
|
||||
|
||||
int screen = DefaultScreen(xDisplay);
|
||||
Window rootWindow = RootWindow(xDisplay, screen);
|
||||
//window = XCreateWindow(display, rootWindow, 0, 0, screen_width, screen_height, 0, 16, InputOutput, CopyFromParent, 0, NULL);
|
||||
window = XCreateSimpleWindow(xDisplay, rootWindow, 0, 0, screen_width, screen_height, 1, 0, 0);
|
||||
XSelectInput(xDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask);
|
||||
XMapRaised(xDisplay, window);
|
||||
XStoreName(xDisplay, window, window_title);
|
||||
|
||||
// Make the close button work. This is also required for the window to show up.
|
||||
// weird
|
||||
Atom WM_DELETE_WINDOW = XInternAtom(xDisplay, "WM_DELETE_WINDOW", false);
|
||||
XSetWMProtocols(xDisplay, window, &WM_DELETE_WINDOW, 1);
|
||||
|
||||
gc = DefaultGC(xDisplay, DefaultScreen(xDisplay));
|
||||
|
||||
int depth = DefaultDepth(xDisplay, DefaultScreen(xDisplay));
|
||||
|
||||
intermediate = XCreatePixmap(xDisplay, window, screenWidth, screenHeight, depth);
|
||||
|
||||
// Setting up the framebuffer
|
||||
framebufferPixels = (char*)malloc(screen_width * screen_height * 3);
|
||||
xfriendlyFB = (char*)malloc(screen_width * screen_height * 4);
|
||||
framebufferImage = XCreateImage(xDisplay, DefaultVisual(xDisplay, DefaultScreen(xDisplay)),
|
||||
depth, ZPixmap, 0,
|
||||
xfriendlyFB, screen_width, screen_height,
|
||||
32, 0);
|
||||
if(framebufferImage == 0) {
|
||||
return false;
|
||||
}
|
||||
framebufferPitch = screen_width * 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
|
||||
{
|
||||
*pitch = framebufferPitch;
|
||||
|
||||
return (unsigned char*)framebufferPixels;
|
||||
}
|
||||
|
||||
void WindowBackend_Software_DestroyWindow(void) {
|
||||
XDestroyWindow(xDisplay, window);
|
||||
}
|
||||
|
||||
void WindowBackend_Software_HandleWindowResize(size_t width, size_t height) {
|
||||
(void)width;
|
||||
(void)height;
|
||||
|
||||
Backend_PrintError("Bro I can't resize, I'm too lazy.");
|
||||
}
|
||||
|
||||
void WindowBackend_Software_Display(void) {
|
||||
int srci = 0;
|
||||
for(int i = 0; i < screenWidth * screenHeight * 4; i++) {
|
||||
int src;
|
||||
switch(i % 4) {
|
||||
case 0:
|
||||
src = srci + 2;
|
||||
break;
|
||||
case 1:
|
||||
src = srci + 1;
|
||||
break;
|
||||
case 2:
|
||||
src = srci + 0;
|
||||
break;
|
||||
case 3:
|
||||
srci += 3;
|
||||
}
|
||||
xfriendlyFB[i] = framebufferPixels[src];
|
||||
// if(i % 4 != 3) {
|
||||
// xfriendlyFB[i] = framebufferPixels[srci];
|
||||
// srci++;
|
||||
// }
|
||||
}
|
||||
XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight);
|
||||
//XCopyArea(xDisplay, intermediate, window, gc, 0, 0, screenWidth, screenHeight, 0, 0);
|
||||
}
|
Loading…
Add table
Reference in a new issue