mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-17 07:50:27 +00:00
Add proper close handling.
This commit is contained in:
parent
69caca6017
commit
ea7f8f5552
46
gfx/xvideo.c
46
gfx/xvideo.c
@ -19,6 +19,7 @@
|
||||
#include "general.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
@ -29,6 +30,8 @@
|
||||
#include <X11/extensions/Xv.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
|
||||
// Adapted from bSNES source.
|
||||
|
||||
typedef struct xv
|
||||
{
|
||||
Display *display;
|
||||
@ -37,6 +40,8 @@ typedef struct xv
|
||||
Colormap colormap;
|
||||
XShmSegmentInfo shminfo;
|
||||
|
||||
Atom quit_atom;
|
||||
|
||||
int port;
|
||||
int depth;
|
||||
int visualid;
|
||||
@ -53,6 +58,13 @@ typedef struct xv
|
||||
uint8_t *vtable;
|
||||
} xv_t;
|
||||
|
||||
|
||||
static volatile sig_atomic_t g_quit = false;
|
||||
static void sighandler(int sig)
|
||||
{
|
||||
g_quit = true;
|
||||
}
|
||||
|
||||
static void init_yuv_tables(xv_t *xv)
|
||||
{
|
||||
xv->ytable = malloc(0x10000);
|
||||
@ -159,7 +171,7 @@ static void* xv_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
XSetWindowAttributes attributes;
|
||||
attributes.colormap = xv->colormap;
|
||||
attributes.border_pixel = 0;
|
||||
attributes.event_mask = StructureNotifyMask;
|
||||
attributes.event_mask = StructureNotifyMask | DestroyNotify | ClientMessage;
|
||||
|
||||
xv->window = XCreateWindow(xv->display, DefaultRootWindow(xv->display),
|
||||
0, 0, video->width, video->height,
|
||||
@ -224,6 +236,17 @@ static void* xv_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
XSync(xv->display, False);
|
||||
memset(xv->image->data, 128, xv->image->data_size);
|
||||
|
||||
xv->quit_atom = XInternAtom(xv->display, "WM_DELETE_WINDOW", False);
|
||||
if (xv->quit_atom)
|
||||
XSetWMProtocols(xv->display, xv->window, &xv->quit_atom, 1);
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = sighandler;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
void *xinput = input_x.init();
|
||||
if (xinput)
|
||||
{
|
||||
@ -340,7 +363,26 @@ static bool xv_frame(void *data, const void* frame, unsigned width, unsigned hei
|
||||
|
||||
static bool xv_alive(void *data)
|
||||
{
|
||||
return true;
|
||||
xv_t *xv = data;
|
||||
|
||||
XEvent event;
|
||||
while (XPending(xv->display))
|
||||
{
|
||||
XNextEvent(xv->display, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case ClientMessage:
|
||||
if (event.xclient.data.l[0] == xv->quit_atom)
|
||||
return false;
|
||||
break;
|
||||
case DestroyNotify:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !g_quit;
|
||||
}
|
||||
|
||||
static bool xv_focus(void *data)
|
||||
|
Loading…
Reference in New Issue
Block a user