]> git.decadent.org.uk Git - ion3.git/blob - ioncore/colormap.c
564336da11a000c0bdcfaf010269c8b216d57cc1
[ion3.git] / ioncore / colormap.c
1 /*
2  * ion/ioncore/colormap.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <libtu/rb.h>
13 #include "common.h"
14 #include "global.h"
15 #include "property.h"
16 #include "clientwin.h"
17 #include "colormap.h"
18 #include "region.h"
19 #include "names.h"
20 #include "xwindow.h"
21
22
23 /*{{{ Installing colormaps */
24
25
26 void rootwin_install_colormap(WRootWin *rootwin, Colormap cmap)
27 {
28     if(cmap==None)
29         cmap=rootwin->default_cmap;
30     XInstallColormap(ioncore_g.dpy, cmap);
31 }
32
33
34 void clientwin_install_colormap(WClientWin *cwin)
35 {
36     WRootWin *rw=region_rootwin_of((WRegion*)cwin);
37     bool found=FALSE;
38     int i;
39
40     for(i=cwin->n_cmapwins-1; i>=0; i--){
41         rootwin_install_colormap(rw, cwin->cmaps[i]);
42         if(cwin->cmapwins[i]==cwin->win)
43             found=TRUE;
44     }
45     
46     if(found)
47         return;
48     
49     rootwin_install_colormap(rw, cwin->cmap);
50 }
51
52
53 /*}}}*/
54
55
56 /*{{{ Management */
57
58
59 static XContext ctx=None;
60
61
62 void xwindow_unmanaged_selectinput(Window win, long mask)
63 {
64     int *p=NULL;
65     
66     /* We may be monitoring for colourmap changes */
67     if(ctx!=None){
68         if(XFindContext(ioncore_g.dpy, win, ctx, (XPointer*)&p)==0){
69             if(*p>0)
70                 mask|=ColormapChangeMask;
71         }
72     }
73     
74     XSelectInput(ioncore_g.dpy, win, mask);
75 }
76
77                 
78         
79 static void xwindow_selcmap(Window win)
80 {
81     int *p=NULL;
82     XWindowAttributes attr;
83     
84     if(ctx==None)
85         ctx=XUniqueContext();
86     
87     if(XFindContext(ioncore_g.dpy, win, ctx, (XPointer*)&p)==0){
88         (*p)++;
89     }else{
90         p=ALLOC(int);
91         if(p==NULL)
92             return;
93         
94         *p=1;
95         if(XSaveContext(ioncore_g.dpy, win, ctx, (XPointer)p)!=0){
96             warn(TR("Unable to store colourmap watch info."));
97             return;
98         }
99
100         if(XWINDOW_REGION_OF(win)==NULL){
101             XGetWindowAttributes(ioncore_g.dpy, win, &attr);
102             XSelectInput(ioncore_g.dpy, win, 
103                          attr.your_event_mask|ColormapChangeMask);
104         }
105     }
106 }
107
108
109 static void xwindow_unselcmap(Window win)
110 {
111     int *p=NULL;
112     XWindowAttributes attr;
113     
114     if(ctx==None)
115         return;
116
117     if(XFindContext(ioncore_g.dpy, win, ctx, (XPointer*)&p)==0){
118         (*p)--;
119         if(*p==0){
120             XDeleteContext(ioncore_g.dpy, win, ctx);
121             free(p);
122             if(XWINDOW_REGION_OF(win)==NULL){
123                 XGetWindowAttributes(ioncore_g.dpy, win, &attr);
124                 XSelectInput(ioncore_g.dpy, win, 
125                              attr.your_event_mask&~ColormapChangeMask);
126             }
127         }
128     }
129 }
130
131
132 void clientwin_get_colormaps(WClientWin *cwin)
133 {
134     Window *wins;
135     XWindowAttributes attr;
136     int i, n;
137
138     clientwin_clear_colormaps(cwin);
139     
140     n=xwindow_get_property(cwin->win, ioncore_g.atom_wm_colormaps,
141                            XA_WINDOW, 100L, TRUE, (uchar**)&wins);
142     
143     if(n<=0)
144         return;
145     
146     cwin->cmaps=ALLOC_N(Colormap, n);
147     
148     if(cwin->cmaps==NULL)
149         return;
150     
151     cwin->cmapwins=wins;
152     cwin->n_cmapwins=n;
153     
154     for(i=0; i<n; i++){
155         if(wins[i]==cwin->win){
156             cwin->cmaps[i]=cwin->cmap;
157         }else{
158             xwindow_selcmap(wins[i]);
159             XGetWindowAttributes(ioncore_g.dpy, wins[i], &attr);
160             cwin->cmaps[i]=attr.colormap;
161         }
162     }
163 }
164
165
166 void clientwin_clear_colormaps(WClientWin *cwin)
167 {
168     int i;
169     XWindowAttributes attr;
170
171     if(cwin->n_cmapwins==0)
172         return;
173
174     for(i=0; i<cwin->n_cmapwins; i++){
175         if(cwin->cmapwins[i]!=cwin->win)
176             xwindow_unselcmap(cwin->cmapwins[i]);
177     }
178     
179     free(cwin->cmapwins);
180     free(cwin->cmaps);
181     cwin->n_cmapwins=0;
182     cwin->cmapwins=NULL;
183     cwin->cmaps=NULL;
184 }
185
186
187 /*}}}*/
188
189
190 /*{{{ Event handling */
191
192
193 static void handle_cwin_cmap(WClientWin *cwin, const XColormapEvent *ev)
194 {
195     int i;
196     
197     if(ev->window==cwin->win){
198         cwin->cmap=ev->colormap;
199         if(REGION_IS_ACTIVE(cwin))
200             clientwin_install_colormap(cwin);
201     }else{
202         for(i=0; i<cwin->n_cmapwins; i++){
203             if(cwin->cmapwins[i]!=ev->window)
204                 continue;
205             cwin->cmaps[i]=ev->colormap;
206             if(REGION_IS_ACTIVE(cwin))
207                 clientwin_install_colormap(cwin);
208             break;
209         }
210     }
211 }
212
213
214 static void handle_all_cmaps(const XColormapEvent *ev)
215 {
216     Rb_node node;
217     
218     if(!ioncore_clientwin_ns.initialised)
219         return;
220     
221     rb_traverse(node, ioncore_clientwin_ns.rb){
222         WClientWin *cwin=(WClientWin*)rb_val(node);
223         if(cwin!=NULL)
224             handle_cwin_cmap(cwin, ev);
225     }
226 }
227
228
229
230 void ioncore_handle_colormap_notify(const XColormapEvent *ev)
231 {
232     WClientWin *cwin;
233     
234     if(!ev->new)
235         return;
236
237     cwin=XWINDOW_REGION_OF_T(ev->window, WClientWin);
238
239     if(cwin!=NULL){
240         handle_cwin_cmap(cwin, ev);
241         /*set_cmap(cwin, ev->colormap);*/
242     }else{
243         handle_all_cmaps(ev);
244     }
245 }
246
247
248 /*}}}*/
249