2014-11-28 16:22:47 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1999-2003 Alfredo K. Kojima, Alban Hertroys
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "dockapp.h"
|
|
|
|
#include "daargs.h"
|
|
|
|
#include "dautil.h"
|
|
|
|
|
2014-11-28 16:22:51 +00:00
|
|
|
#define MIN(a, b) (a < b ? a : b)
|
2014-11-28 16:22:47 +00:00
|
|
|
|
|
|
|
struct DAContext *_daContext;
|
|
|
|
|
2014-11-28 16:22:51 +00:00
|
|
|
DARect DANoRect = {0, 0, 0, 0};
|
|
|
|
Display *DADisplay = NULL;
|
|
|
|
Window DALeader = None;
|
|
|
|
Window DAIcon = None;
|
|
|
|
Window DAWindow = None;
|
|
|
|
int DADepth = 0;
|
|
|
|
Visual *DAVisual = NULL;
|
|
|
|
unsigned long DAExpectedVersion = 0;
|
|
|
|
GC DAGC = NULL, DAClearGC = NULL;
|
|
|
|
DARect DAPreferredIconSizes = {-1, -1, 0, 0};
|
|
|
|
Atom WM_DELETE_WINDOW;
|
2014-11-28 16:22:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DAOpenDisplay(char *display, int argc, char **argv)
|
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
/* Open Connection to X Server */
|
|
|
|
DADisplay = XOpenDisplay(display);
|
|
|
|
if (!DADisplay) {
|
|
|
|
printf("%s: could not open display %s!\n", _daContext->programName,
|
|
|
|
XDisplayName(display));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
DADepth = DefaultDepth(DADisplay, DefaultScreen(DADisplay));
|
|
|
|
DAVisual = DefaultVisual(DADisplay, DefaultScreen(DADisplay));
|
|
|
|
DAGC = DefaultGC(DADisplay, DefaultScreen(DADisplay));
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DAProposeIconSize(unsigned width, unsigned height)
|
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
XIconSize *iconSizes;
|
|
|
|
int nrSizes = 0;
|
|
|
|
|
|
|
|
_daContext->width = width;
|
|
|
|
_daContext->height = height;
|
|
|
|
|
|
|
|
/* Get the nearest allowed icon size if the WM specifies such */
|
|
|
|
iconSizes = XAllocIconSize();
|
|
|
|
if (XGetIconSizes(DADisplay, DefaultRootWindow(DADisplay),
|
|
|
|
&iconSizes, &nrSizes)) {
|
|
|
|
int i;
|
|
|
|
int da = -1;
|
|
|
|
int min_w = -1, min_h = -1;
|
|
|
|
int max_w = 0, max_h = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < nrSizes; i++) {
|
|
|
|
int w1, h1, w, h;
|
|
|
|
|
|
|
|
if ((max_w < iconSizes[i].max_width) ||
|
|
|
|
(max_h < iconSizes[i].max_height)) {
|
|
|
|
max_w = iconSizes[i].max_width;
|
|
|
|
max_h = iconSizes[i].max_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((min_w > iconSizes[i].min_width) ||
|
|
|
|
(min_h > iconSizes[i].min_height) ||
|
|
|
|
(min_w == -1)) {
|
|
|
|
min_w = iconSizes[i].min_width;
|
|
|
|
min_h = iconSizes[i].min_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((width > iconSizes[i].max_width) ||
|
|
|
|
(width < iconSizes[i].min_width) ||
|
|
|
|
(height > iconSizes[i].max_height) ||
|
|
|
|
(height < iconSizes[i].min_height))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
w1 = (iconSizes[i].max_width - width) % iconSizes[i].width_inc;
|
|
|
|
h1 = (iconSizes[i].max_height - height) % iconSizes[i].height_inc;
|
|
|
|
w = MIN(w1, iconSizes[i].width_inc - w1);
|
|
|
|
h = MIN(h1, iconSizes[i].height_inc - h1);
|
|
|
|
|
|
|
|
if ((w * h < da) || (da == -1)) {
|
|
|
|
_daContext->width = width + w;
|
|
|
|
_daContext->height = height + h;
|
|
|
|
da = w * h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DAPreferredIconSizes.x = min_w;
|
|
|
|
DAPreferredIconSizes.y = min_h;
|
|
|
|
DAPreferredIconSizes.width = max_w;
|
|
|
|
DAPreferredIconSizes.height = max_h;
|
|
|
|
|
|
|
|
if (da == -1) /* requested size is out of bounds */
|
|
|
|
DAWarning("Requested icon-size (%d x %d) is out of the range "
|
|
|
|
"allowed by the window manager\n",
|
|
|
|
_daContext->width, _daContext->height);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
2014-11-28 16:22:51 +00:00
|
|
|
XFree(iconSizes);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DACreateIcon(char *name, unsigned width, unsigned height, int argc, char **argv)
|
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
XClassHint *classHint;
|
|
|
|
XWMHints *wmHints;
|
|
|
|
XGCValues gcv;
|
|
|
|
unsigned long valueMask;
|
|
|
|
char *resourceValue;
|
|
|
|
|
|
|
|
_daContext->width = width;
|
|
|
|
_daContext->height = height;
|
|
|
|
|
|
|
|
/* Create Windows */
|
|
|
|
DALeader = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay),
|
|
|
|
0, 0, width, height, 0, 0, 0);
|
|
|
|
|
|
|
|
if (!_daContext->windowed) {
|
|
|
|
DAIcon = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay),
|
|
|
|
0, 0, width, height, 0, 0, 0);
|
|
|
|
DAWindow = DAIcon;
|
|
|
|
} else {
|
|
|
|
DAIcon = None;
|
|
|
|
DAWindow = DALeader;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set ClassHint */
|
|
|
|
classHint = XAllocClassHint();
|
|
|
|
if (!classHint)
|
|
|
|
printf("%s: can't allocate memory for class hints!\n",
|
|
|
|
_daContext->programName), exit(1);
|
|
|
|
classHint->res_class = RES_CLASSNAME;
|
|
|
|
classHint->res_name = name;
|
|
|
|
|
|
|
|
XSetClassHint(DADisplay, DALeader, classHint);
|
|
|
|
XFree(classHint);
|
|
|
|
|
|
|
|
/* Set WMHints */
|
|
|
|
wmHints = XAllocWMHints();
|
|
|
|
if (!wmHints)
|
|
|
|
printf("%s: can't allocate memory for wm hints!\n",
|
|
|
|
_daContext->programName), exit(1);
|
|
|
|
|
|
|
|
wmHints->flags = WindowGroupHint;
|
|
|
|
wmHints->window_group = DALeader;
|
|
|
|
|
|
|
|
if (!_daContext->windowed) {
|
|
|
|
wmHints->flags |= IconWindowHint|StateHint;
|
|
|
|
wmHints->icon_window = DAIcon;
|
|
|
|
wmHints->initial_state = WithdrawnState;
|
|
|
|
}
|
|
|
|
|
|
|
|
XSetWMHints(DADisplay, DALeader, wmHints);
|
|
|
|
XFree(wmHints);
|
|
|
|
|
|
|
|
/* Set WMProtocols */
|
|
|
|
WM_DELETE_WINDOW = XInternAtom(DADisplay, "WM_DELETE_WINDOW", True);
|
|
|
|
XSetWMProtocols(DADisplay, DALeader, &WM_DELETE_WINDOW, 1);
|
|
|
|
|
|
|
|
/* Set Command to start the app so it can be docked properly */
|
|
|
|
XSetCommand(DADisplay, DALeader, argv, argc);
|
|
|
|
|
|
|
|
gcv.graphics_exposures = False;
|
|
|
|
valueMask = GCGraphicsExposures;
|
|
|
|
|
|
|
|
/* continue setting the foreground GC */
|
|
|
|
resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "foreground");
|
|
|
|
if (resourceValue) {
|
|
|
|
gcv.foreground = DAGetColor(resourceValue);
|
|
|
|
valueMask |= GCForeground;
|
|
|
|
}
|
|
|
|
|
|
|
|
XChangeGC(DADisplay, DAGC, valueMask, &gcv);
|
|
|
|
|
|
|
|
/* set background GC values before setting value for foreground */
|
|
|
|
resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "background");
|
|
|
|
if (resourceValue)
|
|
|
|
gcv.foreground = DAGetColor(resourceValue);
|
|
|
|
|
|
|
|
DAClearGC = XCreateGC(DADisplay, DAWindow,
|
|
|
|
GCGraphicsExposures|GCForeground, &gcv);
|
|
|
|
|
|
|
|
XFlush(DADisplay);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DAShow(void)
|
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
DAShowWindow(DALeader);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DAShowWindow(Window window)
|
|
|
|
|
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
XMapRaised(DADisplay, window);
|
|
|
|
if ((window == DALeader) && !_daContext->windowed)
|
|
|
|
XMapSubwindows(DADisplay, DAIcon);
|
|
|
|
else
|
|
|
|
XMapSubwindows(DADisplay, window);
|
|
|
|
|
|
|
|
XFlush(DADisplay);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Deprecated */
|
|
|
|
void
|
|
|
|
DAInitialize(char *display, char *name, unsigned width, unsigned height,
|
2014-11-28 16:22:51 +00:00
|
|
|
int argc, char **argv)
|
2014-11-28 16:22:47 +00:00
|
|
|
{
|
2014-11-28 16:22:51 +00:00
|
|
|
DAOpenDisplay(display, argc, argv);
|
|
|
|
DACreateIcon(name, width, height, argc, argv);
|
2014-11-28 16:22:47 +00:00
|
|
|
}
|