2 * Copyright (c) 1999 Alfredo K. Kojima
3 * Copyright (c) 2001, 2002 Seiichi SATO
4 * Copyright (c) 2007 Daniel Borca
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <X11/extensions/shape.h>
29 #define WINDOWED_SIZE_W 64
30 #define WINDOWED_SIZE_H 64
31 #define DOCKED_SIZE_W (WINDOWED_SIZE_W - 4)
32 #define DOCKED_SIZE_H (WINDOWED_SIZE_H - 4)
36 dockapp_open_window(DOCKAPP
*d
,
37 const char *display_specified
,
38 char *appname
, int iswindowed
,
39 int argc
, char **argv
)
48 /* Open Connection to X Server */
49 d
->display
= XOpenDisplay(display_specified
);
50 if (d
->display
== NULL
) {
54 d
->x_offset
= d
->y_offset
= 0;
58 d
->x_offset
= (WINDOWED_SIZE_W
- DOCKED_SIZE_W
) / 2;
59 d
->y_offset
= (WINDOWED_SIZE_H
- DOCKED_SIZE_H
) / 2;
65 root
= DefaultRootWindow(d
->display
);
66 d
->icon_window
= XCreateSimpleWindow(d
->display
, root
, 0, 0, ww
, wh
, 0, 0, 0);
67 d
->window
= XCreateSimpleWindow(d
->display
, root
, 0, 0, 1, 1, 0, 0, 0);
70 classhint
.res_class
= "DockApp";
71 classhint
.res_name
= appname
;
72 XSetClassHint(d
->display
, d
->window
, &classhint
);
75 wmhints
.flags
= IconWindowHint
| WindowGroupHint
;
77 wmhints
.flags
|= StateHint
;
78 wmhints
.initial_state
= WithdrawnState
;
80 wmhints
.window_group
= d
->window
;
81 wmhints
.icon_window
= d
->icon_window
;
82 XSetWMHints(d
->display
, d
->window
, &wmhints
);
85 sizehints
.flags
= USSize
;
87 sizehints
.flags
|= USPosition
;
88 sizehints
.x
= sizehints
.y
= 0;
90 sizehints
.flags
|= PMinSize
| PMaxSize
;
91 sizehints
.min_width
= sizehints
.max_width
= WINDOWED_SIZE_W
;
92 sizehints
.min_height
= sizehints
.max_height
= WINDOWED_SIZE_H
;
95 sizehints
.height
= wh
;
96 XSetWMNormalHints(d
->display
, d
->icon_window
, &sizehints
);
98 /* Set WindowTitle for AfterStep Wharf */
99 XStringListToTextProperty(&appname
, 1, &title
);
100 XSetWMName(d
->display
, d
->window
, &title
);
101 XSetWMName(d
->display
, d
->icon_window
, &title
);
104 /* Set WM Protocols */
105 d
->delete_win
= XInternAtom(d
->display
, "WM_DELETE_WINDOW", False
);
106 XSetWMProtocols(d
->display
, d
->icon_window
, &d
->delete_win
, 1);
108 /* Set Command to start the app so it can be docked properly */
109 XSetCommand(d
->display
, d
->window
, argv
, argc
);
111 d
->width
= DOCKED_SIZE_W
;
112 d
->height
= DOCKED_SIZE_H
;
113 d
->iswindowed
= iswindowed
;
114 d
->depth
= DefaultDepth(d
->display
, DefaultScreen(d
->display
));
115 d
->gc
= DefaultGC(d
->display
, DefaultScreen(d
->display
));
118 d
->pixmap
= dockapp_createpixmap(d
, ww
, wh
);
119 XSetForeground(d
->display
, d
->gc
, dockapp_get_color(d
, "rgb:ae/aa/ae"));
120 XFillRectangle(d
->display
, d
->pixmap
, d
->gc
, 0, 0, ww
, wh
);
121 XSetWindowBackgroundPixmap(d
->display
, d
->icon_window
, d
->pixmap
);
122 XSetWindowBackgroundPixmap(d
->display
, d
->window
, d
->pixmap
);
123 XClearWindow(d
->display
, d
->icon_window
);
125 if (!d
->iswindowed
) {
126 XMapRaised(d
->display
, d
->window
);
128 XMapRaised(d
->display
, d
->icon_window
);
138 dockapp_set_eventmask(const DOCKAPP
*d
, long mask
)
140 XSelectInput(d
->display
, d
->icon_window
, mask
);
141 XSelectInput(d
->display
, d
->window
, mask
);
146 dockapp_set_shape(const DOCKAPP
*d
, Pixmap mask
)
148 XShapeCombineMask(d
->display
, d
->icon_window
, ShapeBounding
,
149 d
->x_offset
, d
->y_offset
, mask
, ShapeSet
);
150 XShapeCombineMask(d
->display
, d
->window
, ShapeBounding
,
151 d
->x_offset
, d
->y_offset
, mask
, ShapeSet
);
157 dockapp_copy_area(const DOCKAPP
*d
,
159 int x_src
, int y_src
, int w
, int h
, int x_dst
, int y_dst
)
161 XCopyArea(d
->display
, src
, d
->pixmap
, d
->gc
, x_src
, y_src
, w
, h
, x_dst
+ d
->x_offset
, y_dst
+ d
->y_offset
);
166 dockapp_update(const DOCKAPP
*d
)
168 XClearWindow(d
->display
, d
->icon_window
);
173 dockapp_xpm2pixmap(const DOCKAPP
*d
,
174 char **data
, Pixmap
*pixmap
, Pixmap
*mask
,
175 XpmColorSymbol
*colorSymbol
, unsigned int nsymbols
)
177 XpmAttributes xpmAttr
;
178 xpmAttr
.valuemask
= XpmCloseness
;
179 xpmAttr
.closeness
= 1 << 15;
182 xpmAttr
.colorsymbols
= colorSymbol
;
183 xpmAttr
.numsymbols
= nsymbols
;
184 xpmAttr
.valuemask
|= XpmColorSymbols
;
187 return (XpmCreatePixmapFromData(d
->display
, d
->icon_window
, data
, pixmap
, mask
, &xpmAttr
) == 0);
192 dockapp_createpixmap(const DOCKAPP
*d
, int width
, int height
)
194 return XCreatePixmap(d
->display
, d
->icon_window
, width
, height
, d
->depth
);
199 dockapp_nextevent_or_timeout(DOCKAPP
*d
,
200 XEvent
*event
, unsigned long millis
)
202 struct timeval timeout
;
205 XSync(d
->display
, False
);
206 if (XPending(d
->display
)) {
207 XNextEvent(d
->display
, event
);
211 timeout
.tv_sec
= millis
/ 1000;
212 timeout
.tv_usec
= (millis
% 1000) * 1000;
215 FD_SET(ConnectionNumber(d
->display
), &rset
);
216 if (select(ConnectionNumber(d
->display
) + 1, &rset
, NULL
, NULL
, &timeout
) > 0) {
217 XNextEvent(d
->display
, event
);
218 if (event
->type
== ClientMessage
) {
219 if ((Atom
)event
->xclient
.data
.l
[0] == d
->delete_win
) {
225 event
->xbutton
.x
-= d
->x_offset
;
226 event
->xbutton
.y
-= d
->y_offset
;
236 dockapp_get_color(const DOCKAPP
*d
, const char *color_name
)
240 if (!XParseColor(d
->display
, DefaultColormap(d
->display
, DefaultScreen(d
->display
)), color_name
, &color
)) {
241 return BlackPixel(d
->display
, DefaultScreen(d
->display
));
244 if (!XAllocColor(d
->display
, DefaultColormap(d
->display
, DefaultScreen(d
->display
)), &color
)) {
245 return BlackPixel(d
->display
, DefaultScreen(d
->display
));