1 /**************************************************************************
3 * Copyright (C) 2008 Pål Staurland (staura@gmail.com)
4 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 **************************************************************************/
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
24 #include <cairo-xlib.h>
25 #include <pango/pangocairo.h>
33 void visual_refresh ()
35 if (server
.pmap
) XFreePixmap (server
.dsp
, server
.pmap
);
36 server
.pmap
= XCreatePixmap (server
.dsp
, server
.root_win
, panel
.area
.width
, panel
.area
.height
, server
.depth
);
38 XCopyArea (server
.dsp
, panel
.area
.pix
.pmap
, server
.pmap
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
41 GSList
*l
= panel
.area
.list
;
42 for (; l
; l
= l
->next
)
45 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
46 // this feature is disabled !
47 //XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, panel.area.paddingxlr, 0, panel.area.width-(2*panel.area.paddingxlr), panel.area.height, 0, 0);
49 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
55 void set_panel_properties (Window win
)
57 XStoreName (server
.dsp
, win
, "tint2");
59 // TODO: check if the name is really needed for a panel/taskbar ?
61 gchar
*name
= g_locale_to_utf8("tint2", -1, NULL
, &len
, NULL
);
63 XChangeProperty(server
.dsp
, win
, server
.atom
._NET_WM_NAME
, server
.atom
.UTF8_STRING
, 8, PropModeReplace
, (unsigned char *) name
, (int) len
);
68 long val
= server
.atom
._NET_WM_WINDOW_TYPE_DOCK
;
69 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_WINDOW_TYPE
, XA_ATOM
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
72 long struts
[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
73 if (panel
.position
& TOP
) {
74 struts
[2] = panel
.area
.height
+ panel
.marginy
;
75 struts
[8] = server
.posx
;
76 // panel.area.width - 1 allowed full screen on monitor 2
77 struts
[9] = server
.posx
+ panel
.area
.width
- 1;
80 struts
[3] = panel
.area
.height
+ panel
.marginy
;
81 struts
[10] = server
.posx
;
82 // panel.area.width - 1 allowed full screen on monitor 2
83 struts
[11] = server
.posx
+ panel
.area
.width
- 1;
85 // Old specification : fluxbox need _NET_WM_STRUT.
86 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 4);
87 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT_PARTIAL
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 12);
89 // Sticky and below other window
91 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_DESKTOP
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
93 state
[0] = server
.atom
._NET_WM_STATE_SKIP_PAGER
;
94 state
[1] = server
.atom
._NET_WM_STATE_SKIP_TASKBAR
;
95 state
[2] = server
.atom
._NET_WM_STATE_STICKY
;
96 state
[3] = server
.atom
._NET_WM_STATE_BELOW
;
97 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STATE
, XA_ATOM
, 32, PropModeReplace
, (unsigned char *) state
, 4);
100 XSizeHints size_hints
;
101 size_hints
.flags
= PPosition
;
102 XChangeProperty (server
.dsp
, win
, XA_WM_NORMAL_HINTS
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
, (unsigned char *) &size_hints
, sizeof (XSizeHints
) / 4);
106 wmhints
.flags
= InputHint
;
107 wmhints
.input
= False
;
108 XChangeProperty (server
.dsp
, win
, XA_WM_HINTS
, XA_WM_HINTS
, 32, PropModeReplace
, (unsigned char *) &wmhints
, sizeof (XWMHints
) / 4);
111 long prop
[5] = { 2, 0, 0, 0, 0 };
112 XChangeProperty(server
.dsp
, win
, server
.atom
._MOTIF_WM_HINTS
, server
.atom
._MOTIF_WM_HINTS
, 32, PropModeReplace
, (unsigned char *) prop
, 5);
116 void window_draw_panel ()
118 /* panel position determined here */
119 if (panel
.position
& LEFT
) {
120 server
.posx
= server
.monitor
[panel
.monitor
].x
+ panel
.marginleft
;
123 if (panel
.position
& RIGHT
) {
124 //server.posx = server.monitor[panel.monitor].x + server.monitor[panel.monitor].width - panel.area.width - panel.marginright;
125 server
.posx
= server
.monitor
[panel
.monitor
].x
+ server
.monitor
[panel
.monitor
].width
- panel
.area
.width
;
128 server
.posx
= server
.monitor
[panel
.monitor
].x
+ ((server
.monitor
[panel
.monitor
].width
- panel
.area
.width
) / 2);
131 if (panel
.position
& TOP
) {
132 server
.posy
= server
.monitor
[panel
.monitor
].y
+ panel
.marginy
;
135 server
.posy
= server
.monitor
[panel
.monitor
].y
+ server
.monitor
[panel
.monitor
].height
- panel
.area
.height
- panel
.marginy
;
139 XSetWindowAttributes att
= { ParentRelative
, 0L, 0, 0L, 0, 0, Always
, 0L, 0L, False
, ExposureMask
|ButtonPressMask
|ButtonReleaseMask
, NoEventMask
, False
, 0, 0 };
141 // XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib)
142 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
144 if (window
.main_win
) XDestroyWindow(server
.dsp
, window
.main_win
);
145 //win = XCreateWindow (server.dsp, server.root_win, server.posx+panel.area.paddingxlr, server.posy, panel.area.width-(2*panel.area.paddingxlr), panel.area.height, 0, server.depth, InputOutput, CopyFromParent, CWEventMask, &att);
146 win
= XCreateWindow (server
.dsp
, server
.root_win
, server
.posx
, server
.posy
, panel
.area
.width
, panel
.area
.height
, 0, server
.depth
, InputOutput
, CopyFromParent
, CWEventMask
, &att
);
148 set_panel_properties (win
);
149 window
.main_win
= win
;
151 set_panel_background();
153 XMapWindow (server
.dsp
, win
);
158 void visible_object()
160 if (panel
.area
.list
) {
161 g_slist_free(panel
.area
.list
);
165 // list of visible objects
166 // start with clock because draw(clock) can resize others object
168 panel
.area
.list
= g_slist_append(panel
.area
.list
, &panel
.clock
);
172 for (i
=0 ; i
< panel
.nb_desktop
; i
++) {
173 for (j
=0 ; j
< panel
.nb_monitor
; j
++) {
174 taskbar
= &panel
.taskbar
[index(i
,j
)];
175 if (panel
.mode
!= MULTI_DESKTOP
&& taskbar
->desktop
!= server
.desktop
) continue;
177 panel
.area
.list
= g_slist_append(panel
.area
.list
, taskbar
);
180 set_redraw(&panel
.area
);
185 void get_root_pixmap()
193 res
= server_get_property (server
.root_win
, server
.atom
._XROOTPMAP_ID
, XA_PIXMAP
, 0);
195 ret
= *((Pixmap
*)res
);
200 server
.root_pmap
= ret
;
202 if (server
.root_pmap
!= None
) {
206 gcv
.fill_style
= FillTiled
;
207 uint mask
= GCTileStipXOrigin
| GCTileStipYOrigin
| GCFillStyle
| GCTile
;
209 gcv
.tile
= server
.root_pmap
;
210 XChangeGC(server
.dsp
, server
.gc
, mask
, &gcv
);
211 //fprintf(stderr, "pixmap background detected\n");
214 fprintf(stderr
, "pixmap background detection failed\n");
218 void set_panel_background()
222 if (panel
.area
.pix
.pmap
) XFreePixmap (server
.dsp
, panel
.area
.pix
.pmap
);
223 panel
.area
.pix
.pmap
= XCreatePixmap (server
.dsp
, server
.root_win
, panel
.area
.width
, panel
.area
.height
, server
.depth
);
225 // copy background (server.root_pmap) in panel
228 XTranslateCoordinates(server
.dsp
, window
.main_win
, server
.root_win
, 0, 0, &x
, &y
, &dummy
);
229 XSetTSOrigin(server
.dsp
, server
.gc
, -x
, -y
) ;
230 XFillRectangle(server
.dsp
, panel
.area
.pix
.pmap
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
);
232 // draw background panel
235 cs
= cairo_xlib_surface_create (server
.dsp
, panel
.area
.pix
.pmap
, server
.visual
, panel
.area
.width
, panel
.area
.height
);
236 c
= cairo_create (cs
);
238 draw_background (&panel
.area
, c
, 0);
241 cairo_surface_destroy (cs
);
244 set_redraw (&panel
.area
);
246 // copy background panel on desktop window
247 //XCopyArea (server.dsp, panel.area.pix.pmap, server.root_win, server.gc_root, 0, 0, panel.area.width, panel.area.height, server.posx, server.posy);