summaryrefslogtreecommitdiffstats
path: root/progs/egl/segl/segl_x11.c
blob: 7b26917460ab3e034fa43c5ee780e0cfa133107c (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdlib.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include "segl.h"

static Window
x11_create_window(struct segl_winsys *winsys, const char *name,
                  EGLint width, EGLint height, EGLint visual)
{
   XVisualInfo vinfo_template, *vinfo = NULL;
   EGLint val, num_vinfo;
   Window root, win;
   XSetWindowAttributes attrs;
   unsigned long mask;
   EGLint x = 0, y = 0;

   vinfo_template.visualid = (VisualID) val;
   vinfo = XGetVisualInfo(winsys->dpy, VisualIDMask, &vinfo_template, &num_vinfo);
   if (!num_vinfo) {
      if (vinfo)
         XFree(vinfo);
      return None;
   }

   root = DefaultRootWindow(winsys->dpy);

   /* window attributes */
   attrs.background_pixel = 0;
   attrs.border_pixel = 0;
   attrs.colormap = XCreateColormap(winsys->dpy, root, vinfo->visual, AllocNone);
   attrs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
   attrs.override_redirect = False;
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;

   win = XCreateWindow(winsys->dpy, root, x, y, width, height, 0,
         vinfo->depth, InputOutput, vinfo->visual, mask, &attrs);
   XFree(vinfo);

   if (!win)
      return None;

   /* set hints and properties */
   {
      XSizeHints sizehints;
      sizehints.x = x;
      sizehints.y = y;
      sizehints.width  = width;
      sizehints.height = height;
      sizehints.flags = USSize | USPosition;
      XSetNormalHints(winsys->dpy, win, &sizehints);
      XSetStandardProperties(winsys->dpy, win, name, name,
                             None, (char **)NULL, 0, &sizehints);
   }

   XMapWindow(winsys->dpy, win);

   return win;
}

static void
x11_destroy_window(struct segl_winsys *winsys, Window win)
{
   if (win)
      XDestroyWindow(winsys->dpy, win);
}


static Pixmap 
x11_create_pixmap(struct segl_winsys *winsys, EGLint width, EGLint height,
                  EGLint depth)
{
   Window root = DefaultRootWindow(winsys->dpy);
   Pixmap pix;

   pix = XCreatePixmap(winsys->dpy, (Drawable) root, width, height, depth);

   return pix;
}

static void
x11_destroy_pixmap(struct segl_winsys *winsys, Pixmap pix)
{
   if (pix)
      XFreePixmap(winsys->dpy, pix);
}

static double
x11_now(struct segl_winsys *winsys)
{
   struct timeval tv;

   gettimeofday(&tv, NULL);

   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
}

struct segl_winsys *
segl_get_winsys(EGLNativeDisplayType dpy)
{
   struct segl_winsys *winsys;

   winsys = calloc(1, sizeof(*winsys));
   if (winsys) {
      winsys->dpy = dpy;

      winsys->create_window = x11_create_window;
      winsys->destroy_window = x11_destroy_window;
      winsys->create_pixmap = x11_create_pixmap;
      winsys->destroy_pixmap = x11_destroy_pixmap;

      winsys->now = x11_now;
   }

   return winsys;
}