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.
27 #define MIN(a, b) (a < b ? a : b)
29 struct DAContext
*_daContext
;
31 DARect DANoRect
= {0, 0, 0, 0};
32 Display
*DADisplay
= NULL
;
33 Window DALeader
= None
;
35 Window DAWindow
= None
;
37 Visual
*DAVisual
= NULL
;
38 unsigned long DAExpectedVersion
= 0;
39 GC DAGC
= NULL
, DAClearGC
= NULL
;
40 DARect DAPreferredIconSizes
= {-1, -1, 0, 0};
41 Atom WM_DELETE_WINDOW
;
45 DAOpenDisplay(char *display
, int argc
, char **argv
)
47 /* Open Connection to X Server */
48 DADisplay
= XOpenDisplay(display
);
50 printf("%s: could not open display %s!\n", _daContext
->programName
,
51 XDisplayName(display
));
55 DADepth
= DefaultDepth(DADisplay
, DefaultScreen(DADisplay
));
56 DAVisual
= DefaultVisual(DADisplay
, DefaultScreen(DADisplay
));
57 DAGC
= DefaultGC(DADisplay
, DefaultScreen(DADisplay
));
62 DAProposeIconSize(unsigned width
, unsigned height
)
67 _daContext
->width
= width
;
68 _daContext
->height
= height
;
70 /* Get the nearest allowed icon size if the WM specifies such */
71 iconSizes
= XAllocIconSize();
72 if (XGetIconSizes(DADisplay
, DefaultRootWindow(DADisplay
),
73 &iconSizes
, &nrSizes
)) {
76 int min_w
= -1, min_h
= -1;
77 int max_w
= 0, max_h
= 0;
79 for (i
= 0; i
< nrSizes
; i
++) {
82 if ((max_w
< iconSizes
[i
].max_width
) ||
83 (max_h
< iconSizes
[i
].max_height
)) {
84 max_w
= iconSizes
[i
].max_width
;
85 max_h
= iconSizes
[i
].max_height
;
88 if ((min_w
> iconSizes
[i
].min_width
) ||
89 (min_h
> iconSizes
[i
].min_height
) ||
91 min_w
= iconSizes
[i
].min_width
;
92 min_h
= iconSizes
[i
].min_height
;
95 if ((width
> iconSizes
[i
].max_width
) ||
96 (width
< iconSizes
[i
].min_width
) ||
97 (height
> iconSizes
[i
].max_height
) ||
98 (height
< iconSizes
[i
].min_height
))
101 w1
= (iconSizes
[i
].max_width
- width
) % iconSizes
[i
].width_inc
;
102 h1
= (iconSizes
[i
].max_height
- height
) % iconSizes
[i
].height_inc
;
103 w
= MIN(w1
, iconSizes
[i
].width_inc
- w1
);
104 h
= MIN(h1
, iconSizes
[i
].height_inc
- h1
);
106 if ((w
* h
< da
) || (da
== -1)) {
107 _daContext
->width
= width
+ w
;
108 _daContext
->height
= height
+ h
;
113 DAPreferredIconSizes
.x
= min_w
;
114 DAPreferredIconSizes
.y
= min_h
;
115 DAPreferredIconSizes
.width
= max_w
;
116 DAPreferredIconSizes
.height
= max_h
;
118 if (da
== -1) /* requested size is out of bounds */
119 DAWarning("Requested icon-size (%d x %d) is out of the range "
120 "allowed by the window manager\n",
121 _daContext
->width
, _daContext
->height
);
128 DACreateIcon(char *name
, unsigned width
, unsigned height
, int argc
, char **argv
)
130 XClassHint
*classHint
;
133 unsigned long valueMask
;
136 _daContext
->width
= width
;
137 _daContext
->height
= height
;
140 DALeader
= XCreateSimpleWindow(DADisplay
, DefaultRootWindow(DADisplay
),
141 0, 0, width
, height
, 0, 0, 0);
143 if (!_daContext
->windowed
) {
144 DAIcon
= XCreateSimpleWindow(DADisplay
, DefaultRootWindow(DADisplay
),
145 0, 0, width
, height
, 0, 0, 0);
153 classHint
= XAllocClassHint();
155 printf("%s: can't allocate memory for class hints!\n",
156 _daContext
->programName
), exit(1);
157 classHint
->res_class
= RES_CLASSNAME
;
158 classHint
->res_name
= name
;
160 XSetClassHint(DADisplay
, DALeader
, classHint
);
164 wmHints
= XAllocWMHints();
166 printf("%s: can't allocate memory for wm hints!\n",
167 _daContext
->programName
), exit(1);
169 wmHints
->flags
= WindowGroupHint
;
170 wmHints
->window_group
= DALeader
;
172 if (!_daContext
->windowed
) {
173 wmHints
->flags
|= IconWindowHint
|StateHint
;
174 wmHints
->icon_window
= DAIcon
;
175 wmHints
->initial_state
= WithdrawnState
;
178 XSetWMHints(DADisplay
, DALeader
, wmHints
);
181 /* Set WMProtocols */
182 WM_DELETE_WINDOW
= XInternAtom(DADisplay
, "WM_DELETE_WINDOW", True
);
183 XSetWMProtocols(DADisplay
, DALeader
, &WM_DELETE_WINDOW
, 1);
185 /* Set Command to start the app so it can be docked properly */
186 XSetCommand(DADisplay
, DALeader
, argv
, argc
);
188 gcv
.graphics_exposures
= False
;
189 valueMask
= GCGraphicsExposures
;
191 /* continue setting the foreground GC */
192 resourceValue
= XGetDefault(DADisplay
, RES_CLASSNAME
, "foreground");
194 gcv
.foreground
= DAGetColor(resourceValue
);
195 valueMask
|= GCForeground
;
198 XChangeGC(DADisplay
, DAGC
, valueMask
, &gcv
);
200 /* set background GC values before setting value for foreground */
201 resourceValue
= XGetDefault(DADisplay
, RES_CLASSNAME
, "background");
203 gcv
.foreground
= DAGetColor(resourceValue
);
205 DAClearGC
= XCreateGC(DADisplay
, DAWindow
,
206 GCGraphicsExposures
|GCForeground
, &gcv
);
215 DAShowWindow(DALeader
);
220 DAShowWindow(Window window
)
223 XMapRaised(DADisplay
, window
);
224 if ((window
== DALeader
) && !_daContext
->windowed
)
225 XMapSubwindows(DADisplay
, DAIcon
);
227 XMapSubwindows(DADisplay
, window
);
235 DAInitialize(char *display
, char *name
, unsigned width
, unsigned height
,
236 int argc
, char **argv
)
238 DAOpenDisplay(display
, argc
, argv
);
239 DACreateIcon(name
, width
, height
, argc
, argv
);