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