#include "config.h" #include "FvwmIconMan.h" #include "x.h" #include "xmanager.h" #include "../fvwm/fvwm.h" #include "../fvwm/module.h" static char const rcsid[] = "$Id: fvwm.c,v 1.1.1.1 2006/11/26 10:53:49 matthieu Exp $"; typedef struct { Ulong paging_enabled; } m_toggle_paging_data; typedef struct { Ulong desknum; } m_new_desk_data; typedef struct { Ulong app_id; Ulong frame_id; Ulong dbase_entry; Ulong xpos; Ulong ypos; Ulong width; Ulong height; Ulong desknum; Ulong windows_flags; Ulong window_title_height; Ulong window_border_width; Ulong window_base_width; Ulong window_base_height; Ulong window_resize_width_inc; Ulong window_resize_height_inc; Ulong window_min_width; Ulong window_min_height; Ulong window_max_width_inc; Ulong window_max_height_inc; Ulong icon_label_id; Ulong icon_pixmap_id; Ulong window_gravity; } m_add_config_data; typedef struct { Ulong x, y, desknum; } m_new_page_data; typedef struct { Ulong app_id, frame_id, dbase_entry; } m_minimal_data; typedef struct { Ulong app_id, frame_id, dbase_entry; Ulong xpos, ypos, icon_width, icon_height; } m_icon_data; typedef struct { Ulong app_id, frame_id, dbase_entry; union { Ulong name_long[1]; Uchar name[4]; } name; } m_name_data; #ifdef MINI_ICONS typedef struct { Ulong app_id, frame_id, dbase_entry; Ulong width, height, depth, picture, mask; union { Ulong name_long[1]; Uchar name[4]; } name; } m_mini_icon_data; #endif typedef struct { Ulong start, type, len, time /* in fvwm 2 only */; } FvwmPacketHeader; typedef union { m_toggle_paging_data toggle_paging_data; m_new_desk_data new_desk_data; m_add_config_data add_config_data; m_new_page_data new_page_data; m_minimal_data minimal_data; m_icon_data icon_data; m_name_data name_data; #ifdef MINI_ICONS m_mini_icon_data mini_icon_data; #endif } FvwmPacketBody; /* only used by count_nonsticky_in_hashtab */ static WinManager *the_manager; static int count_nonsticky_in_hashtab (void *arg) { WinData *win = (WinData *)arg; WinManager *man = the_manager; if (!(win->fvwm_flags & STICKY) && win->complete && win->manager == man) return 1; return 0; } static void set_draw_mode (WinManager *man, int flag) { int num; if (!man) return; if (man->we_are_drawing == 0 && flag) { draw_manager (man); } else if (man->we_are_drawing && !flag) { the_manager = man; num = accumulate_walk_hashtab (count_nonsticky_in_hashtab); ConsoleDebug (FVWM, "SetDrawMode on 0x%lx, num = %d\n", (unsigned long)man, num); if (num == 0) return; man->configures_expected = num; } man->we_are_drawing = flag; } static int drawing (WinManager *man) { if (!man) return 1; return man->we_are_drawing; } static void got_configure (WinManager *man) { if (man && !man->we_are_drawing) { man->configures_expected--; ConsoleDebug (FVWM, "got_configure on 0x%lx, num_expected now = %d\n", (unsigned long) man, man->configures_expected); if (man->configures_expected <= 0) set_draw_mode (man, 1); } } int win_in_viewport (WinData *win) { WinManager *manager = win->manager; int flag = 0; assert (manager); switch (manager->res) { case SHOW_GLOBAL: flag = 1; break; case SHOW_DESKTOP: if ((win->fvwm_flags & STICKY) || win->desknum == globals.desknum) flag = 1; break; case SHOW_PAGE: if (win->fvwm_flags & STICKY) { flag = 1; } else if (win->desknum == globals.desknum) { /* win and screen intersect if they are not disjoint in x and y */ flag = RECTANGLES_INTERSECT (win->x, win->y, win->width, win->height, 0, 0, globals.screenx, globals.screeny); } break; } return flag; } static WinData *id_to_win (Ulong id) { WinData *win; win = find_win_hashtab (id); if (win == NULL) { win = new_windata (); win->app_id = id; win->app_id_set = 1; insert_win_hashtab (win); } return win; } static void set_win_configuration (WinData *win, FvwmPacketBody *body) { win->desknum = body->add_config_data.desknum; win->x = body->add_config_data.xpos; win->y = body->add_config_data.ypos; win->width = body->add_config_data.width; win->height = body->add_config_data.height; win->geometry_set = 1; win->fvwm_flags = body->add_config_data.windows_flags; } static void configure_window (FvwmPacketBody *body) { Ulong app_id = body->add_config_data.app_id; WinData *win; ConsoleDebug (FVWM, "configure_window: %ld\n", app_id); win = id_to_win (app_id); set_win_configuration (win, body); check_win_complete (win); check_in_window (win); got_configure (win->manager); } static void focus_change (FvwmPacketBody *body) { Ulong app_id = body->minimal_data.app_id; WinData *win = id_to_win (app_id); ConsoleDebug (FVWM, "Focus Change\n"); ConsoleDebug (FVWM, "\tID: %ld\n", app_id); if (globals.focus_win) { del_win_state (globals.focus_win, FOCUS_CONTEXT); if (globals.focus_win->manager && globals.focus_win->manager->focus_button) globals.focus_win->manager->focus_button = NULL; globals.focus_win = NULL; } if (win->complete && win->button && win->manager && win->manager->window_up && win->manager->followFocus) { win->manager->focus_button = win->button; add_win_state (win, FOCUS_CONTEXT); } globals.focus_win = win; ConsoleDebug (FVWM, "leaving focus_change\n"); } static void res_name (FvwmPacketBody *body) { Ulong app_id = body->name_data.app_id; Uchar *name = body->name_data.name.name; WinData *win; ConsoleDebug (FVWM, "In res_name\n"); win = id_to_win (app_id); copy_string (&win->resname, (char *)name); change_windows_manager (win); ConsoleDebug (FVWM, "Exiting res_name\n"); } static void class_name (FvwmPacketBody *body) { Ulong app_id = body->name_data.app_id; Uchar *name = body->name_data.name.name; WinData *win; ConsoleDebug (FVWM, "In class_name\n"); win = id_to_win (app_id); copy_string (&win->classname, (char *)name); change_windows_manager (win); ConsoleDebug (FVWM, "Exiting class_name\n"); } static void icon_name (FvwmPacketBody *body) { WinData *win; Ulong app_id; Uchar *name = body->name_data.name.name; ConsoleDebug (FVWM, "In icon_name\n"); app_id = body->name_data.app_id; win = id_to_win (app_id); if (win->iconname && !strcmp (win->iconname, name)) { ConsoleDebug (FVWM, "No icon change: %s %s\n", win->iconname, name); return; } copy_string (&win->iconname, (char *)name); ConsoleDebug (FVWM, "new icon name: %s\n", win->iconname); if (change_windows_manager (win) == 0 && win->button && (win->manager->format_depend & ICON_NAME)) { if (win->manager->sort) { resort_windows_button (win); } } ConsoleDebug (FVWM, "Exiting icon_name\n"); } static void window_name (FvwmPacketBody *body) { WinData *win; Ulong app_id; Uchar *name = body->name_data.name.name; ConsoleDebug (FVWM, "In window_name\n"); app_id = body->name_data.app_id; win = id_to_win (app_id); /* This is necessary because bash seems to update the window title on every keystroke regardless of whether anything changes */ if (win->titlename && !strcmp (win->titlename, name)) { ConsoleDebug (FVWM, "No name change: %s %s\n", win->titlename, name); return; } copy_string (&win->titlename, (char *)name); if (change_windows_manager (win) == 0 && win->button && (win->manager->format_depend & TITLE_NAME)) { if (win->manager->sort) { resort_windows_button (win); } } ConsoleDebug (FVWM, "Exiting window_name\n"); } static void new_window (FvwmPacketBody *body) { WinData *win; win = new_windata(); if (!(body->add_config_data.windows_flags & TRANSIENT)) { win->app_id = body->add_config_data.app_id; win->app_id_set = 1; set_win_configuration (win, body); insert_win_hashtab (win); check_win_complete (win); check_in_window (win); } } static void destroy_window (FvwmPacketBody *body) { WinData *win; Ulong app_id; app_id = body->minimal_data.app_id; win = id_to_win (app_id); if (win == globals.focus_win) globals.focus_win = NULL; delete_win_hashtab (win); if (win->button) { ConsoleDebug (FVWM, "destroy_window: deleting windows_button\n"); delete_windows_button (win); } free_windata (win); } #ifdef MINI_ICONS static void mini_icon (FvwmPacketBody *body) { Ulong app_id = body->mini_icon_data.app_id; WinData *win; win = id_to_win (app_id); set_win_picture (win, body->mini_icon_data.picture, body->mini_icon_data.mask, body->mini_icon_data.depth, body->mini_icon_data.width, body->mini_icon_data.height); ConsoleDebug (FVWM, "mini_icon: 0x%lx 0x%lx %dx%dx%d\n", (unsigned long) win->pic.picture, (unsigned long) win->pic.mask, win->pic.width, win->pic.height, win->pic.depth); } #endif static void iconify (FvwmPacketBody *body, int dir) { Ulong app_id = body->minimal_data.app_id; WinData *win; win = id_to_win (app_id); set_win_iconified (win, dir); check_win_complete (win); check_in_window (win); } /* only used by new_desk */ static void update_win_in_hashtab (void *arg) { WinData *p = (WinData *)arg; check_in_window (p); } static void new_desk (FvwmPacketBody *body) { globals.desknum = body->new_desk_data.desknum; walk_hashtab (update_win_in_hashtab); draw_managers (); } static void sendtomodule (FvwmPacketBody *body) { extern void execute_function (char *); Uchar *string = body->name_data.name.name; ConsoleDebug (FVWM, "Got string: %s\n", string); execute_function (string); } static void ProcessMessage (Ulong type, FvwmPacketBody *body) { int i; ConsoleDebug (FVWM, "FVWM Message type: %ld\n", type); switch(type) { case M_CONFIGURE_WINDOW: ConsoleDebug (FVWM, "DEBUG::M_CONFIGURE_WINDOW\n"); configure_window (body); break; case M_FOCUS_CHANGE: ConsoleDebug (FVWM, "DEBUG::M_FOCUS_CHANGE\n"); focus_change (body); break; case M_RES_NAME: ConsoleDebug (FVWM, "DEBUG::M_RES_NAME\n"); res_name (body); break; case M_RES_CLASS: ConsoleDebug (FVWM, "DEBUG::M_RES_CLASS\n"); class_name (body); break; case M_MAP: ConsoleDebug (FVWM, "DEBUG::M_MAP\n"); break; case M_ADD_WINDOW: ConsoleDebug (FVWM, "DEBUG::M_ADD_WINDOW\n"); new_window (body); break; case M_DESTROY_WINDOW: ConsoleDebug (FVWM, "DEBUG::M_DESTROY_WINDOW\n"); destroy_window (body); break; #ifdef MINI_ICONS case M_MINI_ICON: ConsoleDebug (FVWM, "DEBUG::M_MINI_ICON\n"); mini_icon (body); break; #endif case M_WINDOW_NAME: ConsoleDebug (FVWM, "DEBUG::M_WINDOW_NAME\n"); window_name (body); break; case M_ICON_NAME: ConsoleDebug (FVWM, "DEBUG::M_ICON_NAME\n"); icon_name (body); break; case M_DEICONIFY: ConsoleDebug (FVWM, "DEBUG::M_DEICONIFY\n"); iconify (body, 0); break; case M_ICONIFY: ConsoleDebug (FVWM, "DEBUG::M_ICONIFY\n"); iconify (body, 1); break; case M_END_WINDOWLIST: ConsoleDebug (FVWM, "DEBUG::M_END_WINDOWLIST\n"); ConsoleDebug (FVWM, ">>>>>>>>>>>>>>>>>>>>>>>End window list<<<<<<<<<<<<<<<\n"); if (globals.focus_win && globals.focus_win->button) { globals.focus_win->manager->focus_button = globals.focus_win->button; } globals.got_window_list = 1; for (i = 0; i < globals.num_managers; i++) { create_manager_window (i); } break; case M_NEW_DESK: ConsoleDebug (FVWM, "DEBUG::M_NEW_DESK\n"); new_desk (body); break; case M_NEW_PAGE: ConsoleDebug (FVWM, "DEBUG::M_NEW_PAGE\n"); if (globals.x == body->new_page_data.x && globals.y == body->new_page_data.y && globals.desknum == body->new_page_data.desknum) { ConsoleDebug (FVWM, "Useless NEW_PAGE received\n"); break; } globals.x = body->new_page_data.x; globals.y = body->new_page_data.y; globals.desknum = body->new_page_data.desknum; for (i = 0; i < globals.num_managers; i++) { set_draw_mode (&globals.managers[i], 0); } break; case M_STRING: ConsoleDebug (FVWM, "DEBUG::M_STRING\n"); sendtomodule (body); break; default: break; } check_managers_consistency(); for (i = 0; i < globals.num_managers; i++) { if (drawing (&globals.managers[i])) draw_manager (&globals.managers[i]); } check_managers_consistency(); } void ReadFvwmPipe (void) { int body_length; FvwmPacketHeader header; FvwmPacketBody *body; PrintMemuse(); ConsoleDebug(FVWM, "DEBUG: entering ReadFvwmPipe\n"); body_length = ReadFvwmPacket(Fvwm_fd[1], (unsigned long *) &header, (unsigned long **)&body); body_length -= HEADER_SIZE; if (header.start == START_FLAG) { ProcessMessage (header.type, body); if (body_length) { Free (body); } } else { DeadPipe (1); } ConsoleDebug(FVWM, "DEBUG: leaving ReadFvwmPipe\n"); }