Implemented MiniFB for X11
This commit is contained in:
parent
e672d8a7ac
commit
78e89dbd3d
148
src/x11/X11MiniFB.c
Normal file
148
src/x11/X11MiniFB.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <MiniFB.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define KEY_FUNCTION 0xFF
|
||||
#define KEY_ESC 0x1B
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Display* s_display;
|
||||
static int s_screen;
|
||||
static int s_width;
|
||||
static int s_height;
|
||||
static Window s_window;
|
||||
static GC s_gc;
|
||||
static XImage *s_ximage;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_open(const char* title, int width, int height)
|
||||
{
|
||||
int depth, i, formatCount, convDepth = -1;
|
||||
XPixmapFormatValues* formats;
|
||||
XSetWindowAttributes windowAttributes;
|
||||
XSizeHints sizeHints;
|
||||
Visual* visual;
|
||||
|
||||
s_display = XOpenDisplay(0);
|
||||
|
||||
if (!s_display)
|
||||
return -1;
|
||||
|
||||
s_screen = DefaultScreen(s_display);
|
||||
visual = DefaultVisual(s_display, s_screen);
|
||||
formats = XListPixmapFormats(s_display, &formatCount);
|
||||
depth = DefaultDepth(s_display, s_screen);
|
||||
Window defaultRootWindow = DefaultRootWindow(s_display);
|
||||
|
||||
for (i = 0; i < formatCount; ++i)
|
||||
{
|
||||
if (depth == formats[i].depth)
|
||||
{
|
||||
convDepth = formats[i].bits_per_pixel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XFree(formats);
|
||||
|
||||
// We only support 32-bit right now
|
||||
if (convDepth != 32)
|
||||
{
|
||||
XCloseDisplay(s_display);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int screenWidth = DisplayWidth(s_display, s_screen);
|
||||
int screenHeight = DisplayHeight(s_display, s_screen);
|
||||
|
||||
windowAttributes.border_pixel = BlackPixel(s_display, s_screen);
|
||||
windowAttributes.background_pixel = BlackPixel(s_display, s_screen);
|
||||
windowAttributes.backing_store = NotUseful;
|
||||
|
||||
s_window = XCreateWindow(s_display, defaultRootWindow, (screenWidth - width) / 2,
|
||||
(screenHeight - height) / 2, width, height, 0, depth, InputOutput,
|
||||
visual, CWBackPixel | CWBorderPixel | CWBackingStore,
|
||||
&windowAttributes);
|
||||
if (!s_window)
|
||||
return 0;
|
||||
|
||||
XSelectInput(s_display, s_window, KeyPressMask | KeyReleaseMask);
|
||||
XStoreName(s_display, s_window, title);
|
||||
|
||||
sizeHints.flags = PPosition | PMinSize | PMaxSize;
|
||||
sizeHints.x = 0;
|
||||
sizeHints.y = 0;
|
||||
sizeHints.min_width = width;
|
||||
sizeHints.max_width = width;
|
||||
sizeHints.min_height = height;
|
||||
sizeHints.max_height = height;
|
||||
|
||||
XSetWMNormalHints(s_display, s_window, &sizeHints);
|
||||
XClearWindow(s_display, s_window);
|
||||
XMapRaised(s_display, s_window);
|
||||
XFlush(s_display);
|
||||
|
||||
s_gc = DefaultGC(s_display, s_screen);
|
||||
|
||||
s_ximage = XCreateImage(s_display, CopyFromParent, depth, ZPixmap, 0, NULL, width, height, 32, width * 4);
|
||||
|
||||
s_width = width;
|
||||
s_height = height;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int processEvents()
|
||||
{
|
||||
XEvent event;
|
||||
KeySym sym;
|
||||
|
||||
if (!XPending(s_display))
|
||||
return;
|
||||
|
||||
XNextEvent(s_display, &event);
|
||||
|
||||
if (event.type != KeyPress)
|
||||
return 0;
|
||||
|
||||
sym = XLookupKeysym(&event.xkey, 0);
|
||||
|
||||
if ((sym >> 8) != KEY_FUNCTION)
|
||||
return 0;
|
||||
|
||||
if ((sym & 0xFF) == KEY_ESC)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_update(void* buffer)
|
||||
{
|
||||
s_ximage->data = (char*)buffer;
|
||||
|
||||
XPutImage(s_display, s_window, s_gc, s_ximage, 0, 0, 0, 0, s_width, s_height);
|
||||
XFlush(s_display);
|
||||
|
||||
if (processEvents() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_close (void)
|
||||
{
|
||||
s_ximage->data = NULL;
|
||||
XDestroyImage(s_ximage);
|
||||
XDestroyWindow(s_display, s_window);
|
||||
XCloseDisplay(s_display);
|
||||
}
|
Loading…
Reference in New Issue
Block a user