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);
108 void window_draw_panel ()
112 /* panel position determined here */
113 if (panel
.position
& LEFT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ panel
.marginx
;
115 if (panel
.position
& RIGHT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ server
.monitor
[panel
.monitor
].width
- panel
.area
.width
- panel
.marginx
;
116 else server
.posx
= server
.monitor
[panel
.monitor
].x
+ ((server
.monitor
[panel
.monitor
].width
- panel
.area
.width
) / 2);
118 if (panel
.position
& TOP
) server
.posy
= server
.monitor
[panel
.monitor
].y
+ panel
.marginy
;
119 else server
.posy
= server
.monitor
[panel
.monitor
].y
+ server
.monitor
[panel
.monitor
].height
- panel
.area
.height
- panel
.marginy
;
121 /* Catch some events */
122 XSetWindowAttributes att
= { ParentRelative
, 0L, 0, 0L, 0, 0, Always
, 0L, 0L, False
, ExposureMask
|ButtonPressMask
|ButtonReleaseMask
, NoEventMask
, False
, 0, 0 };
124 // XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib)
125 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
126 if (window
.main_win
) XDestroyWindow(server
.dsp
, window
.main_win
);
127 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
);
129 set_panel_properties (win
);
130 window
.main_win
= win
;
132 // replaced : server.gc = DefaultGC (server.dsp, 0);
133 if (server
.gc
) XFree(server
.gc
);
135 server
.gc
= XCreateGC(server
.dsp
, win
, (unsigned long) 0, &gcValues
);
136 if (server
.gc_root
) XFree(server
.gc_root
);
137 server
.gc_root
= XCreateGC(server
.dsp
, server
.root_win
, (unsigned long) 0, &gcValues
);
139 XMapWindow (server
.dsp
, win
);
144 void visible_object()
146 if (panel
.area
.list
) {
147 g_slist_free(panel
.area
.list
);
151 // list of visible objects
152 // start with clock because draw(clock) can resize others object
153 if (panel
.clock
.time1_format
)
154 panel
.area
.list
= g_slist_append(panel
.area
.list
, &panel
.clock
);
158 for (i
=0 ; i
< panel
.nb_desktop
; i
++) {
159 for (j
=0 ; j
< panel
.nb_monitor
; j
++) {
160 taskbar
= &panel
.taskbar
[index(i
,j
)];
161 if (panel
.mode
!= MULTI_DESKTOP
&& taskbar
->desktop
!= server
.desktop
) continue;
163 panel
.area
.list
= g_slist_append(panel
.area
.list
, taskbar
);
171 void set_panel_background()
173 Pixmap wall
= get_root_pixmap();
175 panel
.area
.pmap
= server_create_pixmap (panel
.area
.width
, panel
.area
.height
);
177 // add layer of root pixmap
178 XCopyArea (server
.dsp
, wall
, panel
.area
.pmap
, server
.gc
, server
.posx
, server
.posy
, panel
.area
.width
, panel
.area
.height
, 0, 0);
180 // draw background panel
183 cs
= cairo_xlib_surface_create (server
.dsp
, panel
.area
.pmap
, server
.visual
, panel
.area
.width
, panel
.area
.height
);
184 c
= cairo_create (cs
);
186 draw_background (&panel
.area
, c
);
189 cairo_surface_destroy (cs
);
191 // copy background panel on desktop window
192 XCopyArea (server
.dsp
, panel
.area
.pmap
, server
.root_win
, server
.gc_root
, 0, 0, panel
.area
.width
, panel
.area
.height
, server
.posx
, server
.posy
);
194 redraw (&panel
.area
);