2662 lines
69 KiB
C
2662 lines
69 KiB
C
|
/* FvwmIconBox Module --- Copyright 1994, 1995 Nobutaka Suzuki.
|
||
|
*
|
||
|
* No guarantees or warantees or anything are provided or implied in
|
||
|
* any way whatsoever. Use this program at your own risk. Permission
|
||
|
* to use this program for any purpose is given, as long as the
|
||
|
* copyright is kept intact.
|
||
|
*
|
||
|
* The functions based on part of GoodStuff, FvwmScroll, FvwmWinList
|
||
|
* and Fvwm are noted by a small copyright atop that function.
|
||
|
* Full original copyright is described in COPYRIGHT.
|
||
|
*/
|
||
|
|
||
|
#define TRUE 1
|
||
|
#define FALSE 0
|
||
|
|
||
|
#define NONE 0
|
||
|
#define VERTICAL 1
|
||
|
#define HORIZONTAL 2
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#ifdef HAVE_SYS_BSDTYPES_H
|
||
|
#include <sys/bsdtypes.h> /* Saul */
|
||
|
#endif
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <signal.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/wait.h>
|
||
|
#include <sys/time.h>
|
||
|
|
||
|
#if HAVE_SYS_SELECT_H
|
||
|
#include <sys/select.h>
|
||
|
#endif
|
||
|
|
||
|
#include <unistd.h>
|
||
|
#include <ctype.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "../../fvwm/module.h"
|
||
|
|
||
|
#include <X11/Xlib.h>
|
||
|
#include <X11/Xutil.h>
|
||
|
#include <X11/Xproto.h>
|
||
|
#include <X11/Xatom.h>
|
||
|
#include <X11/Intrinsic.h>
|
||
|
|
||
|
#ifdef SHAPE
|
||
|
#include <X11/extensions/shape.h>
|
||
|
#endif /* SHAPE */
|
||
|
|
||
|
/* just as same as wild.c */
|
||
|
#ifndef TRUE
|
||
|
#define TRUE 1
|
||
|
#define FALSE 0
|
||
|
#endif
|
||
|
|
||
|
#include "FvwmIconBox.h"
|
||
|
|
||
|
char *MyName;
|
||
|
|
||
|
XFontStruct *font;
|
||
|
|
||
|
Display *dpy; /* which display are we talking to */
|
||
|
int x_fd,fd_width;
|
||
|
|
||
|
Window Root;
|
||
|
int screen;
|
||
|
int d_depth;
|
||
|
|
||
|
char *Back = "#5f9ea0";
|
||
|
char *Fore = "#82dfe3";
|
||
|
char *IconBack = "#cfcfcf";
|
||
|
char *IconFore = "black";
|
||
|
char *ActIconBack = "white";
|
||
|
char *ActIconFore = "black";
|
||
|
char *font_string = "fixed";
|
||
|
|
||
|
/* same strings as in misc.c */
|
||
|
char NoClass[] = "NoClass";
|
||
|
char NoResource[] = "NoResource";
|
||
|
|
||
|
Pixel fore_pix, hilite_pix, back_pix, shadow_pix;
|
||
|
Pixel icon_fore_pix, icon_back_pix, icon_hilite_pix, icon_shadow_pix;
|
||
|
Pixel act_icon_fore_pix, act_icon_back_pix, act_icon_hilite_pix, act_icon_shadow_pix;
|
||
|
|
||
|
GC NormalGC,ShadowGC,ReliefGC,IconShadowGC,IconReliefGC;
|
||
|
Window main_win;
|
||
|
Window holder_win;
|
||
|
Window icon_win;
|
||
|
Window h_scroll_bar;
|
||
|
Window v_scroll_bar;
|
||
|
Window l_button, r_button, t_button, b_button;
|
||
|
Window Pressed = None;
|
||
|
|
||
|
long CurrentDesk;
|
||
|
|
||
|
int Width, Height;
|
||
|
int UWidth, UHeight;
|
||
|
|
||
|
#define MW_EVENTS (KeyPressMask| ExposureMask | StructureNotifyMask|\
|
||
|
ButtonReleaseMask | ButtonPressMask )
|
||
|
#define SCROLL_EVENTS (ExposureMask | StructureNotifyMask|\
|
||
|
ButtonReleaseMask |ButtonPressMask | PointerMotionMask)
|
||
|
#define BUTTON_EVENTS (ExposureMask | StructureNotifyMask|\
|
||
|
ButtonReleaseMask | ButtonPressMask |\
|
||
|
LeaveWindowMask | PointerMotionMask)
|
||
|
|
||
|
unsigned long m_mask = M_CONFIGURE_WINDOW|M_ADD_WINDOW|M_DESTROY_WINDOW|
|
||
|
M_END_WINDOWLIST| M_ICONIFY|M_DEICONIFY|M_ICON_NAME|
|
||
|
M_RES_NAME|M_RES_CLASS|M_WINDOW_NAME|M_ICON_FILE|
|
||
|
M_DEFAULTICON|M_CONFIG_INFO|M_END_CONFIG_INFO;
|
||
|
|
||
|
struct icon_info *Hilite;
|
||
|
int main_width, main_height;
|
||
|
int num_icons = 0;
|
||
|
int num_rows = 1;
|
||
|
int num_columns = 6;
|
||
|
int Lines = 6;
|
||
|
int max_icon_width = 48,max_icon_height = 48;
|
||
|
int ButtonWidth,ButtonHeight;
|
||
|
int x= -100000,y= -100000,w= -1,h= -1,gravity = NorthWestGravity;
|
||
|
int icon_win_x = 0, icon_win_y = 0, icon_win_width = 100,
|
||
|
icon_win_height = 100;
|
||
|
int interval = 8;
|
||
|
int motion = NONE;
|
||
|
int primary = LEFT, secondary = BOTTOM;
|
||
|
int xneg = 0, yneg = 0;
|
||
|
int ClickTime = 150;
|
||
|
unsigned int bar_width = 9;
|
||
|
int redraw_flag = 3;
|
||
|
int icon_relief = 4;
|
||
|
int margin1 = 8;
|
||
|
int margin2 = 6;
|
||
|
|
||
|
Pixmap IconwinPixmap = None;
|
||
|
char *IconwinPixmapFile = NULL;
|
||
|
|
||
|
int h_margin;
|
||
|
int v_margin;
|
||
|
|
||
|
int fd[2];
|
||
|
|
||
|
struct icon_info *Head = NULL;
|
||
|
struct icon_info *Tail = NULL;
|
||
|
struct iconfile *IconListHead = NULL;
|
||
|
struct iconfile *IconListTail = NULL;
|
||
|
struct iconfile *DefaultIcon = NULL;
|
||
|
struct mousefunc *MouseActions = NULL;
|
||
|
struct keyfunc *KeyActions = NULL;
|
||
|
char *iconPath = NULL;
|
||
|
char *pixmapPath = NULL;
|
||
|
char *FvwmDefaultIcon = NULL;
|
||
|
|
||
|
static Atom wm_del_win;
|
||
|
Atom _XA_WM_PROTOCOLS;
|
||
|
Atom _XA_WM_NAME;
|
||
|
|
||
|
int ready = 0;
|
||
|
unsigned long local_flags = 0;
|
||
|
int sortby = UNSORT;
|
||
|
|
||
|
int save_color_limit; /* color limit from config */
|
||
|
|
||
|
/************************************************************************
|
||
|
Main
|
||
|
Based on main() from GoodStuff:
|
||
|
Copyright 1993, Robert Nation.
|
||
|
************************************************************************/
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
char *display_name = NULL;
|
||
|
char *temp, *s;
|
||
|
XIconSize* size;
|
||
|
|
||
|
temp = argv[0];
|
||
|
|
||
|
s=strrchr(argv[0], '/');
|
||
|
if (s != NULL)
|
||
|
temp = s + 1;
|
||
|
|
||
|
|
||
|
MyName = safemalloc(strlen(temp)+1);
|
||
|
strcpy(MyName, temp);
|
||
|
|
||
|
signal (SIGPIPE, DeadPipe);
|
||
|
|
||
|
if((argc != 6)&&(argc != 7))
|
||
|
{
|
||
|
fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName,
|
||
|
VERSION);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
fd[0] = atoi(argv[1]);
|
||
|
fd[1] = atoi(argv[2]);
|
||
|
|
||
|
if (!(dpy = XOpenDisplay(display_name)))
|
||
|
{
|
||
|
fprintf(stderr,"%s: can't open display %s", MyName,
|
||
|
XDisplayName(display_name));
|
||
|
exit (1);
|
||
|
}
|
||
|
x_fd = XConnectionNumber(dpy);
|
||
|
|
||
|
fd_width = GetFdWidth();
|
||
|
|
||
|
screen= DefaultScreen(dpy);
|
||
|
Root = RootWindow(dpy, screen);
|
||
|
if(Root == None)
|
||
|
{
|
||
|
fprintf(stderr,"%s: Screen %d is not valid ", MyName, screen);
|
||
|
exit(1);
|
||
|
}
|
||
|
InitPictureCMap(dpy,Root); /* store the root cmap */
|
||
|
d_depth = DefaultDepth(dpy, screen);
|
||
|
|
||
|
XSetErrorHandler((XErrorHandler)myErrorHandler);
|
||
|
|
||
|
ParseOptions();
|
||
|
|
||
|
SetMessageMask(fd, m_mask);
|
||
|
|
||
|
if ((local_flags & SETWMICONSIZE) && (size = XAllocIconSize()) != NULL){
|
||
|
size->max_width = size->min_width = max_icon_width + icon_relief;
|
||
|
size->max_height = size->min_height = max_icon_height + icon_relief;
|
||
|
size->width_inc = size->height_inc = 0;
|
||
|
XSetIconSizes(dpy, Root, size, 1);
|
||
|
XFree(size);
|
||
|
}
|
||
|
|
||
|
CreateWindow();
|
||
|
|
||
|
SendFvwmPipe(fd,"Send_WindowList",0);
|
||
|
|
||
|
Loop();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
Loop
|
||
|
Based on Loop() from GoodStuff:
|
||
|
Copyright 1993, Robert Nation.
|
||
|
************************************************************************/
|
||
|
void Loop(void)
|
||
|
{
|
||
|
Window root;
|
||
|
struct icon_info *tmp, *exhilite;
|
||
|
int x,y,border_width,depth;
|
||
|
int i, hr = icon_relief/2;
|
||
|
XEvent Event;
|
||
|
int tw,th;
|
||
|
int diffx, diffy;
|
||
|
int oldw, oldh;
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
if(My_XNextEvent(dpy,&Event))
|
||
|
{
|
||
|
switch(Event.type)
|
||
|
{
|
||
|
case Expose:
|
||
|
if(Event.xexpose.count == 0){
|
||
|
if (Event.xany.window == main_win){
|
||
|
RedrawWindow();
|
||
|
}else{
|
||
|
tmp = Head;
|
||
|
while(tmp != NULL){
|
||
|
if (Event.xany.window == tmp->icon_pixmap_w){
|
||
|
RedrawIcon(tmp, 1);
|
||
|
break;
|
||
|
}else if(Event.xany.window == tmp->IconWin){
|
||
|
RedrawIcon(tmp, 2);
|
||
|
break;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ConfigureNotify:
|
||
|
XGetGeometry(dpy,main_win,&root,&x,&y,
|
||
|
(unsigned int *)&tw,(unsigned int *)&th,
|
||
|
(unsigned int *)&border_width,
|
||
|
(unsigned int *)&depth);
|
||
|
if (ready && (tw != main_width || th != main_height)){
|
||
|
main_width = tw;
|
||
|
main_height= th;
|
||
|
oldw = Width;
|
||
|
oldh = Height;
|
||
|
num_columns = (tw - h_margin - interval + 1) / UWidth;
|
||
|
num_rows = (th - v_margin - interval + 1) / UHeight;
|
||
|
Width = UWidth * num_columns + interval - 1;
|
||
|
Height = UHeight * num_rows + interval -1;
|
||
|
XMoveResizeWindow(dpy, holder_win, margin1+2,
|
||
|
margin1+2,
|
||
|
tw - h_margin, th - v_margin);
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
XResizeWindow(dpy, h_scroll_bar,
|
||
|
Width - bar_width*2, bar_width);
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
XResizeWindow(dpy ,v_scroll_bar,
|
||
|
bar_width, Height - bar_width*2);
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
if (primary == BOTTOM || secondary == BOTTOM)
|
||
|
icon_win_y -= Height - oldh;
|
||
|
if (primary == RIGHT || secondary == RIGHT)
|
||
|
icon_win_x -= Width - oldw;
|
||
|
if (icon_win_x < 0)
|
||
|
icon_win_x = 0;
|
||
|
if (icon_win_y < 0)
|
||
|
icon_win_y = 0;
|
||
|
if (icon_win_x + Width > icon_win_width)
|
||
|
icon_win_x = icon_win_width - Width;
|
||
|
if (icon_win_y + Height > icon_win_height)
|
||
|
icon_win_y = icon_win_height - Height;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x,
|
||
|
-icon_win_y, icon_win_width,
|
||
|
icon_win_height);
|
||
|
AdjustIconWindows();
|
||
|
XClearWindow(dpy,main_win);
|
||
|
RedrawWindow();
|
||
|
}
|
||
|
break;
|
||
|
case KeyPress:
|
||
|
ExecuteKey(Event);
|
||
|
break;
|
||
|
case ButtonPress:
|
||
|
if (!(local_flags & HIDE_H)){
|
||
|
if (Event.xbutton.window == h_scroll_bar)
|
||
|
motion = HORIZONTAL;
|
||
|
else if (Event.xbutton.window == l_button){
|
||
|
Pressed = l_button;
|
||
|
RedrawLeftButton(ShadowGC, ReliefGC);
|
||
|
}
|
||
|
else if (Event.xbutton.window == r_button){
|
||
|
Pressed = r_button;
|
||
|
RedrawRightButton(ShadowGC, ReliefGC);
|
||
|
}
|
||
|
}
|
||
|
if (!(local_flags & HIDE_V)){
|
||
|
if (Event.xbutton.window == v_scroll_bar)
|
||
|
motion = VERTICAL;
|
||
|
else if (Event.xbutton.window == t_button){
|
||
|
Pressed = t_button;
|
||
|
RedrawTopButton(ShadowGC, ReliefGC);
|
||
|
}
|
||
|
else if (Event.xbutton.window == b_button){
|
||
|
Pressed = b_button;
|
||
|
RedrawBottomButton(ShadowGC, ReliefGC);
|
||
|
}
|
||
|
}
|
||
|
if ((tmp = Search(Event.xbutton.window)) != NULL)
|
||
|
ExecuteAction(Event.xbutton.x, Event.xbutton.y, tmp);
|
||
|
break;
|
||
|
|
||
|
case ButtonRelease:
|
||
|
if (!(local_flags & HIDE_H)){
|
||
|
if (Event.xbutton.window == h_scroll_bar && motion ==
|
||
|
HORIZONTAL)
|
||
|
HScroll(Event.xbutton.x * icon_win_width / Width);
|
||
|
else if (Event.xbutton.window == l_button && Pressed ==
|
||
|
l_button){
|
||
|
Pressed = None;
|
||
|
RedrawLeftButton(ReliefGC, ShadowGC);
|
||
|
HScroll(icon_win_x - UWidth);
|
||
|
}
|
||
|
else if (Event.xbutton.window == r_button && Pressed ==
|
||
|
r_button){
|
||
|
Pressed = None;
|
||
|
RedrawRightButton(ReliefGC, ShadowGC);
|
||
|
HScroll(icon_win_x + UWidth);
|
||
|
}
|
||
|
}
|
||
|
if (!(local_flags & HIDE_V)){
|
||
|
if (Event.xbutton.window == v_scroll_bar && motion
|
||
|
== VERTICAL)
|
||
|
VScroll(Event.xbutton.y * icon_win_height / Height);
|
||
|
else if (Event.xbutton.window == t_button && Pressed ==
|
||
|
t_button){
|
||
|
Pressed = None;
|
||
|
RedrawTopButton(ReliefGC, ShadowGC);
|
||
|
VScroll(icon_win_y - UHeight);
|
||
|
}
|
||
|
else if (Event.xbutton.window == b_button && Pressed ==
|
||
|
b_button){
|
||
|
Pressed = None;
|
||
|
RedrawBottomButton(ReliefGC, ShadowGC);
|
||
|
VScroll(icon_win_y + UHeight);
|
||
|
}
|
||
|
}
|
||
|
motion = NONE;
|
||
|
break;
|
||
|
|
||
|
case MotionNotify:
|
||
|
if (motion == VERTICAL){
|
||
|
VScroll(Event.xbutton.y * icon_win_height / Height);
|
||
|
}else if (motion == HORIZONTAL){
|
||
|
HScroll(Event.xbutton.x * icon_win_width / Width);
|
||
|
}
|
||
|
break;
|
||
|
case EnterNotify:
|
||
|
if ((tmp = Search(Event.xcrossing.window)) != NULL)
|
||
|
if ((exhilite = Hilite) != tmp){
|
||
|
Hilite = tmp;
|
||
|
if (exhilite != NULL)
|
||
|
RedrawIcon(exhilite, redraw_flag);
|
||
|
RedrawIcon(tmp, redraw_flag);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LeaveNotify:
|
||
|
if ((tmp = Search(Event.xcrossing.window)) != NULL &&
|
||
|
tmp == Hilite){
|
||
|
Hilite = NULL;
|
||
|
RedrawIcon(tmp, redraw_flag);
|
||
|
}
|
||
|
if (!(local_flags & HIDE_H) && Event.xbutton.window ==
|
||
|
l_button && Pressed == l_button){
|
||
|
Pressed = None;
|
||
|
RedrawLeftButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
else if (!(local_flags & HIDE_H) && Event.xbutton.window ==
|
||
|
r_button && Pressed == r_button){
|
||
|
Pressed = None;
|
||
|
RedrawRightButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
else if (!(local_flags & HIDE_V) && Event.xbutton.window ==
|
||
|
t_button && Pressed == t_button){
|
||
|
Pressed = None;
|
||
|
RedrawTopButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
else if (!(local_flags & HIDE_V) && Event.xbutton.window ==
|
||
|
b_button && Pressed == b_button){
|
||
|
Pressed = None;
|
||
|
RedrawBottomButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
break;
|
||
|
case ClientMessage:
|
||
|
if ((Event.xclient.format==32) &&
|
||
|
(Event.xclient.data.l[0]==wm_del_win))
|
||
|
DeadPipe(1);
|
||
|
break;
|
||
|
case PropertyNotify:
|
||
|
switch (Event.xproperty.atom){
|
||
|
case XA_WM_HINTS:
|
||
|
if (Event.xproperty.state == PropertyDelete)
|
||
|
break;
|
||
|
tmp = Head;
|
||
|
i=0;
|
||
|
while(tmp != NULL){
|
||
|
if (Event.xproperty.window == tmp->id)
|
||
|
break;
|
||
|
tmp = tmp->next;
|
||
|
++i;
|
||
|
}
|
||
|
if (tmp == NULL || tmp->wmhints == NULL || !(tmp->extra_flags & DEFAULTICON))
|
||
|
break;
|
||
|
if (tmp->wmhints)
|
||
|
XFree (tmp->wmhints);
|
||
|
tmp->wmhints = XGetWMHints(dpy, tmp->id);
|
||
|
if (tmp->wmhints && (tmp->wmhints->flags & IconPixmapHint)){
|
||
|
#ifdef SHAPE
|
||
|
/* turn off "old" shape mask */
|
||
|
if (tmp->icon_maskPixmap != None)
|
||
|
XShapeCombineMask(dpy, tmp->icon_pixmap_w,
|
||
|
ShapeBounding, 0, 0, None, ShapeSet);
|
||
|
#endif
|
||
|
if (tmp->iconPixmap != None)
|
||
|
XFreePixmap(dpy, tmp->iconPixmap);
|
||
|
GetIconBitmap(tmp);
|
||
|
#ifdef SHAPE
|
||
|
if (tmp->icon_maskPixmap != None)
|
||
|
XShapeCombineMask(dpy, tmp->icon_pixmap_w,
|
||
|
ShapeBounding, hr, hr,
|
||
|
tmp->icon_maskPixmap, ShapeSet);
|
||
|
#endif
|
||
|
AdjustIconWindow(tmp, i);
|
||
|
if (max_icon_height != 0)
|
||
|
RedrawIcon(tmp, 1);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void HScroll(int x)
|
||
|
{
|
||
|
int oldx = icon_win_x;
|
||
|
|
||
|
if (x + Width > icon_win_width)
|
||
|
x = icon_win_width - Width;
|
||
|
if (x < 0)
|
||
|
x = 0;
|
||
|
if (oldx != x){
|
||
|
icon_win_x = x;
|
||
|
XMoveWindow(dpy,icon_win, -icon_win_x, -icon_win_y);
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
RedrawHScrollbar();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void VScroll(int y)
|
||
|
{
|
||
|
int oldy = icon_win_y;
|
||
|
|
||
|
if (y + Height > icon_win_height)
|
||
|
y = icon_win_height - Height;
|
||
|
if (y < 0)
|
||
|
y = 0;
|
||
|
if (oldy != y){
|
||
|
icon_win_y = y;
|
||
|
XMoveWindow(dpy,icon_win, -icon_win_x, -icon_win_y);
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
RedrawVScrollbar();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct icon_info *Search(Window w)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
|
||
|
tmp = Head;
|
||
|
while (tmp != NULL){
|
||
|
if (tmp->IconWin == w || tmp->icon_pixmap_w == w)
|
||
|
return tmp;
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
*
|
||
|
* Draw the window
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
void RedrawWindow(void)
|
||
|
{
|
||
|
XEvent dummy;
|
||
|
|
||
|
while (XCheckTypedWindowEvent (dpy, main_win, Expose, &dummy));
|
||
|
|
||
|
RelieveWindow(main_win, margin1, margin1, Width + 4,
|
||
|
Height + 4, ShadowGC,ReliefGC);
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
RelieveWindow(main_win, margin1, margin1 + 4 + Height + margin2,
|
||
|
Width + 4, bar_width+4, ShadowGC,ReliefGC);
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
RelieveWindow(main_win, margin1 + 4 + Width + margin2, margin1,
|
||
|
bar_width+4, Height + 4, ShadowGC,ReliefGC);
|
||
|
RelieveWindow(main_win, 0, 0, Width + h_margin, Height + v_margin,
|
||
|
ReliefGC, ShadowGC);
|
||
|
|
||
|
/* scroll bar */
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
RedrawHScrollbar();
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
RedrawVScrollbar();
|
||
|
|
||
|
/* buttons */
|
||
|
if (!(local_flags & HIDE_H)){
|
||
|
RedrawLeftButton(ReliefGC, ShadowGC);
|
||
|
RedrawRightButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
if (!(local_flags & HIDE_V)){
|
||
|
RedrawTopButton(ReliefGC, ShadowGC);
|
||
|
RedrawBottomButton(ReliefGC, ShadowGC);
|
||
|
}
|
||
|
|
||
|
/* icons */
|
||
|
RedrawIcons();
|
||
|
}
|
||
|
|
||
|
void RedrawIcons(void)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
|
||
|
tmp = Head;
|
||
|
while(tmp != NULL){
|
||
|
if (desk_cond(tmp))
|
||
|
RedrawIcon(tmp, redraw_flag);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void RedrawIcon(struct icon_info *item, int f)
|
||
|
{
|
||
|
unsigned long plane = 1;
|
||
|
int hr, len;
|
||
|
int diff, lm ,w, h, tw;
|
||
|
char label[256];
|
||
|
|
||
|
hr = icon_relief/2;
|
||
|
|
||
|
if (Hilite == item){
|
||
|
XSetForeground(dpy, NormalGC, act_icon_fore_pix);
|
||
|
XSetBackground(dpy, NormalGC, act_icon_back_pix);
|
||
|
XSetForeground(dpy, IconReliefGC, act_icon_hilite_pix);
|
||
|
XSetForeground(dpy, IconShadowGC, act_icon_shadow_pix);
|
||
|
|
||
|
if (max_icon_height != 0 && (item->flags & ICON_OURS))
|
||
|
XSetWindowBackground(dpy, item->icon_pixmap_w, act_icon_back_pix);
|
||
|
XSetWindowBackground(dpy, item->IconWin, act_icon_back_pix);
|
||
|
}
|
||
|
|
||
|
/* icon pixmap */
|
||
|
if ((f & 1) && (item->flags & ICON_OURS)){
|
||
|
if (item->iconPixmap != None && item->icon_pixmap_w != None){
|
||
|
if (item->icon_depth != d_depth)
|
||
|
XCopyPlane(dpy, item->iconPixmap, item->icon_pixmap_w, NormalGC,
|
||
|
0, 0, item->icon_w, item->icon_h,
|
||
|
hr, hr, plane);
|
||
|
else
|
||
|
XCopyArea(dpy, item->iconPixmap, item->icon_pixmap_w, NormalGC,
|
||
|
0, 0, item->icon_w, item->icon_h, hr, hr);
|
||
|
}
|
||
|
if (!(item->flags & SHAPED_ICON)){
|
||
|
if (item->icon_w > 0 && item->icon_h > 0)
|
||
|
RelieveWindow(item->icon_pixmap_w, 0, 0, item->icon_w
|
||
|
+icon_relief,
|
||
|
item->icon_h + icon_relief, IconReliefGC,
|
||
|
IconShadowGC);
|
||
|
else
|
||
|
RelieveWindow(item->icon_pixmap_w, 0, 0, max_icon_width
|
||
|
+icon_relief,
|
||
|
max_icon_height + icon_relief, IconReliefGC,
|
||
|
IconShadowGC);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* label */
|
||
|
if (f & 2){
|
||
|
w = max_icon_width + icon_relief;
|
||
|
h = max_icon_height + icon_relief;
|
||
|
|
||
|
if (item->flags & ICONIFIED){
|
||
|
sprintf(label, "(%s)", item->name);
|
||
|
}else
|
||
|
strcpy(label, item->name);
|
||
|
|
||
|
len = strlen(label);
|
||
|
tw = XTextWidth(font, label, len);
|
||
|
diff = max_icon_width + icon_relief - tw;
|
||
|
lm = diff/2;
|
||
|
lm = lm > 4 ? lm : 4;
|
||
|
|
||
|
if (Hilite == item){
|
||
|
XRaiseWindow(dpy, item->IconWin);
|
||
|
XMoveResizeWindow(dpy, item->IconWin,
|
||
|
item->x + min(0, (diff - 8))/2,
|
||
|
item->y + h,
|
||
|
max(tw + 8, w), 6 + font->ascent +
|
||
|
font->descent);
|
||
|
XClearWindow(dpy, item->IconWin);
|
||
|
XDrawString(dpy, item->IconWin, NormalGC, lm, 3 + font->ascent,
|
||
|
label, len);
|
||
|
RelieveWindow(item->IconWin, 0, 0,
|
||
|
max(tw + 8, w), 6 + font->ascent +
|
||
|
font->descent, IconReliefGC, IconShadowGC);
|
||
|
}else{
|
||
|
XMoveResizeWindow(dpy, item->IconWin, item->x, item->y + h,
|
||
|
w, 6 + font->ascent + font->descent);
|
||
|
XClearWindow(dpy, item->IconWin);
|
||
|
XDrawString(dpy, item->IconWin, NormalGC, lm, 3 + font->ascent,
|
||
|
label, len);
|
||
|
RelieveWindow(item->IconWin, 0, 0,
|
||
|
w, 6 + font->ascent + font->descent,
|
||
|
IconReliefGC, IconShadowGC);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Hilite == item){
|
||
|
XSetForeground(dpy, NormalGC, icon_fore_pix);
|
||
|
XSetBackground(dpy, NormalGC, icon_back_pix);
|
||
|
XSetForeground(dpy, IconReliefGC, icon_hilite_pix);
|
||
|
XSetForeground(dpy, IconShadowGC, icon_shadow_pix);
|
||
|
|
||
|
if (max_icon_height != 0 && (item->flags & ICON_OURS))
|
||
|
XSetWindowBackground(dpy, item->icon_pixmap_w, icon_back_pix);
|
||
|
XSetWindowBackground(dpy, item->IconWin, icon_back_pix);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* RedrawHScrollbar
|
||
|
* Based on part of Loop() of GrabWindow.c in FvwmScroll:
|
||
|
* Copyright 1994, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void RedrawHScrollbar(void)
|
||
|
{
|
||
|
int x,width;
|
||
|
|
||
|
x = (Width - bar_width*2) * icon_win_x / icon_win_width;
|
||
|
width = (Width - bar_width*2) * Width / icon_win_width;
|
||
|
XClearArea(dpy, h_scroll_bar, 0, 0, Width, bar_width,False);
|
||
|
RelieveWindow(h_scroll_bar, x, 0, width, bar_width, ReliefGC, ShadowGC);
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* RedrawVScrollbar
|
||
|
* Based on part of Loop() of GrabWindow.c in FvwmScroll:
|
||
|
* Copyright 1994, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void RedrawVScrollbar(void)
|
||
|
{
|
||
|
int y, height;
|
||
|
|
||
|
y = (Height - bar_width*2) * icon_win_y / icon_win_height;
|
||
|
height = (Height - bar_width*2)* Height / icon_win_height;
|
||
|
XClearArea(dpy, v_scroll_bar, 0, 0, bar_width, Height,False);
|
||
|
RelieveWindow(v_scroll_bar, 0, y, bar_width, height, ReliefGC, ShadowGC);
|
||
|
}
|
||
|
|
||
|
void RedrawLeftButton(GC rgc, GC sgc)
|
||
|
{
|
||
|
XSegment seg[4];
|
||
|
int i=0;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = bar_width/2;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = 1;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = bar_width/2;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = 0;
|
||
|
XDrawSegments(dpy, l_button, rgc, seg, i);
|
||
|
|
||
|
i = 0;
|
||
|
seg[i].x1 = 1; seg[i].y1 = bar_width/2;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = bar_width/2;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1;
|
||
|
|
||
|
seg[i].x1 = bar_width - 2; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = bar_width - 1; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1;
|
||
|
XDrawSegments(dpy, l_button, sgc, seg, i);
|
||
|
}
|
||
|
|
||
|
void RedrawRightButton(GC rgc, GC sgc)
|
||
|
{
|
||
|
XSegment seg[4];
|
||
|
int i=0;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = 1;
|
||
|
seg[i].x2 = 1; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = 0;
|
||
|
seg[i].x2 = 0; seg[i++].y2 = bar_width - 1;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width/2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width/2;
|
||
|
|
||
|
XDrawSegments(dpy, r_button, rgc, seg, i);
|
||
|
|
||
|
i = 0;
|
||
|
seg[i].x1 = 1; seg[i].y1 = bar_width - 2;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width/2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = bar_width - 1;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width/2;
|
||
|
XDrawSegments(dpy, r_button, sgc, seg, i);
|
||
|
}
|
||
|
|
||
|
void RedrawTopButton(GC rgc, GC sgc)
|
||
|
{
|
||
|
XSegment seg[4];
|
||
|
int i=0;
|
||
|
|
||
|
seg[i].x1 = bar_width/2; seg[i].y1 = 1;
|
||
|
seg[i].x2 = 1; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = bar_width/2; seg[i].y1 = 0;
|
||
|
seg[i].x2 = 0; seg[i++].y2 = bar_width - 1;
|
||
|
XDrawSegments(dpy, t_button, rgc, seg, i);
|
||
|
|
||
|
i = 0;
|
||
|
seg[i].x1 = bar_width/2; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = bar_width/2; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = bar_width - 2;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = bar_width - 1;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = bar_width - 1;
|
||
|
XDrawSegments(dpy, t_button, sgc, seg, i);
|
||
|
}
|
||
|
|
||
|
void RedrawBottomButton(GC rgc, GC sgc)
|
||
|
{
|
||
|
XSegment seg[4];
|
||
|
int i=0;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 1;
|
||
|
|
||
|
seg[i].x1 = 1; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width - 2; seg[i++].y2 = 1;
|
||
|
|
||
|
seg[i].x1 = 0; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width - 1; seg[i++].y2 = 0;
|
||
|
XDrawSegments(dpy, b_button, rgc, seg, i);
|
||
|
|
||
|
i = 0;
|
||
|
seg[i].x1 = bar_width - 2; seg[i].y1 = 1;
|
||
|
seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 2;
|
||
|
|
||
|
seg[i].x1 = bar_width - 1; seg[i].y1 = 0;
|
||
|
seg[i].x2 = bar_width/2; seg[i++].y2 = bar_width - 1;
|
||
|
XDrawSegments(dpy, b_button, sgc, seg, i);
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
RelieveWindow
|
||
|
Original work from GoodStuff:
|
||
|
Copyright 1993, Robert Nation.
|
||
|
************************************************************************/
|
||
|
void RelieveWindow(Window win,int x,int y,int w,int h, GC rgc,GC sgc)
|
||
|
{
|
||
|
XSegment seg[4];
|
||
|
int i;
|
||
|
|
||
|
i=0;
|
||
|
seg[i].x1 = x; seg[i].y1 = y;
|
||
|
seg[i].x2 = w+x-1; seg[i++].y2 = y;
|
||
|
|
||
|
seg[i].x1 = x; seg[i].y1 = y;
|
||
|
seg[i].x2 = x; seg[i++].y2 = h+y-1;
|
||
|
|
||
|
seg[i].x1 = x+1; seg[i].y1 = y+1;
|
||
|
seg[i].x2 = x+w-2; seg[i++].y2 = y+1;
|
||
|
|
||
|
seg[i].x1 = x+1; seg[i].y1 = y+1;
|
||
|
seg[i].x2 = x+1; seg[i++].y2 = y+h-2;
|
||
|
XDrawSegments(dpy, win, rgc, seg, i);
|
||
|
|
||
|
i=0;
|
||
|
seg[i].x1 = x; seg[i].y1 = y+h-1;
|
||
|
seg[i].x2 = w+x-1; seg[i++].y2 = y+h-1;
|
||
|
|
||
|
seg[i].x1 = x+w-1; seg[i].y1 = y;
|
||
|
seg[i].x2 = x+w-1; seg[i++].y2 = y+h-1;
|
||
|
if(d_depth<2)
|
||
|
XDrawSegments(dpy, win, ShadowGC, seg, i);
|
||
|
else
|
||
|
XDrawSegments(dpy, win, sgc, seg, i);
|
||
|
|
||
|
i=0;
|
||
|
seg[i].x1 = x+1; seg[i].y1 = y+h-2;
|
||
|
seg[i].x2 = x+w-2; seg[i++].y2 = y+h-2;
|
||
|
|
||
|
seg[i].x1 = x+w-2; seg[i].y1 = y+1;
|
||
|
seg[i].x2 = x+w-2; seg[i++].y2 = y+h-2;
|
||
|
|
||
|
XDrawSegments(dpy, win, sgc, seg, i);
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* CreateWindow --Sizes and creates the window
|
||
|
* Based on CreateWindow() from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void CreateWindow(void)
|
||
|
{
|
||
|
XGCValues gcv;
|
||
|
unsigned long gcm;
|
||
|
unsigned long mask;
|
||
|
char *list[2];
|
||
|
XSetWindowAttributes attributes;
|
||
|
XSizeHints mysizehints;
|
||
|
XTextProperty name;
|
||
|
XClassHint class_hints;
|
||
|
|
||
|
h_margin = margin1*2 + bar_width + margin2 + 8;
|
||
|
v_margin = margin1*2 + bar_width + margin2 + 8;
|
||
|
|
||
|
wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False);
|
||
|
_XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
|
||
|
|
||
|
/* load the font */
|
||
|
if ((font = XLoadQueryFont(dpy, font_string)) == NULL)
|
||
|
{
|
||
|
if ((font = XLoadQueryFont(dpy, "fixed")) == NULL)
|
||
|
{
|
||
|
fprintf(stderr,"%s: No fonts available\n",MyName);
|
||
|
exit(1);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if ((local_flags & HIDE_H))
|
||
|
v_margin -= bar_width + margin2 + 4;
|
||
|
if ((local_flags & HIDE_V))
|
||
|
h_margin -= bar_width + margin2 + 4;
|
||
|
|
||
|
UWidth = max_icon_width + icon_relief + interval;
|
||
|
UHeight = font->ascent + font->descent + max_icon_height +
|
||
|
icon_relief + 6 + interval;
|
||
|
Width = UWidth * num_columns + interval -1;
|
||
|
Height = UHeight * num_rows + interval -1;
|
||
|
|
||
|
mysizehints.flags = PWinGravity| PResizeInc | PMinSize;
|
||
|
|
||
|
/* subtract one for the right/bottom border */
|
||
|
mysizehints.min_width = UWidth + interval - 1 + h_margin;
|
||
|
main_width = mysizehints.width = Width + h_margin;
|
||
|
mysizehints.min_height = UHeight + interval - 1 + v_margin;
|
||
|
main_height = mysizehints.height = Height + v_margin;
|
||
|
mysizehints.width_inc = UWidth;
|
||
|
mysizehints.height_inc = UHeight;
|
||
|
|
||
|
if(x > -100000)
|
||
|
{
|
||
|
if (xneg)
|
||
|
{
|
||
|
mysizehints.x = DisplayWidth(dpy,screen) + x - mysizehints.width;
|
||
|
gravity = NorthEastGravity;
|
||
|
}
|
||
|
else
|
||
|
mysizehints.x = x;
|
||
|
if (yneg)
|
||
|
{
|
||
|
mysizehints.y = DisplayHeight(dpy,screen) + y - mysizehints.height;
|
||
|
gravity = SouthWestGravity;
|
||
|
}
|
||
|
else
|
||
|
mysizehints.y = y;
|
||
|
|
||
|
if((xneg) && (yneg))
|
||
|
gravity = SouthEastGravity;
|
||
|
|
||
|
mysizehints.flags |= USPosition;
|
||
|
}
|
||
|
|
||
|
mysizehints.win_gravity = gravity;
|
||
|
|
||
|
if(d_depth < 2)
|
||
|
{
|
||
|
back_pix = icon_back_pix = act_icon_fore_pix = GetColor("white");
|
||
|
fore_pix = icon_fore_pix = act_icon_back_pix = GetColor("black");
|
||
|
hilite_pix = icon_hilite_pix = act_icon_shadow_pix = icon_back_pix;
|
||
|
shadow_pix = icon_shadow_pix = act_icon_hilite_pix = icon_fore_pix;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fore_pix = GetColor(Fore);
|
||
|
back_pix = GetColor(Back);
|
||
|
icon_back_pix = GetColor(IconBack);
|
||
|
icon_fore_pix = GetColor(IconFore);
|
||
|
icon_hilite_pix = GetHilite(icon_back_pix);
|
||
|
icon_shadow_pix = GetShadow(icon_back_pix);
|
||
|
act_icon_back_pix = GetColor(ActIconBack);
|
||
|
act_icon_fore_pix = GetColor(ActIconFore);
|
||
|
act_icon_hilite_pix = GetHilite(act_icon_back_pix);
|
||
|
act_icon_shadow_pix = GetShadow(act_icon_back_pix);
|
||
|
hilite_pix = GetHilite(back_pix);
|
||
|
shadow_pix = GetShadow(back_pix);
|
||
|
}
|
||
|
|
||
|
main_win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y,
|
||
|
mysizehints.width,mysizehints.height,
|
||
|
0,fore_pix,back_pix);
|
||
|
XSetWMProtocols(dpy,main_win,&wm_del_win,1);
|
||
|
XSelectInput(dpy,main_win,MW_EVENTS);
|
||
|
|
||
|
/* set normal_hits, wm_hints, and, class_hints */
|
||
|
list[0]=MyName;
|
||
|
list[1]=NULL;
|
||
|
if (XStringListToTextProperty(list,1,&name) == 0)
|
||
|
{
|
||
|
fprintf(stderr,"%s: cannot allocate window name",MyName);
|
||
|
return;
|
||
|
}
|
||
|
class_hints.res_name = MyName;
|
||
|
class_hints.res_class = "FvwmIconBox";
|
||
|
XSetWMProperties(dpy,main_win,&name,&name,
|
||
|
NULL,0,&mysizehints,NULL,&class_hints);
|
||
|
XFree(name.value);
|
||
|
|
||
|
mysizehints.width -= h_margin;
|
||
|
mysizehints.height -= v_margin;
|
||
|
holder_win = XCreateSimpleWindow(dpy,main_win,margin1+2,
|
||
|
margin1+2,
|
||
|
mysizehints.width,
|
||
|
mysizehints.height,
|
||
|
0,fore_pix,back_pix);
|
||
|
|
||
|
icon_win = XCreateSimpleWindow(dpy,holder_win,-icon_win_x,-icon_win_y,
|
||
|
icon_win_width,
|
||
|
icon_win_height,
|
||
|
0,fore_pix,back_pix);
|
||
|
|
||
|
gcm = GCForeground|GCBackground;
|
||
|
gcv.foreground = hilite_pix;
|
||
|
gcv.background = back_pix;
|
||
|
ReliefGC = XCreateGC(dpy, Root, gcm, &gcv);
|
||
|
|
||
|
gcm = GCForeground|GCBackground;
|
||
|
gcv.foreground = shadow_pix;
|
||
|
gcv.background = back_pix;
|
||
|
ShadowGC = XCreateGC(dpy, Root, gcm, &gcv);
|
||
|
|
||
|
gcm = GCForeground|GCBackground;
|
||
|
gcv.foreground = icon_hilite_pix;
|
||
|
gcv.background = icon_back_pix;
|
||
|
IconReliefGC = XCreateGC(dpy, Root, gcm, &gcv);
|
||
|
|
||
|
gcm = GCForeground|GCBackground;
|
||
|
gcv.foreground = icon_shadow_pix;
|
||
|
gcv.background = icon_back_pix;
|
||
|
IconShadowGC = XCreateGC(dpy, Root, gcm, &gcv);
|
||
|
|
||
|
gcm = GCForeground|GCBackground|GCFont;
|
||
|
gcv.foreground = fore_pix;
|
||
|
gcv.background = back_pix;
|
||
|
gcv.font = font->fid;
|
||
|
NormalGC = XCreateGC(dpy, Root, gcm, &gcv);
|
||
|
|
||
|
|
||
|
/* icon_win's background */
|
||
|
if (GetBackPixmap() == True){
|
||
|
XSetWindowBackgroundPixmap(dpy, icon_win, IconwinPixmap);
|
||
|
/* special thanks to Dave Goldberg <dsg@mitre.org>
|
||
|
for his helpful information */
|
||
|
XFreePixmap(dpy, IconwinPixmap);
|
||
|
}
|
||
|
|
||
|
XSetForeground(dpy, NormalGC, icon_fore_pix);
|
||
|
XSetBackground(dpy, NormalGC, icon_back_pix);
|
||
|
|
||
|
/* scroll bars */
|
||
|
mask = CWWinGravity | CWBackPixel;
|
||
|
attributes.background_pixel = back_pix;
|
||
|
if (!(local_flags & HIDE_H)){
|
||
|
attributes.win_gravity = SouthWestGravity;
|
||
|
h_scroll_bar = XCreateWindow(dpy ,main_win, margin1 + 2 +
|
||
|
bar_width,
|
||
|
margin1 + 6 + Height + margin2,
|
||
|
Width - bar_width*2, bar_width,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
XSelectInput(dpy,h_scroll_bar,SCROLL_EVENTS);
|
||
|
}
|
||
|
if (!(local_flags & HIDE_V)){
|
||
|
attributes.win_gravity = NorthEastGravity;
|
||
|
v_scroll_bar = XCreateWindow(dpy ,main_win, margin1 + 6 +
|
||
|
Width + margin2,
|
||
|
margin1 + 2 + bar_width,
|
||
|
bar_width, Height - bar_width*2,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
XSelectInput(dpy,v_scroll_bar,SCROLL_EVENTS);
|
||
|
}
|
||
|
|
||
|
/* buttons */
|
||
|
if (!(local_flags & HIDE_H)){
|
||
|
attributes.win_gravity = SouthWestGravity;
|
||
|
l_button = XCreateWindow(dpy, main_win, margin1 + 2,
|
||
|
margin1 + 6 + Height + margin2,
|
||
|
bar_width, bar_width,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
attributes.win_gravity = SouthEastGravity;
|
||
|
r_button = XCreateWindow(dpy, main_win, margin1 + 2 + Width -
|
||
|
bar_width,
|
||
|
margin1 + 6 + Height + margin2,
|
||
|
bar_width, bar_width,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
XSelectInput(dpy,l_button,BUTTON_EVENTS);
|
||
|
XSelectInput(dpy,r_button,BUTTON_EVENTS);
|
||
|
}
|
||
|
if (!(local_flags & HIDE_V)){
|
||
|
attributes.win_gravity = NorthEastGravity;
|
||
|
t_button = XCreateWindow(dpy, main_win, margin1 + 6 +
|
||
|
Width + margin2, margin1 + 2,
|
||
|
bar_width, bar_width,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
attributes.win_gravity = SouthEastGravity;
|
||
|
b_button = XCreateWindow(dpy, main_win, margin1 + 6 +
|
||
|
Width + margin2,
|
||
|
margin1 + 2 + Height - bar_width,
|
||
|
bar_width, bar_width,
|
||
|
0, CopyFromParent,
|
||
|
InputOutput, CopyFromParent,
|
||
|
mask, &attributes);
|
||
|
XSelectInput(dpy,t_button,BUTTON_EVENTS);
|
||
|
XSelectInput(dpy,b_button,BUTTON_EVENTS);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void GetIconwinSize(int *dx, int *dy)
|
||
|
{
|
||
|
*dx = icon_win_width;
|
||
|
*dy = icon_win_height;
|
||
|
|
||
|
if (primary == LEFT || primary == RIGHT){
|
||
|
icon_win_width = max(Width, UWidth * Lines + interval - 1);
|
||
|
icon_win_height = max(Height, UHeight * (max(0,
|
||
|
(num_icons-1))/Lines
|
||
|
+ 1) - 1 + interval);
|
||
|
}else{
|
||
|
icon_win_width = max(Width, UWidth * (max(0,num_icons-1) / Lines +
|
||
|
1) + interval - 1);
|
||
|
icon_win_height = max(Height, UHeight * Lines - 1 + interval);
|
||
|
}
|
||
|
*dx = icon_win_width - *dx;
|
||
|
*dy = icon_win_height - *dy;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* nocolor
|
||
|
* Original work from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void nocolor(char *a, char *b)
|
||
|
{
|
||
|
fprintf(stderr,"%s: can't %s %s\n", MyName, a,b);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
* GetColor
|
||
|
* Original work from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
Pixel GetColor(char *name)
|
||
|
{
|
||
|
XColor color;
|
||
|
XWindowAttributes attributes;
|
||
|
|
||
|
XGetWindowAttributes(dpy,Root,&attributes);
|
||
|
color.pixel = 0;
|
||
|
if (!XParseColor (dpy, attributes.colormap, name, &color))
|
||
|
{
|
||
|
nocolor("parse",name);
|
||
|
}
|
||
|
else if(!XAllocColor (dpy, attributes.colormap, &color))
|
||
|
{
|
||
|
nocolor("alloc",name);
|
||
|
}
|
||
|
return color.pixel;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
SendFvwmPipe - Send a message back to fvwm
|
||
|
Original work from FvwmWinList:
|
||
|
Copyright 1994, Mike Finger.
|
||
|
************************************************************************/
|
||
|
void SendFvwmPipe(int *fd, char *message,unsigned long window)
|
||
|
{
|
||
|
int w;
|
||
|
char *hold,*temp,*temp_msg;
|
||
|
hold=message;
|
||
|
|
||
|
while(1) {
|
||
|
temp=strchr(hold,',');
|
||
|
if (temp!=NULL) {
|
||
|
temp_msg=malloc(temp-hold+1);
|
||
|
strncpy(temp_msg,hold,(temp-hold));
|
||
|
temp_msg[(temp-hold)]='\0';
|
||
|
hold=temp+1;
|
||
|
} else temp_msg=hold;
|
||
|
|
||
|
if (!ExecIconBoxFunction(temp_msg)){
|
||
|
write(fd[0],&window, sizeof(unsigned long));
|
||
|
|
||
|
w=strlen(temp_msg);
|
||
|
write(fd[0],&w,sizeof(int));
|
||
|
write(fd[0],temp_msg,w);
|
||
|
|
||
|
/* keep going */
|
||
|
w=1;
|
||
|
write(fd[0],&w,sizeof(int));
|
||
|
|
||
|
}
|
||
|
if(temp_msg!=hold) free(temp_msg);
|
||
|
else break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Bool ExecIconBoxFunction(char *msg)
|
||
|
{
|
||
|
if (strncasecmp(msg, "Next", 4) == 0){
|
||
|
Next();
|
||
|
return True;
|
||
|
}else if (strncasecmp(msg, "Prev", 4) == 0){
|
||
|
Prev();
|
||
|
return True;
|
||
|
}else if (strncasecmp(msg, "Left", 4) == 0){
|
||
|
HScroll(icon_win_x - UWidth);
|
||
|
return True;
|
||
|
}else if (strncasecmp(msg, "Right", 5) == 0){
|
||
|
HScroll(icon_win_x + UWidth);
|
||
|
return True;
|
||
|
}else if (strncasecmp(msg, "Up", 2) == 0){
|
||
|
VScroll(icon_win_y - UHeight);
|
||
|
return True;
|
||
|
}else if (strncasecmp(msg, "Down", 4) == 0){
|
||
|
VScroll(icon_win_y + UHeight);
|
||
|
return True;
|
||
|
}
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
void Next(void)
|
||
|
{
|
||
|
struct icon_info *new, *old;
|
||
|
int i;
|
||
|
|
||
|
old = new = Hilite;
|
||
|
|
||
|
if (new != NULL)
|
||
|
new = new->next;
|
||
|
|
||
|
if (new != NULL)
|
||
|
Hilite = new;
|
||
|
else
|
||
|
new = Hilite = Head;
|
||
|
|
||
|
if (new == NULL)
|
||
|
return;
|
||
|
|
||
|
if (old != NULL)
|
||
|
RedrawIcon(old, redraw_flag);
|
||
|
if (new != NULL)
|
||
|
RedrawIcon(new, redraw_flag);
|
||
|
|
||
|
i=0;
|
||
|
if (new->x < icon_win_x){
|
||
|
while (new->x + UWidth * ++i < icon_win_x)
|
||
|
;
|
||
|
HScroll(icon_win_x - UWidth*i);
|
||
|
}else if (new->x > icon_win_x + Width){
|
||
|
while (new->x - UWidth * ++i > icon_win_x + Width)
|
||
|
;
|
||
|
HScroll(icon_win_x + UWidth*i);
|
||
|
}
|
||
|
|
||
|
i=0;
|
||
|
if (new->y < icon_win_y){
|
||
|
while (new->y + UHeight * ++i < icon_win_y)
|
||
|
;
|
||
|
VScroll(icon_win_y - UHeight*i);
|
||
|
}else if (new->y > icon_win_y + Height){
|
||
|
while (new->y - UHeight * ++i > icon_win_y + Height)
|
||
|
;
|
||
|
VScroll(icon_win_y + UHeight*i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Prev(void)
|
||
|
{
|
||
|
struct icon_info *new, *old;
|
||
|
int i;
|
||
|
|
||
|
old = new = Hilite;
|
||
|
|
||
|
if (new != NULL)
|
||
|
new = new->prev;
|
||
|
|
||
|
if (new != NULL)
|
||
|
Hilite = new;
|
||
|
else
|
||
|
new = Hilite = Tail;
|
||
|
|
||
|
if (new == NULL)
|
||
|
return;
|
||
|
|
||
|
if (old != NULL)
|
||
|
RedrawIcon(old, redraw_flag);
|
||
|
if (new != NULL)
|
||
|
RedrawIcon(new, redraw_flag);
|
||
|
|
||
|
i=0;
|
||
|
if (new->x < icon_win_x){
|
||
|
while (new->x + UWidth * ++i < icon_win_x)
|
||
|
;
|
||
|
HScroll(icon_win_x - UWidth*i);
|
||
|
}else if (new->x > icon_win_x + Width){
|
||
|
while (new->x - UWidth * ++i > icon_win_x + Width)
|
||
|
;
|
||
|
HScroll(icon_win_x + UWidth*i);
|
||
|
}
|
||
|
|
||
|
i=0;
|
||
|
if (new->y < icon_win_y){
|
||
|
while (new->y + UHeight * ++i < icon_win_y)
|
||
|
;
|
||
|
VScroll(icon_win_y - UHeight*i);
|
||
|
}else if (new->y > icon_win_y + Height){
|
||
|
while (new->y - UHeight * ++i > icon_win_y + Height)
|
||
|
;
|
||
|
VScroll(icon_win_y + UHeight*i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* DeadPipe --Dead pipe handler
|
||
|
* Based on DeadPipe() from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void DeadPipe(int nonsense)
|
||
|
{
|
||
|
#if 0 /* can't do X or malloc stuff in a signal handler, so just exit */
|
||
|
struct icon_info *tmpi, *tmpi2;
|
||
|
struct mousefunc *tmpm, *tmpm2;
|
||
|
struct keyfunc *tmpk, *tmpk2;
|
||
|
struct iconfile *tmpf, *tmpf2;
|
||
|
|
||
|
if (FvwmDefaultIcon != NULL)
|
||
|
free(FvwmDefaultIcon);
|
||
|
|
||
|
tmpm = MouseActions;
|
||
|
while(tmpm != NULL){
|
||
|
tmpm2 = tmpm;
|
||
|
tmpm = tmpm->next;
|
||
|
free(tmpm2->action);
|
||
|
free(tmpm2);
|
||
|
}
|
||
|
|
||
|
tmpk = KeyActions;
|
||
|
while(tmpk != NULL){
|
||
|
tmpk2 = tmpk;
|
||
|
tmpk = tmpk->next;
|
||
|
free(tmpk2->action);
|
||
|
free(tmpk2->name);
|
||
|
free(tmpk2);
|
||
|
}
|
||
|
|
||
|
tmpf = IconListHead;
|
||
|
while(tmpf != NULL){
|
||
|
tmpf2 = tmpf;
|
||
|
tmpf = tmpf->next;
|
||
|
free(tmpf2->name);
|
||
|
free(tmpf2->iconfile);
|
||
|
free(tmpf2);
|
||
|
}
|
||
|
|
||
|
tmpi = Head;
|
||
|
while(tmpi != NULL){
|
||
|
tmpi2 = tmpi;
|
||
|
tmpi = tmpi->next;
|
||
|
freeitem(tmpi2, 0);
|
||
|
}
|
||
|
if ((local_flags & SETWMICONSIZE))
|
||
|
XDeleteProperty(dpy, Root, XA_WM_ICON_SIZE);
|
||
|
XSync(dpy,0);
|
||
|
#endif /* 0 */
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
* ParseOptions
|
||
|
* Based on ParseConfig() from FvwmWinList:
|
||
|
* Copyright 1994, Mike Finger.
|
||
|
***********************************************************************/
|
||
|
void ParseOptions(void)
|
||
|
{
|
||
|
char *tline= NULL,*tmp;
|
||
|
int Clength;
|
||
|
|
||
|
Clength = strlen(MyName);
|
||
|
|
||
|
GetConfigLine(fd,&tline);
|
||
|
|
||
|
while(tline != NULL)
|
||
|
{
|
||
|
int g_x, g_y, flags;
|
||
|
unsigned width,height;
|
||
|
|
||
|
if(strlen(&tline[0])>1){
|
||
|
if (strncasecmp(tline,CatString3("*", MyName,
|
||
|
"Geometry"),Clength+9)==0){
|
||
|
tmp = &tline[Clength+9];
|
||
|
while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
|
||
|
tmp++;
|
||
|
tmp[strlen(tmp)-1] = 0;
|
||
|
flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height);
|
||
|
if (flags & WidthValue)
|
||
|
num_columns = width;
|
||
|
if (flags & HeightValue)
|
||
|
num_rows = height;
|
||
|
if (flags & XValue)
|
||
|
x = g_x;
|
||
|
if (flags & YValue)
|
||
|
y = g_y;
|
||
|
if (flags & XNegative)
|
||
|
xneg = 1;
|
||
|
if (flags & YNegative)
|
||
|
yneg = 1;
|
||
|
} else if (strncasecmp(tline,CatString3("*", MyName,
|
||
|
"MaxIconSize"),Clength+12)==0){
|
||
|
tmp = &tline[Clength+12];
|
||
|
while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
|
||
|
tmp++;
|
||
|
tmp[strlen(tmp)-1] = 0;
|
||
|
|
||
|
flags = XParseGeometry(tmp,&g_x,&g_y,&width,&height);
|
||
|
if (flags & WidthValue)
|
||
|
max_icon_width = width;
|
||
|
if (flags & HeightValue)
|
||
|
max_icon_height = height;
|
||
|
if (height == 0){
|
||
|
icon_relief = 0;
|
||
|
redraw_flag = 2;
|
||
|
max_icon_width += 4;
|
||
|
}
|
||
|
}else if
|
||
|
(strncasecmp(tline,CatString3("*",MyName,"Font"),Clength+5)==0)
|
||
|
CopyString(&font_string,&tline[Clength+5]);
|
||
|
else if
|
||
|
(strncasecmp(tline,CatString3("*",MyName,"IconFore"),Clength+9)==0)
|
||
|
CopyString(&IconFore,&tline[Clength+9]);
|
||
|
else if
|
||
|
(strncasecmp(tline,CatString3("*",MyName,"IconBack"),Clength+9)==0)
|
||
|
CopyString(&IconBack,&tline[Clength+9]);
|
||
|
else if
|
||
|
(strncasecmp(tline,CatString3("*",MyName,"IconHiFore"),Clength+11)==0)
|
||
|
CopyString(&ActIconFore,&tline[Clength+11]);
|
||
|
else if
|
||
|
(strncasecmp(tline,CatString3("*",MyName,"IconHiBack"),Clength+11)==0)
|
||
|
CopyString(&ActIconBack,&tline[Clength+11]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Fore"),Clength+5)==0)
|
||
|
CopyString(&Fore,&tline[Clength+5]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Back"),Clength+5)==0)
|
||
|
CopyString(&Back,&tline[Clength+5]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Pixmap"),Clength+7)==0)
|
||
|
CopyString(&IconwinPixmapFile,&tline[Clength+7]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Padding"),Clength+8)==0)
|
||
|
interval = max(0,atoi(&tline[Clength+8]));
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"FrameWidth"),Clength+11)==0){
|
||
|
sscanf(&tline[Clength+11], "%d %d", &margin1, &margin2);
|
||
|
margin1 = max(0, margin1);
|
||
|
margin2 = max(0, margin2);
|
||
|
}else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Lines"),Clength+6)==0)
|
||
|
Lines = max(1,atoi(&tline[Clength+6]));
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"SBWidth"),Clength+8)==0)
|
||
|
bar_width = max(5,atoi(&tline[Clength+8]));
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Placement"),Clength+10)==0)
|
||
|
parseplacement(&tline[Clength+10]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"SetWMIconSize"),Clength+14)==0)
|
||
|
local_flags |= SETWMICONSIZE;
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"HilightFocusWin"),Clength+16)==0)
|
||
|
m_mask |= M_FOCUS_CHANGE;
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Resolution"),Clength+11)==0){
|
||
|
tmp = &tline[Clength+11];
|
||
|
while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
|
||
|
tmp++;
|
||
|
if (strncasecmp(tmp, "Desk", 4) == 0){
|
||
|
m_mask |= M_NEW_DESK;
|
||
|
local_flags |= CURRENT_ONLY;
|
||
|
}
|
||
|
}else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Mouse"),Clength+6)==0)
|
||
|
parsemouse(&tline[Clength + 6]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"Key"),Clength+4)==0)
|
||
|
parsekey(&tline[Clength + 4]);
|
||
|
else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"SortIcons"),Clength+10)==0){
|
||
|
tmp = &tline[Clength+10];
|
||
|
while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
|
||
|
tmp++;
|
||
|
if (strlen(tmp) == 0){ /* the case where no argument is given */
|
||
|
sortby = ICONNAME;
|
||
|
return;
|
||
|
}
|
||
|
if (strncasecmp(tmp, "WindowName", 10) == 0)
|
||
|
sortby = WINDOWNAME;
|
||
|
else if (strncasecmp(tmp, "IconName", 8) == 0)
|
||
|
sortby = ICONNAME;
|
||
|
else if (strncasecmp(tmp, "ResClass", 8) == 0)
|
||
|
sortby = RESCLASS;
|
||
|
else if (strncasecmp(tmp, "ResName", 7) == 0)
|
||
|
sortby = RESNAME;
|
||
|
}else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
"HideSC"),Clength+7)==0){
|
||
|
tmp = &tline[Clength+7];
|
||
|
while(((isspace(*tmp))&&(*tmp != '\n'))&&(*tmp != 0))
|
||
|
tmp++;
|
||
|
if (strncasecmp(tmp, "Horizontal", 10) == 0)
|
||
|
local_flags |= HIDE_H;
|
||
|
else if (strncasecmp(tmp, "Vertical", 8) == 0)
|
||
|
local_flags |= HIDE_V;
|
||
|
}else if (strncasecmp(tline,CatString3("*",MyName,
|
||
|
""),Clength+1)==0)
|
||
|
parseicon(&tline[Clength + 1]);
|
||
|
else if (strncasecmp(tline,"IconPath",8)==0)
|
||
|
CopyString(&iconPath,&tline[8]);
|
||
|
else if (strncasecmp(tline,"PixmapPath",10)==0)
|
||
|
CopyString(&pixmapPath,&tline[10]);
|
||
|
else if (strncasecmp(tline,"ClickTime",9)==0)
|
||
|
ClickTime = atoi(&tline[9]);
|
||
|
else if (strncasecmp(tline,"ColorLimit",10)==0) {
|
||
|
save_color_limit = atoi(&tline[10]);
|
||
|
}
|
||
|
}
|
||
|
GetConfigLine(fd,&tline);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void parseicon(char *tline)
|
||
|
{
|
||
|
int len;
|
||
|
struct iconfile *tmp;
|
||
|
char *ptr, *start, *end;
|
||
|
|
||
|
tmp = (struct iconfile *)safemalloc(sizeof(struct iconfile));
|
||
|
|
||
|
|
||
|
/* windowname */
|
||
|
tmp->name = stripcpy2(tline);
|
||
|
if(tmp->name == NULL){
|
||
|
free(tmp);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* skip windowname, based on strpcpy3 of configure.c */
|
||
|
while((*tline != '"')&&(tline != NULL))
|
||
|
tline++;
|
||
|
if(*tline != 0)
|
||
|
tline++;
|
||
|
while((*tline != '"')&&(tline != NULL))
|
||
|
tline++;
|
||
|
if(*tline == 0){
|
||
|
free(tmp);
|
||
|
return;
|
||
|
}
|
||
|
tline++;
|
||
|
|
||
|
/* file */
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
while(!isspace(*end)&&(*end != '\n')&&(*end != 0))
|
||
|
end++;
|
||
|
len = end - start;
|
||
|
ptr = safemalloc(len+1);
|
||
|
strncpy(ptr, start, len);
|
||
|
ptr[len] = 0;
|
||
|
tmp->iconfile = ptr;
|
||
|
|
||
|
if (strcmp(tmp->name, "*") == 0)
|
||
|
DefaultIcon = tmp;
|
||
|
|
||
|
tmp->next = NULL;
|
||
|
|
||
|
if (IconListHead == NULL)
|
||
|
IconListHead = IconListTail = tmp;
|
||
|
else{
|
||
|
IconListTail->next = tmp;
|
||
|
IconListTail = tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void parseplacement(char *tline)
|
||
|
{
|
||
|
char p[240], s[240];
|
||
|
|
||
|
sscanf(tline, "%s %s", p, s);
|
||
|
|
||
|
if (strncasecmp(p, "Left", 4) == 0)
|
||
|
primary = LEFT;
|
||
|
else if (strncasecmp(p, "Right", 5) == 0)
|
||
|
primary = RIGHT;
|
||
|
else if (strncasecmp(p, "Top", 3) == 0)
|
||
|
primary = TOP;
|
||
|
else if (strncasecmp(p, "Bottom", 6) == 0)
|
||
|
primary = BOTTOM;
|
||
|
|
||
|
if (strncasecmp(s, "Left", 4) == 0)
|
||
|
secondary = LEFT;
|
||
|
else if (strncasecmp(s, "Right", 5) == 0)
|
||
|
secondary = RIGHT;
|
||
|
else if (strncasecmp(s, "Top", 3) == 0)
|
||
|
secondary = TOP;
|
||
|
else if (strncasecmp(s, "Bottom", 6) == 0)
|
||
|
secondary = BOTTOM;
|
||
|
}
|
||
|
|
||
|
void parsemouse(char *tline)
|
||
|
{
|
||
|
struct mousefunc *f = NULL;
|
||
|
int len;
|
||
|
char *ptr,*start,*end,*tmp;
|
||
|
|
||
|
f = (struct mousefunc *)safemalloc(sizeof(struct mousefunc));
|
||
|
f->next = NULL;
|
||
|
f->mouse = 0;
|
||
|
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
while((!isspace(*end))&&(*end!='\n')&&(*end!=0))
|
||
|
end++;
|
||
|
if (strncasecmp(start, "1", 1) == 0)
|
||
|
f->mouse = Button1;
|
||
|
else if (strncasecmp(start, "2", 1) == 0)
|
||
|
f->mouse = Button2;
|
||
|
else if (strncasecmp(start, "3", 1) == 0)
|
||
|
f->mouse = Button3;
|
||
|
/* click or doubleclick */
|
||
|
tline = end;
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
while((!isspace(*end))&&(*end!='\n')&&(*end!=0))
|
||
|
end++;
|
||
|
if (strncasecmp(start, "Click", 5) == 0)
|
||
|
f->type = CLICK;
|
||
|
else if (strncasecmp(start, "DoubleClick", 11) == 0)
|
||
|
f->type = DOUBLE_CLICK;
|
||
|
|
||
|
/* actions */
|
||
|
tline = end;
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
tmp = tline;
|
||
|
while((*tmp!='\n')&&(*tmp!=0)){
|
||
|
if (!isspace(*tmp))
|
||
|
end = tmp;
|
||
|
tmp++;
|
||
|
}
|
||
|
end++;
|
||
|
len = end - start;
|
||
|
ptr = safemalloc(len+1);
|
||
|
strncpy(ptr, start, len);
|
||
|
ptr[len] = 0;
|
||
|
f->action = ptr;
|
||
|
f->next = MouseActions;
|
||
|
MouseActions = f;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
parsekey
|
||
|
Based on part of AddFunckey() of configure.c in Fvwm.
|
||
|
Copyright 1988, Evans and Sutherland Computer Corporation,
|
||
|
Copyright 1989, Massachusetts Institute of Technology,
|
||
|
Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void parsekey(char *tline)
|
||
|
{
|
||
|
struct keyfunc *k;
|
||
|
int nlen, alen;
|
||
|
char *nptr, *aptr, *start, *end, *tmp;
|
||
|
int i, kmin, kmax;
|
||
|
KeySym keysym;
|
||
|
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
while((!isspace(*end))&&(*end!='\n')&&(*end!=0))
|
||
|
end++;
|
||
|
nlen = end - start;
|
||
|
nptr = safemalloc(nlen+1);
|
||
|
strncpy(nptr, start, nlen);
|
||
|
nptr[nlen] = 0;
|
||
|
|
||
|
/* actions */
|
||
|
tline = end;
|
||
|
/* skip spaces */
|
||
|
while(isspace(*tline)&&(*tline != '\n')&&(*tline != 0))
|
||
|
tline++;
|
||
|
start = tline;
|
||
|
end = tline;
|
||
|
tmp = tline;
|
||
|
while((*tmp!='\n')&&(*tmp!=0)){
|
||
|
if (!isspace(*tmp))
|
||
|
end = tmp;
|
||
|
tmp++;
|
||
|
}
|
||
|
end++;
|
||
|
alen = end - start;
|
||
|
aptr = safemalloc(alen+1);
|
||
|
strncpy(aptr, start, alen);
|
||
|
aptr[alen] = 0;
|
||
|
|
||
|
if ((keysym = XStringToKeysym(nptr)) == NoSymbol ||
|
||
|
XKeysymToKeycode(dpy, keysym) == 0){
|
||
|
free(nptr);
|
||
|
free(aptr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
XDisplayKeycodes(dpy, &kmin, &kmax);
|
||
|
for (i=kmin; i<=kmax; i++)
|
||
|
if (XKeycodeToKeysym(dpy, i, 0) == keysym)
|
||
|
{
|
||
|
k = (struct keyfunc *)safemalloc(sizeof(struct keyfunc));
|
||
|
k->name = nptr;
|
||
|
k->keycode = i;
|
||
|
k->action = aptr;
|
||
|
k->next = KeyActions;
|
||
|
KeyActions = k;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* change_window_name
|
||
|
* Original work from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void change_window_name(char *str)
|
||
|
{
|
||
|
XTextProperty name;
|
||
|
|
||
|
if (XStringListToTextProperty(&str,1,&name) == 0)
|
||
|
{
|
||
|
fprintf(stderr,"%s: cannot allocate window name",MyName);
|
||
|
return;
|
||
|
}
|
||
|
XSetWMName(dpy,main_win,&name);
|
||
|
XSetWMIconName(dpy,main_win,&name);
|
||
|
XFree(name.value);
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* My_XNextEvent
|
||
|
* Original work from GoodStuff:
|
||
|
* Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
int My_XNextEvent(Display *dpy, XEvent *event)
|
||
|
{
|
||
|
fd_set in_fdset;
|
||
|
unsigned long header[HEADER_SIZE];
|
||
|
static int miss_counter = 0;
|
||
|
unsigned long *body;
|
||
|
|
||
|
if(XPending(dpy))
|
||
|
{
|
||
|
XNextEvent(dpy,event);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
FD_ZERO(&in_fdset);
|
||
|
FD_SET(x_fd,&in_fdset);
|
||
|
FD_SET(fd[1],&in_fdset);
|
||
|
|
||
|
select(fd_width,SELECT_TYPE_ARG234 &in_fdset, 0, 0, NULL);
|
||
|
|
||
|
if(FD_ISSET(x_fd, &in_fdset))
|
||
|
{
|
||
|
if(XPending(dpy))
|
||
|
{
|
||
|
XNextEvent(dpy,event);
|
||
|
miss_counter = 0;
|
||
|
return 1;
|
||
|
}
|
||
|
else
|
||
|
miss_counter++;
|
||
|
if(miss_counter > 100)
|
||
|
DeadPipe(0);
|
||
|
}
|
||
|
|
||
|
if(FD_ISSET(fd[1], &in_fdset))
|
||
|
{
|
||
|
if(ReadFvwmPacket(fd[1],header,&body) > 0)
|
||
|
{
|
||
|
process_message(header[1],body);
|
||
|
free(body);
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************
|
||
|
* process_message
|
||
|
* Based on ProcessMassage() from FvwmWinList:
|
||
|
* Copyright 1994, Mike Finger.
|
||
|
*************************************************************************/
|
||
|
int diffx, diffy;
|
||
|
void process_message(unsigned long type, unsigned long *body)
|
||
|
{
|
||
|
struct icon_info *tmp, *old;
|
||
|
char *str;
|
||
|
long olddesk;
|
||
|
|
||
|
switch(type){
|
||
|
case M_CONFIGURE_WINDOW:
|
||
|
if (ready){
|
||
|
if (!(local_flags & CURRENT_ONLY)) break;
|
||
|
tmp = Head;
|
||
|
while(tmp != NULL){
|
||
|
if (tmp->id == body[0]){
|
||
|
if ((tmp->desk != body[7]) && !(tmp->flags & STICKY)){
|
||
|
olddesk = tmp->desk;
|
||
|
tmp->desk = body[7];
|
||
|
if (olddesk == CurrentDesk || tmp->desk == CurrentDesk){
|
||
|
if (tmp->desk == CurrentDesk && sortby != UNSORT)
|
||
|
SortItem(NULL);
|
||
|
num_icons = AdjustIconWindows();
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
if (diffy && (primary == BOTTOM || secondary == BOTTOM))
|
||
|
icon_win_y += diffy;
|
||
|
if (diffx && (primary == RIGHT || secondary == RIGHT))
|
||
|
icon_win_x += diffx;
|
||
|
if (icon_win_y < 0)
|
||
|
icon_win_y = 0;
|
||
|
if (icon_win_x < 0)
|
||
|
icon_win_x = 0;
|
||
|
if (icon_win_x + Width > icon_win_width)
|
||
|
icon_win_x = icon_win_width - Width;
|
||
|
if (icon_win_y + Height > icon_win_height)
|
||
|
icon_win_y = icon_win_height - Height;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y,
|
||
|
icon_win_width, icon_win_height);
|
||
|
if (tmp->desk == CurrentDesk){
|
||
|
XMapWindow(dpy, tmp->IconWin);
|
||
|
if (max_icon_height != 0)
|
||
|
XMapWindow(dpy, tmp->icon_pixmap_w);
|
||
|
}else{
|
||
|
XUnmapWindow(dpy, tmp->IconWin);
|
||
|
if (max_icon_height != 0)
|
||
|
XUnmapWindow(dpy, tmp->icon_pixmap_w);
|
||
|
}
|
||
|
if (!(local_flags & HIDE_H) && diffx)
|
||
|
RedrawHScrollbar();
|
||
|
if (!(local_flags & HIDE_V) && diffy)
|
||
|
RedrawVScrollbar();
|
||
|
}
|
||
|
}else if ((body[8] & STICKY) && !(tmp->flags & STICKY)) /* stick */
|
||
|
tmp->flags |= STICKY;
|
||
|
else if (!(body[8] & STICKY) && (tmp->flags & STICKY)){ /* unstick */
|
||
|
tmp->flags &= ~STICKY;
|
||
|
tmp->desk = body[7];
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case M_ADD_WINDOW:
|
||
|
if (AddItem(body[0], body[7], body[8]) == True && ready){
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
if (diffy && (primary == BOTTOM || secondary == BOTTOM))
|
||
|
icon_win_y += diffy;
|
||
|
if (diffx && (primary == RIGHT || secondary == RIGHT))
|
||
|
icon_win_x += diffx;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y,
|
||
|
icon_win_width, icon_win_height);
|
||
|
}
|
||
|
break;
|
||
|
case M_DESTROY_WINDOW:
|
||
|
if (DeleteItem(body[0]) && ready){
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
if (diffy && (primary == BOTTOM || secondary == BOTTOM))
|
||
|
icon_win_y += diffy;
|
||
|
if (diffx && (primary == RIGHT || secondary == RIGHT))
|
||
|
icon_win_x += diffx;
|
||
|
if (icon_win_y < 0)
|
||
|
icon_win_y = 0;
|
||
|
if (icon_win_x < 0)
|
||
|
icon_win_x = 0;
|
||
|
if (icon_win_x + Width > icon_win_width)
|
||
|
icon_win_x = icon_win_width - Width;
|
||
|
if (icon_win_y + Height > icon_win_height)
|
||
|
icon_win_y = icon_win_height - Height;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y,
|
||
|
icon_win_width, icon_win_height);
|
||
|
AdjustIconWindows();
|
||
|
if (!(local_flags & HIDE_H) && diffx)
|
||
|
RedrawHScrollbar();
|
||
|
if (!(local_flags & HIDE_V) && diffy)
|
||
|
RedrawVScrollbar();
|
||
|
}
|
||
|
break;
|
||
|
case M_ICON_FILE:
|
||
|
case M_RES_CLASS:
|
||
|
UpdateItem(type, body[0], (char *)&body[3]);
|
||
|
break;
|
||
|
case M_WINDOW_NAME:
|
||
|
tmp = UpdateItem(type, body[0], (char *)&body[3]);
|
||
|
if (!ready || tmp == NULL)
|
||
|
break;
|
||
|
if (sortby == WINDOWNAME && tmp->IconWin != None
|
||
|
&& desk_cond(tmp) && SortItem(tmp) == True)
|
||
|
AdjustIconWindows();
|
||
|
break;
|
||
|
case M_RES_NAME:
|
||
|
if ((tmp = UpdateItem(type, body[0], (char *)&body[3])) == NULL)
|
||
|
break;
|
||
|
if (LookInList(tmp) && ready){
|
||
|
if (sortby != UNSORT)
|
||
|
SortItem(tmp);
|
||
|
CreateIconWindow(tmp);
|
||
|
ConfigureIconWindow(tmp);
|
||
|
AdjustIconWindows();
|
||
|
if (desk_cond(tmp)){
|
||
|
if (max_icon_height != 0)
|
||
|
XMapWindow(dpy, tmp->icon_pixmap_w);
|
||
|
XMapWindow(dpy, tmp->IconWin);
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
RedrawHScrollbar();
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
RedrawVScrollbar();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case M_ICON_NAME:
|
||
|
tmp = UpdateItem(type, body[0], (char *)&body[3]);
|
||
|
if (!ready || tmp == NULL)
|
||
|
break;
|
||
|
if (sortby != UNSORT && tmp->IconWin != None
|
||
|
&& desk_cond(tmp) && SortItem(tmp) == True)
|
||
|
AdjustIconWindows();
|
||
|
if (tmp->IconWin != None && desk_cond(tmp))
|
||
|
RedrawIcon(tmp, 2);
|
||
|
break;
|
||
|
case M_DEFAULTICON:
|
||
|
str = (char *)safemalloc(strlen((char *)&body[3])+1);
|
||
|
strcpy(str, (char *)&body[3]);
|
||
|
FvwmDefaultIcon = str;
|
||
|
break;
|
||
|
case M_ICONIFY:
|
||
|
case M_DEICONIFY:
|
||
|
if (ready && (tmp = SetFlag(body[0], type)) != NULL)
|
||
|
RedrawIcon(tmp, 2);
|
||
|
break;
|
||
|
case M_FOCUS_CHANGE:
|
||
|
if (!ready)
|
||
|
break;
|
||
|
tmp = Head;
|
||
|
while(tmp != NULL){
|
||
|
if (tmp->id == body[0]) break;
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
old = Hilite;
|
||
|
Hilite = tmp;
|
||
|
if (old != NULL)
|
||
|
RedrawIcon(old, redraw_flag);
|
||
|
if (tmp != NULL)
|
||
|
RedrawIcon(tmp, redraw_flag);
|
||
|
break;
|
||
|
case M_NEW_DESK:
|
||
|
if (CurrentDesk != body[0]){
|
||
|
CurrentDesk = body[0];
|
||
|
if (body[0] != 10000 && ready){ /* 10000 is a "magic" number used in FvwmPager */
|
||
|
if (sortby != UNSORT)
|
||
|
SortItem(NULL);
|
||
|
num_icons = AdjustIconWindows();
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
icon_win_x = icon_win_y = 0;
|
||
|
if (primary == BOTTOM || secondary == BOTTOM)
|
||
|
icon_win_y = icon_win_height - Height;
|
||
|
if (primary == RIGHT || secondary == RIGHT)
|
||
|
icon_win_x = icon_win_width - Width;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y,
|
||
|
icon_win_width, icon_win_height);
|
||
|
XUnmapSubwindows(dpy, icon_win);
|
||
|
mapicons();
|
||
|
if (!(local_flags & HIDE_H))
|
||
|
RedrawHScrollbar();
|
||
|
if (!(local_flags & HIDE_V))
|
||
|
RedrawVScrollbar();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case M_END_WINDOWLIST:
|
||
|
GetIconwinSize(&diffx, &diffy);
|
||
|
tmp = Head;
|
||
|
while(tmp != NULL){
|
||
|
CreateIconWindow(tmp);
|
||
|
ConfigureIconWindow(tmp);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
if (sortby != UNSORT)
|
||
|
SortItem(NULL);
|
||
|
if (primary == BOTTOM || secondary == BOTTOM)
|
||
|
icon_win_y = icon_win_height - Height;
|
||
|
if (primary == RIGHT || secondary == RIGHT)
|
||
|
icon_win_x = icon_win_width - Width;
|
||
|
XMoveResizeWindow(dpy, icon_win, -icon_win_x, -icon_win_y,
|
||
|
icon_win_width, icon_win_height);
|
||
|
AdjustIconWindows();
|
||
|
XMapWindow(dpy,main_win);
|
||
|
XMapSubwindows(dpy, main_win);
|
||
|
XMapWindow(dpy, icon_win);
|
||
|
mapicons();
|
||
|
ready = 1;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct icon_info *SetFlag(unsigned long id, int t)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
tmp = Head;
|
||
|
|
||
|
while(tmp != NULL){
|
||
|
if (tmp->id == id){
|
||
|
if (t == M_ICONIFY)
|
||
|
tmp->flags |= ICONIFIED;
|
||
|
else
|
||
|
tmp->flags ^= ICONIFIED;
|
||
|
return tmp;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void mapicons(void)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
tmp = Head;
|
||
|
|
||
|
while(tmp != NULL){
|
||
|
if (desk_cond(tmp)){
|
||
|
XMapWindow(dpy, tmp->IconWin);
|
||
|
if (max_icon_height != 0)
|
||
|
XMapWindow(dpy, tmp->icon_pixmap_w);
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int AdjustIconWindows(void)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
int i = 0;
|
||
|
tmp = Head;
|
||
|
|
||
|
while(tmp != NULL){
|
||
|
if (desk_cond(tmp) && tmp->IconWin != None)
|
||
|
AdjustIconWindow(tmp, i++);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
int desk_cond(struct icon_info *item)
|
||
|
{
|
||
|
if (!(local_flags & CURRENT_ONLY) ||
|
||
|
(item->flags & STICKY) || (item->desk == CurrentDesk))
|
||
|
return 1;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* AddItem
|
||
|
* Skeleton based on AddItem() from FvwmWinList:
|
||
|
* Copyright 1994, Mike Finger.
|
||
|
***********************************************************************/
|
||
|
Bool AddItem(unsigned long id, long desk, unsigned long flags)
|
||
|
{
|
||
|
struct icon_info *new, *tmp;
|
||
|
tmp = Head;
|
||
|
|
||
|
if (id == main_win || (flags & TRANSIENT) || !(flags & SUPPRESSICON))
|
||
|
return False;
|
||
|
|
||
|
while (tmp != NULL){
|
||
|
if (tmp->id == id ||
|
||
|
(tmp->wmhints && (tmp->wmhints->flags & IconWindowHint) &&
|
||
|
tmp->wmhints->icon_window == id))
|
||
|
return False;
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
|
||
|
new = (struct icon_info *)safemalloc(sizeof(struct icon_info));
|
||
|
new->name = NULL;
|
||
|
new->window_name = NULL;
|
||
|
new->res_class = NULL;
|
||
|
new->res_name = NULL;
|
||
|
new->action = NULL;
|
||
|
new->icon_file = NULL;
|
||
|
new->icon_w = 0;
|
||
|
new->icon_h = 0;
|
||
|
new->IconWin = None;
|
||
|
new->iconPixmap = None;
|
||
|
new->icon_maskPixmap = None;
|
||
|
new->icon_pixmap_w = None;
|
||
|
new->icon_depth = 0;
|
||
|
new->desk = desk;
|
||
|
new->id = id;
|
||
|
new->extra_flags = DEFAULTICON;
|
||
|
new->flags = flags | ICON_OURS;
|
||
|
new->wmhints = NULL;
|
||
|
|
||
|
/* add new item to the head of the list
|
||
|
|
||
|
new->prev = NULL;
|
||
|
new->next = Head;
|
||
|
if (Head != NULL)
|
||
|
Head->prev = new;
|
||
|
else
|
||
|
Tail = new;
|
||
|
Head = new; */
|
||
|
|
||
|
/* add new item to the tail of the list */
|
||
|
new->prev = Tail;
|
||
|
new->next = NULL;
|
||
|
if (Tail != NULL)
|
||
|
Tail->next = new;
|
||
|
else
|
||
|
Head = new;
|
||
|
Tail = new;
|
||
|
|
||
|
if (desk_cond(new)) num_icons++;
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* Deletetem
|
||
|
* Skeleton based on DeleteItem() from FvwmWinList:
|
||
|
* Copyright 1994, Mike Finger.
|
||
|
***********************************************************************/
|
||
|
Bool DeleteItem(unsigned long id)
|
||
|
{
|
||
|
struct icon_info *tmp = Head;
|
||
|
|
||
|
while(tmp != NULL){
|
||
|
if (tmp->id == id){
|
||
|
if (desk_cond(tmp))
|
||
|
num_icons--;
|
||
|
if (Hilite == tmp)
|
||
|
Hilite = NULL;
|
||
|
if ((tmp->icon_pixmap_w != None) && (tmp->flags & ICON_OURS))
|
||
|
XDestroyWindow(dpy, tmp->icon_pixmap_w);
|
||
|
if (tmp->IconWin != None)
|
||
|
XDestroyWindow(dpy, tmp->IconWin);
|
||
|
if (tmp == Head){
|
||
|
Head = tmp->next;
|
||
|
if (Head != NULL)
|
||
|
Head->prev = NULL;
|
||
|
else
|
||
|
Tail = NULL;
|
||
|
}else {
|
||
|
if (Tail == tmp)
|
||
|
Tail = tmp->prev;
|
||
|
tmp->prev->next = tmp->next;
|
||
|
if (tmp->next != NULL)
|
||
|
tmp->next->prev = tmp->prev;
|
||
|
}
|
||
|
freeitem(tmp, 1);
|
||
|
return True;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* UpdateItem
|
||
|
* Skeleton based on UpdateItem() from FvwmWinList:
|
||
|
* Copyright 1994, Mike Finger.
|
||
|
***********************************************************************/
|
||
|
struct icon_info *UpdateItem(unsigned long type, unsigned long id, char *item)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
char *str;
|
||
|
XClassHint classhint;
|
||
|
int ret;
|
||
|
|
||
|
tmp = Head;
|
||
|
while (tmp != NULL){
|
||
|
if (tmp->id == id){
|
||
|
str = (char *)safemalloc(strlen(item)+1);
|
||
|
strcpy(str, item);
|
||
|
|
||
|
switch (type){
|
||
|
case M_ICON_NAME:
|
||
|
if (tmp->name != NULL)
|
||
|
free(tmp->name);
|
||
|
tmp->name = str;
|
||
|
return tmp;
|
||
|
case M_ICON_FILE:
|
||
|
tmp->icon_file = str;
|
||
|
tmp->extra_flags &= ~DEFAULTICON;
|
||
|
return tmp;
|
||
|
case M_WINDOW_NAME:
|
||
|
if (tmp->window_name != NULL)
|
||
|
free(tmp->window_name);
|
||
|
tmp->window_name = str;
|
||
|
return tmp;
|
||
|
case M_RES_CLASS:
|
||
|
tmp->res_class = str;
|
||
|
ret = 0;
|
||
|
if (sortby == RESCLASS && strcmp(NoClass, str) == 0
|
||
|
&& !(ret = XGetClassHint(dpy, tmp->id, &classhint))){
|
||
|
tmp->extra_flags |= NOCLASS;
|
||
|
}
|
||
|
if (ret){
|
||
|
if (classhint.res_class != NULL)
|
||
|
XFree(classhint.res_class);
|
||
|
if (classhint.res_name != NULL)
|
||
|
XFree(classhint.res_name);
|
||
|
}
|
||
|
return tmp;
|
||
|
case M_RES_NAME:
|
||
|
tmp->res_name = str;
|
||
|
ret = 0;
|
||
|
if (sortby == RESNAME && strcmp(NoResource, str) == 0
|
||
|
&& !(ret = XGetClassHint(dpy, tmp->id, &classhint)))
|
||
|
tmp->extra_flags |= NONAME;
|
||
|
if (ret){
|
||
|
if (classhint.res_class != NULL)
|
||
|
XFree(classhint.res_class);
|
||
|
if (classhint.res_name != NULL)
|
||
|
XFree(classhint.res_name);
|
||
|
}
|
||
|
return tmp;
|
||
|
}
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
Bool SortItem(struct icon_info *item)
|
||
|
{
|
||
|
struct icon_info *tmp1=Head, *a, *b, *tmp2;
|
||
|
|
||
|
if (tmp1 == NULL)
|
||
|
return False;
|
||
|
|
||
|
if (item != NULL &&
|
||
|
((itemcmp(item->prev, item) <= 0) &&
|
||
|
(itemcmp(item->next, item) >= 0)))
|
||
|
return False;
|
||
|
|
||
|
while (tmp1->next != NULL){
|
||
|
tmp2 = MinItem(tmp1);
|
||
|
if (tmp1 == tmp2){
|
||
|
tmp1 = tmp1->next;
|
||
|
continue;
|
||
|
}
|
||
|
if (tmp1 == Head)
|
||
|
Head = tmp2;
|
||
|
a = tmp1->prev;
|
||
|
b = tmp1->next;
|
||
|
if (tmp1->prev != NULL)
|
||
|
tmp1->prev->next = tmp2;
|
||
|
if (b != tmp2)
|
||
|
tmp1->next->prev = tmp2;
|
||
|
if (b != tmp2)
|
||
|
tmp2->prev->next = tmp1;
|
||
|
if (tmp2->next != NULL)
|
||
|
tmp2->next->prev = tmp1;
|
||
|
if (b == tmp2){
|
||
|
tmp1->prev = tmp2;
|
||
|
tmp1->next = tmp2->next;
|
||
|
tmp2->prev = a;
|
||
|
tmp2->next = tmp1;
|
||
|
}else{
|
||
|
tmp1->prev = tmp2->prev;
|
||
|
tmp1->next = tmp2->next;
|
||
|
tmp2->prev = a;
|
||
|
tmp2->next = b;
|
||
|
}
|
||
|
tmp1 = b;
|
||
|
}
|
||
|
Tail = tmp1;
|
||
|
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
struct icon_info *MinItem(struct icon_info *head)
|
||
|
{
|
||
|
struct icon_info *tmp, *i_min;
|
||
|
|
||
|
if (head == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
i_min = head;
|
||
|
tmp = head->next;
|
||
|
while (tmp != NULL){
|
||
|
if (itemcmp(i_min, tmp) > 0)
|
||
|
i_min = tmp;
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return i_min;
|
||
|
}
|
||
|
|
||
|
int itemcmp(struct icon_info *item1, struct icon_info *item2)
|
||
|
{
|
||
|
int ret1, ret2;
|
||
|
|
||
|
if (item1 == NULL){
|
||
|
if (item2 == NULL)
|
||
|
return 0;
|
||
|
else
|
||
|
return -1;
|
||
|
} else if (item2 == NULL)
|
||
|
return 1;
|
||
|
|
||
|
/* skip items not on the current desk */
|
||
|
ret1 = desk_cond(item1);
|
||
|
ret2 = desk_cond(item2);
|
||
|
if (!ret1 || !ret2)
|
||
|
return (ret1 - ret2);
|
||
|
|
||
|
ret1 = 0;
|
||
|
ret2 = strcmp(item1->name, item2->name);
|
||
|
|
||
|
switch(sortby){
|
||
|
case WINDOWNAME:
|
||
|
ret1 = strcmp(item1->window_name, item2->window_name);
|
||
|
break;
|
||
|
case RESCLASS:
|
||
|
if ((item1->extra_flags & NOCLASS)){
|
||
|
if ((item2->extra_flags & NOCLASS))
|
||
|
ret1 = 0;
|
||
|
else if (!(item2->extra_flags & NOCLASS))
|
||
|
ret1 = -1;
|
||
|
}else if ((item2->extra_flags & NOCLASS))
|
||
|
ret1 = 1;
|
||
|
else
|
||
|
ret1 = strcmp(item1->res_class, item2->res_class);
|
||
|
break;
|
||
|
case RESNAME:
|
||
|
if ((item1->extra_flags & NOCLASS)){
|
||
|
if ((item2->extra_flags & NOCLASS))
|
||
|
ret1 = 0;
|
||
|
else if (!(item2->extra_flags & NOCLASS))
|
||
|
ret1 = -1;
|
||
|
}else if ((item2->extra_flags & NOCLASS))
|
||
|
ret1 = 1;
|
||
|
else
|
||
|
ret1 = strcmp(item1->res_name, item2->res_name);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return (ret1 != 0 ? ret1 : ret2);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
void ShowItem(struct icon_info *head)
|
||
|
{
|
||
|
struct icon_info *tmp;
|
||
|
|
||
|
fprintf(stderr, "The contents of item are as follows:\n");
|
||
|
tmp = head;
|
||
|
while (tmp != NULL){
|
||
|
fprintf(stderr, "id:%x name:%s resname:%s class%s iconfile:%s\n",
|
||
|
tmp->id,
|
||
|
tmp->name == NULL ? "NULL" : tmp->name, tmp->res_name,
|
||
|
tmp->res_class, tmp->icon_file);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ShowAction(void)
|
||
|
{
|
||
|
struct mousefunc *tmp;
|
||
|
|
||
|
tmp = MouseActions;
|
||
|
while (tmp != NULL){
|
||
|
fprintf(stderr, "mouse:%d type %d action:%s\n", tmp->mouse,
|
||
|
tmp->type, tmp->action);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ShowKAction(void)
|
||
|
{
|
||
|
struct keyfunc *tmp;
|
||
|
|
||
|
tmp = KeyActions;
|
||
|
while (tmp != NULL){
|
||
|
fprintf(stderr, "key:%s keycode:%d action:%s\n", tmp->name,
|
||
|
tmp->keycode, tmp->action);
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
void freeitem(struct icon_info *item, int d)
|
||
|
{
|
||
|
if (item == NULL)
|
||
|
return;
|
||
|
|
||
|
if (!(item->flags & ICON_OURS)){
|
||
|
if (max_icon_height != 0)
|
||
|
XUnmapWindow(dpy, item->icon_pixmap_w);
|
||
|
if (d == 0)
|
||
|
XReparentWindow(dpy, item->icon_pixmap_w, Root, 0, 0);
|
||
|
}
|
||
|
|
||
|
if (item->name != NULL)
|
||
|
free(item->name);
|
||
|
if (item->window_name != NULL)
|
||
|
free(item->window_name);
|
||
|
if (item->res_name != NULL)
|
||
|
free(item->res_name);
|
||
|
if (item->res_class != NULL)
|
||
|
free(item->res_class);
|
||
|
if (item->wmhints != NULL)
|
||
|
XFree(item->wmhints);
|
||
|
if (item->iconPixmap != None)
|
||
|
XFreePixmap(dpy, item->iconPixmap);
|
||
|
if (item->icon_maskPixmap != None &&
|
||
|
(item->wmhints == NULL ||
|
||
|
!(item->wmhints->flags & (IconPixmapHint|IconWindowHint))))
|
||
|
XFreePixmap(dpy, item->icon_maskPixmap);
|
||
|
|
||
|
free(item);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
IsClick
|
||
|
Based on functions.c from Fvwm:
|
||
|
Copyright 1988, Evans and Sutherland Computer Corporation,
|
||
|
Copyright 1989, Massachusetts Institute of Technology,
|
||
|
Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
Bool IsClick(int x,int y,unsigned EndMask, XEvent *d)
|
||
|
{
|
||
|
int xcurrent,ycurrent,total = 0;
|
||
|
|
||
|
xcurrent = x;
|
||
|
ycurrent = y;
|
||
|
while((total < ClickTime)&&
|
||
|
(x - xcurrent < 5)&&(x - xcurrent > -5)&&
|
||
|
(y - ycurrent < 5)&&(y - ycurrent > -5))
|
||
|
{
|
||
|
usleep(10000);
|
||
|
total+=10;
|
||
|
if(XCheckMaskEvent (dpy,EndMask, d))
|
||
|
return True;
|
||
|
if(XCheckMaskEvent (dpy,ButtonMotionMask|PointerMotionMask, d))
|
||
|
{
|
||
|
xcurrent = d->xmotion.x_root;
|
||
|
ycurrent = d->xmotion.y_root;
|
||
|
}
|
||
|
}
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* ExecuteAction
|
||
|
* Based on part of ComplexFunction() of functions.c from fvwm:
|
||
|
Copyright 1988, Evans and Sutherland Computer Corporation,
|
||
|
Copyright 1989, Massachusetts Institute of Technology,
|
||
|
Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
void ExecuteAction(int x, int y, struct icon_info *item)
|
||
|
{
|
||
|
int type = NO_CLICK;
|
||
|
XEvent *ev;
|
||
|
XEvent d;
|
||
|
struct mousefunc *tmp;
|
||
|
|
||
|
/* Wait and see if we have a click, or a move */
|
||
|
/* wait 100 msec, see if the used releases the button */
|
||
|
if(IsClick(x,y,ButtonReleaseMask,&d))
|
||
|
{
|
||
|
type = CLICK;
|
||
|
ev = &d;
|
||
|
}
|
||
|
|
||
|
/* If it was a click, wait to see if its a double click */
|
||
|
if((type == CLICK) && (IsClick(x,y,ButtonPressMask, &d)))
|
||
|
{
|
||
|
type = ONE_AND_A_HALF_CLICKS;
|
||
|
ev = &d;
|
||
|
}
|
||
|
if((type == ONE_AND_A_HALF_CLICKS) &&
|
||
|
(IsClick(x,y,ButtonReleaseMask, &d)))
|
||
|
{
|
||
|
type = DOUBLE_CLICK;
|
||
|
ev = &d;
|
||
|
}
|
||
|
tmp = MouseActions;
|
||
|
|
||
|
while (tmp != NULL){
|
||
|
if (tmp->mouse == d.xbutton.button && tmp->type == type){
|
||
|
SendFvwmPipe(fd, tmp->action, item->id);
|
||
|
return;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ExecuteKey(XEvent event)
|
||
|
{
|
||
|
struct icon_info *item;
|
||
|
struct keyfunc *tmp;
|
||
|
|
||
|
if ((item = Hilite) == NULL)
|
||
|
if ((item = Head) == NULL)
|
||
|
return;
|
||
|
|
||
|
tmp = KeyActions;
|
||
|
event.xkey.keycode =
|
||
|
XKeysymToKeycode(dpy,XKeycodeToKeysym(dpy,event.xkey.keycode,0));
|
||
|
while (tmp != NULL){
|
||
|
if (tmp->keycode == event.xkey.keycode){
|
||
|
SendFvwmPipe(fd, tmp->action, item->id);
|
||
|
return;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
LookInList
|
||
|
Based on part of LookInList() of add_window.c from fvwm:
|
||
|
Copyright 1988, Evans and Sutherland Computer Corporation,
|
||
|
Copyright 1989, Massachusetts Institute of Technology,
|
||
|
Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
int LookInList(struct icon_info *item)
|
||
|
{
|
||
|
int isdefault=1;
|
||
|
char *value=NULL;
|
||
|
struct iconfile *nptr;
|
||
|
|
||
|
if (IconListHead == NULL) {
|
||
|
if ((item->extra_flags & DEFAULTICON) && (FvwmDefaultIcon != NULL))
|
||
|
item->icon_file = FvwmDefaultIcon;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
for (nptr = IconListHead; nptr != NULL; nptr = nptr->next){
|
||
|
if (nptr == DefaultIcon)
|
||
|
isdefault = 1;
|
||
|
|
||
|
if (matchWildcards(nptr->name, item->res_class) == TRUE){
|
||
|
value = nptr->iconfile;
|
||
|
if (nptr != DefaultIcon)
|
||
|
isdefault = 0;
|
||
|
}
|
||
|
|
||
|
if (matchWildcards(nptr->name, item->res_name) == TRUE){
|
||
|
value = nptr->iconfile;
|
||
|
if (nptr != DefaultIcon)
|
||
|
isdefault = 0;
|
||
|
}
|
||
|
|
||
|
if (matchWildcards(nptr->name, item->window_name) == TRUE){
|
||
|
value = nptr->iconfile;
|
||
|
if (nptr != DefaultIcon)
|
||
|
isdefault = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isdefault){
|
||
|
item->icon_file = value;
|
||
|
item->extra_flags &= ~DEFAULTICON;
|
||
|
}else if ((item->extra_flags & DEFAULTICON)){
|
||
|
if (DefaultIcon != NULL)
|
||
|
item->icon_file = DefaultIcon->iconfile;
|
||
|
else if (FvwmDefaultIcon != NULL)
|
||
|
item->icon_file = FvwmDefaultIcon;
|
||
|
}
|
||
|
|
||
|
/* Icon is not shown if "-" is specified */
|
||
|
if (item->icon_file != NULL && (strcmp(item->icon_file, "-") == 0)){
|
||
|
DeleteItem(item->id);
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
strcpy
|
||
|
Based on stripcpy2() of configure.c from Fvwm:
|
||
|
Copyright 1988, Evans and Sutherland Computer Corporation,
|
||
|
Copyright 1989, Massachusetts Institute of Technology,
|
||
|
Copyright 1993, Robert Nation.
|
||
|
***********************************************************************/
|
||
|
char *stripcpy2(char *source)
|
||
|
{
|
||
|
char *ptr;
|
||
|
int count = 0;
|
||
|
while((*source != '"')&&(*source != 0))
|
||
|
source++;
|
||
|
if(*source == 0)
|
||
|
return 0;
|
||
|
|
||
|
source++;
|
||
|
ptr = source;
|
||
|
while((*ptr!='"')&&(*ptr != 0)){
|
||
|
ptr++;
|
||
|
count++;
|
||
|
}
|
||
|
ptr = safemalloc(count+1);
|
||
|
strncpy(ptr,source,count);
|
||
|
ptr[count]=0;
|
||
|
return ptr;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
Error handler
|
||
|
***********************************************************************/
|
||
|
XErrorHandler myErrorHandler(Display *dpy, XErrorEvent *event)
|
||
|
{
|
||
|
char msg[256];
|
||
|
|
||
|
if (event->error_code == BadWindow)
|
||
|
return 0;
|
||
|
|
||
|
XGetErrorText(dpy, event->error_code, msg, 256);
|
||
|
|
||
|
fprintf(stderr, "Error in %s: %s \n", MyName, msg);
|
||
|
fprintf(stderr, "Major opcode of failed request: %d \n",
|
||
|
event->request_code);
|
||
|
fprintf(stderr, "Resource id of failed request: 0x%lx \n",
|
||
|
event->resourceid);
|
||
|
return 0;
|
||
|
}
|