dockapps/wmmemfree/dockapp.c
2018-07-14 00:05:48 +01:00

298 lines
8.8 KiB
C

/*
* dockapp.c - dockapp part
*
* Copyright (C) 2003 Draghicioiu Mihai <misuceldestept@go.ro>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/shapeconst.h>
#include <X11/cursorfont.h>
#include "wmmemfree.h"
#include "options.h"
#include "xpm/bg.xpm"
#include "xpm/on.xpm"
#include "xpm/off.xpm"
#include "xpm/numbers.xpm"
#include "xpm/panel.xpm"
#define WINDOW_WIDTH 64
#define WINDOW_HEIGHT 64
Display *display;
int screen;
Window iconwindow, window, mapwindow;
Colormap colormap;
GC gc;
Pixmap background, backgroundmask, on, off, numbers, buffer, panel;
Atom wm_delete_window;
Atom _motif_wm_hints;
int moving, oldx, oldy;
int screenwidth, screenheight;
Cursor fleur;
void free_stuff()
{
XUnmapWindow(display, mapwindow);
XFreeGC(display, gc);
XDestroyWindow(display, iconwindow);
XDestroyWindow(display, window);
XFreePixmap(display, buffer);
XFreePixmap(display, numbers);
XFreePixmap(display, off);
XFreePixmap(display, on);
XFreePixmap(display, backgroundmask);
XFreePixmap(display, background);
XCloseDisplay(display);
}
void handle_signal(int sig)
{
switch(sig)
{
case SIGINT:
fprintf(stderr, "Interrupt received\n");
break;
case SIGQUIT:
fprintf(stderr, "Quit signal received\n");
break;
case SIGTERM:
fprintf(stderr, "Terminate signal received\n");
default:
fprintf(stderr, "Got signal %d\n", sig);
}
stop_timer();
free_stuff();
exit(0);
}
void make_window()
{
Window rootwindow;
XpmAttributes xpmattributes;
XSetWindowAttributes windowattributes;
int shapeevent, shapeerror;
XWMHints *wmhints;
XClassHint *classhint;
XSizeHints *sizehints;
XGCValues gcvalues;
unsigned int depth;
struct
{
long flags;
long functions;
long decorations;
long input_mode;
long unknown;
} mwmhints;
display = XOpenDisplay(opt_display);
if(!display)
{
fprintf(stderr, "Could not open display %s\n", opt_display);
exit(1);
}
screen = DefaultScreen(display);
screenwidth = DisplayWidth(display, screen);
screenheight = DisplayHeight(display, screen);
rootwindow = RootWindow(display, screen);
colormap = DefaultColormap(display, screen);
depth = DefaultDepth(display, screen);
xpmattributes.valuemask = XpmColormap | XpmCloseness;
xpmattributes.colormap = colormap;
xpmattributes.closeness = 40000;
XpmCreatePixmapFromData(display, rootwindow, bg_xpm,
&background, &backgroundmask, &xpmattributes);
XpmCreatePixmapFromData(display, rootwindow, on_xpm,
&on, None, &xpmattributes);
XpmCreatePixmapFromData(display, rootwindow, off_xpm,
&off, None, &xpmattributes);
XpmCreatePixmapFromData(display, rootwindow, numbers_xpm,
&numbers, None, &xpmattributes);
buffer = XCreatePixmap(display, rootwindow,
WINDOW_WIDTH, WINDOW_HEIGHT, depth);
windowattributes.background_pixmap = background;
windowattributes.event_mask = ExposureMask |
ButtonPressMask |
ButtonReleaseMask |
PointerMotionMask |
PropertyChangeMask;
windowattributes.colormap = colormap;
window = XCreateWindow(display, rootwindow,
0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixmap | CWEventMask | CWColormap,
&windowattributes);
iconwindow = XCreateWindow(display, rootwindow,
0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixmap | CWEventMask,
&windowattributes);
fleur = XCreateFontCursor(display, XC_fleur);
if(XShapeQueryExtension(display, &shapeevent, &shapeerror) && opt_shape)
{
XShapeCombineMask(display, window, ShapeBounding,
0, 0, backgroundmask, ShapeSet);
XShapeCombineMask(display, iconwindow, ShapeBounding,
0, 0, backgroundmask, ShapeSet);
}
else
{
XpmCreatePixmapFromData(display, rootwindow, panel_xpm,
&panel, None, &xpmattributes);
gcvalues.function = GXcopy;
gcvalues.graphics_exposures = False;
gcvalues.clip_mask = backgroundmask;
gcvalues.clip_x_origin = 0;
gcvalues.clip_y_origin = 0;
gc = XCreateGC(display, rootwindow,
GCFunction |
GCGraphicsExposures |
GCClipMask |
GCClipXOrigin |
GCClipYOrigin,
&gcvalues);
XCopyArea(display, background, panel, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
gcvalues.clip_mask = None;
XChangeGC(display, gc, GCClipMask, &gcvalues);
XCopyArea(display, panel, background, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
XFreeGC(display, gc);
XFreePixmap(display, panel);
}
mapwindow = opt_window ? iconwindow : window;
wmhints = XAllocWMHints();
wmhints -> flags = InputHint | WindowGroupHint | IconWindowHint | StateHint;
wmhints -> input = True;
wmhints -> window_group = window;
wmhints -> icon_window = iconwindow;
wmhints -> initial_state = WithdrawnState;
XSetWMHints(display, window, wmhints);
XFree(wmhints);
classhint = XAllocClassHint();
classhint -> res_name = OPT_CLASS_NAME;
classhint -> res_class = OPT_CLASS_CLASS;
XSetClassHint(display, mapwindow, classhint);
XFree(classhint);
sizehints = XAllocSizeHints();
sizehints -> flags = USSize | PSize | PMinSize | PMaxSize | PBaseSize;
sizehints -> width = WINDOW_WIDTH;
sizehints -> height = WINDOW_HEIGHT;
sizehints -> min_width = WINDOW_WIDTH;
sizehints -> min_height = WINDOW_HEIGHT;
sizehints -> max_width = WINDOW_WIDTH;
sizehints -> max_height = WINDOW_HEIGHT;
sizehints -> base_width = WINDOW_WIDTH;
sizehints -> base_height = WINDOW_HEIGHT;
XSetWMNormalHints(display, mapwindow, sizehints);
XFree(sizehints);
XStoreName(display, window, OPT_WINDOW_NAME);
XStoreName(display, iconwindow, OPT_WINDOW_NAME); /* For other wms */
gcvalues.graphics_exposures = False;
gcvalues.function = GXcopy;
gc = XCreateGC(display, rootwindow,
GCGraphicsExposures | GCFunction,
&gcvalues);
XCopyArea(display, background, buffer, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
XSetCommand(display, window, argv, argc);
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(display, mapwindow, &wm_delete_window, 1);
if(opt_window)
{
_motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
mwmhints.flags = 2;
mwmhints.functions = 0x71; /* WTF IS THIS ? */
mwmhints.decorations = 0;
XChangeProperty(display, mapwindow,
_motif_wm_hints, _motif_wm_hints,
32, PropModeReplace, (unsigned char *)&mwmhints, 5);
}
XMapWindow(display, mapwindow);
signal(SIGINT, handle_signal);
signal(SIGQUIT, handle_signal);
signal(SIGTERM, handle_signal);
}
void update_window()
{
XCopyArea(display, buffer, iconwindow, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
XCopyArea(display, buffer, window, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
}
void process_events()
{
XEvent event;
int winx, winy;
XNextEvent(display, &event);
switch(event.type)
{
case Expose:
update_window();
break;
case ButtonPress:
if(opt_window && (event.xbutton.button == 1))
{
XDefineCursor(display, mapwindow, fleur);
moving = 1;
oldx = event.xbutton.x;
oldy = event.xbutton.y;
}
break;
case MotionNotify:
winx = event.xmotion.x_root - oldx;
winy = event.xmotion.y_root - oldy;
if(winx < 0) winx = 0;
if(winy < 0) winy = 0;
if(winx > (screenwidth - WINDOW_WIDTH))
winx = screenwidth - WINDOW_WIDTH;
if(winy > (screenheight - WINDOW_HEIGHT))
winy = screenheight - WINDOW_HEIGHT;
if(moving)
XMoveWindow(display, mapwindow, winx, winy);
break;
case ButtonRelease:
if(opt_window)
{
moving = 0;
XUndefineCursor(display, mapwindow);
}
break;
case ClientMessage:
if(event.xclient.data.l[0] == wm_delete_window)
exitloop = 1;
break;
}
}