xenocara/app/fvwm/modules/FvwmIconMan/fvwm.c

576 lines
13 KiB
C

#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");
}