2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "FvwmIconMan.h"
23 #include "libs/fvwmlib.h"
24 #include "libs/FScreen.h"
25 #include "libs/Module.h"
26 #include "libs/Parse.h"
27 #include "libs/Strings.h"
29 static WinData
*fvwm_focus_win
= NULL
;
33 } m_toggle_paging_data
;
44 Ulong app_id
, frame_id
, dbase_entry
;
48 Ulong app_id
, frame_id
, dbase_entry
;
49 Ulong xpos
, ypos
, icon_width
, icon_height
;
53 Ulong app_id
, frame_id
, dbase_entry
;
61 Ulong arg
, toggle
, id
;
66 Ulong app_id
, frame_id
, dbase_entry
;
67 Ulong width
, height
, depth
, picture
, mask
, alpha
;
75 m_toggle_paging_data toggle_paging_data
;
76 m_new_desk_data new_desk_data
;
77 ConfigWinPacket add_config_data
;
78 m_new_page_data new_page_data
;
79 m_minimal_data minimal_data
;
80 m_icon_data icon_data
;
81 m_name_data name_data
;
82 m_mini_icon_data mini_icon_data
;
83 m_property_data property_data
;
86 /* only used by count_nonsticky_in_hashtab */
87 static WinManager
*the_manager
;
89 static int count_nonsticky_in_hashtab(void *arg
)
91 WinData
*win
= (WinData
*)arg
;
92 WinManager
*man
= the_manager
;
94 if (!(IS_STICKY_ACROSS_DESKS(win
) || IS_STICKY_ACROSS_PAGES(win
)) &&
95 !(WINDATA_ICONIFIED(win
) && (IS_ICON_STICKY_ACROSS_PAGES(win
) ||
96 IS_ICON_STICKY_ACROSS_DESKS(win
))) &&
97 win
->complete
&& win
->manager
== man
)
105 static void set_draw_mode(WinManager
*man
, int flag
)
114 if (man
->we_are_drawing
== 0 && flag
)
118 else if (man
->we_are_drawing
&& !flag
)
121 num
= accumulate_walk_hashtab(count_nonsticky_in_hashtab
);
123 FVWM
, "SetDrawMode on 0x%lx, num = %d\n",
124 (unsigned long)man
, num
);
130 man
->configures_expected
= num
;
132 man
->we_are_drawing
= flag
;
135 static int drawing(WinManager
*man
)
142 return man
->we_are_drawing
;
145 static void got_configure(WinManager
*man
)
147 if (man
&& !man
->we_are_drawing
)
149 man
->configures_expected
--;
151 FVWM
, "got_configure on 0x%lx, num_expected now = %d\n",
152 (unsigned long) man
, man
->configures_expected
);
153 if (man
->configures_expected
<= 0)
155 set_draw_mode(man
, 1);
160 /* MMH <mikehan@best.com> 6/99
161 * Following a gruesome hack this function has been hijacked.
162 * The function is no longer about whether or not the window is in the
163 * viewport, but whether or not the manager wants to display the window,
164 * based on its current location.
166 int win_in_viewport(WinData
*win
)
168 return check_resolution(win
->manager
, win
);
172 WinData
*id_to_win(Ulong id
)
176 win
= find_win_hashtab(id
);
182 insert_win_hashtab(win
);
188 static void set_win_configuration(WinData
*win
, FvwmPacketBody
*body
)
190 win
->desknum
= body
->add_config_data
.desk
;
191 win
->x
= body
->add_config_data
.frame_x
;
192 win
->y
= body
->add_config_data
.frame_y
;
193 win
->width
= body
->add_config_data
.frame_width
;
194 win
->height
= body
->add_config_data
.frame_height
;
195 win
->iconified
= IS_ICONIFIED(&(body
->add_config_data
));
196 win
->state
= (win
== fvwm_focus_win
) ? FOCUS_CONTEXT
: PLAIN_CONTEXT
;
197 win
->geometry_set
= 1;
198 memcpy(&(win
->flags
), &(body
->add_config_data
.flags
),
201 int wb_x
= body
->add_config_data
.border_width
;
202 int wb_y
= body
->add_config_data
.border_width
;
206 if (HAS_TITLE_DIR(win
, DIR_N
))
208 wb_y
+= body
->add_config_data
.title_height
;
209 t_h
+= body
->add_config_data
.title_height
;
211 else if (HAS_TITLE_DIR(win
, DIR_W
))
213 wb_x
+= body
->add_config_data
.title_height
;
214 t_w
+= body
->add_config_data
.title_height
;
216 if (HAS_TITLE_DIR(win
, DIR_S
))
218 t_h
+= body
->add_config_data
.title_height
;
220 if (HAS_TITLE_DIR(win
, DIR_E
))
222 t_w
+= body
->add_config_data
.title_height
;
224 win
->real_g
.x
= win
->x
+ wb_x
;
225 win
->real_g
.y
= win
->y
+ wb_y
;
226 win
->real_g
.width
= win
->width
- t_w
;
227 win
->real_g
.height
= win
->height
- t_h
;
231 static void handle_config_info(unsigned long *body
)
233 char *tline
, *token
, *rest
;
235 extern void process_dynamic_config_line(char *line
);
237 tline
= (char*)&(body
[3]);
238 token
= PeekToken(tline
, &rest
);
239 if (StrEquals(token
, "Colorset"))
241 color
= LoadColorset(rest
);
242 change_colorset(color
);
244 else if (StrEquals(token
, XINERAMA_CONFIG_STRING
))
246 FScreenConfigureModule(rest
);
248 else if (StrEquals(token
, "IgnoreModifiers"))
250 sscanf(rest
, "%d", &mods_unused
);
252 else if (strncasecmp(tline
, Module
, ModuleLen
) == 0)
254 process_dynamic_config_line(tline
);
258 static void configure_window(FvwmPacketBody
*body
)
260 Ulong app_id
= body
->add_config_data
.w
;
262 ConsoleDebug(FVWM
, "configure_window: %ld\n", app_id
);
264 win
= id_to_win(app_id
);
266 set_win_configuration(win
, body
);
268 check_win_complete(win
);
269 check_in_window(win
);
270 got_configure(win
->manager
);
273 static void focus_change(FvwmPacketBody
*body
)
275 Ulong app_id
= body
->minimal_data
.app_id
;
276 WinData
*win
= id_to_win(app_id
);
278 ConsoleDebug(FVWM
, "Focus Change\n");
279 ConsoleDebug(FVWM
, "\tID: %ld\n", app_id
);
281 if (fvwm_focus_win
&&
282 fvwm_focus_win
->button
&&
283 fvwm_focus_win
->manager
->showonlyfocused
)
284 delete_windows_button(fvwm_focus_win
);
286 if (fvwm_focus_win
&& win
!= fvwm_focus_win
)
288 del_win_state(fvwm_focus_win
, FOCUS_CONTEXT
);
289 if (fvwm_focus_win
->manager
&&
290 fvwm_focus_win
->manager
->focus_button
)
292 fvwm_focus_win
->manager
->focus_button
= NULL
;
294 fvwm_focus_win
= NULL
;
300 win
->manager
->window_up
&&
301 win
->manager
->followFocus
)
303 win
->manager
->focus_button
= win
->button
;
305 add_win_state(win
, FOCUS_CONTEXT
);
307 check_in_window(win
);
309 globals
.focus_win
= win
;
310 fvwm_focus_win
= win
;
311 ConsoleDebug(FVWM
, "leaving focus_change\n");
314 static void res_name(FvwmPacketBody
*body
)
316 Ulong app_id
= body
->name_data
.app_id
;
317 Uchar
*name
= body
->name_data
.name
.name
;
320 ConsoleDebug(FVWM
, "In res_name\n");
322 win
= id_to_win(app_id
);
324 copy_string(&win
->resname
, (char *)name
);
325 change_windows_manager(win
);
327 ConsoleDebug(FVWM
, "Exiting res_name\n");
330 static void class_name(FvwmPacketBody
*body
)
332 Ulong app_id
= body
->name_data
.app_id
;
333 Uchar
*name
= body
->name_data
.name
.name
;
336 ConsoleDebug(FVWM
, "In class_name\n");
338 win
= id_to_win(app_id
);
340 copy_string(&win
->classname
, (char *)name
);
341 change_windows_manager(win
);
343 ConsoleDebug(FVWM
, "Exiting class_name\n");
346 static void icon_name(FvwmPacketBody
*body
)
350 Uchar
*name
= body
->name_data
.name
.name
;
352 ConsoleDebug(FVWM
, "In icon_name\n");
354 app_id
= body
->name_data
.app_id
;
356 win
= id_to_win(app_id
);
358 if (win
->iconname
&& !strcmp(win
->iconname
, (char *)name
))
361 FVWM
, "No icon change: %s %s\n", win
->iconname
, name
);
365 copy_string(&win
->iconname
, (char *)name
);
366 ConsoleDebug(FVWM
, "new icon name: %s\n", win
->iconname
);
368 ConsoleDebug(FVWM
, "Exiting icon_name\n");
371 static void visible_icon_name(FvwmPacketBody
*body
)
375 Uchar
*name
= body
->name_data
.name
.name
;
377 ConsoleDebug(FVWM
, "In visible_icon_name\n");
379 app_id
= body
->name_data
.app_id
;
381 win
= id_to_win(app_id
);
383 if (win
->visible_icon_name
&&
384 !strcmp(win
->visible_icon_name
, (char *)name
))
387 FVWM
, "No icon change: %s %s\n", win
->iconname
, name
);
391 copy_string(&win
->visible_icon_name
, (char *)name
);
393 FVWM
, "new visible icon name: %s\n", win
->visible_icon_name
);
394 if (change_windows_manager(win
) == 0 && win
->button
&&
395 (win
->manager
->format_depend
& ICON_NAME
))
397 if (win
->manager
->sort
)
399 resort_windows_button(win
);
403 ConsoleDebug(FVWM
, "Exiting icon_name\n");
406 static void window_name(FvwmPacketBody
*body
)
410 Uchar
*name
= body
->name_data
.name
.name
;
412 ConsoleDebug(FVWM
, "In window_name\n");
414 app_id
= body
->name_data
.app_id
;
416 win
= id_to_win(app_id
);
418 /* This is necessary because bash seems to update the window title on
419 every keystroke regardless of whether anything changes */
420 if (win
->titlename
&& !strcmp(win
->titlename
, (char *)name
))
423 FVWM
, "No name change: %s %s\n", win
->titlename
, name
);
427 copy_string(&win
->titlename
, (char *)name
);
429 ConsoleDebug(FVWM
, "Exiting window_name\n");
432 static void visible_name(FvwmPacketBody
*body
)
436 Uchar
*name
= body
->name_data
.name
.name
;
438 ConsoleDebug(FVWM
, "In visible_name\n");
440 app_id
= body
->name_data
.app_id
;
442 win
= id_to_win(app_id
);
444 /* This is necessary because bash seems to update the window title on
445 every keystroke regardless of whether anything changes */
446 if (win
->visible_name
&& !strcmp(win
->visible_name
, (char *)name
))
449 FVWM
, "No visible name change: %s %s\n",
450 win
->visible_name
, name
);
454 copy_string(&win
->visible_name
, (char *)name
);
455 if (change_windows_manager(win
) == 0 && win
->button
&&
456 (win
->manager
->format_depend
& TITLE_NAME
))
458 if (win
->manager
->sort
)
460 resort_windows_button(win
);
463 ConsoleDebug(FVWM
, "Exiting visible_name\n");
467 static void new_window(FvwmPacketBody
*body
)
471 win
= id_to_win(body
->add_config_data
.w
);
472 memcpy(&(win
->flags
), &(body
->add_config_data
.flags
), sizeof(win
->flags
));
473 set_win_configuration(win
, body
);
474 got_configure(win
->manager
);
475 check_win_complete(win
);
476 check_in_window(win
);
477 /* FIXME: not perfect, the manager is not know yet */
478 tips_cancel(win
->manager
);
481 static void destroy_window(FvwmPacketBody
*body
)
486 app_id
= body
->minimal_data
.app_id
;
487 win
= id_to_win(app_id
);
490 tips_cancel(win
->manager
);
492 if (win
== globals
.focus_win
)
494 globals
.focus_win
= NULL
;
496 delete_win_hashtab(win
);
499 ConsoleDebug(FVWM
, "destroy_window: deleting windows_button\n");
500 delete_windows_button(win
);
502 if (win
== fvwm_focus_win
)
504 fvwm_focus_win
= NULL
;
509 static void mini_icon(FvwmPacketBody
*body
)
511 Ulong app_id
= body
->mini_icon_data
.app_id
;
514 if (!FMiniIconsSupported
)
518 win
= id_to_win(app_id
);
520 win
, body
->mini_icon_data
.picture
, body
->mini_icon_data
.mask
,
521 body
->mini_icon_data
.alpha
, body
->mini_icon_data
.depth
,
522 body
->mini_icon_data
.width
, body
->mini_icon_data
.height
);
526 FVWM
, "mini_icon: 0x%lx 0x%lx %dx%dx%d\n",
527 (unsigned long) win
->pic
.picture
, (unsigned long) win
->pic
.mask
,
528 win
->pic
.width
, win
->pic
.height
, win
->pic
.depth
);
531 static void icon_location(FvwmPacketBody
*body
)
533 Ulong app_id
= body
->minimal_data
.app_id
;
536 win
= id_to_win(app_id
);
541 win
->icon_g
.x
= body
->icon_data
.xpos
;
542 win
->icon_g
.y
= body
->icon_data
.ypos
;
543 win
->icon_g
.width
= body
->icon_data
.icon_width
;
544 if (win
->icon_g
.width
<= 0)
546 win
->icon_g
.width
= 1;
548 win
->icon_g
.height
= body
->icon_data
.icon_height
;
549 if (win
->icon_g
.height
<= 0)
551 win
->icon_g
.height
= 1;
553 check_in_window(win
);
556 static void iconify(FvwmPacketBody
*body
, int dir
)
558 Ulong app_id
= body
->minimal_data
.app_id
;
561 win
= id_to_win(app_id
);
562 set_win_iconified(win
, dir
);
564 check_win_complete(win
);
565 check_in_window(win
);
568 static void window_shade(FvwmPacketBody
*body
, int do_shade
)
573 w
= (Window
)(body
->minimal_data
.app_id
);
574 man
= find_windows_manager(w
);
581 man
->flags
.needs_resize_after_unshade
= 0;
582 man
->flags
.is_shaded
= 1;
586 man
->flags
.is_shaded
= 0;
587 if (man
->flags
.needs_resize_after_unshade
)
590 man
->flags
.needs_resize_after_unshade
= 0;
597 /* only used by remanage_winlist */
599 static void update_win_in_hashtab(void *arg
)
601 WinData
*p
= (WinData
*)arg
;
605 void remanage_winlist(void)
607 walk_hashtab(update_win_in_hashtab
);
611 static void new_desk(FvwmPacketBody
*body
)
613 globals
.desknum
= body
->new_desk_data
.desknum
;
617 static void sendtomodule(FvwmPacketBody
*body
)
619 extern void execute_function(char *);
620 Uchar
*string
= body
->name_data
.name
.name
;
622 ConsoleDebug(FVWM
, "Got string: %s\n", string
);
624 execute_function((char *)string
);
627 static void property_change(FvwmPacketBody
*body
)
629 WinManager
*man
= NULL
;
632 if (body
->property_data
.id
!= 0)
634 if (!(man
= find_windows_manager(body
->property_data
.id
)))
638 if (body
->property_data
.arg
== MX_PROPERTY_CHANGE_BACKGROUND
)
641 CSET_IS_TRANSPARENT_PR(man
->colorsets
[DEFAULT
]))
643 recreate_background(man
, DEFAULT
);
644 force_manager_redraw(man
);
650 for (j
= 0; j
< globals
.num_managers
; j
++)
652 man
= &globals
.managers
[j
];
653 if (CSET_IS_TRANSPARENT_PR(man
->colorsets
[DEFAULT
]))
655 recreate_background(man
, DEFAULT
);
656 force_manager_redraw(man
);
660 else if (body
->property_data
.arg
== MX_PROPERTY_CHANGE_SWALLOW
&&
663 man
->swallowed
= body
->property_data
.toggle
;
664 if (man
->swallowed
&& body
->property_data
.str
)
668 if (sscanf((char *)body
->property_data
.str
, "%lu",
671 man
->swallower_win
= (Window
)u
;
675 man
->swallower_win
= 0;
681 static void ProcessMessage(Ulong type
, FvwmPacketBody
*body
)
685 ConsoleDebug(FVWM
, "fvwm message type: %ld\n", type
);
690 ConsoleDebug(FVWM
, "DEBUG::M_CONFIG_INFO\n");
691 handle_config_info((unsigned long*)body
);
694 case M_CONFIGURE_WINDOW
:
695 ConsoleDebug(FVWM
, "DEBUG::M_CONFIGURE_WINDOW\n");
696 configure_window(body
);
700 ConsoleDebug(FVWM
, "DEBUG::M_FOCUS_CHANGE\n");
705 ConsoleDebug(FVWM
, "DEBUG::M_RES_NAME\n");
710 ConsoleDebug(FVWM
, "DEBUG::M_RES_CLASS\n");
715 ConsoleDebug(FVWM
, "DEBUG::M_MAP\n");
719 ConsoleDebug(FVWM
, "DEBUG::M_ADD_WINDOW\n");
723 case M_DESTROY_WINDOW
:
724 ConsoleDebug(FVWM
, "DEBUG::M_DESTROY_WINDOW\n");
725 destroy_window(body
);
729 ConsoleDebug(FVWM
, "DEBUG::M_MINI_ICON\n");
734 ConsoleDebug(FVWM
, "DEBUG::M_WINDOW_NAME\n");
739 ConsoleDebug(FVWM
, "DEBUG::M_VISIBLE_NAME\n");
744 ConsoleDebug(FVWM
, "DEBUG::M_ICON_NAME\n");
748 case MX_VISIBLE_ICON_NAME
:
749 ConsoleDebug(FVWM
, "DEBUG::MX_VISIBLE_ICON_NAME\n");
750 visible_icon_name(body
);
754 ConsoleDebug(FVWM
, "DEBUG::M_DEICONIFY\n");
756 SendUnlockNotification(fvwm_fd
);
760 ConsoleDebug(FVWM
, "DEBUG::M_ICONIFY\n");
762 SendUnlockNotification(fvwm_fd
);
765 case M_ICON_LOCATION
:
769 case M_END_WINDOWLIST
:
770 ConsoleDebug(FVWM
, "DEBUG::M_END_WINDOWLIST\n");
772 FVWM
, "+++++ End window list +++++\n");
773 if (globals
.focus_win
&& globals
.focus_win
->button
)
775 globals
.focus_win
->manager
->focus_button
=
776 globals
.focus_win
->button
;
778 globals
.got_window_list
= 1;
779 for (i
= 0; i
< globals
.num_managers
; i
++)
781 create_manager_window(i
);
786 ConsoleDebug(FVWM
, "DEBUG::M_NEW_DESK\n");
791 ConsoleDebug(FVWM
, "DEBUG::M_NEW_PAGE\n");
792 if (globals
.x
== body
->new_page_data
.x
&&
793 globals
.y
== body
->new_page_data
.y
&&
794 globals
.desknum
== body
->new_page_data
.desknum
)
796 ConsoleDebug(FVWM
, "Useless NEW_PAGE received\n");
799 globals
.x
= body
->new_page_data
.x
;
800 globals
.y
= body
->new_page_data
.y
;
801 globals
.desknum
= body
->new_page_data
.desknum
;
802 if (fvwm_focus_win
&& fvwm_focus_win
->manager
&&
803 fvwm_focus_win
->manager
->followFocus
)
805 /* need to set the focus on a page change */
806 add_win_state(fvwm_focus_win
, FOCUS_CONTEXT
);
808 for (i
= 0; i
< globals
.num_managers
; i
++)
810 set_draw_mode(&globals
.managers
[i
], 0);
815 ConsoleDebug(FVWM
, "DEBUG::M_STRING\n");
819 case MX_PROPERTY_CHANGE
:
820 ConsoleDebug(FVWM
, "DEBUG::MX_PROPERTY_CHANGE\n");
821 property_change(body
);
825 window_shade(body
, 1);
828 case M_DEWINDOWSHADE
:
829 window_shade(body
, 0);
836 check_managers_consistency();
838 for (i
= 0; i
< globals
.num_managers
; i
++)
840 if (drawing(&globals
.managers
[i
]))
842 draw_manager(&globals
.managers
[i
]);
846 check_managers_consistency();
849 void ReadFvwmPipe(void)
854 ConsoleDebug(FVWM
, "DEBUG: entering ReadFvwmPipe\n");
856 if ((packet
= ReadFvwmPacket(fvwm_fd
[1])) == NULL
)
862 ProcessMessage(packet
->type
, (FvwmPacketBody
*)packet
->body
);
865 ConsoleDebug(FVWM
, "DEBUG: leaving ReadFvwmPipe\n");