]>
Dogcows Code - chaz/tint2/blob - tint.c
9ff04fc2cf5363dab6764ba059498eb4b27ddb6d
1 /**************************************************************************
5 * Copyright (C) 2007 Pål Staurland (staura@gmail.com)
6 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * 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.
19 **************************************************************************/
27 #include <X11/Xutil.h>
28 #include <X11/Xatom.h>
29 #include <X11/Xlocale.h>
44 void signal_handler(int sig
)
46 // signal handler is light as it should be
47 panel
.signal_pending
= sig
;
54 signal(SIGUSR1
, signal_handler
);
55 signal(SIGINT
, signal_handler
);
56 signal(SIGTERM
, signal_handler
);
59 memset(&panel
, 0, sizeof(Panel
));
60 memset(&server
, 0, sizeof(Server_global
));
61 memset(&g_task
, 0, sizeof(Global_task
));
62 memset(&g_taskbar
, 0, sizeof(Area
));
63 panel
.clock
.area
.draw_foreground
= draw_foreground_clock
;
64 g_task
.area
.draw_foreground
= draw_foreground_task
;
67 server
.dsp
= XOpenDisplay (NULL
);
69 fprintf(stderr
, "Could not open display.\n");
73 server
.screen
= DefaultScreen (server
.dsp
);
74 server
.root_win
= RootWindow(server
.dsp
, server
.screen
);
75 server
.depth
= DefaultDepth (server
.dsp
, server
.screen
);
76 server
.visual
= DefaultVisual (server
.dsp
, server
.screen
);
77 server
.desktop
= server_get_current_desktop ();
79 XSetErrorHandler ((XErrorHandler
) server_catch_error
);
83 root
= RootWindow(display
, DefaultScreen(display
));
84 //create_main_window();
89 imlib_context_set_display (server
.dsp
);
90 imlib_context_set_visual (server
.visual
);
91 imlib_context_set_colormap (DefaultColormap (server
.dsp
, server
.screen
));
94 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
96 setlocale (LC_ALL
, "");
100 void window_action (Task
*tsk
, int action
)
104 set_close (tsk
->win
);
107 set_active(tsk
->win
);
110 XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
113 if (tsk
== panel
.task_active
) XIconifyWindow (server
.dsp
, tsk
->win
, server
.screen
);
114 else set_active (tsk
->win
);
117 window_toggle_shade (tsk
->win
);
123 void event_button_press (int x
, int y
)
125 if (panel
.mode
== SINGLE_DESKTOP
) {
126 // drag and drop disabled
127 XLowerWindow (server
.dsp
, window
.main_win
);
133 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
135 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
141 for (l0
= tskbar
->area
.list
; l0
; l0
= l0
->next
) {
143 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
144 panel
.task_drag
= tsk
;
150 XLowerWindow (server
.dsp
, window
.main_win
);
154 void event_button_release (int button
, int x
, int y
)
156 int action
= TOGGLE_ICONIFY
;
157 // TODO: convert event_button_press(int x, int y) to area->event_button_press()
162 action
= panel
.mouse_middle
;
165 action
= panel
.mouse_right
;
168 action
= panel
.mouse_scroll_up
;
171 action
= panel
.mouse_scroll_down
;
178 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
180 if (x
>= tskbar
->area
.posx
&& x
<= (tskbar
->area
.posx
+ tskbar
->area
.width
))
184 // TODO: check better solution to keep window below
185 XLowerWindow (server
.dsp
, window
.main_win
);
190 // drag and drop task
191 if (panel
.task_drag
) {
192 if (tskbar
!= panel
.task_drag
->area
.parent
&& action
== TOGGLE_ICONIFY
) {
193 if (!panel
.task_drag
->all_desktop
&& panel
.mode
== MULTI_DESKTOP
) {
194 windows_set_desktop(panel
.task_drag
->win
, tskbar
->desktop
);
195 if (tskbar
->desktop
== server
.desktop
)
196 set_active(panel
.task_drag
->win
);
201 else panel
.task_drag
= 0;
205 if (panel
.mode
== MULTI_DESKTOP
)
206 if (tskbar
->desktop
!= server
.desktop
&& action
!= CLOSE
)
207 set_desktop (tskbar
->desktop
);
212 for (l
= tskbar
->area
.list
; l
; l
= l
->next
) {
214 if (x
>= tsk
->area
.posx
&& x
<= (tsk
->area
.posx
+ tsk
->area
.width
)) {
215 window_action (tsk
, action
);
220 // to keep window below
221 XLowerWindow (server
.dsp
, window
.main_win
);
225 void event_property_notify (Window win
, Atom at
)
228 if (win
== server
.root_win
) {
229 if (!server
.got_root_win
) {
230 XSelectInput (server
.dsp
, server
.root_win
, PropertyChangeMask
|StructureNotifyMask
);
231 server
.got_root_win
= 1;
234 /* Change number of desktops */
235 else if (at
== server
.atom
._NET_NUMBER_OF_DESKTOPS
) {
240 else if (at
== server
.atom
._NET_CURRENT_DESKTOP
) {
241 server
.desktop
= server_get_current_desktop ();
242 if (panel
.mode
!= MULTI_DESKTOP
) {
247 else if (at
== server
.atom
._NET_CLIENT_LIST
) {
248 task_refresh_tasklist ();
252 else if (at
== server
.atom
._NET_ACTIVE_WINDOW
) {
253 if (panel
.task_active
) {
254 if (panel
.task_active
->all_desktop
) {
258 nb
= server
.nb_desktop
* server
.nb_monitor
;
259 for (i
=0 ; i
< nb
; i
++) {
260 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
262 tsk
->area
.is_active
= 0;
267 panel
.task_active
->area
.is_active
= 0;
268 panel
.task_active
= 0;
270 Window w1
= window_get_active ();
271 Task
*t
= task_get_task(w1
);
274 if (XGetTransientForHint(server
.dsp
, w1
, &w2
) != 0)
275 if (w2
) t
= task_get_task(w2
);
278 if (t
->all_desktop
) {
282 nb
= server
.nb_desktop
* server
.nb_monitor
;
283 for (i
=0 ; i
< nb
; i
++) {
284 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
286 if (tsk
->win
== t
->win
)
287 tsk
->area
.is_active
= 1;
292 t
->area
.is_active
= 1;
293 panel
.task_active
= t
;
297 /* Wallpaper changed */
298 else if (at
== server
.atom
._XROOTPMAP_ID
) {
299 XFreePixmap (server
.dsp
, panel
.area
.pix
.pmap
);
300 panel
.area
.pix
.pmap
= 0;
306 tsk
= task_get_task (win
);
308 //printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
310 /* Window title changed */
311 if (at
== server
.atom
._NET_WM_VISIBLE_NAME
|| at
== server
.atom
._NET_WM_NAME
|| at
== server
.atom
.WM_NAME
) {
312 if (tsk
->all_desktop
) {
316 nb
= server
.nb_desktop
* server
.nb_monitor
;
317 for (i
=0 ; i
< nb
; i
++) {
318 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
320 if (tsk
->win
== tsk2
->win
) {
322 tsk2
->area
.redraw
= 1;
329 tsk
->area
.redraw
= 1;
334 else if (at
== server
.atom
.WM_STATE
) {
335 if (window_is_iconified (win
))
336 if (panel
.task_active
) {
337 if (panel
.task_active
->win
== tsk
->win
) {
338 if (tsk
->all_desktop
) {
342 nb
= server
.nb_desktop
* server
.nb_monitor
;
343 for (i
=0 ; i
< nb
; i
++) {
344 for (l0
= panel
.taskbar
[i
].area
.list
; l0
; l0
= l0
->next
) {
346 tsk2
->area
.is_active
= 0;
351 panel
.task_active
->area
.is_active
= 0;
352 panel
.task_active
= 0;
356 /* Window icon changed */
357 else if (at
== server
.atom
._NET_WM_ICON
) {
358 if (tsk
->icon_data
) {
359 free (tsk
->icon_data
);
362 tsk
->area
.redraw
= 1;
365 /* Window desktop changed */
366 else if (at
== server
.atom
._NET_WM_DESKTOP
) {
372 if (!server
.got_root_win
) server
.root_win
= RootWindow (server
.dsp
, server
.screen
);
377 void event_configure_notify (Window win
)
379 if (panel
.mode
!= MULTI_MONITOR
) return;
381 Task
*tsk
= task_get_task (win
);
384 Taskbar
*tskbar
= tsk
->area
.parent
;
385 if (tskbar
->monitor
!= window_get_monitor (win
)) {
386 // task on another monitor
398 if (!panel
.clock
.time1_format
) return;
400 if (gettimeofday(&stv
, 0)) return;
402 if (abs(stv
.tv_sec
- panel
.clock
.clock
.tv_sec
) < panel
.clock
.time_precision
) return;
405 panel
.clock
.clock
.tv_sec
= stv
.tv_sec
;
406 panel
.clock
.clock
.tv_sec
-= panel
.clock
.clock
.tv_sec
% panel
.clock
.time_precision
;
407 panel
.clock
.area
.redraw
= 1;
412 int main (int argc
, char *argv
[])
419 c
= getopt (argc
, argv
, "c:");
423 if (panel
.area
.pix
.pmap
) XFreePixmap (server
.dsp
, panel
.area
.pix
.pmap
);
424 panel
.area
.pix
.pmap
= 0;
425 // append full transparency background
426 list_back
= g_slist_append(0, calloc(1, sizeof(Area
)));
428 // read tint2rc config
431 i
= config_read_file (optarg
);
435 fprintf(stderr
, "usage: tint2 [-c] <config_file>\n");
441 window_draw_panel ();
443 // BUG: refresh(clock) is needed here, but 'on the paper' it's not necessary.
444 refresh(&panel
.clock
.area
);
446 x11_fd
= ConnectionNumber (server
.dsp
);
447 XSync (server
.dsp
, False
);
450 // thanks to AngryLlama for the timer
451 // Create a File Description Set containing x11_fd
453 FD_SET (x11_fd
, &fd
);
458 // Wait for X Event or a Timer
459 if (select(x11_fd
+1, &fd
, 0, 0, &tv
)) {
460 while (XPending (server
.dsp
)) {
461 XNextEvent(server
.dsp
, &e
);
465 if (e
.xbutton
.button
== 1) event_button_press (e
.xbutton
.x
, e
.xbutton
.y
);
469 event_button_release (e
.xbutton
.button
, e
.xbutton
.x
, e
.xbutton
.y
);
473 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
);
474 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);
478 //printf("PropertyNotify\n");
479 event_property_notify (e
.xproperty
.window
, e
.xproperty
.atom
);
482 case ConfigureNotify
:
483 if (e
.xconfigure
.window
== server
.root_win
)
486 event_configure_notify (e
.xconfigure
.window
);
493 switch (panel
.signal_pending
) {
502 if (panel
.refresh
&& !panel
.sleep_mode
) {
504 //printf(" *** visual_refresh\n");
This page took 0.062933 seconds and 3 git commands to generate.