2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 /* This module is all new
20 * This code handles colormaps for fvwm.
22 * Copyright 1994 Robert Nation. No restrictions are placed on this code,
23 * as long as the copyright notice is preserved . No guarantees or
24 * warrantees of any sort whatsoever are given or implied or anything.
27 /* ---------------------------- included header files ---------------------- */
33 #include "libs/fvwmlib.h"
37 #include "execcontext.h"
38 #include "eventhandler.h"
39 #include "functions.h"
43 #include "colormaps.h"
45 /* ---------------------------- local definitions -------------------------- */
47 /* ---------------------------- local macros ------------------------------- */
49 /* ---------------------------- imports ------------------------------------ */
51 /* ---------------------------- included code files ------------------------ */
53 /* ---------------------------- local types -------------------------------- */
55 /* ---------------------------- forward declarations ----------------------- */
57 /* ---------------------------- local variables ---------------------------- */
59 static Bool client_controls_colormaps
= False
;
60 static Colormap last_cmap
= None
;
62 /* ---------------------------- exported variables (globals) --------------- */
64 const FvwmWindow
*colormap_win
;
66 /* ---------------------------- local functions ---------------------------- */
68 /* ---------------------------- interface functions ------------------------ */
70 void set_client_controls_colormaps(Bool flag
)
72 client_controls_colormaps
= flag
;
77 /* HandleColormapNotify - colormap notify event handler
79 * This procedure handles both a client changing its own colormap, and
80 * a client explicitly installing its colormap itself (only the window
81 * manager should do that, so we must set it correctly).
83 void colormap_handle_colormap_notify(const evh_args_t
*ea
)
86 XColormapEvent
*cevent
= (XColormapEvent
*)ea
->exc
->x
.etrigger
;
87 Bool ReInstall
= False
;
88 XWindowAttributes attr
;
89 FvwmWindow
*fw
= ea
->exc
->w
.fw
;
97 if (XGetWindowAttributes(dpy
, FW_W(fw
), &attr
) != 0)
99 fw
->attr_backup
.colormap
= attr
.colormap
;
100 if (fw
== colormap_win
&&
101 fw
->number_cmap_windows
== 0)
103 last_cmap
= attr
.colormap
;
108 else if ((cevent
->state
== ColormapUninstalled
)&&
109 (last_cmap
== cevent
->colormap
))
111 /* Some window installed its colormap, change it back */
115 while (FCheckTypedEvent(dpy
, ColormapNotify
, &evdummy
))
118 dpy
, cevent
->window
, FvwmContext
,
119 (caddr_t
*) &fw
) == XCNOENT
)
123 if ((fw
)&&(cevent
->new))
125 if (XGetWindowAttributes(dpy
, FW_W(fw
), &attr
) != 0)
127 fw
->attr_backup
.colormap
= attr
.colormap
;
128 if (fw
== colormap_win
&&
129 fw
->number_cmap_windows
== 0)
131 last_cmap
= attr
.colormap
;
137 (cevent
->state
== ColormapUninstalled
)&&
138 (last_cmap
== cevent
->colormap
))
140 /* Some window installed its colormap, change it back */
144 (cevent
->state
== ColormapInstalled
)&&
145 (last_cmap
== cevent
->colormap
))
147 /* The last color map installed was the correct one.
148 * Do not change anything */
153 /* Reinstall the colormap that we think should be installed,
154 * UNLESS and unrecognized window has the focus - it might be
155 * an override-redirect window that has its own colormap. */
156 if (ReInstall
&& Scr
.UnknownWinFocused
== None
&&
157 !client_controls_colormaps
)
159 XInstallColormap(dpy
,last_cmap
);
165 /* Re-Install the active colormap */
166 void ReInstallActiveColormap(void)
168 InstallWindowColormaps(colormap_win
);
174 * InstallWindowColormaps - install the colormaps for one fvwm window
177 * type - type of event that caused the installation
178 * tmp - for a subset of event types, the address of the
179 * window structure, whose colormaps are to be installed.
181 void InstallWindowColormaps(const FvwmWindow
*fw
)
184 XWindowAttributes attributes
;
186 Bool ThisWinInstalled
= False
;
188 /* If no window, then install fvwm colormap */
195 /* Save the colormap to be loaded for when force loading of
196 * root colormap(s) ends.
198 Scr
.pushed_window
= fw
;
199 /* Don't load any new colormap if root/fvwm colormap(s) has been
202 if (Scr
.root_pushes
|| Scr
.fvwm_pushes
|| client_controls_colormaps
)
207 if (fw
->number_cmap_windows
> 0)
209 for (i
=fw
->number_cmap_windows
-1; i
>=0;i
--)
211 w
= fw
->cmap_windows
[i
];
214 ThisWinInstalled
= True
;
216 if (!XGetWindowAttributes(dpy
,w
,&attributes
))
218 attributes
.colormap
= last_cmap
;
222 * On Sun X servers, don't install 24 bit TrueColor
223 * colourmaps. Despite what the server says, these
224 * colourmaps are always installed. */
225 if (last_cmap
!= attributes
.colormap
226 #if defined(sun) && defined(TRUECOLOR_ALWAYS_INSTALLED)
227 && !(attributes
.depth
== 24 &&
228 attributes
.visual
->class == TrueColor
)
232 last_cmap
= attributes
.colormap
;
233 XInstallColormap(dpy
, last_cmap
);
238 if (!ThisWinInstalled
)
240 if (last_cmap
!= fw
->attr_backup
.colormap
241 #if defined(sun) && defined(TRUECOLOR_ALWAYS_INSTALLED)
242 && !(fw
->attr_backup
.depth
== 24 &&
243 fw
->attr_backup
.visual
->class == TrueColor
)
247 last_cmap
= fw
->attr_backup
.colormap
;
248 XInstallColormap(dpy
, last_cmap
);
256 /* Force (un)loads root colormap(s)
258 * These matching routines provide a mechanism to insure that
259 * the root colormap(s) is installed during operations like
260 * rubber banding that require colors from
261 * that colormap. Calls may be nested arbitrarily deeply,
262 * as long as there is one UninstallRootColormap call per
263 * InstallRootColormap call.
265 * {Uni,I}nstall{Root,Fvwm}Colormap calls may be freely intermixed
267 void InstallRootColormap(void)
269 if (last_cmap
!= DefaultColormap(dpy
, Scr
.screen
))
271 last_cmap
= DefaultColormap(dpy
, Scr
.screen
);
272 XInstallColormap(dpy
, last_cmap
);
279 /* Unstacks one layer of root colormap pushing
280 * If we peel off the last layer, re-install the application colormap
281 * or the fvwm colormap if fvwm has a menu posted
283 void UninstallRootColormap(void)
290 if (!Scr
.root_pushes
)
292 if (!Scr
.fvwm_pushes
)
294 InstallWindowColormaps(Scr
.pushed_window
);
296 else if (last_cmap
!= Pcmap
)
299 XInstallColormap(dpy
, last_cmap
);
307 * {Uni/I}nstallFvwmColormap - Force (un)loads fvwm colormap(s)
308 * This is used to ensure the fvwm colormap is installed during
311 void InstallFvwmColormap(void)
313 if (last_cmap
!= Pcmap
)
316 XInstallColormap(dpy
, last_cmap
);
323 void UninstallFvwmColormap(void)
330 if (!Scr
.fvwm_pushes
)
332 if (!Scr
.root_pushes
)
334 InstallWindowColormaps(Scr
.pushed_window
);
336 else if (last_cmap
!= DefaultColormap(dpy
, Scr
.screen
))
338 last_cmap
= DefaultColormap(dpy
, Scr
.screen
);
339 XInstallColormap(dpy
, last_cmap
);
346 /* Gets the WM_COLORMAP_WINDOWS property from the window
348 * This property typically doesn't exist, but a few applications
349 * use it. These seem to occur mostly on SGI machines.
351 void FetchWmColormapWindows (FvwmWindow
*fw
)
353 XWindowAttributes getattribs
;
354 XSetWindowAttributes setattribs
;
356 unsigned long valuemask
;
358 if (fw
->cmap_windows
!= (Window
*)NULL
)
360 XFree((void *)fw
->cmap_windows
);
363 if (!XGetWMColormapWindows (dpy
, FW_W(fw
), &(fw
->cmap_windows
),
364 &(fw
->number_cmap_windows
)))
366 fw
->number_cmap_windows
= 0;
367 fw
->cmap_windows
= NULL
;
369 /* we need to be notified of Enter events into these subwindows
370 * so we can set their colormaps */
371 if (fw
->number_cmap_windows
!= 0)
373 for (i
= 0; i
< fw
->number_cmap_windows
; i
++)
375 if (XGetWindowAttributes(
376 dpy
, fw
->cmap_windows
[i
], &getattribs
))
378 valuemask
= CWEventMask
;
379 setattribs
.event_mask
=
380 getattribs
.your_event_mask
|
381 EnterWindowMask
| LeaveWindowMask
;
382 XChangeWindowAttributes(
383 dpy
, fw
->cmap_windows
[i
], valuemask
,
391 /* Looks through the window list for any matching COLORMAP_WINDOWS
392 * windows and installs the colormap if one exists.
394 void EnterSubWindowColormap(Window win
)
398 XWindowAttributes attribs
;
400 for (t
= Scr
.FvwmRoot
.next
; t
!= NULL
; t
= t
->next
)
402 if (t
->number_cmap_windows
!= 0)
404 for (i
= 0; i
< t
->number_cmap_windows
; i
++)
406 if (t
->cmap_windows
[i
] == win
)
408 if (XGetWindowAttributes(
411 last_cmap
= attribs
.colormap
;
424 void LeaveSubWindowColormap(Window win
)
428 int bWinInList
, bParentInList
;
430 for (t
= Scr
.FvwmRoot
.next
; t
!= NULL
; t
= t
->next
)
432 if (t
->number_cmap_windows
!= 0)
436 for (i
=0;i
<t
->number_cmap_windows
;i
++)
438 if (t
->cmap_windows
[i
] == win
)
442 if (t
->cmap_windows
[i
] == FW_W(t
))
451 InstallWindowColormaps(t
);
455 InstallWindowColormaps(NULL
);