wmclockmon: update change-log
[dockapps.git] / libdockapp / src / damain.c
blob2a64ffc9b13b35e34fe74dff1521248e16bbfccf
1 /*
2 * Copyright (c) 1999-2003 Alfredo K. Kojima, Alban Hertroys
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include "dockapp.h"
24 #include "daargs.h"
25 #include "dautil.h"
26 #include <ctype.h>
28 #define MIN(a, b) (a < b ? a : b)
30 struct DAContext *_daContext;
32 DARect DANoRect = {0, 0, 0, 0};
33 Display *DADisplay = NULL;
34 Window DALeader = None;
35 Window DAIcon = None;
36 Window DAWindow = None;
37 int DADepth = 0;
38 Visual *DAVisual = NULL;
39 unsigned long DAExpectedVersion = 0;
40 GC DAGC = NULL, DAClearGC = NULL;
41 DARect DAPreferredIconSizes = {-1, -1, 0, 0};
42 Atom WM_DELETE_WINDOW;
45 void
46 DAOpenDisplay(char *display, int argc, char **argv)
48 /* Open Connection to X Server */
49 DADisplay = XOpenDisplay(display);
50 if (!DADisplay) {
51 printf("%s: could not open display %s!\n", _daContext->programName,
52 XDisplayName(display));
53 exit(EXIT_FAILURE);
56 DADepth = DefaultDepth(DADisplay, DefaultScreen(DADisplay));
57 DAVisual = DefaultVisual(DADisplay, DefaultScreen(DADisplay));
58 DAGC = DefaultGC(DADisplay, DefaultScreen(DADisplay));
62 void
63 DAProposeIconSize(unsigned width, unsigned height)
65 XIconSize *iconSizes;
66 int nrSizes = 0;
68 _daContext->width = width;
69 _daContext->height = height;
71 /* Get the nearest allowed icon size if the WM specifies such */
72 iconSizes = XAllocIconSize();
73 if (XGetIconSizes(DADisplay, DefaultRootWindow(DADisplay),
74 &iconSizes, &nrSizes)) {
75 int i;
76 int da = -1;
77 int min_w = -1, min_h = -1;
78 int max_w = 0, max_h = 0;
80 for (i = 0; i < nrSizes; i++) {
81 int w1, h1, w, h;
83 if ((max_w < iconSizes[i].max_width) ||
84 (max_h < iconSizes[i].max_height)) {
85 max_w = iconSizes[i].max_width;
86 max_h = iconSizes[i].max_height;
89 if ((min_w > iconSizes[i].min_width) ||
90 (min_h > iconSizes[i].min_height) ||
91 (min_w == -1)) {
92 min_w = iconSizes[i].min_width;
93 min_h = iconSizes[i].min_height;
96 if ((width > iconSizes[i].max_width) ||
97 (width < iconSizes[i].min_width) ||
98 (height > iconSizes[i].max_height) ||
99 (height < iconSizes[i].min_height))
100 continue;
102 w1 = (iconSizes[i].max_width - width) % iconSizes[i].width_inc;
103 h1 = (iconSizes[i].max_height - height) % iconSizes[i].height_inc;
104 w = MIN(w1, iconSizes[i].width_inc - w1);
105 h = MIN(h1, iconSizes[i].height_inc - h1);
107 if ((w * h < da) || (da == -1)) {
108 _daContext->width = width + w;
109 _daContext->height = height + h;
110 da = w * h;
114 DAPreferredIconSizes.x = min_w;
115 DAPreferredIconSizes.y = min_h;
116 DAPreferredIconSizes.width = max_w;
117 DAPreferredIconSizes.height = max_h;
119 if (da == -1) /* requested size is out of bounds */
120 DAWarning("Requested icon-size (%d x %d) is out of the range "
121 "allowed by the window manager\n",
122 _daContext->width, _daContext->height);
124 XFree(iconSizes);
128 void
129 DACreateIcon(char *name, unsigned width, unsigned height, int argc, char **argv)
131 XClassHint *classHint;
132 XWMHints *wmHints;
133 XTextProperty window_name;
134 XGCValues gcv;
135 unsigned long valueMask;
136 char *resourceValue;
137 char class[100];
139 if (!_daContext)
140 _daContext = DAContextInit(argc, argv);
142 _daContext->width = width;
143 _daContext->height = height;
145 /* Create Windows */
146 DALeader = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay),
147 0, 0, width, height, 0, 0, 0);
149 if (!_daContext->windowed) {
150 DAIcon = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay),
151 0, 0, width, height, 0, 0, 0);
152 DAWindow = DAIcon;
153 } else {
154 DAIcon = None;
155 DAWindow = DALeader;
158 /* Set ClassHint */
159 classHint = XAllocClassHint();
160 if (!classHint)
161 printf("%s: can't allocate memory for class hints!\n",
162 _daContext->programName), exit(1);
163 if (!_daContext->windowed) {
164 classHint->res_class = RES_CLASSNAME;
165 } else {
166 snprintf(class, 100, "%c%s", toupper(name[0]), name + 1);
167 classHint->res_class = class;
169 classHint->res_name = name;
170 XSetClassHint(DADisplay, DALeader, classHint);
171 XFree(classHint);
173 /* Set WMName */
174 if (XStringListToTextProperty(&name, 1, &window_name) == 0)
175 printf("%s: can't allocate window name.\n",
176 _daContext->programName), exit(1);
177 XSetWMName(DADisplay, DALeader, &window_name);
178 XFree(window_name.value);
180 /* Set WMHints */
181 wmHints = XAllocWMHints();
182 if (!wmHints)
183 printf("%s: can't allocate memory for wm hints!\n",
184 _daContext->programName), exit(1);
186 wmHints->flags = WindowGroupHint;
187 wmHints->window_group = DALeader;
189 if (!_daContext->windowed) {
190 wmHints->flags |= IconWindowHint|StateHint;
191 wmHints->icon_window = DAIcon;
192 wmHints->initial_state = WithdrawnState;
195 XSetWMHints(DADisplay, DALeader, wmHints);
196 XFree(wmHints);
198 /* Set WMProtocols */
199 WM_DELETE_WINDOW = XInternAtom(DADisplay, "WM_DELETE_WINDOW", True);
200 XSetWMProtocols(DADisplay, DALeader, &WM_DELETE_WINDOW, 1);
202 /* Set Command to start the app so it can be docked properly */
203 XSetCommand(DADisplay, DALeader, argv, argc);
205 gcv.graphics_exposures = False;
206 valueMask = GCGraphicsExposures;
208 /* continue setting the foreground GC */
209 resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "foreground");
210 if (resourceValue) {
211 gcv.foreground = DAGetColor(resourceValue);
212 valueMask |= GCForeground;
215 XChangeGC(DADisplay, DAGC, valueMask, &gcv);
217 /* set background GC values before setting value for foreground */
218 resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "background");
219 if (resourceValue)
220 gcv.foreground = DAGetColor(resourceValue);
222 DAClearGC = XCreateGC(DADisplay, DAWindow,
223 GCGraphicsExposures|GCForeground, &gcv);
225 XFlush(DADisplay);
229 void
230 DAShow(void)
232 DAShowWindow(DALeader);
236 void
237 DAShowWindow(Window window)
240 XMapRaised(DADisplay, window);
241 if ((window == DALeader) && !_daContext->windowed)
242 XMapSubwindows(DADisplay, DAIcon);
243 else
244 XMapSubwindows(DADisplay, window);
246 XFlush(DADisplay);
250 /* Deprecated */
251 void
252 DAInitialize(char *display, char *name, unsigned width, unsigned height,
253 int argc, char **argv)
255 DAOpenDisplay(display, argc, argv);
256 DACreateIcon(name, width, height, argc, argv);