Prevent overflow while calculating frame size hints
[notion/jeffpc.git] / ioncore / colormap.c
blob9f80f499ef6f467854fe7b53b3bd2776d0914e4a
1 /*
2 * ion/ioncore/colormap.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
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"
20 /*{{{ Installing colormaps */
23 void rootwin_install_colormap(WRootWin *rootwin, Colormap cmap)
25 if(cmap==None)
26 cmap=rootwin->default_cmap;
27 XInstallColormap(ioncore_g.dpy, cmap);
31 void clientwin_install_colormap(WClientWin *cwin)
33 WRootWin *rw=region_rootwin_of((WRegion*)cwin);
34 bool found=FALSE;
35 int i;
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;
43 if(found)
44 return;
46 rootwin_install_colormap(rw, cwin->cmap);
50 /*}}}*/
53 /*{{{ Management */
56 static XContext ctx=None;
59 void xwindow_unmanaged_selectinput(Window win, long mask)
61 int *p=NULL;
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;
71 XSelectInput(ioncore_g.dpy, win, mask);
76 static void xwindow_selcmap(Window win)
78 int *p=NULL;
79 XWindowAttributes attr;
81 if(ctx==None)
82 ctx=XUniqueContext();
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;
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;
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);
106 static void xwindow_unselcmap(Window win)
108 int *p=NULL;
109 XWindowAttributes attr;
111 if(ctx==None)
112 return;
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);
129 void clientwin_get_colormaps(WClientWin *cwin)
131 Window *wins;
132 XWindowAttributes attr;
133 int i, n;
135 clientwin_clear_colormaps(cwin);
137 n=xwindow_get_property(cwin->win, ioncore_g.atom_wm_colormaps,
138 XA_WINDOW, 100L, TRUE, (uchar**)&wins);
140 if(n<=0)
141 return;
143 cwin->cmaps=ALLOC_N(Colormap, n);
145 if(cwin->cmaps==NULL)
146 return;
148 cwin->cmapwins=wins;
149 cwin->n_cmapwins=n;
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;
163 void clientwin_clear_colormaps(WClientWin *cwin)
165 int i;
166 XWindowAttributes attr;
168 if(cwin->n_cmapwins==0)
169 return;
171 for(i=0; i<cwin->n_cmapwins; i++){
172 if(cwin->cmapwins[i]!=cwin->win)
173 xwindow_unselcmap(cwin->cmapwins[i]);
176 free(cwin->cmapwins);
177 free(cwin->cmaps);
178 cwin->n_cmapwins=0;
179 cwin->cmapwins=NULL;
180 cwin->cmaps=NULL;
184 /*}}}*/
187 /*{{{ Event handling */
190 static void handle_cwin_cmap(WClientWin *cwin, const XColormapEvent *ev)
192 int i;
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;
211 static void handle_all_cmaps(const XColormapEvent *ev)
213 Rb_node node;
215 if(!ioncore_clientwin_ns.initialised)
216 return;
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);
227 void ioncore_handle_colormap_notify(const XColormapEvent *ev)
229 WClientWin *cwin;
231 if(!ev->new)
232 return;
234 cwin=XWINDOW_REGION_OF_T(ev->window, WClientWin);
236 if(cwin!=NULL){
237 handle_cwin_cmap(cwin, ev);
238 /*set_cmap(cwin, ev->colormap);*/
239 }else{
240 handle_all_cmaps(ev);
245 /*}}}*/