/****************************************************************************
* This module is mostly all new
* by Rob Nation
* A little of it is borrowed from ctwm.
* Copyright 1993 Robert Nation. No restrictions are placed on this code,
* as long as the copyright notice is preserved
****************************************************************************/
/***********************************************************************
*
* fvwm icon code
*
***********************************************************************/
#include <FVWMconfig.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#ifdef NeXT
#include <fcntl.h>
#endif
#include <X11/Intrinsic.h>
#ifdef XPM
#include <X11/xpm.h>
#endif /* XPM */
#include "fvwm.h"
#include "menus.h"
#include "misc.h"
#include "parse.h"
#include "screen.h"
#include "module.h"
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif /* SHAPE */
void GrabIconButtons(FvwmWindow *, Window);
void GrabIconKeys(FvwmWindow *, Window);
/****************************************************************************
*
* Creates an icon window as needed
*
****************************************************************************/
void CreateIconWindow(FvwmWindow *tmp_win, int def_x, int def_y)
{
int final_x, final_y;
unsigned long valuemask; /* mask for create windows */
XSetWindowAttributes attributes; /* attributes for create windows */
tmp_win->flags |= ICON_OURS;
tmp_win->flags &= ~PIXMAP_OURS;
tmp_win->flags &= ~SHAPED_ICON;
tmp_win->icon_pixmap_w = None;
tmp_win->iconPixmap = None;
tmp_win->iconDepth = 0;
if(tmp_win->flags & SUPPRESSICON)
return;
/* First, see if it was specified in the .fvwmrc */
tmp_win->icon_p_height = 0;
tmp_win->icon_p_width = 0;
/* First, check for a monochrome bitmap */
if(tmp_win->icon_bitmap_file != NULL)
GetBitmapFile(tmp_win);
/* Next, check for a color pixmap */
if((tmp_win->icon_bitmap_file != NULL)&&
(tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0))
GetXPMFile(tmp_win);
/* Next, See if the app supplies its own icon window */
if((tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0)&&
(tmp_win->wmhints) && (tmp_win->wmhints->flags & IconWindowHint))
GetIconWindow(tmp_win);
/* Finally, try to get icon bitmap from the application */
if((tmp_win->icon_p_height == 0)&&(tmp_win->icon_p_width == 0)&&
(tmp_win->wmhints)&&(tmp_win->wmhints->flags & IconPixmapHint))
GetIconBitmap(tmp_win);
/* figure out the icon window size */
if (!(tmp_win->flags & NOICON_TITLE)||(tmp_win->icon_p_height == 0))
{
if (tmp_win->icon_name == NULL)
tmp_win->icon_name = tmp_win->name;
tmp_win->icon_t_width = XTextWidth(Scr.IconFont.font,
tmp_win->icon_name,
strlen(tmp_win->icon_name));
tmp_win->icon_w_height = ICON_HEIGHT;
}
else
{
tmp_win->icon_t_width = 0;
tmp_win->icon_w_height = 0;
}
if((tmp_win->flags & ICON_OURS)&&(tmp_win->icon_p_height >0))
{
tmp_win->icon_p_width += 4;
tmp_win->icon_p_height +=4;
}
if(tmp_win->icon_p_width == 0)
tmp_win->icon_p_width = tmp_win->icon_t_width+6;
tmp_win->icon_w_width = tmp_win->icon_p_width;
final_x = def_x;
final_y = def_y;
if(final_x <0)
final_x = 0;
if(final_y <0)
final_y = 0;
if(final_x + tmp_win->icon_w_width >=Scr.MyDisplayWidth)
final_x = Scr.MyDisplayWidth - tmp_win->icon_w_width-1;
if(final_y + tmp_win->icon_w_height >=Scr.MyDisplayHeight)
final_y = Scr.MyDisplayHeight - tmp_win->icon_w_height-1;
tmp_win->icon_x_loc = final_x;
tmp_win->icon_xl_loc = final_x;
tmp_win->icon_y_loc = final_y;
/* clip to fit on screen */
attributes.background_pixel = Scr.WinColors.back;
valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel;
attributes.border_pixel = Scr.WinColors.fore;
attributes.cursor = Scr.FvwmCursors[DEFAULT];
attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask |
ExposureMask | KeyPressMask|EnterWindowMask |
FocusChangeMask );
if (!(tmp_win->flags & NOICON_TITLE)||(tmp_win->icon_p_height == 0))
tmp_win->icon_w =
XCreateWindow(dpy, Scr.Root, final_x, final_y+tmp_win->icon_p_height,
tmp_win->icon_w_width, tmp_win->icon_w_height,0,
CopyFromParent,
CopyFromParent,CopyFromParent,valuemask,&attributes);
if((tmp_win->flags & ICON_OURS)&&(tmp_win->icon_p_width>0)&&
(tmp_win->icon_p_height>0))
{
tmp_win->icon_pixmap_w =
XCreateWindow(dpy, Scr.Root, final_x, final_y, tmp_win->icon_p_width,
tmp_win->icon_p_height, 0, CopyFromParent,
CopyFromParent,CopyFromParent,valuemask,&attributes);
}
else
{
attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask |
KeyPressMask|EnterWindowMask |
FocusChangeMask | LeaveWindowMask );
valuemask = CWEventMask;
XChangeWindowAttributes(dpy,tmp_win->icon_pixmap_w,
valuemask,&attributes);
}
#ifdef XPM
#ifdef SHAPE
if (ShapesSupported && (tmp_win->flags & SHAPED_ICON))
{
XShapeCombineMask(dpy, tmp_win->icon_pixmap_w, ShapeBounding,2, 2,
tmp_win->icon_maskPixmap, ShapeSet);
}
#endif
#endif
if(tmp_win->icon_w != None)
{
XSaveContext(dpy, tmp_win->icon_w, FvwmContext, (caddr_t)tmp_win);
XDefineCursor(dpy, tmp_win->icon_w, Scr.FvwmCursors[DEFAULT]);
GrabIconButtons(tmp_win,tmp_win->icon_w);
GrabIconKeys(tmp_win,tmp_win->icon_w);
}
if(tmp_win->icon_pixmap_w != None)
{
XSaveContext(dpy, tmp_win->icon_pixmap_w, FvwmContext, (caddr_t)tmp_win);
XDefineCursor(dpy, tmp_win->icon_pixmap_w, Scr.FvwmCursors[DEFAULT]);
GrabIconButtons(tmp_win,tmp_win->icon_pixmap_w);
GrabIconKeys(tmp_win,tmp_win->icon_pixmap_w);
}
return;
}
/****************************************************************************
*
* Draws the icon window
*
****************************************************************************/
void DrawIconWindow(FvwmWindow *Tmp_win)
{
GC Shadow, Relief;
Pixel TextColor,BackColor;
int x ;
if(Tmp_win->flags & SUPPRESSICON)
return;
if(Tmp_win->icon_w != None)
flush_expose (Tmp_win->icon_w);
if(Tmp_win->icon_pixmap_w != None)
flush_expose (Tmp_win->icon_pixmap_w);
if(Scr.Hilite == Tmp_win)
{
if(Scr.d_depth < 2)
Relief = Scr.WinShadowGC; /*was HiShadow!*/
else
Relief = Scr.WinReliefGC; /*was HiRelief!*/
Shadow = Scr.WinShadowGC;
/* resize the icon name window */
if(Tmp_win->icon_w != None)
{
Tmp_win->icon_w_width = Tmp_win->icon_t_width+6;
if(Tmp_win->icon_w_width < Tmp_win->icon_p_width)
Tmp_win->icon_w_width = Tmp_win->icon_p_width;
Tmp_win->icon_xl_loc = Tmp_win->icon_x_loc -
(Tmp_win->icon_w_width - Tmp_win->icon_p_width)/2;
}
TextColor = Scr.ActiveTitleColors.fore;
BackColor = Scr.ActiveTitleColors.back;
}
else
{
if(Scr.d_depth < 2)
{
Relief = Scr.WinReliefGC;
Shadow = Scr.WinShadowGC;
}
else
{
Globalgcv.foreground = Tmp_win->TextPixel; /* ->ReliefPixel */
Globalgcm = GCForeground;
XChangeGC(dpy,Scr.ScratchGC1,Globalgcm,&Globalgcv);
Relief = Scr.ScratchGC1;
Globalgcv.foreground = Tmp_win->TextPixel; /* ->ShadowPixel */
XChangeGC(dpy,Scr.ScratchGC2,Globalgcm,&Globalgcv);
Shadow = Scr.ScratchGC2;
}
/* resize the icon name window */
if(Tmp_win->icon_w != None)
{
Tmp_win->icon_w_width = Tmp_win->icon_p_width;
Tmp_win->icon_xl_loc = Tmp_win->icon_x_loc;
}
TextColor = Tmp_win->TextPixel;
BackColor = Tmp_win->BackPixel;
}
if((Tmp_win->flags & ICON_OURS)&&(Tmp_win->icon_pixmap_w != None))
XSetWindowBackground(dpy,Tmp_win->icon_pixmap_w,
BackColor);
if(Tmp_win->icon_w != None)
XSetWindowBackground(dpy,Tmp_win->icon_w,BackColor);
/* write the icon label */
NewFontAndColor(Scr.IconFont.font->fid,TextColor,BackColor);
if(Tmp_win->icon_pixmap_w != None)
XMoveWindow(dpy,Tmp_win->icon_pixmap_w,Tmp_win->icon_x_loc,
Tmp_win->icon_y_loc);
if(Tmp_win->icon_w != None)
{
Tmp_win->icon_w_height = ICON_HEIGHT;
XMoveResizeWindow(dpy, Tmp_win->icon_w, Tmp_win->icon_xl_loc,
Tmp_win->icon_y_loc+Tmp_win->icon_p_height,
Tmp_win->icon_w_width,ICON_HEIGHT);
XClearWindow(dpy,Tmp_win->icon_w);
}
if((Tmp_win->iconPixmap != None)&&(!(Tmp_win->flags & SHAPED_ICON)))
RelieveWindow(Tmp_win,Tmp_win->icon_pixmap_w,0,0,
Tmp_win->icon_p_width, Tmp_win->icon_p_height,
Relief,Shadow, FULL_HILITE);
/* need to locate the icon pixmap */
if(Tmp_win->iconPixmap != None)
{
if(Tmp_win->iconDepth == Scr.d_depth)
{
XCopyArea(dpy,Tmp_win->iconPixmap,Tmp_win->icon_pixmap_w,Scr.ScratchGC3,
0,0,Tmp_win->icon_p_width-4, Tmp_win->icon_p_height-4,2,2);
}
else
XCopyPlane(dpy,Tmp_win->iconPixmap,Tmp_win->icon_pixmap_w,Scr.ScratchGC3,0,
0,Tmp_win->icon_p_width-4, Tmp_win->icon_p_height-4,2,2,1);
}
if(Tmp_win->icon_w != None)
{
/* text position */
x = (Tmp_win->icon_w_width - Tmp_win->icon_t_width)/2;
if(x<3)x=3;
#ifdef I18N
#undef FONTSET
#define FONTSET Scr.IconFont.fontset
#endif
XDrawString (dpy, Tmp_win->icon_w, Scr.ScratchGC3, x,
Tmp_win->icon_w_height-Scr.IconFont.height+
Scr.IconFont.y-3,
Tmp_win->icon_name, strlen(Tmp_win->icon_name));
RelieveWindow(Tmp_win,Tmp_win->icon_w,0,0,Tmp_win->icon_w_width,
ICON_HEIGHT,Relief,Shadow, FULL_HILITE);
}
}
/***********************************************************************
*
* Procedure:
* RedoIconName - procedure to re-position the icon window and name
*
************************************************************************/
void RedoIconName(FvwmWindow *Tmp_win)
{
if(Tmp_win->flags & SUPPRESSICON)
return;
if (Tmp_win->icon_w == (int)NULL)
return;
if (Tmp_win->icon_name == NULL)
Tmp_win->icon_name = Tmp_win->name;
Tmp_win->icon_t_width = XTextWidth(Scr.IconFont.font,Tmp_win->icon_name,
strlen(Tmp_win->icon_name));
/* clear the icon window, and trigger a re-draw via an expose event */
if (Tmp_win->flags & ICONIFIED)
XClearArea(dpy, Tmp_win->icon_w, 0, 0, 0, 0, True);
return;
}
/***********************************************************************
*
* Procedure:
* AutoPlace - Find a home for an icon
*
************************************************************************/
void AutoPlace(FvwmWindow *t)
{
int test_x=0, test_y=0,tw,th,tx,ty,temp_h,temp_w;
int base_x, base_y;
int width,height;
FvwmWindow *test_window;
Bool loc_ok;
int real_x=10, real_y=10;
int new_x, new_y;
/* New! Put icon in same page as the center of the window */
/* Not a good idea for StickyIcons */
if((t->flags & StickyIcon)||(t->flags & STICKY))
{
base_x = 0;
base_y = 0;
/*Also, if its a stickyWindow, put it on the current page! */
new_x = t->frame_x % Scr.MyDisplayWidth;
new_y = t->frame_y % Scr.MyDisplayHeight;
if(new_x < 0)new_x += Scr.MyDisplayWidth;
if(new_y < 0)new_y += Scr.MyDisplayHeight;
SetupFrame(t,new_x,new_y,
t->frame_width,t->frame_height,False);
t->Desk = Scr.CurrentDesk;
}
else
{
base_x=((t->frame_x+Scr.Vx+(t->frame_width>>1))/Scr.MyDisplayWidth)*
Scr.MyDisplayWidth - Scr.Vx;
base_y=((t->frame_y+Scr.Vy+(t->frame_height>>1))/Scr.MyDisplayHeight)*
Scr.MyDisplayHeight - Scr.Vy;
}
if(t->flags & ICON_MOVED)
{
/* just make sure the icon is on this screen */
t->icon_x_loc = t->icon_x_loc % Scr.MyDisplayWidth + base_x;
t->icon_y_loc = t->icon_y_loc % Scr.MyDisplayHeight + base_y;
if(t->icon_x_loc < 0)
t->icon_x_loc += Scr.MyDisplayWidth;
if(t->icon_y_loc < 0)
t->icon_y_loc += Scr.MyDisplayHeight;
}
else if (t->wmhints && t->wmhints->flags & IconPositionHint)
{
t->icon_x_loc = t->wmhints->icon_x;
t->icon_y_loc = t->wmhints->icon_y;
}
else if(t->IconBox[0] >= 0)
{
width = t->icon_p_width;
height = t->icon_w_height + t->icon_p_height;
loc_ok = False;
/* check all boxes in order */
/* In each IconBox, start at the upper left, travel right, then
* down */
test_y = t->IconBox[1]+base_y;
temp_h = height;
temp_w = width;
/* OK second try at this.
* If the window is taller than the icon box, ignore the icon height
* when figuring where to put it. Same goes for the width */
/* This should permit reasonably graceful handling of big icons. */
if(width >= (t->IconBox[2] - t->IconBox[0]))
temp_w = 0;
if(height >= (t->IconBox[3] - t->IconBox[1]))
temp_h = 0;
while(((test_y + temp_h) < (t->IconBox[3]+base_y))&&(!loc_ok))
{
test_x = t->IconBox[0]+base_x;
while(((test_x + temp_w) < (t->IconBox[2]+base_x))&&
(!loc_ok))
{
real_x = test_x;
real_y = test_y;
if(test_x + width > (Scr.MyDisplayWidth-2+base_x))
real_x = Scr.MyDisplayWidth - width -2 + base_x;
if(test_y + height > (Scr.MyDisplayHeight-2+base_y))
real_y = Scr.MyDisplayHeight - height -2+base_y;
if(test_x <base_x)
real_x = base_x;
if(test_y < base_y)
real_y = base_y;
loc_ok = True;
test_window = Scr.FvwmRoot.next;
while((test_window != (FvwmWindow *)0)&&(loc_ok == True))
{
if(test_window->Desk == t->Desk)
{
if((test_window->flags&ICONIFIED)&&
(test_window->icon_w||test_window->icon_pixmap_w)&&
(test_window != t))
{
tw=test_window->icon_p_width;
th=test_window->icon_p_height+
test_window->icon_w_height;
tx = test_window->icon_x_loc;
ty = test_window->icon_y_loc;
if((tx<(real_x+width+3))&&((tx+tw+3) > real_x)&&
(ty<(real_y+height+3))&&((ty+th + 3)>real_y))
{
loc_ok = False;
}
}
}
test_window = test_window->next;
}
test_x +=3;
}
test_y +=3;
}
if(loc_ok == False)
return;
t->icon_x_loc = real_x;
t->icon_y_loc = real_y;
if(t->icon_pixmap_w)
XMoveWindow(dpy,t->icon_pixmap_w,t->icon_x_loc, t->icon_y_loc);
t->icon_w_width = t->icon_p_width;
t->icon_xl_loc = t->icon_x_loc;
if (t->icon_w != None)
XMoveResizeWindow(dpy, t->icon_w, t->icon_xl_loc,
t->icon_y_loc+t->icon_p_height,
t->icon_w_width,ICON_HEIGHT);
Broadcast(M_ICON_LOCATION,7,t->w,t->frame,
(unsigned long)t,
t->icon_x_loc,t->icon_y_loc,
t->icon_w_width, t->icon_w_height+ t->icon_p_height);
}
}
/***********************************************************************
*
* Procedure:
* GrabIconButtons - grab needed buttons for the icon window
*
* Inputs:
* tmp_win - the fvwm window structure to use
*
***********************************************************************/
void GrabIconButtons(FvwmWindow *tmp_win, Window w)
{
Binding *MouseEntry;
MouseEntry = Scr.AllBindings;
while(MouseEntry != (Binding *)0)
{
if((MouseEntry->Action != NULL)&&(MouseEntry->Context & C_ICON)&&
(MouseEntry->IsMouse == 1))
{
if(MouseEntry->Button_Key >0)
XGrabButton(dpy, MouseEntry->Button_Key, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
else
{
XGrabButton(dpy, 1, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
XGrabButton(dpy, 2, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
XGrabButton(dpy, 3, MouseEntry->Modifier, w,
True, ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
Scr.FvwmCursors[DEFAULT]);
}
}
MouseEntry = MouseEntry->NextBinding;
}
return;
}
/***********************************************************************
*
* Procedure:
* GrabIconKeys - grab needed keys for the icon window
*
* Inputs:
* tmp_win - the fvwm window structure to use
*
***********************************************************************/
void GrabIconKeys(FvwmWindow *tmp_win,Window w)
{
Binding *tmp;
for (tmp = Scr.AllBindings; tmp != NULL; tmp = tmp->NextBinding)
{
if ((tmp->Context & C_ICON)&&(tmp->IsMouse == 0))
XGrabKey(dpy, tmp->Button_Key, tmp->Modifier, w, True,
GrabModeAsync, GrabModeAsync);
}
return;
}
/****************************************************************************
*
* Looks for a monochrome icon bitmap file
*
****************************************************************************/
void GetBitmapFile(FvwmWindow *tmp_win)
{
char *path = NULL;
int HotX,HotY;
extern char *IconPath;
path = findIconFile(tmp_win->icon_bitmap_file, IconPath,R_OK);
if(path == NULL)return;
if(XReadBitmapFile (dpy, Scr.Root,path,
(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height,
&tmp_win->iconPixmap,
&HotX, &HotY) != BitmapSuccess)
{
tmp_win->icon_p_width = 0;
tmp_win->icon_p_height = 0;
}
free(path);
}
/****************************************************************************
*
* Looks for a color XPM icon file
*
****************************************************************************/
void GetXPMFile(FvwmWindow *tmp_win)
{
#ifdef XPM
XWindowAttributes root_attr;
XpmAttributes xpm_attributes;
extern char *PixmapPath;
char *path = NULL;
path = findIconFile(tmp_win->icon_bitmap_file, PixmapPath,R_OK);
if(path == NULL)return;
XGetWindowAttributes(dpy,Scr.Root,&root_attr);
xpm_attributes.colormap = root_attr.colormap;
xpm_attributes.closeness = 40000; /* Allow for "similar" colors */
xpm_attributes.valuemask = XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness;
if(XpmReadFileToPixmap(dpy, Scr.Root, path,
&tmp_win->iconPixmap,
&tmp_win->icon_maskPixmap,
&xpm_attributes) == XpmSuccess)
{
tmp_win->icon_p_width = xpm_attributes.width;
tmp_win->icon_p_height = xpm_attributes.height;
tmp_win->flags |= PIXMAP_OURS;
tmp_win->iconDepth = Scr.d_depth;
#ifdef SHAPE
if (ShapesSupported && tmp_win->icon_maskPixmap)
tmp_win->flags |= SHAPED_ICON;
#endif
}
free(path);
#endif /* XPM */
}
/****************************************************************************
*
* Looks for an application supplied icon window
*
****************************************************************************/
void GetIconWindow(FvwmWindow *tmp_win)
{
/* We are guaranteed that wmhints is non-null when calling this
* routine */
if(XGetGeometry(dpy, tmp_win->wmhints->icon_window, &JunkRoot,
&JunkX, &JunkY,(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height,
&JunkBW, &JunkDepth)==0)
{
fvwm_msg(ERR,"GetIconWindow","Help! Bad Icon Window!");
}
tmp_win->icon_p_width += JunkBW<<1;
tmp_win->icon_p_height += JunkBW<<1;
/*
* Now make the new window the icon window for this window,
* and set it up to work as such (select for key presses
* and button presses/releases, set up the contexts for it,
* and define the cursor for it).
*/
tmp_win->icon_pixmap_w = tmp_win->wmhints->icon_window;
#ifdef SHAPE
if (ShapesSupported && (tmp_win->wmhints->flags & IconMaskHint))
{
tmp_win->flags |= SHAPED_ICON;
tmp_win->icon_maskPixmap = tmp_win->wmhints->icon_mask;
}
#endif
/* Make sure that the window is a child of the root window ! */
/* Olwais screws this up, maybe others do too! */
XReparentWindow(dpy, tmp_win->icon_pixmap_w, Scr.Root, 0,0);
tmp_win->flags &= ~ICON_OURS;
}
/****************************************************************************
*
* Looks for an application supplied bitmap or pixmap
*
****************************************************************************/
void GetIconBitmap(FvwmWindow *tmp_win)
{
/* We are guaranteed that wmhints is non-null when calling this
* routine */
XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, &JunkRoot, &JunkX, &JunkY,
(unsigned int *)&tmp_win->icon_p_width,
(unsigned int *)&tmp_win->icon_p_height, &JunkBW, &JunkDepth);
tmp_win->iconPixmap = tmp_win->wmhints->icon_pixmap;
tmp_win->iconDepth = JunkDepth;
#ifdef SHAPE
if (ShapesSupported && (tmp_win->wmhints->flags & IconMaskHint))
{
tmp_win->flags |= SHAPED_ICON;
tmp_win->icon_maskPixmap = tmp_win->wmhints->icon_mask;
}
#endif
}
/***********************************************************************
*
* Procedure:
* DeIconify a window
*
***********************************************************************/
void DeIconify(FvwmWindow *tmp_win)
{
FvwmWindow *t,*tmp;
if(!tmp_win)
return;
RaiseWindow(tmp_win);
/* now de-iconify transients */
for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
{
if ((t == tmp_win)||
((t->flags & TRANSIENT) &&(t->transientfor == tmp_win->w)))
{
t->flags |= MAPPED;
if(Scr.Hilite == t)
SetBorder (t, False,True,True,None);
XMapWindow(dpy, t->w);
if(t->Desk == Scr.CurrentDesk)
{
XMapWindow(dpy, t->frame);
t->flags |= MAP_PENDING;
}
XMapWindow(dpy, t->Parent);
SetMapStateProp(t, NormalState);
t->flags &= ~ICONIFIED;
t->flags &= ~ICON_UNMAPPED;
/* Need to make sure the border is colored correctly,
* in case it was stuck or unstuck while iconified. */
tmp = Scr.Hilite;
Scr.Hilite = t;
SetBorder(t,False,True,True,None);
Scr.Hilite = tmp;
XRaiseWindow(dpy,t->w);
if (t->icon_w)
XUnmapWindow(dpy, t->icon_w);
if (t->icon_pixmap_w)
XUnmapWindow(dpy, t->icon_pixmap_w);
Broadcast(M_DEICONIFY,3,t->w,t->frame,(unsigned long)t,0,0,0,0);
}
}
if(tmp_win->flags & ClickToFocus)
FocusOn(tmp_win, 1, 1);
KeepOnTop();
return;
}
/****************************************************************************
*
* Iconifies the selected window
*
****************************************************************************/
void Iconify(FvwmWindow *tmp_win, int def_x, int def_y)
{
FvwmWindow *t;
XWindowAttributes winattrs;
unsigned long eventMask;
if(!tmp_win)
return;
XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
eventMask = winattrs.your_event_mask;
if((tmp_win)&&(tmp_win == Scr.Hilite)&&
(tmp_win->flags & ClickToFocus)&&(tmp_win->next))
{
SetFocus(tmp_win->next->w,tmp_win->next,1);
}
/* iconify transients first */
for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
{
if ((t==tmp_win)||
((t->flags & TRANSIENT) && (t->transientfor == tmp_win->w)))
{
/*
* Prevent the receipt of an UnmapNotify, since that would
* cause a transition to the Withdrawn state.
*/
t->flags &= ~MAPPED;
XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask);
XUnmapWindow(dpy, t->w);
XSelectInput(dpy, t->w, eventMask);
XUnmapWindow(dpy, t->frame);
t->DeIconifyDesk = t->Desk;
if (t->icon_w)
XUnmapWindow(dpy, t->icon_w);
if (t->icon_pixmap_w)
XUnmapWindow(dpy, t->icon_pixmap_w);
SetMapStateProp(t, IconicState);
SetBorder (t, False,False,False,None);
if(t != tmp_win)
{
t->flags |= ICONIFIED|ICON_UNMAPPED;
Broadcast(M_ICONIFY,7,t->w,t->frame,
(unsigned long)t,
-10000, -10000,
t->icon_w_width,
t->icon_w_height+t->icon_p_height);
BroadcastConfig(M_CONFIGURE_WINDOW,t);
}
}
}
if (tmp_win->icon_w == None)
if(tmp_win->flags & ICON_MOVED)
CreateIconWindow(tmp_win,tmp_win->icon_x_loc,tmp_win->icon_y_loc);
else
CreateIconWindow(tmp_win, def_x, def_y);
AutoPlace(tmp_win);
tmp_win->flags |= ICONIFIED;
tmp_win->flags &= ~ICON_UNMAPPED;
Broadcast(M_ICONIFY,7,tmp_win->w,tmp_win->frame,
(unsigned long)tmp_win,
tmp_win->icon_x_loc,tmp_win->icon_y_loc,
tmp_win->icon_w_width,
tmp_win->icon_w_height+tmp_win->icon_p_height);
BroadcastConfig(M_CONFIGURE_WINDOW,tmp_win);
LowerWindow(tmp_win);
if(tmp_win->Desk == Scr.CurrentDesk)
{
if (tmp_win->icon_w != None)
XMapWindow(dpy, tmp_win->icon_w);
if(tmp_win->icon_pixmap_w != None)
XMapWindow(dpy, tmp_win->icon_pixmap_w);
KeepOnTop();
}
if((tmp_win->flags & ClickToFocus)||(tmp_win->flags & SloppyFocus))
{
if (tmp_win == Scr.Focus)
{
if(Scr.PreviousFocus == Scr.Focus)
Scr.PreviousFocus = NULL;
if((tmp_win->flags & ClickToFocus)&&(tmp_win->next))
SetFocus(tmp_win->next->w, tmp_win->next,1);
else
{
SetFocus(Scr.NoFocusWin, NULL,1);
}
}
}
return;
}
/****************************************************************************
*
* This is used to tell applications which windows on the screen are
* top level appication windows, and which windows are the icon windows
* that go with them.
*
****************************************************************************/
void SetMapStateProp(FvwmWindow *tmp_win, int state)
{
unsigned long data[2]; /* "suggested" by ICCCM version 1 */
data[0] = (unsigned long) state;
data[1] = (unsigned long) tmp_win->icon_w;
/* data[2] = (unsigned long) tmp_win->icon_pixmap_w;*/
XChangeProperty (dpy, tmp_win->w, _XA_WM_STATE, _XA_WM_STATE, 32,
PropModeReplace, (unsigned char *) data, 2);
return;
}
syntax highlighted by Code2HTML, v. 0.9.1