]> icculus.org git repositories - dana/openbox.git/blob - render2/instance.c
only enable blend when needed
[dana/openbox.git] / render2 / instance.c
1 #include "instance.h"
2 #include "surface.h"
3 #include "debug.h"
4 #include "glft/glft.h"
5 #include <stdlib.h>
6 #include <assert.h>
7
8 static int glft_init = 0;
9
10 static int glx_rating(Display *display, XVisualInfo *v)
11 {
12     int rating = 0;
13     int val;
14     RrDebug("evaluating visual %d\n", (int)v->visualid);
15     glXGetConfig(display, v, GLX_BUFFER_SIZE, &val);
16     RrDebug("buffer size %d\n", val);
17
18     switch (val) {
19     case 32:
20         rating += 300;
21     break;
22     case 24:
23         rating += 200;
24     break;
25     case 16:
26         rating += 100;
27     break;
28     }
29
30     glXGetConfig(display, v, GLX_LEVEL, &val);
31     RrDebug("level %d\n", val);
32     if (val != 0)
33         rating = -10000;
34
35     glXGetConfig(display, v, GLX_DEPTH_SIZE, &val);
36     RrDebug("depth size %d\n", val);
37     switch (val) {
38     case 32:
39         rating += 30;
40     break;
41     case 24:
42         rating += 20;
43     break;
44     case 16:
45         rating += 10;
46     break;
47     case 0:
48         rating -= 10000;
49     }
50
51     glXGetConfig(display, v, GLX_DOUBLEBUFFER, &val);
52     RrDebug("double buffer %d\n", val);
53     if (val)
54         rating++;
55     return rating;
56 }
57
58 struct RrInstance *RrInstanceNew(Display *display, int screen)
59 {
60     int count, i = 0, val, best = 0, rate = 0, temp, ok;
61     XVisualInfo vimatch, *vilist;
62
63     vimatch.screen = screen;
64     vimatch.class = TrueColor;
65     vilist = XGetVisualInfo(display, VisualScreenMask | VisualClassMask,
66                             &vimatch, &count);
67
68     if (vilist) {
69         RrDebug("looking for a GL visual in %d visuals\n", count);
70         for (i = 0; i < count; i++) {
71             glXGetConfig(display, &vilist[i], GLX_USE_GL, &val);
72             if (val) {
73                 temp = glx_rating(display, &vilist[i]);
74                 if (temp > rate) {
75                     best = i;
76                     rate = temp;
77                 }
78             }
79         }
80     }
81     if (rate > 0) {
82         struct RrInstance *inst;
83
84         RrDebug("picked visual %d with rating %d\n", best, rate);
85
86         if (!glft_init) {
87             if (!GlftInit())
88                 return NULL;
89             glft_init = 1;
90         }
91
92         inst = malloc(sizeof(struct RrInstance));
93         inst->display = display;
94         inst->screen = screen;
95         inst->visinfo = vilist[best];
96         inst->cmap = XCreateColormap(display, RootWindow(display, screen),
97                                      RrVisual(inst), AllocNone);
98         inst->glx_context = glXCreateContext(display, &vilist[best],
99                                              NULL, True);
100         inst->shape_window = XCreateWindow(display,RootWindow(display, screen),
101                                            0, 0, 1, 1, 0,
102                                            RrInstanceDepth(inst), InputOutput,
103                                            RrInstanceVisual(inst), 0, NULL);
104         /* make the context current on anything we can so we can dl 
105            textures */
106
107         ok = glXMakeCurrent(display, inst->shape_window, inst->glx_context);
108         assert(ok);
109         inst->surface_map = g_hash_table_new(g_int_hash, g_int_equal);
110
111         assert(inst->glx_context);
112         glEnable(GL_CULL_FACE);
113         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
114
115         glMatrixMode(GL_PROJECTION);
116         glLoadIdentity();
117         glOrtho(-0.1, RrScreenWidth(inst) - 1.1,
118                 -0.1, RrScreenHeight(inst) - 1.1, 0, 10);
119
120         glMatrixMode(GL_MODELVIEW);
121         glLoadIdentity();
122
123         inst->gl_linewidth = 1.0;
124
125         return inst;
126     }
127
128     RrDebug("unable to find a suitable GL visual\n");
129     return NULL;
130 }
131
132 void RrInstanceFree(struct RrInstance *inst)
133 {
134     if (inst) {
135         g_hash_table_destroy(inst->surface_map);
136         glXDestroyContext(inst->display, inst->glx_context);
137         XFreeColormap(inst->display, inst->cmap);
138         free(inst);
139     }
140 }
141
142 int RrInstanceDepth(struct RrInstance *inst)
143 {
144     return inst->visinfo.depth;
145 }
146
147 Colormap RrInstanceColormap(struct RrInstance *inst)
148 {
149     return inst->cmap;
150 }
151
152 Visual *RrInstanceVisual(struct RrInstance *inst)
153 {
154     return inst->visinfo.visual;
155 }
156
157 void RrInstaceAddSurface(struct RrSurface *sur)
158 {
159     g_hash_table_replace(RrSurfaceInstance(sur)->surface_map, &sur->win, sur);
160 }
161
162 void RrInstaceRemoveSurface(struct RrSurface *sur)
163 {
164     g_hash_table_remove(RrSurfaceInstance(sur)->surface_map, &sur->win);
165 }
166
167 struct RrSurface *RrInstaceLookupSurface(struct RrInstance *inst, Window win)
168 {
169     return g_hash_table_lookup(inst->surface_map, &win);
170 }