2 * Copyright (c) 1990, 2015, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
28 #include <X11/Xatom.h>
34 ** Common utility routines shared by the Workspace Colors programs
35 ** cmcsave, cmcshow, cmcinit.
40 disp_err_handler (Display
*dpy
)
43 fatal_error("cannot open display \"%s\"", display_name
);
47 ** Open display and handle any errors.
51 open_display (const char *dpyname
)
56 ** Catch errors opening display so user doesn't
57 ** get confusing 'XIOError: Broken Pipe' message.
59 XSetIOErrorHandler(disp_err_handler
);
61 display_name
= XDisplayName(dpyname
);
62 if (!(dpy
= XOpenDisplay(dpyname
)))
66 XSetIOErrorHandler(NULL
);
73 ** Return true if default visual of screen is dynamic.
77 dynamic_indexed_default_visual (Screen
*screen
)
79 int class = DefaultVisualOfScreen(screen
)->class;
81 return (class == GrayScale
||
82 class == PseudoColor
);
86 ** If file name is not already absolute, make absolute
87 ** relative to home directory.
91 fn_absolutize (const char *relname
)
94 static char filename
[256];
100 if (!(homedir
= (char *) getenv("HOME")))
102 sprintf(filename
, "%s/%s", homedir
, relname
);
108 comp_colors_filename (const char *basename
)
112 basename
= COMPACTED_COLORS_FILE
;
113 return fn_absolutize(basename
);
125 (void)fwrite(&scr_num
, sizeof(int), 1, f
);
126 (void)fwrite(&ncolors
, sizeof(int), 1, f
);
127 (void)fwrite(colors
, sizeof(XColor
), ncolors
, f
);
134 ** 0 is returned on EOF; 1 otherwise
145 if (!fread(scr_num
, sizeof(int), 1, f
))
148 if (!fread(ncolors
, sizeof(int), 1, f
)) {
149 fprintf(stderr
, "error: premature end-of-file\n");
150 fatal_error("cannot read number of saved colors");
153 if (!(*colors
= (XColor
*) malloc(*ncolors
* sizeof(XColor
))))
154 fatal_error("not enough memory");
156 if (!fread(*colors
, sizeof(XColor
), *ncolors
, f
)) {
157 fprintf(stderr
, "error: premature end-of-file\n");
158 fatal_error("cannot read saved colors");
172 /* write magic number and version */
174 (void)fwrite(&value
, sizeof(int), 1, f
);
176 (void)fwrite(&value
, sizeof(int), 1, f
);
187 /* check magic number */
188 if (!fread(&value
, sizeof(int), 1, f
) ||
190 fatal_error("Unrecognized colors file. Expected magic number = %x, \
191 Actual = %x", CMC_MAGIC
, value
);
193 /* check version number */
194 if (!fread(&value
, sizeof(int), 1, f
) ||
195 value
!= CMC_VERSION
)
196 fatal_error("Unrecognized colors file. Expected version number = %x, \
197 Actual = %x", CMC_VERSION
, value
);
212 /* intern the property name */
213 Atom atom
= XInternAtom(dpy
, name
, 0);
215 /* create or replace the property */
216 XChangeProperty(dpy
, w
, atom
, type
, format
, PropModeReplace
,
217 (unsigned char *)&data
, nelem
);
222 ** Sets the close-down mode of the cmc client to 'RetainPermanent'
223 ** so all client resources will be preserved after the client
224 ** exits. Puts a property on the default root window containing
225 ** an XID of the client so that the resources can later be killed.
233 Window w
= DefaultRootWindow(dpy
);
235 /* create dummy resource */
236 Pixmap pm
= XCreatePixmap(dpy
, w
, 1, 1, 1);
238 /* create/replace the property */
239 prop_update(dpy
, w
, RETAIN_PROP_NAME
, XA_PIXMAP
, 32, (int)pm
, 1);
241 /* retain all client resources until explicitly killed */
242 XSetCloseDownMode(dpy
, RetainPermanent
);
247 ** Flushes any resources previously retained by a cmc client,
257 Atom actual_type
; /* NOTUSED */
259 unsigned long nitems
;
260 unsigned long bytes_after
;
262 /* intern the property name */
263 Atom atom
= XInternAtom(dpy
, RETAIN_PROP_NAME
, 0);
265 /* look for existing resource allocation */
266 if (XGetWindowProperty(dpy
, DefaultRootWindow(dpy
), atom
, 0, 1,
267 1/*delete*/, AnyPropertyType
, &actual_type
, &format
, &nitems
,
268 &bytes_after
, (unsigned char **) &pm
) == Success
271 if (actual_type
== XA_PIXMAP
&& format
== 32 &&
272 nitems
== 1 && bytes_after
== 0) {
274 XKillClient(dpy
, *pm
);
276 } else if (actual_type
!= None
) {
277 extern char *program
;
278 fprintf(stderr
, "%s: warning: invalid format encountered for property %s\n",
279 RETAIN_PROP_NAME
, program
);