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 win
->complete
&& win
->manager
== man
)
102 static void set_draw_mode(WinManager
*man
, int flag
)
111 if (man
->we_are_drawing
== 0 && flag
)
115 else if (man
->we_are_drawing
&& !flag
)
118 num
= accumulate_walk_hashtab(count_nonsticky_in_hashtab
);
120 FVWM
, "SetDrawMode on 0x%lx, num = %d\n",
121 (unsigned long)man
, num
);
127 man
->configures_expected
= num
;
129 man
->we_are_drawing
= flag
;
132 static int drawing(WinManager
*man
)
139 return man
->we_are_drawing
;
142 static void got_configure(WinManager
*man
)
144 if (man
&& !man
->we_are_drawing
)
146 man
->configures_expected
--;
148 FVWM
, "got_configure on 0x%lx, num_expected now = %d\n",
149 (unsigned long) man
, man
->configures_expected
);
150 if (man
->configures_expected
<= 0)
152 set_draw_mode(man
, 1);
157 /* MMH <mikehan@best.com> 6/99
158 * Following a gruesome hack this function has been hijacked.
159 * The function is no longer about whether or not the window is in the
160 * viewport, but whether or not the manager wants to display the window,
161 * based on its current location.
163 int win_in_viewport(WinData
*win
)
165 return check_resolution(win
->manager
, win
);
169 WinData
*id_to_win(Ulong id
)
173 win
= find_win_hashtab(id
);
179 insert_win_hashtab(win
);
185 static void set_win_configuration(WinData
*win
, FvwmPacketBody
*body
)
187 win
->desknum
= body
->add_config_data
.desk
;
188 win
->x
= body
->add_config_data
.frame_x
;
189 win
->y
= body
->add_config_data
.frame_y
;
190 win
->width
= body
->add_config_data
.frame_width
;
191 win
->height
= body
->add_config_data
.frame_height
;
192 win
->iconified
= IS_ICONIFIED(&(body
->add_config_data
));
193 win
->state
= (win
== fvwm_focus_win
) ? FOCUS_CONTEXT
: PLAIN_CONTEXT
;
194 win
->geometry_set
= 1;
195 memcpy(&(win
->flags
), &(body
->add_config_data
.flags
),
198 int wb_x
= body
->add_config_data
.border_width
;
199 int wb_y
= body
->add_config_data
.border_width
;
203 if (HAS_TITLE_DIR(win
, DIR_N
))
205 wb_y
+= body
->add_config_data
.title_height
;
206 t_h
+= body
->add_config_data
.title_height
;
208 else if (HAS_TITLE_DIR(win
, DIR_W
))
210 wb_x
+= body
->add_config_data
.title_height
;
211 t_w
+= body
->add_config_data
.title_height
;
213 if (HAS_TITLE_DIR(win
, DIR_S
))
215 t_h
+= body
->add_config_data
.title_height
;
217 if (HAS_TITLE_DIR(win
, DIR_E
))
219 t_w
+= body
->add_config_data
.title_height
;
221 win
->real_g
.x
= win
->x
+ wb_x
;
222 win
->real_g
.y
= win
->y
+ wb_y
;
223 win
->real_g
.width
= win
->width
- t_w
;
224 win
->real_g
.height
= win
->height
- t_h
;
228 static void handle_config_info(unsigned long *body
)
230 char *tline
, *token
, *rest
;
232 extern void process_dynamic_config_line(char *line
);
234 tline
= (char*)&(body
[3]);
235 token
= PeekToken(tline
, &rest
);
236 if (StrEquals(token
, "Colorset"))
238 color
= LoadColorset(rest
);
239 change_colorset(color
);
241 else if (StrEquals(token
, XINERAMA_CONFIG_STRING
))
243 FScreenConfigureModule(rest
);
245 else if (StrEquals(token
, "IgnoreModifiers"))
247 sscanf(rest
, "%d", &mods_unused
);
249 else if (strncasecmp(tline
, Module
, ModuleLen
) == 0)
251 process_dynamic_config_line(tline
);
255 static void configure_window(FvwmPacketBody
*body
)
257 Ulong app_id
= body
->add_config_data
.w
;
259 ConsoleDebug(FVWM
, "configure_window: %ld\n", app_id
);
261 win
= id_to_win(app_id
);
263 set_win_configuration(win
, body
);
265 check_win_complete(win
);
266 check_in_window(win
);
267 got_configure(win
->manager
);
270 static void focus_change(FvwmPacketBody
*body
)
272 Ulong app_id
= body
->minimal_data
.app_id
;
273 WinData
*win
= id_to_win(app_id
);
275 ConsoleDebug(FVWM
, "Focus Change\n");
276 ConsoleDebug(FVWM
, "\tID: %ld\n", app_id
);
278 if (fvwm_focus_win
&&
279 fvwm_focus_win
->button
&&
280 fvwm_focus_win
->manager
->showonlyfocused
)
281 delete_windows_button(fvwm_focus_win
);
283 if (fvwm_focus_win
&& win
!= fvwm_focus_win
)
285 del_win_state(fvwm_focus_win
, FOCUS_CONTEXT
);
286 if (fvwm_focus_win
->manager
&&
287 fvwm_focus_win
->manager
->focus_button
)
289 fvwm_focus_win
->manager
->focus_button
= NULL
;
291 fvwm_focus_win
= NULL
;
297 win
->manager
->window_up
&&
298 win
->manager
->followFocus
)
300 win
->manager
->focus_button
= win
->button
;
302 add_win_state(win
, FOCUS_CONTEXT
);
304 check_in_window(win
);
306 globals
.focus_win
= win
;
307 fvwm_focus_win
= win
;
308 ConsoleDebug(FVWM
, "leaving focus_change\n");
311 static void res_name(FvwmPacketBody
*body
)
313 Ulong app_id
= body
->name_data
.app_id
;
314 Uchar
*name
= body
->name_data
.name
.name
;
317 ConsoleDebug(FVWM
, "In res_name\n");
319 win
= id_to_win(app_id
);
321 copy_string(&win
->resname
, (char *)name
);
322 change_windows_manager(win
);
324 ConsoleDebug(FVWM
, "Exiting res_name\n");
327 static void class_name(FvwmPacketBody
*body
)
329 Ulong app_id
= body
->name_data
.app_id
;
330 Uchar
*name
= body
->name_data
.name
.name
;
333 ConsoleDebug(FVWM
, "In class_name\n");
335 win
= id_to_win(app_id
);
337 copy_string(&win
->classname
, (char *)name
);
338 change_windows_manager(win
);
340 ConsoleDebug(FVWM
, "Exiting class_name\n");
343 static void icon_name(FvwmPacketBody
*body
)
347 Uchar
*name
= body
->name_data
.name
.name
;
349 ConsoleDebug(FVWM
, "In icon_name\n");
351 app_id
= body
->name_data
.app_id
;
353 win
= id_to_win(app_id
);
355 if (win
->iconname
&& !strcmp(win
->iconname
, (char *)name
))
358 FVWM
, "No icon change: %s %s\n", win
->iconname
, name
);
362 copy_string(&win
->iconname
, (char *)name
);
363 ConsoleDebug(FVWM
, "new icon name: %s\n", win
->iconname
);
365 ConsoleDebug(FVWM
, "Exiting icon_name\n");
368 static void visible_icon_name(FvwmPacketBody
*body
)
372 Uchar
*name
= body
->name_data
.name
.name
;
374 ConsoleDebug(FVWM
, "In visible_icon_name\n");
376 app_id
= body
->name_data
.app_id
;
378 win
= id_to_win(app_id
);
380 if (win
->visible_icon_name
&&
381 !strcmp(win
->visible_icon_name
, (char *)name
))
384 FVWM
, "No icon change: %s %s\n", win
->iconname
, name
);
388 copy_string(&win
->visible_icon_name
, (char *)name
);
390 FVWM
, "new visible icon name: %s\n", win
->visible_icon_name
);
391 if (change_windows_manager(win
) == 0 && win
->button
&&
392 (win
->manager
->format_depend
& ICON_NAME
))
394 if (win
->manager
->sort
)
396 resort_windows_button(win
);
400 ConsoleDebug(FVWM
, "Exiting icon_name\n");
403 static void window_name(FvwmPacketBody
*body
)
407 Uchar
*name
= body
->name_data
.name
.name
;
409 ConsoleDebug(FVWM
, "In window_name\n");
411 app_id
= body
->name_data
.app_id
;
413 win
= id_to_win(app_id
);
415 /* This is necessary because bash seems to update the window title on
416 every keystroke regardless of whether anything changes */
417 if (win
->titlename
&& !strcmp(win
->titlename
, (char *)name
))
420 FVWM
, "No name change: %s %s\n", win
->titlename
, name
);
424 copy_string(&win
->titlename
, (char *)name
);
426 ConsoleDebug(FVWM
, "Exiting window_name\n");
429 static void visible_name(FvwmPacketBody
*body
)
433 Uchar
*name
= body
->name_data
.name
.name
;
435 ConsoleDebug(FVWM
, "In visible_name\n");
437 app_id
= body
->name_data
.app_id
;
439 win
= id_to_win(app_id
);
441 /* This is necessary because bash seems to update the window title on
442 every keystroke regardless of whether anything changes */
443 if (win
->visible_name
&& !strcmp(win
->visible_name
, (char *)name
))
446 FVWM
, "No visible name change: %s %s\n",
447 win
->visible_name
, name
);
451 copy_string(&win
->visible_name
, (char *)name
);
452 if (change_windows_manager(win
) == 0 && win
->button
&&
453 (win
->manager
->format_depend
& TITLE_NAME
))
455 if (win
->manager
->sort
)
457 resort_windows_button(win
);
460 ConsoleDebug(FVWM
, "Exiting visible_name\n");
464 static void new_window(FvwmPacketBody
*body
)
468 win
= id_to_win(body
->add_config_data
.w
);
469 memcpy(&(win
->flags
), &(body
->add_config_data
.flags
), sizeof(win
->flags
));
470 set_win_configuration(win
, body
);
471 got_configure(win
->manager
);
472 check_win_complete(win
);
473 check_in_window(win
);
474 /* FIXME: not perfect, the manager is not know yet */
475 tips_cancel(win
->manager
);
478 static void destroy_window(FvwmPacketBody
*body
)
483 app_id
= body
->minimal_data
.app_id
;
484 win
= id_to_win(app_id
);
487 tips_cancel(win
->manager
);
489 if (win
== globals
.focus_win
)
491 globals
.focus_win
= NULL
;
493 delete_win_hashtab(win
);
496 ConsoleDebug(FVWM
, "destroy_window: deleting windows_button\n");
497 delete_windows_button(win
);
499 if (win
== fvwm_focus_win
)
501 fvwm_focus_win
= NULL
;
506 static void mini_icon(FvwmPacketBody
*body
)
508 Ulong app_id
= body
->mini_icon_data
.app_id
;
511 if (!FMiniIconsSupported
)
515 win
= id_to_win(app_id
);
517 win
, body
->mini_icon_data
.picture
, body
->mini_icon_data
.mask
,
518 body
->mini_icon_data
.alpha
, body
->mini_icon_data
.depth
,
519 body
->mini_icon_data
.width
, body
->mini_icon_data
.height
);
523 FVWM
, "mini_icon: 0x%lx 0x%lx %dx%dx%d\n",
524 (unsigned long) win
->pic
.picture
, (unsigned long) win
->pic
.mask
,
525 win
->pic
.width
, win
->pic
.height
, win
->pic
.depth
);
528 static void icon_location(FvwmPacketBody
*body
)
530 Ulong app_id
= body
->minimal_data
.app_id
;
533 win
= id_to_win(app_id
);
538 win
->icon_g
.x
= body
->icon_data
.xpos
;
539 win
->icon_g
.y
= body
->icon_data
.ypos
;
540 win
->icon_g
.width
= body
->icon_data
.icon_width
;
541 if (win
->icon_g
.width
<= 0)
543 win
->icon_g
.width
= 1;
545 win
->icon_g
.height
= body
->icon_data
.icon_height
;
546 if (win
->icon_g
.height
<= 0)
548 win
->icon_g
.height
= 1;
550 check_in_window(win
);
553 static void iconify(FvwmPacketBody
*body
, int dir
)
555 Ulong app_id
= body
->minimal_data
.app_id
;
558 win
= id_to_win(app_id
);
559 set_win_iconified(win
, dir
);
561 check_win_complete(win
);
562 check_in_window(win
);
565 static void window_shade(FvwmPacketBody
*body
, int do_shade
)
570 w
= (Window
)(body
->minimal_data
.app_id
);
571 man
= find_windows_manager(w
);
578 man
->flags
.needs_resize_after_unshade
= 0;
579 man
->flags
.is_shaded
= 1;
583 man
->flags
.is_shaded
= 0;
584 if (man
->flags
.needs_resize_after_unshade
)
587 man
->flags
.needs_resize_after_unshade
= 0;
594 /* only used by remanage_winlist */
596 static void update_win_in_hashtab(void *arg
)
598 WinData
*p
= (WinData
*)arg
;
602 void remanage_winlist(void)
604 walk_hashtab(update_win_in_hashtab
);
608 static void new_desk(FvwmPacketBody
*body
)
610 globals
.desknum
= body
->new_desk_data
.desknum
;
614 static void sendtomodule(FvwmPacketBody
*body
)
616 extern void execute_function(char *);
617 Uchar
*string
= body
->name_data
.name
.name
;
619 ConsoleDebug(FVWM
, "Got string: %s\n", string
);
621 execute_function((char *)string
);
624 static void property_change(FvwmPacketBody
*body
)
626 WinManager
*man
= NULL
;
629 if (body
->property_data
.id
!= 0)
631 if (!(man
= find_windows_manager(body
->property_data
.id
)))
635 if (body
->property_data
.arg
== MX_PROPERTY_CHANGE_BACKGROUND
)
638 CSET_IS_TRANSPARENT_PR(man
->colorsets
[DEFAULT
]))
640 recreate_background(man
, DEFAULT
);
641 force_manager_redraw(man
);
647 for (j
= 0; j
< globals
.num_managers
; j
++)
649 man
= &globals
.managers
[j
];
650 if (CSET_IS_TRANSPARENT_PR(man
->colorsets
[DEFAULT
]))
652 recreate_background(man
, DEFAULT
);
653 force_manager_redraw(man
);
657 else if (body
->property_data
.arg
== MX_PROPERTY_CHANGE_SWALLOW
&&
660 man
->swallowed
= body
->property_data
.toggle
;
661 if (man
->swallowed
&& body
->property_data
.str
)
665 if (sscanf((char *)body
->property_data
.str
, "%lu",
668 man
->swallower_win
= (Window
)u
;
672 man
->swallower_win
= 0;
678 static void ProcessMessage(Ulong type
, FvwmPacketBody
*body
)
682 ConsoleDebug(FVWM
, "fvwm message type: %ld\n", type
);
687 ConsoleDebug(FVWM
, "DEBUG::M_CONFIG_INFO\n");
688 handle_config_info((unsigned long*)body
);
691 case M_CONFIGURE_WINDOW
:
692 ConsoleDebug(FVWM
, "DEBUG::M_CONFIGURE_WINDOW\n");
693 configure_window(body
);
697 ConsoleDebug(FVWM
, "DEBUG::M_FOCUS_CHANGE\n");
702 ConsoleDebug(FVWM
, "DEBUG::M_RES_NAME\n");
707 ConsoleDebug(FVWM
, "DEBUG::M_RES_CLASS\n");
712 ConsoleDebug(FVWM
, "DEBUG::M_MAP\n");
716 ConsoleDebug(FVWM
, "DEBUG::M_ADD_WINDOW\n");
720 case M_DESTROY_WINDOW
:
721 ConsoleDebug(FVWM
, "DEBUG::M_DESTROY_WINDOW\n");
722 destroy_window(body
);
726 ConsoleDebug(FVWM
, "DEBUG::M_MINI_ICON\n");
731 ConsoleDebug(FVWM
, "DEBUG::M_WINDOW_NAME\n");
736 ConsoleDebug(FVWM
, "DEBUG::M_VISIBLE_NAME\n");
741 ConsoleDebug(FVWM
, "DEBUG::M_ICON_NAME\n");
745 case MX_VISIBLE_ICON_NAME
:
746 ConsoleDebug(FVWM
, "DEBUG::MX_VISIBLE_ICON_NAME\n");
747 visible_icon_name(body
);
751 ConsoleDebug(FVWM
, "DEBUG::M_DEICONIFY\n");
753 SendUnlockNotification(fvwm_fd
);
757 ConsoleDebug(FVWM
, "DEBUG::M_ICONIFY\n");
759 SendUnlockNotification(fvwm_fd
);
762 case M_ICON_LOCATION
:
766 case M_END_WINDOWLIST
:
767 ConsoleDebug(FVWM
, "DEBUG::M_END_WINDOWLIST\n");
769 FVWM
, "+++++ End window list +++++\n");
770 if (globals
.focus_win
&& globals
.focus_win
->button
)
772 globals
.focus_win
->manager
->focus_button
=
773 globals
.focus_win
->button
;
775 globals
.got_window_list
= 1;
776 for (i
= 0; i
< globals
.num_managers
; i
++)
778 create_manager_window(i
);
783 ConsoleDebug(FVWM
, "DEBUG::M_NEW_DESK\n");
788 ConsoleDebug(FVWM
, "DEBUG::M_NEW_PAGE\n");
789 if (globals
.x
== body
->new_page_data
.x
&&
790 globals
.y
== body
->new_page_data
.y
&&
791 globals
.desknum
== body
->new_page_data
.desknum
)
793 ConsoleDebug(FVWM
, "Useless NEW_PAGE received\n");
796 globals
.x
= body
->new_page_data
.x
;
797 globals
.y
= body
->new_page_data
.y
;
798 globals
.desknum
= body
->new_page_data
.desknum
;
799 if (fvwm_focus_win
&& fvwm_focus_win
->manager
&&
800 fvwm_focus_win
->manager
->followFocus
)
802 /* need to set the focus on a page change */
803 add_win_state(fvwm_focus_win
, FOCUS_CONTEXT
);
805 for (i
= 0; i
< globals
.num_managers
; i
++)
807 set_draw_mode(&globals
.managers
[i
], 0);
812 ConsoleDebug(FVWM
, "DEBUG::M_STRING\n");
816 case MX_PROPERTY_CHANGE
:
817 ConsoleDebug(FVWM
, "DEBUG::MX_PROPERTY_CHANGE\n");
818 property_change(body
);
822 window_shade(body
, 1);
825 case M_DEWINDOWSHADE
:
826 window_shade(body
, 0);
833 check_managers_consistency();
835 for (i
= 0; i
< globals
.num_managers
; i
++)
837 if (drawing(&globals
.managers
[i
]))
839 draw_manager(&globals
.managers
[i
]);
843 check_managers_consistency();
846 void ReadFvwmPipe(void)
851 ConsoleDebug(FVWM
, "DEBUG: entering ReadFvwmPipe\n");
853 if ((packet
= ReadFvwmPacket(fvwm_fd
[1])) == NULL
)
859 ProcessMessage(packet
->type
, (FvwmPacketBody
*)packet
->body
);
862 ConsoleDebug(FVWM
, "DEBUG: leaving ReadFvwmPipe\n");