blob: 5b8713443467fd49920327cb7be74a48e3950b19 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#include "../include/mgl/mgl.h"
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <stdio.h>
#ifndef NDEBUG
#include <stdlib.h>
#endif
static mgl_context context;
static int init_count = 0;
static XErrorHandler prev_xerror = NULL;
static XIOErrorHandler prev_xioerror = NULL;
static int ignore_xerror(Display *display, XErrorEvent *ee) {
(void)display;
(void)ee;
return 0;
}
static int ignore_xioerror(Display *display) {
(void)display;
return 0;
}
int mgl_init(void) {
++init_count;
if(init_count == 1) {
context.connection = XOpenDisplay(NULL);
if(!context.connection) {
fprintf(stderr, "mgl error: XOpenDisplay failed\n");
mgl_deinit();
return -1;
}
prev_xerror = XSetErrorHandler(ignore_xerror);
prev_xioerror = XSetIOErrorHandler(ignore_xioerror);
XInitThreads();
XkbSetDetectableAutoRepeat(context.connection, True, NULL);
context.wm_delete_window_atom = XInternAtom(context.connection, "WM_DELETE_WINDOW", False);
context.net_wm_ping_atom = XInternAtom(context.connection, "_NET_WM_PING", False);
context.net_wm_pid_atom = XInternAtom(context.connection, "_NET_WM_PID", False);
if(mgl_gl_load(&context.gl) != 0) {
mgl_deinit();
return -1;
}
}
return 0;
}
void mgl_deinit(void) {
if(init_count == 1) {
if(context.connection) {
XSetIOErrorHandler(prev_xioerror);
prev_xioerror = NULL;
XSetErrorHandler(prev_xerror);
prev_xerror = NULL;
XCloseDisplay(context.connection);
context.connection = NULL;
/*
GLX needs to be unloaded after closing the display on nvidia because
nvidia registers cleanup callbacks on exit, that uses the x11 display.
*/
mgl_gl_unload(&context.gl);
}
}
if(init_count > 0)
--init_count;
}
mgl_context* mgl_get_context(void) {
#ifndef NDEBUG
if(init_count == 0) {
fprintf(stderr, "mgl error: mgl_get_context was called before mgl_init\n");
abort();
}
#endif
return &context;
}
|