mirror of
https://github.com/NishiOwO/fvwm1.git
synced 2025-04-22 01:04:42 +00:00
918 lines
26 KiB
C
918 lines
26 KiB
C
/****************************************************************************
|
|
* 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 "../configure.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);
|
|
MyFont *IconFont;
|
|
|
|
/****************************************************************************
|
|
*
|
|
* 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 &= ~XPM_FLAG;
|
|
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))
|
|
{
|
|
tmp_win->icon_t_width = XTextWidth(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.StdColors.back;
|
|
valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel;
|
|
attributes.border_pixel = Scr.StdColors.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 (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.HiShadowGC;
|
|
else
|
|
Relief = Scr.HiReliefGC;
|
|
Shadow = Scr.HiShadowGC;
|
|
/* 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.HiColors.fore;
|
|
BackColor = Scr.HiColors.back;
|
|
}
|
|
else
|
|
{
|
|
if((Tmp_win->flags & STICKY)&&(Scr.d_depth < 2))
|
|
{
|
|
Relief = Scr.StickyShadowGC;
|
|
Shadow = Scr.StickyShadowGC;
|
|
}
|
|
else if(Scr.d_depth < 2)
|
|
{
|
|
Relief = Scr.StdShadowGC;
|
|
Shadow = Scr.StdShadowGC;
|
|
}
|
|
else
|
|
{
|
|
if(Tmp_win->BackPixel != Scr.StdColors.back)
|
|
{
|
|
Globalgcv.foreground = Tmp_win->ReliefPixel;
|
|
Globalgcm = GCForeground;
|
|
XChangeGC(dpy,Scr.ScratchGC1,Globalgcm,&Globalgcv);
|
|
Relief = Scr.ScratchGC1;
|
|
|
|
Globalgcv.foreground = Tmp_win->ShadowPixel;
|
|
XChangeGC(dpy,Scr.ScratchGC2,Globalgcm,&Globalgcv);
|
|
Shadow = Scr.ScratchGC2;
|
|
}
|
|
else
|
|
{
|
|
Relief = Scr.StdReliefGC;
|
|
Shadow = Scr.StdShadowGC;
|
|
}
|
|
}
|
|
/* 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(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)
|
|
{
|
|
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.FontGC,
|
|
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.FontGC,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;
|
|
|
|
XDrawString (dpy, Tmp_win->icon_w, Scr.FontGC, x,
|
|
Tmp_win->icon_w_height-IconFont->height+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)
|
|
{
|
|
#ifndef NO_PAGER
|
|
if(Scr.PagerFont.height > 0)
|
|
{
|
|
XClearWindow(dpy,Tmp_win->pager_view);
|
|
RedrawPager();
|
|
}
|
|
#endif
|
|
|
|
if(Tmp_win->flags & SUPPRESSICON)
|
|
return;
|
|
|
|
if (Tmp_win->icon_w == (int)NULL)
|
|
return;
|
|
|
|
Tmp_win->icon_t_width = XTextWidth(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,i,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;
|
|
|
|
/* New! Put icon in same page as the center of the window */
|
|
/* Not a good idea for StickyIcons */
|
|
if((Scr.flags & StickyIcons)||(t->flags & STICKY))
|
|
{
|
|
base_x = 0;
|
|
base_y = 0;
|
|
}
|
|
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
|
|
{
|
|
width = t->icon_p_width;
|
|
height = t->icon_w_height + t->icon_p_height;
|
|
loc_ok = False;
|
|
|
|
/* check all boxes in order */
|
|
i=0;
|
|
while((i<Scr.NumBoxes)&&(!loc_ok))
|
|
{
|
|
/* In each IconBox, start at the upper left, travel right, then
|
|
* down */
|
|
test_y = Scr.IconBoxes[i][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 >= (Scr.IconBoxes[i][2] - Scr.IconBoxes[i][0]))
|
|
temp_w = 0;
|
|
if(height >= (Scr.IconBoxes[i][3] - Scr.IconBoxes[i][1]))
|
|
temp_h = 0;
|
|
|
|
while(((test_y + temp_h) < (Scr.IconBoxes[i][3]+base_y))&&(!loc_ok))
|
|
{
|
|
|
|
test_x = Scr.IconBoxes[i][0]+base_x;
|
|
while(((test_x + temp_w) < (Scr.IconBoxes[i][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;
|
|
}
|
|
}
|
|
if(Scr.flags & StubbornIconPlacement)
|
|
{
|
|
if(!(test_window->flags&ICONIFIED)&&
|
|
(test_window!=t))
|
|
{
|
|
tw=test_window->frame_width;
|
|
th=test_window->frame_height;
|
|
tx = test_window->frame_x;
|
|
ty = test_window->frame_y;
|
|
|
|
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;
|
|
}
|
|
i++;
|
|
}
|
|
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)
|
|
{
|
|
MouseButton *MouseEntry;
|
|
|
|
MouseEntry = Scr.MouseButtonRoot;
|
|
while(MouseEntry != (MouseButton *)0)
|
|
{
|
|
if((MouseEntry->func != (int)0)&&(MouseEntry->Context & C_ICON))
|
|
{
|
|
if(MouseEntry->Button >0)
|
|
XGrabButton(dpy, MouseEntry->Button, 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->NextButton;
|
|
}
|
|
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)
|
|
{
|
|
FuncKey *tmp;
|
|
for (tmp = Scr.FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
|
|
{
|
|
if (tmp->cont & C_ICON)
|
|
XGrabKey(dpy, tmp->keycode, tmp->mods, 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 |= XPM_FLAG;
|
|
tmp_win->flags |= PIXMAP_OURS;
|
|
tmp_win->iconDepth = Scr.d_depth;
|
|
#ifdef SHAPE
|
|
if (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)
|
|
{
|
|
fprintf(stderr,"Help! Bad Icon Window!\n");
|
|
}
|
|
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 (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 (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;
|
|
int new_x,new_y,w2,h2;
|
|
|
|
/* 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);
|
|
/* make sure that the window is on this screen */
|
|
if((t->frame_x < 0)||(t->frame_y<0)||
|
|
(t->frame_x >= Scr.MyDisplayWidth)||
|
|
(t->frame_y >= Scr.MyDisplayHeight))
|
|
|
|
{
|
|
/* try to put at least half the window
|
|
* in the current screen, if the current desktop
|
|
* is the windows desktop */
|
|
if(Scr.flags & StubbornIcons)
|
|
t->Desk = t->DeIconifyDesk;
|
|
else
|
|
t->Desk = Scr.CurrentDesk;
|
|
|
|
if(t->Desk == Scr.CurrentDesk)
|
|
{
|
|
new_x = t->frame_x;
|
|
new_y = t->frame_y;
|
|
w2 = (t->frame_width>>1);
|
|
h2 = (t->frame_height>>1);
|
|
if(!(Scr.flags & StubbornIcons))
|
|
{
|
|
if (( new_x < -w2) || (new_x > (Scr.MyDisplayWidth-w2 )))
|
|
{
|
|
new_x = new_x % Scr.MyDisplayWidth;
|
|
if ( new_x < -w2 )
|
|
new_x += Scr.MyDisplayWidth;
|
|
}
|
|
if ((new_y < -h2) || (new_y > (Scr.MyDisplayHeight-h2 )))
|
|
{
|
|
new_y = new_y % Scr.MyDisplayHeight;
|
|
if ( new_y < -h2 )
|
|
new_y += Scr.MyDisplayHeight;
|
|
}
|
|
}
|
|
SetupFrame(t,new_x,new_y,
|
|
t->frame_width,t->frame_height,False);
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
RaiseWindow(tmp_win);
|
|
|
|
if((Scr.flags & StubbornIcons)||(Scr.flags & ClickToFocus))
|
|
FocusOn(tmp_win,1);
|
|
|
|
KeepOnTop();
|
|
|
|
MoveResizePagerView(tmp_win);
|
|
return;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Iconifies the selected window
|
|
*
|
|
****************************************************************************/
|
|
void Iconify(FvwmWindow *tmp_win, int def_x, int def_y)
|
|
{
|
|
FvwmWindow *t;
|
|
XWindowAttributes winattrs;
|
|
unsigned long eventMask;
|
|
|
|
XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
|
|
eventMask = winattrs.your_event_mask;
|
|
|
|
if((tmp_win)&&(tmp_win == Scr.Hilite)&&
|
|
(Scr.flags & ClickToFocus)&&(tmp_win->next))
|
|
{
|
|
SetFocus(tmp_win->next->w,tmp_win->next);
|
|
ClearCirculatedFlag();
|
|
}
|
|
|
|
|
|
/* 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(t!= tmp_win)
|
|
MoveResizePagerView(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();
|
|
MoveResizePagerView(tmp_win);
|
|
}
|
|
if((Scr.flags & ClickToFocus)||(Scr.flags & SloppyFocus))
|
|
{
|
|
if ((tmp_win)&&(tmp_win == Scr.Focus))
|
|
{
|
|
if(Scr.PreviousFocus == Scr.Focus)
|
|
Scr.PreviousFocus = NULL;
|
|
if((Scr.flags & ClickToFocus)&&(tmp_win->next))
|
|
SetFocus(tmp_win->next->w, tmp_win->next);
|
|
else
|
|
{
|
|
SetFocus(Scr.NoFocusWin, NULL);
|
|
}
|
|
ClearCirculatedFlag();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|