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.
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
;
36 Window DAWindow
= None
;
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
;
46 DAOpenDisplay(char *display
, int argc
, char **argv
)
48 /* Open Connection to X Server */
49 DADisplay
= XOpenDisplay(display
);
51 printf("%s: could not open display %s!\n", _daContext
->programName
,
52 XDisplayName(display
));
56 DADepth
= DefaultDepth(DADisplay
, DefaultScreen(DADisplay
));
57 DAVisual
= DefaultVisual(DADisplay
, DefaultScreen(DADisplay
));
58 DAGC
= DefaultGC(DADisplay
, DefaultScreen(DADisplay
));
63 DAProposeIconSize(unsigned width
, unsigned height
)
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
)) {
77 int min_w
= -1, min_h
= -1;
78 int max_w
= 0, max_h
= 0;
80 for (i
= 0; i
< nrSizes
; i
++) {
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
) ||
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
))
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
;
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
);
129 DACreateIcon(char *name
, unsigned width
, unsigned height
, int argc
, char **argv
)
131 XClassHint
*classHint
;
133 XTextProperty window_name
;
135 unsigned long valueMask
;
140 _daContext
= DAContextInit(argc
, argv
);
142 _daContext
->width
= width
;
143 _daContext
->height
= height
;
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);
159 classHint
= XAllocClassHint();
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
;
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
);
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
);
180 wmHints
= XAllocWMHints();
182 printf("%s: can't allocate memory for wm hints!\n",
183 _daContext
->programName
), exit(1);
185 wmHints
->flags
= WindowGroupHint
;
186 wmHints
->window_group
= DALeader
;
188 if (!_daContext
->windowed
) {
189 wmHints
->flags
|= IconWindowHint
|StateHint
;
190 wmHints
->icon_window
= DAIcon
;
191 wmHints
->initial_state
= WithdrawnState
;
194 XSetWMHints(DADisplay
, DALeader
, wmHints
);
197 /* Set WMProtocols */
198 WM_DELETE_WINDOW
= XInternAtom(DADisplay
, "WM_DELETE_WINDOW", True
);
199 XSetWMProtocols(DADisplay
, DALeader
, &WM_DELETE_WINDOW
, 1);
201 /* Set Command to start the app so it can be docked properly */
202 XSetCommand(DADisplay
, DALeader
, argv
, argc
);
204 gcv
.graphics_exposures
= False
;
205 valueMask
= GCGraphicsExposures
;
207 /* continue setting the foreground GC */
208 resourceValue
= XGetDefault(DADisplay
, RES_CLASSNAME
, "foreground");
210 gcv
.foreground
= DAGetColor(resourceValue
);
211 valueMask
|= GCForeground
;
214 XChangeGC(DADisplay
, DAGC
, valueMask
, &gcv
);
216 /* set background GC values before setting value for foreground */
217 resourceValue
= XGetDefault(DADisplay
, RES_CLASSNAME
, "background");
219 gcv
.foreground
= DAGetColor(resourceValue
);
221 DAClearGC
= XCreateGC(DADisplay
, DAWindow
,
222 GCGraphicsExposures
|GCForeground
, &gcv
);
231 DAShowWindow(DALeader
);
236 DAShowWindow(Window window
)
239 XMapRaised(DADisplay
, window
);
240 if ((window
== DALeader
) && !_daContext
->windowed
)
241 XMapSubwindows(DADisplay
, DAIcon
);
243 XMapSubwindows(DADisplay
, window
);
251 DAInitialize(char *display
, char *name
, unsigned width
, unsigned height
,
252 int argc
, char **argv
)
254 DAOpenDisplay(display
, argc
, argv
);
255 DACreateIcon(name
, width
, height
, argc
, argv
);