2 * Copyright (c) 1999 Alfredo K. Kojima
3 * Copyright (c) 2001, 2002 Seiichi SATO <ssato@sh.rim.or.jp>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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 THE
18 * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * This code is based on libdockapp-0.4.0
23 * modified by Seiichi SATO <ssato@sh.rim.or.jp>
28 #define WINDOWED_SIZE_W 64
29 #define WINDOWED_SIZE_H 64
32 Display
*display
= NULL
;
33 Bool dockapp_iswindowed
= False
;
34 Bool dockapp_isbrokenwm
= False
;
37 static Window window
= None
;
38 static Window icon_window
= None
;
41 static Atom delete_win
;
42 static int width
, height
;
43 static int offset_w
, offset_h
;
46 dockapp_open_window(char *display_specified
, char *appname
,
47 unsigned w
, unsigned h
, int argc
, char **argv
)
49 XClassHint
*classhint
;
56 /* Open Connection to X Server */
57 display
= XOpenDisplay(display_specified
);
59 fprintf(stderr
, "%s: could not open display %s!\n", argv
[0],
60 XDisplayName(display_specified
));
63 root
= DefaultRootWindow(display
);
68 if (dockapp_iswindowed
) {
69 offset_w
= (WINDOWED_SIZE_W
- w
) / 2;
70 offset_h
= (WINDOWED_SIZE_H
- h
) / 2;
74 offset_w
= offset_h
= 0;
80 icon_window
= XCreateSimpleWindow(display
, root
, 0, 0, ww
, wh
, 0, 0, 0);
81 if (dockapp_isbrokenwm
) {
82 window
= XCreateSimpleWindow(display
, root
, 0, 0, ww
, wh
, 0, 0, 0);
84 window
= XCreateSimpleWindow(display
, root
, 0, 0, 1, 1, 0, 0, 0);
88 classhint
= XAllocClassHint();
89 if (classhint
== NULL
) {
90 fprintf(stderr
, "%s: can't allocate memory for wm hints!\n", argv
[0]);
93 classhint
->res_class
= "DockApp";
94 classhint
->res_name
= appname
;
95 XSetClassHint(display
, window
, classhint
);
99 wmhints
= XAllocWMHints();
100 if (wmhints
== NULL
) {
101 fprintf(stderr
, "%s: can't allocate memory for wm hints!\n", argv
[0]);
104 wmhints
->flags
= IconWindowHint
| WindowGroupHint
;
105 if (!dockapp_iswindowed
) {
106 wmhints
->flags
|= StateHint
;
107 wmhints
->initial_state
= WithdrawnState
;
109 wmhints
->window_group
= window
;
110 wmhints
->icon_window
= icon_window
;
111 XSetWMHints(display
, window
, wmhints
);
114 /* Set WM Protocols */
115 delete_win
= XInternAtom(display
, "WM_DELETE_WINDOW", False
);
116 XSetWMProtocols (display
, icon_window
, &delete_win
, 1);
119 sizehints
.flags
= USSize
;
120 if (!dockapp_iswindowed
) {
121 sizehints
.flags
|= USPosition
;
122 sizehints
.x
= sizehints
.y
= 0;
124 sizehints
.flags
|= PMinSize
| PMaxSize
;
125 sizehints
.min_width
= sizehints
.max_width
= WINDOWED_SIZE_W
;
126 sizehints
.min_height
= sizehints
.max_height
= WINDOWED_SIZE_H
;
128 sizehints
.width
= ww
;
129 sizehints
.height
= wh
;
130 XSetWMNormalHints(display
, icon_window
, &sizehints
);
132 /* Set WindowTitle for AfterStep Wharf */
133 XStringListToTextProperty(&appname
, 1, &title
);
134 XSetWMName(display
, window
, &title
);
135 XSetWMName(display
, icon_window
, &title
);
137 /* Set Command to start the app so it can be docked properly */
138 XSetCommand(display
, window
, argv
, argc
);
140 depth
= DefaultDepth(display
, DefaultScreen(display
));
141 gc
= DefaultGC(display
, DefaultScreen(display
));
148 dockapp_set_eventmask(long mask
)
150 XSelectInput(display
, icon_window
, mask
);
151 XSelectInput(display
, window
, mask
);
156 create_bg_pixmap(void)
160 bg
= XCreatePixmap(display
, icon_window
, WINDOWED_SIZE_W
, WINDOWED_SIZE_H
,
162 XSetForeground(display
, gc
, dockapp_getcolor("rgb:ae/aa/ae"));
163 XFillRectangle(display
, bg
, gc
, 0, 0, WINDOWED_SIZE_W
, WINDOWED_SIZE_H
);
164 XSetForeground(display
, gc
, dockapp_getcolor("rgb:ff/ff/ff"));
165 XDrawLine(display
, bg
, gc
, 0, 0, 0, 63);
166 XDrawLine(display
, bg
, gc
, 1, 0, 1, 62);
167 XDrawLine(display
, bg
, gc
, 2, 0, 63, 0);
168 XDrawLine(display
, bg
, gc
, 2, 1, 62, 1);
169 XSetForeground(display
, gc
, dockapp_getcolor("rgb:52/55/52"));
170 XDrawLine(display
, bg
, gc
, 1, 63, 63, 63);
171 XDrawLine(display
, bg
, gc
, 2, 62, 63, 62);
172 XDrawLine(display
, bg
, gc
, 63, 1, 63, 61);
173 XDrawLine(display
, bg
, gc
, 62, 2, 62, 61);
180 dockapp_set_background(Pixmap pixmap
)
182 if (dockapp_iswindowed
) {
184 bg
= create_bg_pixmap();
185 XCopyArea(display
, pixmap
, bg
, gc
, 0, 0, width
, height
,
187 XSetWindowBackgroundPixmap(display
, icon_window
, bg
);
188 XSetWindowBackgroundPixmap(display
, window
, bg
);
189 XFreePixmap(display
, bg
);
191 XSetWindowBackgroundPixmap(display
, icon_window
, pixmap
);
192 XSetWindowBackgroundPixmap(display
, window
, pixmap
);
194 XClearWindow(display
, icon_window
);
202 if (!dockapp_iswindowed
)
203 XMapRaised(display
, window
);
205 XMapRaised(display
, icon_window
);
212 dockapp_xpm2pixmap(char **data
, Pixmap
*pixmap
, Pixmap
*mask
,
213 XpmColorSymbol
* colorSymbol
, unsigned int nsymbols
)
215 XpmAttributes xpmAttr
;
216 xpmAttr
.valuemask
= XpmCloseness
;
217 xpmAttr
.closeness
= 40000;
220 xpmAttr
.colorsymbols
= colorSymbol
;
221 xpmAttr
.numsymbols
= nsymbols
;
222 xpmAttr
.valuemask
|= XpmColorSymbols
;
225 if (XpmCreatePixmapFromData(display
, icon_window
, data
, pixmap
, mask
, &xpmAttr
) != 0)
233 dockapp_file2pixmap(char *filename
, Pixmap
*pixmap
, Pixmap
*mask
,
234 XpmColorSymbol
* colorSymbol
, unsigned int nsymbols
)
236 XpmAttributes xpmAttr
;
237 xpmAttr
.valuemask
= XpmCloseness
;
238 xpmAttr
.closeness
= 40000;
241 xpmAttr
.colorsymbols
= colorSymbol
;
242 xpmAttr
.numsymbols
= nsymbols
;
243 xpmAttr
.valuemask
|= XpmColorSymbols
;
246 if (XpmReadFileToPixmap(display
, icon_window
, filename
, pixmap
, mask
, &xpmAttr
) != 0)
254 dockapp_XCreatePixmap(int w
, int h
)
256 return (XCreatePixmap(display
, icon_window
, w
, h
, depth
));
261 dockapp_setshape(Pixmap mask
, int x_ofs
, int y_ofs
)
263 XShapeCombineMask(display
, icon_window
, ShapeBounding
, -x_ofs
, -y_ofs
,
265 XShapeCombineMask(display
, window
, ShapeBounding
, -x_ofs
, -y_ofs
,
272 dockapp_copyarea(Pixmap src
, Pixmap dist
, int x_src
, int y_src
, int w
, int h
,
273 int x_dist
, int y_dist
)
275 XCopyArea(display
, src
, dist
, gc
, x_src
, y_src
, w
, h
, x_dist
, y_dist
);
280 dockapp_copy2window (Pixmap src
)
282 if (dockapp_isbrokenwm
) {
283 XCopyArea(display
, src
, window
, gc
, 0, 0, width
, height
, offset_w
,
286 XCopyArea(display
, src
, icon_window
, gc
, 0, 0, width
, height
, offset_w
,
293 dockapp_nextevent_or_timeout(XEvent
*event
, unsigned long miliseconds
)
295 struct timeval timeout
;
298 XSync(display
, False
);
299 if (XPending(display
)) {
300 XNextEvent(display
, event
);
304 timeout
.tv_sec
= miliseconds
/ 1000;
305 timeout
.tv_usec
= (miliseconds
% 1000) * 1000;
308 FD_SET(ConnectionNumber(display
), &rset
);
309 if (select(ConnectionNumber(display
)+1, &rset
, NULL
, NULL
, &timeout
) > 0) {
310 XNextEvent(display
, event
);
311 if (event
->type
== ClientMessage
) {
312 if ((Atom
) event
->xclient
.data
.l
[0] == delete_win
) {
313 XDestroyWindow(display
,event
->xclient
.window
);
314 XCloseDisplay(display
);
318 if (dockapp_iswindowed
) {
319 event
->xbutton
.x
-= offset_w
;
320 event
->xbutton
.y
-= offset_h
;
330 dockapp_getcolor(char *color_name
)
334 if (!XParseColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
336 fprintf(stderr
, "can't parse color %s\n", color_name
), exit(1);
338 if (!XAllocColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
340 fprintf(stderr
, "can't allocate color %s. Using black\n", color_name
);
341 return BlackPixel(display
, DefaultScreen(display
));
349 Noberasco Michele <noberasco.gnu@disi.unige.it>
350 divide given color by a factor of n
353 dockapp_dividecolor(char *color_name
, int n
)
357 if ( (n
<=0) || (n
>127) ) {
358 fprintf(stderr
, "Divisor must be >0 and <127\n");
362 if (!XParseColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
364 fprintf(stderr
, "can't parse color %s\n", color_name
), exit(1);
366 if (!XAllocColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
368 fprintf(stderr
, "can't allocate color %s. Using black\n", color_name
);
369 return BlackPixel(display
, DefaultScreen(display
));
372 if (DefaultDepth(display
, DefaultScreen(display
)) < 16)
375 color
.red
= color
.red
/ n
;
376 color
.green
= color
.green
/ n
;
377 color
.blue
= color
.blue
/ n
;
379 color
.flags
= DoRed
| DoGreen
| DoBlue
;
381 if (!XAllocColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
383 fprintf(stderr
, "can't allocate color %s. Using black\n", color_name
);
384 return BlackPixel(display
, DefaultScreen(display
));
392 dockapp_blendedcolor(char *color_name
, int r
, int g
, int b
, float fac
)
396 if ((r
< -255 || r
> 255)||(g
< -255 || g
> 255)||(b
< -255 || b
> 255)){
397 fprintf(stderr
, "r:%d,g:%d,b:%d (r,g,b must be 0 to 255)", r
, g
, b
);
405 if (!XParseColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
407 fprintf(stderr
, "can't parse color %s\n", color_name
), exit(1);
409 if (!XAllocColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
411 fprintf(stderr
, "can't allocate color %s. Using black\n", color_name
);
412 return BlackPixel(display
, DefaultScreen(display
));
415 if (DefaultDepth(display
, DefaultScreen(display
)) < 16)
419 if (color
.red
+ r
> 0xffff) {
421 } else if (color
.red
+ r
< 0) {
424 color
.red
= (unsigned short)(fac
* color
.red
+ r
);
428 if (color
.green
+ g
> 0xffff) {
429 color
.green
= 0xffff;
430 } else if (color
.green
+ g
< 0) {
433 color
.green
= (unsigned short)(fac
* color
.green
+ g
);
437 if (color
.blue
+ b
> 0xffff) {
439 } else if (color
.blue
+ b
< 0) {
442 color
.blue
= (unsigned short)(fac
* color
.blue
+ b
);
445 color
.flags
= DoRed
| DoGreen
| DoBlue
;
447 if (!XAllocColor(display
, DefaultColormap(display
, DefaultScreen(display
)),
449 fprintf(stderr
, "can't allocate color %s. Using black\n", color_name
);
450 return BlackPixel(display
, DefaultScreen(display
));