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 **************************************************************************/
20 #include <X11/Xutil.h>
21 #include <X11/Xatom.h>
23 #include <cairo-xlib.h>
24 #include <pango/pangocairo.h>
32 void visual_refresh ()
35 set_panel_background();
37 if (server
.pmap
) XFreePixmap (server
.dsp
, server
.pmap
);
38 server
.pmap
= server_create_pixmap (panel
.area
.width
, panel
.area
.height
);
39 XCopyArea (server
.dsp
, panel
.area
.pmap
, server
.pmap
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
42 GSList
*l
= panel
.area
.list
;
43 for (; l
; l
= l
->next
)
46 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
47 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, panel
.area
.paddingx
, 0, panel
.area
.width
-(2*panel
.area
.paddingx
), panel
.area
.height
, 0, 0);
53 void set_panel_properties (Window win
)
55 XStoreName (server
.dsp
, win
, "tint2");
57 // TODO: check if the name is really needed for a panel/taskbar ?
59 gchar
*name
= g_locale_to_utf8("tint2", -1, NULL
, &len
, NULL
);
61 XChangeProperty(server
.dsp
, win
, server
.atom
._NET_WM_NAME
, server
.atom
.UTF8_STRING
, 8, PropModeReplace
, (unsigned char *) name
, (int) len
);
66 long val
= server
.atom
._NET_WM_WINDOW_TYPE_DOCK
;
67 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_WINDOW_TYPE
, XA_ATOM
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
70 long struts
[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
71 if (panel
.position
& TOP
) {
72 struts
[2] = panel
.area
.height
+ panel
.marginy
;
73 struts
[8] = server
.posx
;
74 struts
[9] = server
.posx
+ panel
.area
.width
;
77 struts
[3] = panel
.area
.height
+ panel
.marginy
;
78 struts
[10] = server
.posx
;
79 struts
[11] = server
.posx
+ panel
.area
.width
;
81 // Old specification : fluxbox need _NET_WM_STRUT.
82 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 4);
83 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT_PARTIAL
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 12);
85 // Sticky and below other window
87 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_DESKTOP
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
89 state
[0] = server
.atom
._NET_WM_STATE_SKIP_PAGER
;
90 state
[1] = server
.atom
._NET_WM_STATE_SKIP_TASKBAR
;
91 state
[2] = server
.atom
._NET_WM_STATE_STICKY
;
92 state
[3] = server
.atom
._NET_WM_STATE_BELOW
;
93 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STATE
, XA_ATOM
, 32, PropModeReplace
, (unsigned char *) state
, 4);
96 XSizeHints size_hints
;
97 size_hints
.flags
= PPosition
;
98 XChangeProperty (server
.dsp
, win
, XA_WM_NORMAL_HINTS
, XA_WM_SIZE_HINTS
, 32, PropModeReplace
, (unsigned char *) &size_hints
, sizeof (XSizeHints
) / 4);
102 wmhints
.flags
= InputHint
;
103 wmhints
.input
= False
;
104 XChangeProperty (server
.dsp
, win
, XA_WM_HINTS
, XA_WM_HINTS
, 32, PropModeReplace
, (unsigned char *) &wmhints
, sizeof (XWMHints
) / 4);
107 long prop
[5] = { 2, 0, 0, 0, 0 };
108 XChangeProperty(server
.dsp
, win
, server
.atom
._MOTIF_WM_HINTS
, server
.atom
._MOTIF_WM_HINTS
, 32, PropModeReplace
, (unsigned char *) prop
, 5);
112 void window_draw_panel ()
116 /* panel position determined here */
117 if (panel
.position
& LEFT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ panel
.marginx
;
119 if (panel
.position
& RIGHT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ server
.monitor
[panel
.monitor
].width
- panel
.area
.width
- panel
.marginx
;
120 else server
.posx
= server
.monitor
[panel
.monitor
].x
+ ((server
.monitor
[panel
.monitor
].width
- panel
.area
.width
) / 2);
122 if (panel
.position
& TOP
) server
.posy
= server
.monitor
[panel
.monitor
].y
+ panel
.marginy
;
123 else server
.posy
= server
.monitor
[panel
.monitor
].y
+ server
.monitor
[panel
.monitor
].height
- panel
.area
.height
- panel
.marginy
;
125 /* Catch some events */
126 XSetWindowAttributes att
= { ParentRelative
, 0L, 0, 0L, 0, 0, Always
, 0L, 0L, False
, ExposureMask
|ButtonPressMask
|ButtonReleaseMask
, NoEventMask
, False
, 0, 0 };
128 // XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib)
129 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
130 if (window
.main_win
) XDestroyWindow(server
.dsp
, window
.main_win
);
131 win
= XCreateWindow (server
.dsp
, server
.root_win
, server
.posx
+panel
.area
.paddingx
, server
.posy
, panel
.area
.width
-(2*panel
.area
.paddingx
), panel
.area
.height
, 0, server
.depth
, InputOutput
, CopyFromParent
, CWEventMask
, &att
);
133 set_panel_properties (win
);
134 window
.main_win
= win
;
136 // replaced : server.gc = DefaultGC (server.dsp, 0);
137 if (server
.gc
) XFree(server
.gc
);
139 server
.gc
= XCreateGC(server
.dsp
, win
, (unsigned long) 0, &gcValues
);
140 if (server
.gc_root
) XFree(server
.gc_root
);
141 server
.gc_root
= XCreateGC(server
.dsp
, server
.root_win
, (unsigned long) 0, &gcValues
);
143 XMapWindow (server
.dsp
, win
);
148 void visible_object()
150 if (panel
.area
.list
) {
151 g_slist_free(panel
.area
.list
);
155 // list of visible objects
156 // start with clock because draw(clock) can resize others object
157 if (panel
.clock
.time1_format
)
158 panel
.area
.list
= g_slist_append(panel
.area
.list
, &panel
.clock
);
162 for (i
=0 ; i
< panel
.nb_desktop
; i
++) {
163 for (j
=0 ; j
< panel
.nb_monitor
; j
++) {
164 taskbar
= &panel
.taskbar
[index(i
,j
)];
165 if (panel
.mode
!= MULTI_DESKTOP
&& taskbar
->desktop
!= server
.desktop
) continue;
167 panel
.area
.list
= g_slist_append(panel
.area
.list
, taskbar
);
170 set_redraw(&panel
.area
);
175 void set_panel_background()
177 Pixmap wall
= get_root_pixmap();
179 panel
.area
.pmap
= server_create_pixmap (panel
.area
.width
, panel
.area
.height
);
181 // add layer of root pixmap
182 XCopyArea (server
.dsp
, wall
, panel
.area
.pmap
, server
.gc
, server
.posx
, server
.posy
, panel
.area
.width
, panel
.area
.height
, 0, 0);
184 // draw background panel
187 cs
= cairo_xlib_surface_create (server
.dsp
, panel
.area
.pmap
, server
.visual
, panel
.area
.width
, panel
.area
.height
);
188 c
= cairo_create (cs
);
190 draw_background (&panel
.area
, c
);
193 cairo_surface_destroy (cs
);
195 // copy background panel on desktop window
196 XCopyArea (server
.dsp
, panel
.area
.pmap
, server
.root_win
, server
.gc_root
, 0, 0, panel
.area
.width
, panel
.area
.height
, server
.posx
, server
.posy
);
198 set_redraw (&panel
.area
);