mirror of
https://github.com/NishiOwO/fvwm1.git
synced 2025-04-21 08:44:39 +00:00
388 lines
10 KiB
C
388 lines
10 KiB
C
/***********************************************************************
|
|
* icons.c
|
|
* Based on icons.c of GoodStuff:
|
|
* Copyright 1993, Robert Nation.
|
|
***********************************************************************/
|
|
|
|
/* Copyright 1993, Robert Nation. 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. */
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Derived from fvwm icon code
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "../../configure.h"
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/Xproto.h>
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Intrinsic.h>
|
|
|
|
#include "../../fvwm/module.h"
|
|
|
|
#ifdef NeXT
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
#include "FvwmIconBox.h"
|
|
|
|
#ifdef XPM
|
|
#include <X11/xpm.h>
|
|
#endif /* XPM */
|
|
#ifdef SHAPE
|
|
#include <X11/extensions/shape.h>
|
|
#endif /* SHAPE */
|
|
|
|
#define ICON_EVENTS (ExposureMask | StructureNotifyMask|\
|
|
ButtonReleaseMask | ButtonPressMask | EnterWindowMask | LeaveWindowMask)
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Creates an Icon Window
|
|
*
|
|
****************************************************************************/
|
|
void CreateIconWindow(struct icon_info *item)
|
|
{
|
|
unsigned long valuemask; /* mask for create windows */
|
|
XSetWindowAttributes attributes; /* attributes for create windows */
|
|
|
|
attributes.background_pixel = icon_back_pix;
|
|
attributes.event_mask = ExposureMask;
|
|
valuemask = CWEventMask | CWBackPixel;
|
|
|
|
/* pixmap */
|
|
item->icon_pixmap_w =
|
|
XCreateWindow(dpy, icon_win, 0, 0,
|
|
max(max_icon_width,item->icon_w),
|
|
max(max_icon_height,item->icon_h),
|
|
0,CopyFromParent,CopyFromParent,
|
|
CopyFromParent,valuemask,&attributes);
|
|
XSelectInput(dpy, item->icon_pixmap_w, ICON_EVENTS);
|
|
|
|
/* label */
|
|
item->IconWin =
|
|
XCreateWindow(dpy, icon_win, 0, 0,
|
|
max_icon_width,
|
|
max_icon_height,
|
|
0,CopyFromParent,CopyFromParent,
|
|
CopyFromParent,valuemask,&attributes);
|
|
XSelectInput(dpy, item->IconWin, ICON_EVENTS);
|
|
}
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Loads an icon file and combines icon shape masks after a resize
|
|
*
|
|
****************************************************************************/
|
|
void ConfigureIconWindow(struct icon_info *item)
|
|
{
|
|
Pixmap temp;
|
|
unsigned int nchildren;
|
|
int i, hr = ICON_RELIEF/2;
|
|
Window Junkroot, Junkparent;
|
|
Window *wlist;
|
|
|
|
XQueryTree(dpy, Root, &Junkroot, &Junkparent, &wlist, &nchildren);
|
|
for (i=nchildren-1; i>=0; --i)
|
|
if (item->fid == wlist[i]){
|
|
XSelectInput(dpy, item->id, PropertyChangeMask);
|
|
item->wmhints = XGetWMHints(dpy, item->id);
|
|
break;
|
|
}
|
|
XFree(wlist);
|
|
|
|
if (item->icon_file != NULL && (item->defaulticon == 0 || !(item->wmhints &&
|
|
item->wmhints->flags &
|
|
(IconPixmapHint|IconWindowHint)))){
|
|
/* monochrome bitmap */
|
|
GetBitmapFile(item);
|
|
|
|
/* color pixmap */
|
|
if((item->icon_w == 0)&&(item->icon_h == 0))
|
|
GetXPMFile(item);
|
|
}
|
|
|
|
if((item->icon_h == 0)&&(item->icon_w == 0)&&
|
|
(item->wmhints) && (item->wmhints->flags & IconWindowHint))
|
|
GetIconWindow(item);
|
|
|
|
/* icon bitmap from the application */
|
|
if((item->icon_h == 0)&&(item->icon_w == 0)&&
|
|
(item->wmhints)&&(item->wmhints->flags & IconPixmapHint))
|
|
GetIconBitmap(item);
|
|
|
|
#ifdef XPM
|
|
#ifdef SHAPE
|
|
if (item->icon_maskPixmap != None)
|
|
{
|
|
XShapeCombineMask(dpy, item->icon_pixmap_w, ShapeBounding,
|
|
hr, hr, item->icon_maskPixmap, ShapeSet);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
if(item->icon_depth == -1)
|
|
{
|
|
temp = item->iconPixmap;
|
|
item->iconPixmap =
|
|
XCreatePixmap(dpy, Root, item->icon_w,
|
|
item->icon_h,d_depth);
|
|
XCopyPlane(dpy,temp,item->iconPixmap,NormalGC,
|
|
0,0,item->icon_w,item->icon_h,0,0,1);
|
|
}
|
|
}
|
|
|
|
void AdjustIconWindow(struct icon_info *item, int n)
|
|
{
|
|
int x=0,y=0,w,h,h2,h3,w3;
|
|
|
|
w3 = w = max_icon_width + ICON_RELIEF;
|
|
h3 = h2 = max_icon_height + ICON_RELIEF;
|
|
h = h2 + 6 + font->ascent + font->descent;
|
|
|
|
switch (primary){
|
|
case LEFT:
|
|
case RIGHT:
|
|
if (secondary == BOTTOM)
|
|
y = icon_win_height - (n / Lines + 1)*(h + interval);
|
|
else if (secondary == TOP)
|
|
y = (n / Lines)*(h + interval) + interval;
|
|
|
|
if (primary == LEFT)
|
|
x = (n % Lines)*(w + interval) + interval;
|
|
else
|
|
x = icon_win_width - (n % Lines + 1)*(w + interval);
|
|
break;
|
|
case TOP:
|
|
case BOTTOM:
|
|
if (secondary == RIGHT)
|
|
x = icon_win_width - (n / Lines + 1)*(w + interval);
|
|
else if (secondary == LEFT)
|
|
x = (n / Lines)*(w + interval) + interval;
|
|
|
|
if (primary == TOP)
|
|
y = (n % Lines)*(h + interval) + interval;
|
|
else
|
|
y = icon_win_height - (n % Lines + 1)*(h + interval);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
item->x = x;
|
|
item->y = y;
|
|
|
|
if (item->icon_w > 0 && item->icon_h > 0){
|
|
w3 = min(max_icon_width, item->icon_w) + ICON_RELIEF;
|
|
h3 = min(max_icon_height, item->icon_h) + ICON_RELIEF;
|
|
}
|
|
XMoveResizeWindow(dpy, item->icon_pixmap_w, x + (w - w3)/2,
|
|
y + (h2 - h3)/2,w3,h3);
|
|
XMoveResizeWindow(dpy, item->IconWin, x,y + h2,w,h - h2);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Looks for a monochrome icon bitmap file
|
|
*
|
|
**************************************************************************/
|
|
void GetBitmapFile(struct icon_info *item)
|
|
{
|
|
char *path = NULL;
|
|
int HotX,HotY;
|
|
|
|
path = findIconFile(item->icon_file, iconPath,R_OK);
|
|
if(path == NULL)return;
|
|
|
|
if(XReadBitmapFile (dpy, Root,path,(unsigned int *)&item->icon_w,
|
|
(unsigned int *)&item->icon_h,
|
|
&item->iconPixmap,
|
|
(int *)&HotX,
|
|
(int *)&HotY) != BitmapSuccess)
|
|
{
|
|
item->icon_w = 0;
|
|
item->icon_h = 0;
|
|
}
|
|
else
|
|
item->icon_depth = 1;
|
|
|
|
item->icon_w = min(max_icon_width, item->icon_w);
|
|
item->icon_h = min(max_icon_height, item->icon_h);
|
|
item->icon_maskPixmap = None;
|
|
free(path);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Looks for a color XPM icon file
|
|
*
|
|
****************************************************************************/
|
|
void GetXPMFile(struct icon_info *item)
|
|
{
|
|
#ifdef XPM
|
|
XWindowAttributes root_attr;
|
|
XpmAttributes xpm_attributes;
|
|
char *path = NULL;
|
|
|
|
path = findIconFile(item->icon_file, pixmapPath,R_OK);
|
|
if(path == NULL)return;
|
|
|
|
XGetWindowAttributes(dpy,Root,&root_attr);
|
|
xpm_attributes.colormap = root_attr.colormap;
|
|
xpm_attributes.valuemask = XpmSize | XpmReturnPixels|XpmColormap;
|
|
if(XpmReadFileToPixmap(dpy, Root, path,
|
|
&item->iconPixmap,
|
|
&item->icon_maskPixmap,
|
|
&xpm_attributes) == XpmSuccess)
|
|
{
|
|
item->icon_w = min(max_icon_width, xpm_attributes.width);
|
|
item->icon_h = min(max_icon_height, xpm_attributes.height);
|
|
item->icon_depth = d_depth;
|
|
}
|
|
free(path);
|
|
#endif /* XPM */
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
*
|
|
* Looks for an application supplied icon window
|
|
*
|
|
***************************************************************************
|
|
*/
|
|
void GetIconWindow(struct icon_info *item)
|
|
{
|
|
int x, y;
|
|
unsigned int bw;
|
|
Window Junkroot;
|
|
|
|
if(!XGetGeometry(dpy, item->wmhints->icon_window, &Junkroot,
|
|
&x, &y, (unsigned int *)&item->icon_w,
|
|
(unsigned int *)&item->icon_h,
|
|
&bw, (unsigned int *)&item->icon_depth)){
|
|
fprintf(stderr,"Help! Bad Icon Window!\n");
|
|
exit(1);
|
|
}
|
|
|
|
item->icon_pixmap_w = item->wmhints->icon_window;
|
|
|
|
#ifdef SHAPE
|
|
if (item->wmhints->flags & IconMaskHint)
|
|
{
|
|
item->flags |= SHAPED_ICON;
|
|
item->icon_maskPixmap = item->wmhints->icon_mask;
|
|
}
|
|
#endif
|
|
|
|
item->icon_w = min(max_icon_width, item->icon_w);
|
|
item->icon_h = min(max_icon_height, item->icon_h);
|
|
|
|
XReparentWindow(dpy, item->icon_pixmap_w, icon_win, 0, 0);
|
|
XSetWindowBorderWidth(dpy, item->icon_pixmap_w, 0);
|
|
item->flags &= ~ICON_OURS;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
*
|
|
* Looks for an application supplied bitmap or pixmap
|
|
*
|
|
***************************************************************************
|
|
*/
|
|
void GetIconBitmap(struct icon_info *item)
|
|
{
|
|
int x, y;
|
|
unsigned int bw, depth;
|
|
Window Junkroot;
|
|
GC gc;
|
|
|
|
if (!XGetGeometry(dpy, item->wmhints->icon_pixmap, &Junkroot, &x, &y,
|
|
(unsigned int *)&item->icon_w,
|
|
(unsigned int *)&item->icon_h, &bw, &depth)){
|
|
fprintf(stderr, "invalid icon pixmap.\n");
|
|
exit(1);
|
|
}
|
|
|
|
item->icon_depth = depth;
|
|
item->icon_file = NULL;
|
|
item->icon_maskPixmap = None;
|
|
#ifdef SHAPE
|
|
if (item->wmhints->flags & IconMaskHint)
|
|
{
|
|
item->flags |= SHAPED_ICON;
|
|
item->icon_maskPixmap = item->wmhints->icon_mask;
|
|
}
|
|
#endif
|
|
|
|
item->icon_w = min(max_icon_width, item->icon_w);
|
|
item->icon_h = min(max_icon_height, item->icon_h);
|
|
|
|
item->iconPixmap = XCreatePixmap(dpy, Root, item->icon_w,
|
|
item->icon_h, depth);
|
|
gc = XCreateGC(dpy, item->iconPixmap, 0, NULL);
|
|
XCopyArea(dpy, item->wmhints->icon_pixmap, item->iconPixmap,
|
|
gc, 0, 0, item->icon_w, item->icon_h, 0, 0);
|
|
XFreeGC(dpy, gc);
|
|
}
|
|
|
|
Bool GetBackPixmap(void)
|
|
{
|
|
XWindowAttributes root_attr;
|
|
#ifdef XPM
|
|
XpmAttributes xpm_attributes;
|
|
#endif
|
|
char *path = NULL;
|
|
Pixmap tmp_bitmap, maskPixmap;
|
|
int x, y, w=0, h=0;
|
|
|
|
if (IconwinPixmapFile == NULL)
|
|
return False;
|
|
|
|
if ((path = findIconFile(IconwinPixmapFile, iconPath,R_OK)) != NULL){
|
|
if (XReadBitmapFile(dpy, Root,path,(unsigned int *)&w,
|
|
(unsigned int *)&h, &tmp_bitmap,
|
|
(int *)&x, (int *)&y)!= BitmapSuccess)
|
|
w = h = 0;
|
|
else{
|
|
IconwinPixmap = XCreatePixmap(dpy, Root, w, h, d_depth);
|
|
XCopyPlane(dpy, tmp_bitmap, IconwinPixmap, NormalGC, 0, 0, w, h,
|
|
0, 0, 1);
|
|
XFreePixmap(dpy, tmp_bitmap);
|
|
}
|
|
free(path);
|
|
}
|
|
|
|
#ifdef XPM
|
|
if ( w == 0 && h == 0 && (path = findIconFile(IconwinPixmapFile,
|
|
pixmapPath,R_OK)) != NULL)
|
|
{
|
|
XGetWindowAttributes(dpy,Root,&root_attr);
|
|
xpm_attributes.colormap = root_attr.colormap;
|
|
xpm_attributes.valuemask = XpmSize|XpmReturnPixels|XpmColormap;
|
|
if (XpmReadFileToPixmap(dpy, Root, path, &IconwinPixmap,
|
|
&maskPixmap, &xpm_attributes) ==
|
|
XpmSuccess){
|
|
w = xpm_attributes.width;
|
|
h = xpm_attributes.height;
|
|
}
|
|
free(path);
|
|
}
|
|
#endif
|
|
if (w != 0 && h != 0)
|
|
return True;
|
|
return False;
|
|
}
|