mirror of
https://github.com/openbsd/xenocara.git
synced 2025-12-11 03:39:26 +00:00
Importing from XF4, plus BSD make infrastructure
This commit is contained in:
34
app/fvwm/libs/ClientMsg.c
Normal file
34
app/fvwm/libs/ClientMsg.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all
|
||||
* client messages will have the following form:
|
||||
*
|
||||
* event type ClientMessage
|
||||
* message type _XA_WM_PROTOCOLS
|
||||
* window tmp->w
|
||||
* format 32
|
||||
* data[0] message atom
|
||||
* data[1] time stamp
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
Atom _XA_WM_PROTOCOLS = None;
|
||||
|
||||
void send_clientmessage (Display *disp, Window w, Atom a, Time timestamp)
|
||||
{
|
||||
XClientMessageEvent ev;
|
||||
|
||||
if (_XA_WM_PROTOCOLS == None)
|
||||
_XA_WM_PROTOCOLS = XInternAtom(disp, "WM_PROTOCOLS", False);
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = w;
|
||||
ev.message_type = _XA_WM_PROTOCOLS;
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = a;
|
||||
ev.data.l[1] = timestamp;
|
||||
XSendEvent (disp, w, False, 0L, (XEvent *) &ev);
|
||||
}
|
||||
261
app/fvwm/libs/ColorUtils.c
Normal file
261
app/fvwm/libs/ColorUtils.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* The following GPL code from scwm implements a good, fast 3D-shadowing
|
||||
* algorithm. It converts the color from RGB to HLS space, then
|
||||
* multiplies both the luminosity and the saturation by a specified
|
||||
* factor (clipping at the extremes). Then it converts back to RGB and
|
||||
* creates a color. The guts of it, i.e. the `color_mult' routine, looks
|
||||
* a bit longish, but this is only because there are 6-way conditionals
|
||||
* at the begining and end; it actually runs quite fast. The algorithm is
|
||||
* the same as Gtk's, but the implemenation is independent and more
|
||||
* streamlined.
|
||||
*
|
||||
* Calling `adjust_pixel_brightness' with a `factor' of 1.3 for hilights
|
||||
* and 0.7 for shadows exactly emulates Gtk's shadowing, which is, IMO
|
||||
* the most visually pleasing shadowing of any widget set; using 1.2 and
|
||||
* 0.5 respectively gives something closer to the "classic" fvwm effect
|
||||
* with deeper shadows and more subtle hilights, but still (IMO) smoother
|
||||
* and more attractive than fvwm.
|
||||
*
|
||||
* The only color these routines do not usefully handle is black; black
|
||||
* will be returned even for a factor greater than 1.0, when optimally
|
||||
* one would like to see a very dark gray. This could possibly be
|
||||
* addressed by adding a small additive factor when brightening
|
||||
* colors. If anyone adds that feature, please feed it upstream to me.
|
||||
*
|
||||
* Feel free to use this code in fvwm2, of course.
|
||||
*
|
||||
* - Maciej Stachowiak
|
||||
*
|
||||
* And, of course, history shows, we took him up on the offer.
|
||||
* Integrated into fvwm2 by Dan Espen, 11/13/98.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997, 1998, Maciej Stachowiak and Greg J. Badros
|
||||
*
|
||||
* 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, 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 software; see the file COPYING.GPL. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h" /* must be first */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <X11/Xproto.h> /* for X functions in general */
|
||||
#include "fvwmlib.h" /* prototype GetShadow GetHilit */
|
||||
|
||||
#define SCALE 65535.0
|
||||
#define HALF_SCALE (SCALE / 2)
|
||||
typedef enum {
|
||||
R_MAX_G_MIN, R_MAX_B_MIN,
|
||||
G_MAX_B_MIN, G_MAX_R_MIN,
|
||||
B_MAX_R_MIN, B_MAX_G_MIN
|
||||
} MinMaxState;
|
||||
|
||||
|
||||
/* Multiply the HLS-space lightness and saturation of the color by the
|
||||
given multiple, k - based on the way gtk does shading, but independently
|
||||
coded. Should give better relief colors for many cases than the old
|
||||
fvwm algorithm. */
|
||||
|
||||
/* FIXMS: This can probably be optimized more, examine later. */
|
||||
|
||||
static void
|
||||
color_mult (unsigned short *red,
|
||||
unsigned short *green,
|
||||
unsigned short *blue, double k)
|
||||
{
|
||||
if (*red == *green && *red == *blue) {
|
||||
double temp;
|
||||
/* A shade of gray */
|
||||
temp = k * (double) (*red);
|
||||
if (temp > SCALE) {
|
||||
temp = SCALE;
|
||||
}
|
||||
*red = (unsigned short)(temp);
|
||||
*green = *red;
|
||||
*blue = *red;
|
||||
} else {
|
||||
/* Non-zero saturation */
|
||||
double r, g, b;
|
||||
double min, max;
|
||||
double a, l, s;
|
||||
double delta;
|
||||
double middle;
|
||||
MinMaxState min_max_state;
|
||||
|
||||
r = (double) *red;
|
||||
g = (double) *green;
|
||||
b = (double) *blue;
|
||||
|
||||
if (r > g) {
|
||||
if (r > b) {
|
||||
max = r;
|
||||
if (g < b) {
|
||||
min = g;
|
||||
min_max_state = R_MAX_G_MIN;
|
||||
a = b - g;
|
||||
} else {
|
||||
min = b;
|
||||
min_max_state = R_MAX_B_MIN;
|
||||
a = g - b;
|
||||
}
|
||||
} else {
|
||||
max = b;
|
||||
min = g;
|
||||
min_max_state = B_MAX_G_MIN;
|
||||
a = r - g;
|
||||
}
|
||||
} else {
|
||||
if (g > b) {
|
||||
max = g;
|
||||
if (b < r) {
|
||||
min = b;
|
||||
min_max_state = G_MAX_B_MIN;
|
||||
a = r - b;
|
||||
} else {
|
||||
min = r;
|
||||
min_max_state = G_MAX_R_MIN;
|
||||
a = b - r;
|
||||
}
|
||||
} else {
|
||||
max = b;
|
||||
min = r;
|
||||
min_max_state = B_MAX_R_MIN;
|
||||
a = g - r;
|
||||
}
|
||||
}
|
||||
|
||||
delta = max - min;
|
||||
a = a / delta;
|
||||
|
||||
l = (max + min) / 2;
|
||||
if (l <= HALF_SCALE) {
|
||||
s = max + min;
|
||||
} else {
|
||||
s = 2.0 * SCALE - (max + min);
|
||||
}
|
||||
s = delta/s;
|
||||
|
||||
l *= k;
|
||||
if (l > SCALE) {
|
||||
l = SCALE;
|
||||
}
|
||||
s *= k;
|
||||
if (s > 1.0) {
|
||||
s = 1.0;
|
||||
}
|
||||
|
||||
if (l <= HALF_SCALE) {
|
||||
max = l * (1 + s);
|
||||
} else {
|
||||
max = s * SCALE + l - s * l;
|
||||
}
|
||||
|
||||
min = 2 * l - max;
|
||||
delta = max - min;
|
||||
middle = min + delta * a;
|
||||
|
||||
switch (min_max_state) {
|
||||
case R_MAX_G_MIN:
|
||||
r = max;
|
||||
g = min;
|
||||
b = middle;
|
||||
break;
|
||||
case R_MAX_B_MIN:
|
||||
r = max;
|
||||
g = middle;
|
||||
b = min;
|
||||
break;
|
||||
case G_MAX_B_MIN:
|
||||
r = middle;
|
||||
g = max;
|
||||
b = min;
|
||||
break;
|
||||
case G_MAX_R_MIN:
|
||||
r = min;
|
||||
g = max;
|
||||
b = middle;
|
||||
break;
|
||||
case B_MAX_G_MIN:
|
||||
r = middle;
|
||||
g = min;
|
||||
b = max;
|
||||
break;
|
||||
case B_MAX_R_MIN:
|
||||
r = min;
|
||||
g = middle;
|
||||
b = max;
|
||||
break;
|
||||
}
|
||||
|
||||
*red = (unsigned short) r;
|
||||
*green = (unsigned short) g;
|
||||
*blue = (unsigned short) b;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine uses PictureSaveDisplay and PictureCMap which must be
|
||||
* created by InitPictureCMAP in Picture.c.
|
||||
*
|
||||
* If you attempt to use GetShadow and GetHilit, make sure your module
|
||||
* calls InitPictureCMAP first.
|
||||
*/
|
||||
static Pixel
|
||||
adjust_pixel_brightness(Pixel pixel, double factor)
|
||||
{
|
||||
extern Colormap PictureCMap;
|
||||
extern Display *PictureSaveDisplay;
|
||||
XColor c;
|
||||
c.pixel = pixel;
|
||||
XQueryColor (PictureSaveDisplay, PictureCMap, &c);
|
||||
color_mult(&c.red, &c.green, &c.blue, factor);
|
||||
XAllocColor (PictureSaveDisplay, PictureCMap, &c);
|
||||
|
||||
return c.pixel;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the original fvwm2 APIs, one for highlights and one for
|
||||
* shadows. Together, if used in a frame around a rectangle, they
|
||||
* produce a 3d appearance.
|
||||
*
|
||||
* The input pixel, is normally the background color used in the
|
||||
* rectangle. One would hope, when the user selects to color something
|
||||
* with a multi-color pixmap, they will have the insight to also assign a
|
||||
* background color to the pixmaped area that approximates the average
|
||||
* color of the pixmap.
|
||||
*
|
||||
* Currently callers handle monochrome before calling this routine. The
|
||||
* next logical enhancement is for that logic to be moved here. Probably
|
||||
* a new API that deals with foreground/background/hilite/shadow
|
||||
* allocation all in 1 call is the next logical extenstion.
|
||||
*
|
||||
* Color allocation is also a good candidate for becoming a library
|
||||
* routine. The color allocation logic in FvwmButtons using the XPM
|
||||
* library closeness stuff may be the ideal model.
|
||||
* (dje 11/15/98)
|
||||
*/
|
||||
#define DARKNESS_FACTOR 0.5
|
||||
Pixel GetShadow(Pixel background) {
|
||||
return adjust_pixel_brightness(background, DARKNESS_FACTOR);
|
||||
}
|
||||
|
||||
#define BRIGHTNESS_FACTOR 1.4
|
||||
Pixel GetHilite(Pixel background) {
|
||||
return adjust_pixel_brightness(background, BRIGHTNESS_FACTOR);
|
||||
}
|
||||
32
app/fvwm/libs/GetFont.c
Normal file
32
app/fvwm/libs/GetFont.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
/*
|
||||
** loads font or "fixed" on failure
|
||||
*/
|
||||
XFontStruct *GetFontOrFixed(Display *disp, char *fontname)
|
||||
{
|
||||
XFontStruct *fnt;
|
||||
|
||||
if ((fnt = XLoadQueryFont(disp,fontname))==NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[GetFontOrFixed]: WARNING -- can't get font %s, trying 'fixed'",
|
||||
fontname);
|
||||
/* fixed should always be avail, so try that */
|
||||
if ((fnt = XLoadQueryFont(disp,"fixed"))==NULL)
|
||||
{
|
||||
fprintf(stderr,"[GetFontOrFixed]: ERROR -- can't get font 'fixed'");
|
||||
}
|
||||
}
|
||||
return fnt;
|
||||
}
|
||||
|
||||
38
app/fvwm/libs/GetFontSet.c
Normal file
38
app/fvwm/libs/GetFontSet.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/* This file brings from GetFont.c */
|
||||
|
||||
#include "../configure.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
/*
|
||||
** loads fontset or "fixed" on failure
|
||||
*/
|
||||
XFontSet GetFontSetOrFixed(Display *disp, char *fontname)
|
||||
{
|
||||
XFontSet fontset;
|
||||
char **ml;
|
||||
int mc;
|
||||
char *ds;
|
||||
|
||||
if ((fontset = XCreateFontSet(disp,fontname,&ml,&mc,&ds))==NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[FVWM][GetFontSetOrFixed]: WARNING -- can't get fontset %s, trying 'fixed'\n",
|
||||
fontname);
|
||||
/* fixed should always be avail, so try that */
|
||||
/* plain X11R6.3 hack */
|
||||
if ((fontset = XCreateFontSet(disp,"fixed,-*--14-*",&ml,&mc,&ds))==NULL)
|
||||
{
|
||||
fprintf(stderr,"[FVWM][GetFontSetOrFixed]: ERROR -- can't get fontset 'fixed'\n");
|
||||
}
|
||||
}
|
||||
return fontset;
|
||||
}
|
||||
|
||||
31
app/fvwm/libs/Grab.c
Normal file
31
app/fvwm/libs/Grab.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
** MyXGrabServer & MyXUngrabServer - to handle nested grab server calls
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/* Made into global for module interface. See module.c. */
|
||||
int myxgrabcount = 0;
|
||||
|
||||
void MyXGrabServer(Display *disp)
|
||||
{
|
||||
if (myxgrabcount == 0)
|
||||
{
|
||||
XGrabServer(disp);
|
||||
}
|
||||
++myxgrabcount;
|
||||
}
|
||||
|
||||
void MyXUngrabServer(Display *disp)
|
||||
{
|
||||
if (--myxgrabcount < 0) /* should never happen */
|
||||
{
|
||||
/* fvwm_msg(ERR,"MyXUngrabServer","too many ungrabs!\n"); */
|
||||
myxgrabcount = 0;
|
||||
}
|
||||
if (myxgrabcount == 0)
|
||||
{
|
||||
XUngrabServer(disp);
|
||||
}
|
||||
}
|
||||
|
||||
20
app/fvwm/libs/Imakefile
Normal file
20
app/fvwm/libs/Imakefile
Normal file
@@ -0,0 +1,20 @@
|
||||
XCOMM $OpenBSD: Imakefile,v 1.1.1.1 2006/11/26 10:53:40 matthieu Exp $
|
||||
|
||||
#define DoNormalLib YES
|
||||
#define LibName fvwm
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
SRCS= ClientMsg.c GetFont.c Grab.c ModParse.c ModParse.h \
|
||||
Module.c Parse.c Picture.c Strings.c System.c \
|
||||
envvar.c fvwmlib.h safemalloc.c wild.c \
|
||||
lang-strings.h XResource.c debug.c ColorUtils.c
|
||||
|
||||
OBJS= ClientMsg.o GetFont.o Grab.o ModParse.o ModParse.h \
|
||||
Module.o Parse.o Picture.o Strings.o System.o \
|
||||
envvar.o fvwmlib.h safemalloc.o wild.o \
|
||||
lang-strings.h XResource.o debug.o ColorUtils.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
DependTarget()
|
||||
20
app/fvwm/libs/Makefile
Normal file
20
app/fvwm/libs/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
# $Xenocara: Makefile,v 1.1 2006/04/17 17:51:34 matthieu Exp $
|
||||
|
||||
.include "../Makefile.inc"
|
||||
|
||||
.PATH: $(DIST)/libs
|
||||
|
||||
LIB= fvwm
|
||||
SRCS= ClientMsg.c GetFont.c Grab.c ModParse.c ModParse.h \
|
||||
Module.c Parse.c Picture.c Strings.c System.c \
|
||||
envvar.c fvwmlib.h safemalloc.c wild.c \
|
||||
lang-strings.h XResource.c debug.c ColorUtils.c
|
||||
|
||||
DEBUGLIBS= no
|
||||
NOPROFILE= yes
|
||||
NOPIC= yes
|
||||
|
||||
install:
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
.include <bsd.xorg.mk>
|
||||
316
app/fvwm/libs/ModParse.c
Normal file
316
app/fvwm/libs/ModParse.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
File: ModParse.c
|
||||
|
||||
Modifications:
|
||||
|
||||
Changed 08/30/98 by Dan Espen:
|
||||
- Copied from FvwmEvent/Parse.c. Set up for general use by modules.
|
||||
Still to be done, try to integrate with Parse.c which is used by fvwm
|
||||
itself for parsing.
|
||||
*/
|
||||
|
||||
|
||||
#include "fvwmlib.h"
|
||||
#include "ModParse.h"
|
||||
|
||||
/*
|
||||
** PeekArgument: returns next token from string, leaving string intact
|
||||
** (you should free returned string later)
|
||||
**
|
||||
** notes - quotes and brakets deonte blocks, which are returned MINUS
|
||||
** the start & end delimiters. Delims within block may be escaped
|
||||
** with a backslash \ (which is removed when returned). Backslash
|
||||
** must be escaped too, if you want one... (\\). Arguments may be up
|
||||
** to MAX_TOKEN_LENGTH in size.
|
||||
*/
|
||||
|
||||
|
||||
char *DoPeekArgument(const char *pstr, char **pret)
|
||||
{
|
||||
char *tok=NULL;
|
||||
const char *p;
|
||||
char bc=0,be=0,tmptok[MAX_TOKEN_LENGTH];
|
||||
int len=0;
|
||||
|
||||
if (!pstr)
|
||||
return NULL;
|
||||
|
||||
p=pstr;
|
||||
EatWS(p); /* skip leading space */
|
||||
if (*p)
|
||||
{
|
||||
if (IsQuote(*p) || IsBlockStart(*p)) /* quoted string or block start? */
|
||||
{
|
||||
bc = *p; /* save block start char */
|
||||
p++;
|
||||
}
|
||||
/* find end of token */
|
||||
while (*p && len < MAX_TOKEN_LENGTH)
|
||||
{
|
||||
/* first, check stop conditions based on block or normal token */
|
||||
if (bc)
|
||||
{
|
||||
if ((IsQuote(*p) && bc == *p) || IsBlockEnd(*p,bc))
|
||||
{
|
||||
be = *p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* normal token */
|
||||
{
|
||||
if (isspace(*p) || *p == ',')
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == '\\' && *(p+1)) /* if \, copy next char verbatim */
|
||||
p++;
|
||||
tmptok[len] = *p;
|
||||
len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* sanity checks: */
|
||||
if (bc && !be) /* did we have block start, but not end? */
|
||||
{
|
||||
/* should yell about this */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
tok = (char *)safemalloc(len+1);
|
||||
strncpy(tok,tmptok,len);
|
||||
tok[len]='\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (!isspace(*p)) p++;
|
||||
if (pret) *pret = p;
|
||||
return tok;
|
||||
}
|
||||
|
||||
char *PeekArgument(const char *pstr)
|
||||
{
|
||||
return DoPeekArgument(pstr, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
** GetArgument: destructively rips next token from string, returning it
|
||||
** (you should free returned string later)
|
||||
*/
|
||||
char *GetArgument(char **pstr)
|
||||
{
|
||||
char *tok ;
|
||||
|
||||
if (!pstr || !*pstr || !(tok=DoPeekArgument(*pstr, pstr)))
|
||||
return NULL; /* *pstr=NULL; ???? */
|
||||
|
||||
/* skip tok and following whitespace/separators in pstr & DON'T realloc */
|
||||
EatWS(*pstr);
|
||||
|
||||
if (!**pstr)
|
||||
*pstr=NULL; /* change \0 to NULL */
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
/*
|
||||
** CmpArgument: does case-insensitive compare on next token in string, leaving
|
||||
** string intact (return code like strcmp)
|
||||
*/
|
||||
int CmpArgument(const char *pstr,char *tok)
|
||||
{
|
||||
int rc=0;
|
||||
char *ntok=PeekArgument(pstr);
|
||||
if (ntok)
|
||||
{
|
||||
rc = strcasecmp(tok,ntok);
|
||||
free(ntok);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** MatchArgument: does case-insensitive compare on next token in string, leaving
|
||||
** string intact (returns true if matches, false otherwise)
|
||||
*/
|
||||
int MatchArgument(const char *pstr,char *tok)
|
||||
{
|
||||
int rc=0;
|
||||
char *ntok=PeekArgument(pstr);
|
||||
if (ntok)
|
||||
{
|
||||
rc = (strcasecmp(tok,ntok)==0);
|
||||
free(ntok);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** GetNextArgument: equiv interface of old parsing routine, for ease of transition
|
||||
*/
|
||||
char *GetNextArgument(char *indata,char **token)
|
||||
{
|
||||
char *nindata=indata;
|
||||
|
||||
*token = PeekArgument(indata);
|
||||
|
||||
if (*token)
|
||||
nindata+=strlen(*token);
|
||||
EatWS(nindata);
|
||||
|
||||
return nindata;
|
||||
}
|
||||
#else
|
||||
/****************************************************************************
|
||||
*
|
||||
* Gets the next "word" of input from char string indata.
|
||||
* "word" is a string with no spaces, or a qouted string.
|
||||
* Return value is ptr to indata,updated to point to text after the word
|
||||
* which is extracted.
|
||||
* token is the extracted word, which is copied into a malloced
|
||||
* space, and must be freed after use.
|
||||
*
|
||||
**************************************************************************/
|
||||
char *GetNextArgument(char *indata,char **token)
|
||||
{
|
||||
char *t,*start, *end, *text;
|
||||
|
||||
t = indata;
|
||||
if(t == NULL)
|
||||
{
|
||||
*token = NULL;
|
||||
return NULL;
|
||||
}
|
||||
while(isspace(*t)&&(*t != 0))t++;
|
||||
start = t;
|
||||
while(!isspace(*t)&&(*t != 0))
|
||||
{
|
||||
/* Check for qouted text */
|
||||
if(*t == '"')
|
||||
{
|
||||
t++;
|
||||
while((*t != '"')&&(*t != 0))
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space " */
|
||||
if((*t == '\\')&&(*(t+1) != 0))
|
||||
t++;
|
||||
t++;
|
||||
}
|
||||
if(*t == '"')
|
||||
t++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space " */
|
||||
if((*t == '\\')&&(*(t+1) != 0))
|
||||
t++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
end = t;
|
||||
|
||||
text = safemalloc(end-start+1);
|
||||
*token = text;
|
||||
|
||||
while(start < end)
|
||||
{
|
||||
/* Check for qouted text */
|
||||
if(*start == '"')
|
||||
{
|
||||
start++;
|
||||
while((*start != '"')&&(*start != 0))
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space " */
|
||||
if((*start == '\\')&&(*(start+1) != 0))
|
||||
start++;
|
||||
*text++ = *start++;
|
||||
}
|
||||
if(*start == '"')
|
||||
start++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space " */
|
||||
if((*start == '\\')&&(*(start+1) != 0))
|
||||
start++;
|
||||
*text++ = *start++;
|
||||
}
|
||||
}
|
||||
*text = 0;
|
||||
if(*end != 0)
|
||||
end++;
|
||||
|
||||
return end;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
function: MatchToken
|
||||
description: matches one word
|
||||
returns: pointer to delimiter character
|
||||
NULL if no match
|
||||
*/
|
||||
|
||||
#if 0 /* supported in 2.0.47b */
|
||||
const char *MatchToken(register const char *s, register const char *w)
|
||||
{
|
||||
if (s==NULL) return NULL;
|
||||
assert(w!=NULL); /* the token may not be NULL -> design flaw */
|
||||
|
||||
while (*w && (*s==*w ||
|
||||
#ifdef WORD_IS_UPPERCASE
|
||||
isupper(*s) && _toupper(*s)==*w
|
||||
#else
|
||||
toupper(*s)==toupper(*w)
|
||||
#endif
|
||||
))
|
||||
s++,w++;
|
||||
|
||||
if (*w=='\0' && /* end of word and */
|
||||
(*s=='\0' || ispunct(*s) || isspace(*s))) /* same in string */
|
||||
return s; /* return endptr */
|
||||
else
|
||||
return NULL; /* no match */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
function: CmpToken
|
||||
description: compare 1st word of s to 1st word of w
|
||||
returns: < 0 if s < t
|
||||
= 0 if s = t
|
||||
> 0 if s > t
|
||||
|
||||
Note arguments are not declares register, so the function can be
|
||||
used with the bsearch() <search.h> function of the c library.
|
||||
|
||||
*/
|
||||
|
||||
int XCmpToken(char *s, char **t)
|
||||
{
|
||||
register char *w=*t;
|
||||
|
||||
if (w==NULL) return 1; /* non existant word */
|
||||
if (s==NULL) return -1; /* non existant string */
|
||||
|
||||
while (*w && (*s==*w ||
|
||||
#ifdef WORD_IS_UPPERCASE
|
||||
isupper(*s) && _toupper(*s)==*w
|
||||
#else
|
||||
toupper(*s)==toupper(*w)
|
||||
#endif
|
||||
))
|
||||
s++,w++;
|
||||
|
||||
if ((*s=='\0' && (ispunct(*w) || isspace(*w)))||
|
||||
(*w=='\0' && (ispunct(*s) || isspace(*s))) )
|
||||
return 0; /* 1st word equal */
|
||||
else
|
||||
return toupper(*s)-toupper(*w); /* smaller/greater */
|
||||
}
|
||||
|
||||
76
app/fvwm/libs/ModParse.h
Normal file
76
app/fvwm/libs/ModParse.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef MODPARSE_H
|
||||
#define MODPARSE_H
|
||||
/*
|
||||
File: ModParse.h
|
||||
Date: Wed Jan 29 21:13:36 1997
|
||||
Author: Albrecht Kadlec (albrecht)
|
||||
|
||||
Changed 08/30/98 by Dan Espen:
|
||||
- Copied from FvwmEvent/Parse.h. Set up for general use by modules.
|
||||
Still to be done, try to integrate with Parse.c which is used by fvwm
|
||||
itself for parsing.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> /* for free() */
|
||||
|
||||
char *PeekArgument(const char *pstr);
|
||||
char *GetArgument(char **pstr);
|
||||
int CmpArgument(const char *pstr,char *tok);
|
||||
int MatchArgument(const char *pstr,char *tok);
|
||||
#define NukeArgument(pstr) free(GetArgument(pstr))
|
||||
|
||||
|
||||
/*
|
||||
function: FindToken
|
||||
description: find the entry of type 'struct_entry'
|
||||
holding 'key' in 'table'
|
||||
returns: pointer to the matching entry
|
||||
NULL if not found
|
||||
|
||||
table must be sorted in ascending order for FindToken.
|
||||
*/
|
||||
|
||||
#define FindToken(key,table,struct_entry) \
|
||||
(struct_entry *) bsearch(key, \
|
||||
(char *)(table), \
|
||||
sizeof(table) / sizeof(struct_entry), \
|
||||
sizeof(struct_entry), \
|
||||
XCmpToken)
|
||||
|
||||
int XCmpToken(); /* (char *s, char **t); but avoid compiler warning */
|
||||
/* needed by (L)FindToken */
|
||||
|
||||
#if 0
|
||||
/* e.g: */
|
||||
|
||||
struct entry /* these are stored in the table */
|
||||
{ char *token;
|
||||
/* ... */ /* any info */
|
||||
};
|
||||
|
||||
struct entry table[] = { /* ... */ }; /* define entries here */
|
||||
|
||||
char *word = GetArgument( /* ... */);
|
||||
entry_ptr = FindToken(word,table,struct entry);
|
||||
|
||||
(struct token *)bsearch("Style",
|
||||
(char *)table, sizeof (table)/sizeof (struct entry),
|
||||
sizeof(struct entry), CmpToken);
|
||||
#endif /* 0 */
|
||||
|
||||
#if 0
|
||||
/* Note that lfind() is not part of the ANSI standard. This is never used
|
||||
* currently; I think we should just keep it that way...
|
||||
*/
|
||||
# define LFindToken(key,table,struct_entry) \
|
||||
(struct_entry *) lfind(key, \
|
||||
(char *)(table), \
|
||||
sizeof(table) / sizeof(struct_entry), \
|
||||
sizeof(struct_entry), \
|
||||
XCmpToken)
|
||||
#endif /* 0 */
|
||||
|
||||
#endif /* MODPARSE_H */
|
||||
165
app/fvwm/libs/Module.c
Normal file
165
app/fvwm/libs/Module.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
** Module.c: code for modules to communicate with fvwm
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
#include "../fvwm/module.h"
|
||||
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* Reads a single packet of info from fvwm. Prototype is:
|
||||
* unsigned long header[HEADER_SIZE];
|
||||
* unsigned long *body;
|
||||
* int fd[2];
|
||||
* void DeadPipe(int nonsense); * Called if the pipe is no longer open *
|
||||
*
|
||||
* ReadFvwmPacket(fd[1],header, &body);
|
||||
*
|
||||
* Returns:
|
||||
* > 0 everything is OK.
|
||||
* = 0 invalid packet.
|
||||
* < 0 pipe is dead. (Should never occur)
|
||||
* body is a malloc'ed space which needs to be freed
|
||||
*
|
||||
**************************************************************************/
|
||||
int ReadFvwmPacket(int fd, unsigned long *header, unsigned long **body)
|
||||
{
|
||||
int count,total,count2,body_length;
|
||||
char *cbody;
|
||||
extern RETSIGTYPE DeadPipe(int);
|
||||
|
||||
errno = 0;
|
||||
if((count = read(fd,header,HEADER_SIZE*sizeof(unsigned long))) >0)
|
||||
{
|
||||
if(header[0] == START_FLAG)
|
||||
{
|
||||
body_length = header[2]-HEADER_SIZE;
|
||||
*body = (unsigned long *)
|
||||
safemalloc(body_length * sizeof(unsigned long));
|
||||
cbody = (char *)(*body);
|
||||
total = 0;
|
||||
while(total < body_length*sizeof(unsigned long))
|
||||
{
|
||||
errno = 0;
|
||||
if((count2=
|
||||
read(fd,&cbody[total],
|
||||
body_length*sizeof(unsigned long)-total)) >0)
|
||||
{
|
||||
total += count2;
|
||||
}
|
||||
else if(count2 < 0)
|
||||
{
|
||||
DeadPipe(errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
count = 0;
|
||||
}
|
||||
if(count <= 0)
|
||||
DeadPipe(errno);
|
||||
return count;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* SendText - Sends arbitrary text/command back to fvwm
|
||||
*
|
||||
***********************************************************************/
|
||||
void SendText(int *fd,char *message,unsigned long window)
|
||||
{
|
||||
int w;
|
||||
|
||||
if(message != NULL)
|
||||
{
|
||||
write(fd[0],&window, sizeof(unsigned long));
|
||||
|
||||
w=strlen(message);
|
||||
write(fd[0],&w,sizeof(int));
|
||||
if (w)
|
||||
write(fd[0],message,w);
|
||||
|
||||
/* keep going */
|
||||
w = 1;
|
||||
write(fd[0],&w,sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Sets the which-message-types-do-I-want mask for modules
|
||||
*
|
||||
**************************************************************************/
|
||||
void SetMessageMask(int *fd, unsigned long mask)
|
||||
{
|
||||
char set_mask_mesg[50];
|
||||
|
||||
sprintf(set_mask_mesg,"SET_MASK %lu\n",mask);
|
||||
SendText(fd,set_mask_mesg,0);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Gets a module configuration line from fvwm. Returns NULL if there are
|
||||
* no more lines to be had. "line" is a pointer to a char *.
|
||||
*
|
||||
* Changed 10/19/98 by Dan Espen:
|
||||
*
|
||||
* - The "isspace" call was referring to memory beyond the end of the
|
||||
* input area. This could have led to the creation of a core file. Added
|
||||
* "body_size" to keep it in bounds.
|
||||
**************************************************************************/
|
||||
void GetConfigLine(int *fd, char **tline)
|
||||
{
|
||||
static int first_pass = 1;
|
||||
int count,done = 0;
|
||||
int body_size;
|
||||
static char *line = NULL;
|
||||
unsigned long header[HEADER_SIZE];
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
if(first_pass)
|
||||
{
|
||||
SendInfo(fd,"Send_ConfigInfo",0);
|
||||
first_pass = 0;
|
||||
}
|
||||
|
||||
while(!done)
|
||||
{
|
||||
count = ReadFvwmPacket(fd[1],header,(unsigned long **)&line);
|
||||
/* DB(("Packet count is %d", count)); */
|
||||
if (count <= 0)
|
||||
*tline = NULL;
|
||||
else {
|
||||
*tline = &line[3*sizeof(long)];
|
||||
body_size = header[2]-HEADER_SIZE;
|
||||
/* DB(("Config line (%d): `%s'", body_size, body_size ? *tline : "")); */
|
||||
while((body_size > 0)
|
||||
&& isspace(**tline)) {
|
||||
(*tline)++;
|
||||
--body_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* fprintf(stderr,"%x %x\n",header[1],M_END_CONFIG_INFO);*/
|
||||
if(header[1] == M_CONFIG_INFO)
|
||||
done = 1;
|
||||
else if(header[1] == M_END_CONFIG_INFO)
|
||||
{
|
||||
done = 1;
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
line = NULL;
|
||||
*tline = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
580
app/fvwm/libs/Parse.c
Normal file
580
app/fvwm/libs/Parse.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
** Parse.c: routines for parsing in fvwm & modules
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "fvwmlib.h"
|
||||
|
||||
/* If the string s begins with a quote chracter SkipQuote returns a pointer
|
||||
* to the first unquoted character or to the final '\0'. If it does not, a
|
||||
* pointer to the next character in the string is returned.
|
||||
* There are three possible types of quoting: a backslash quotes the next
|
||||
* character only. Long quotes like " " or ' ' quoting everything in
|
||||
* between and quote pairs like ( ) or { }.
|
||||
*
|
||||
* precedence:
|
||||
*
|
||||
* 1) Backslashes are honoured always, even inside long or pair quotes.
|
||||
* 2) long quotes do quote quoting pair characters but not simple quotes. All
|
||||
* long quotes can quote all other types of long quotes).
|
||||
* 3) pair quotes none of the above. Text between a pair of quotes is treated
|
||||
* as a single token.
|
||||
*
|
||||
* qlong - string of long quoted (defaults to "'` )
|
||||
* qstart - string of pair quote start characters (defaults to empty string)
|
||||
* qend - string of pair quote end characters (defaults to empty string)
|
||||
*
|
||||
* The defaults are used if NULL is passed for the corresponding string.
|
||||
*/
|
||||
char *SkipQuote(char *s, const char *qlong, const char *qstart,
|
||||
const char *qend)
|
||||
{
|
||||
char *t;
|
||||
|
||||
if (s == NULL || *s == 0)
|
||||
return s;
|
||||
if (!qlong)
|
||||
qlong = "\"'`";
|
||||
if (!qstart)
|
||||
qstart = "";
|
||||
if (!qend)
|
||||
qend = "";
|
||||
|
||||
if (*s == '\\' && s[1] != 0)
|
||||
return s+2;
|
||||
else if (*qlong && (t = strchr(qlong, *s)))
|
||||
{
|
||||
char c = *t;
|
||||
|
||||
s++;
|
||||
while(*s && *s != c)
|
||||
{
|
||||
/* Skip over escaped text, ie \quote */
|
||||
if(*s == '\\' && *(s+1) != 0)
|
||||
s++;
|
||||
s++;
|
||||
}
|
||||
if(*s == c)
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
else if (*qstart && (t = strchr(qstart, *s)))
|
||||
{
|
||||
char c = *((t - qstart) + qend);
|
||||
|
||||
while (*s && *s != c)
|
||||
s = SkipQuote(s, qlong, "", "");
|
||||
return (*s == *t) ? ++s : s;
|
||||
}
|
||||
else
|
||||
return ++s;
|
||||
}
|
||||
|
||||
/* Returns a string up to the first character from the string delims in a
|
||||
* malloc'd area just like GetNextToken. Quotes are not removed from the
|
||||
* returned string. The returned string is stored in *sout, the return value
|
||||
* of this call is a pointer to the first character after the delimiter or
|
||||
* to the terminating '\0'. Quoting is handled like in SkipQuote. */
|
||||
char *GetQuotedString(char *sin, char **sout, const char *delims,
|
||||
const char *qlong, const char *qstart, const char *qend)
|
||||
{
|
||||
char *t = sin;
|
||||
unsigned int len;
|
||||
|
||||
if (!sout || !sin)
|
||||
return NULL;
|
||||
|
||||
while (*t && !strchr(delims, *t))
|
||||
t = SkipQuote(t, qlong, qstart, qend);
|
||||
len = t - sin;
|
||||
*sout = (char *)safemalloc(len + 1);
|
||||
memcpy(*sout, sin, len);
|
||||
(*sout)[len] = 0;
|
||||
if (*t)
|
||||
t++;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** PeekToken: returns next token from string, leaving string intact
|
||||
** (you should free returned string later)
|
||||
**
|
||||
** notes - quotes and brakets denote blocks, which are returned MINUS
|
||||
** the start & end delimiters. Delims within block may be escaped
|
||||
** with a backslash \ (which is removed when returned). Backslash
|
||||
** must be escaped too, if you want one... (\\). Tokens may be up
|
||||
** to MAX_TOKEN_LENGTH in size.
|
||||
*/
|
||||
char *PeekToken(const char *pstr)
|
||||
{
|
||||
char *tok=NULL;
|
||||
const char* p;
|
||||
char bc=0,be=0,tmptok[MAX_TOKEN_LENGTH];
|
||||
int len=0;
|
||||
|
||||
if (!pstr)
|
||||
return NULL;
|
||||
|
||||
p=pstr;
|
||||
EatWS(p); /* skip leading space */
|
||||
if (*p)
|
||||
{
|
||||
if (IsQuote(*p) || IsBlockStart(*p)) /* quoted string or block start? */
|
||||
{
|
||||
bc = *p; /* save block start char */
|
||||
p++;
|
||||
}
|
||||
/* find end of token */
|
||||
while (*p && len < MAX_TOKEN_LENGTH)
|
||||
{
|
||||
/* first, check stop conditions based on block or normal token */
|
||||
if (bc)
|
||||
{
|
||||
if ((IsQuote(*p) && bc == *p) || IsBlockEnd(*p,bc))
|
||||
{
|
||||
be = *p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* normal token */
|
||||
{
|
||||
if (isspace((unsigned char)*p) || *p == ',')
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == '\\' && *(p+1)) /* if \, copy next char verbatim */
|
||||
p++;
|
||||
tmptok[len] = *p;
|
||||
len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* sanity checks: */
|
||||
if (bc && !be) /* did we have block start, but not end? */
|
||||
{
|
||||
/* should yell about this */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
tok = (char *)malloc(len+1);
|
||||
strncpy(tok,tmptok,len);
|
||||
tok[len]='\0';
|
||||
}
|
||||
}
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
/*
|
||||
** CmpToken: does case-insensitive compare on next token in string, leaving
|
||||
** string intact (return code like strcmp)
|
||||
*/
|
||||
int CmpToken(const char *pstr,char *tok)
|
||||
{
|
||||
int rc=0;
|
||||
char *ntok=PeekToken(pstr);
|
||||
if (ntok)
|
||||
{
|
||||
rc = strcasecmp(tok,ntok);
|
||||
free(ntok);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** MatchToken: does case-insensitive compare on next token in string, leaving
|
||||
** string intact (returns true if matches, false otherwise)
|
||||
*/
|
||||
int MatchToken(const char *pstr,char *tok)
|
||||
{
|
||||
int rc=0;
|
||||
char *ntok=PeekToken(pstr);
|
||||
if (ntok)
|
||||
{
|
||||
rc = (strcasecmp(tok,ntok)==0);
|
||||
free(ntok);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** NukeToken: removes next token from string
|
||||
*/
|
||||
void NukeToken(char **pstr)
|
||||
{
|
||||
char *tok;
|
||||
char *next;
|
||||
char *temp = NULL;
|
||||
|
||||
next = GetNextToken(*pstr, &tok);
|
||||
if (next != NULL);
|
||||
temp = strdup(next);
|
||||
if (pstr && *pstr)
|
||||
free(*pstr);
|
||||
*pstr = temp;
|
||||
if (tok)
|
||||
free(tok);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Gets the next "word" of input from string indata.
|
||||
* "word" is a string with no spaces, or a qouted string.
|
||||
* Return value is ptr to indata,updated to point to text after the word
|
||||
* which is extracted.
|
||||
* token is the extracted word, which is copied into a malloced
|
||||
* space, and must be freed after use. DoGetNextToken *never* returns an
|
||||
* empty string or token. If the token consists only of whitespace or
|
||||
* delimiters, the returned token is NULL instead. If out_delim is given,
|
||||
* the character ending the string is returned therein.
|
||||
*
|
||||
* spaces = string of characters to treat as spaces
|
||||
* delims = string of characters delimiting token
|
||||
*
|
||||
* Use "spaces" and "delims" to define additional space/delimiter
|
||||
* characters (spaces are skipped before a token, delimiters are not).
|
||||
*
|
||||
**************************************************************************/
|
||||
char *DoGetNextToken(char *indata, char **token, char *spaces, char *delims,
|
||||
char *out_delim)
|
||||
{
|
||||
char *t, *start, *end, *text;
|
||||
int snum;
|
||||
int dnum;
|
||||
|
||||
snum = (spaces) ? strlen(spaces) : 0;
|
||||
dnum = (delims) ? strlen(delims) : 0;
|
||||
if(indata == NULL)
|
||||
{
|
||||
if (out_delim)
|
||||
*out_delim = '\0';
|
||||
*token = NULL;
|
||||
return NULL;
|
||||
}
|
||||
t = indata;
|
||||
while ( (*t != 0) &&
|
||||
( isspace((unsigned char)*t) ||
|
||||
(snum &&
|
||||
strchr(spaces, *t)) ) )
|
||||
t++;
|
||||
start = t;
|
||||
while ( (*t != 0) &&
|
||||
!( isspace((unsigned char)*t) ||
|
||||
(snum &&
|
||||
strchr(spaces, *t)) ||
|
||||
(dnum &&
|
||||
strchr(delims, *t)) ) )
|
||||
{
|
||||
/* Check for qouted text */
|
||||
if (IsQuote(*t))
|
||||
{
|
||||
char c = *t;
|
||||
|
||||
t++;
|
||||
while((*t != c)&&(*t != 0))
|
||||
{
|
||||
/* Skip over escaped text, ie \quote */
|
||||
if((*t == '\\')&&(*(t+1) != 0))
|
||||
t++;
|
||||
t++;
|
||||
}
|
||||
if(*t == c)
|
||||
t++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space */
|
||||
if((*t == '\\')&&(*(t+1) != 0))
|
||||
t++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
end = t;
|
||||
if (out_delim)
|
||||
*out_delim = *end;
|
||||
|
||||
text = safemalloc(end-start+1);
|
||||
*token = text;
|
||||
|
||||
/* copy token */
|
||||
while(start < end)
|
||||
{
|
||||
/* Check for qouted text */
|
||||
if(IsQuote(*start))
|
||||
{
|
||||
char c = *start;
|
||||
start++;
|
||||
while((*start != c)&&(*start != 0))
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space */
|
||||
if((*start == '\\')&&(*(start+1) != 0))
|
||||
start++;
|
||||
*text++ = *start++;
|
||||
}
|
||||
if(*start == c)
|
||||
start++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over escaped text, ie \" or \space */
|
||||
if((*start == '\\')&&(*(start+1) != 0))
|
||||
start++;
|
||||
*text++ = *start++;
|
||||
}
|
||||
}
|
||||
*text = 0;
|
||||
if(*end != 0)
|
||||
end++;
|
||||
|
||||
if (**token == 0)
|
||||
{
|
||||
free(*token);
|
||||
*token = NULL;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
char *GetNextToken(char *indata, char **token)
|
||||
{
|
||||
return DoGetNextToken(indata, token, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
char *GetNextOption(char *indata, char **token)
|
||||
{
|
||||
return DoGetNextToken(indata, token, ",", NULL, NULL);
|
||||
}
|
||||
|
||||
char *SkipNTokens(char *indata, unsigned int n)
|
||||
{
|
||||
char *tmp;
|
||||
char *junk;
|
||||
|
||||
tmp = indata;
|
||||
for ( ; n > 0 ; n--)
|
||||
{
|
||||
tmp = GetNextToken(tmp, &junk);
|
||||
if (junk)
|
||||
free(junk);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Works like GetNextToken, but with the following differences:
|
||||
*
|
||||
* If *indata begins with a "*" followed by the string module_name,
|
||||
* it returns the string following directly after module_name as the
|
||||
* new token. Otherwise NULL is returned.
|
||||
* e.g. GetModuleResource("*FvwmPagerGeometry", &token, "FvwmPager")
|
||||
* returns "Geometry" in token.
|
||||
*
|
||||
**************************************************************************/
|
||||
char *GetModuleResource(char *indata, char **resource, char *module_name)
|
||||
{
|
||||
char *tmp;
|
||||
char *next;
|
||||
|
||||
if (!module_name)
|
||||
{
|
||||
*resource = NULL;
|
||||
return indata;
|
||||
}
|
||||
next = GetNextToken(indata, &tmp);
|
||||
if (!tmp)
|
||||
return next;
|
||||
|
||||
if (tmp[0] != '*' || strncasecmp(tmp+1, module_name, strlen(module_name)))
|
||||
{
|
||||
*resource = NULL;
|
||||
return indata;
|
||||
}
|
||||
CopyString(resource, tmp+1+strlen(module_name));
|
||||
free(tmp);
|
||||
return next;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* This function uses GetNextToken to parse action for up to num integer
|
||||
* arguments. The number of values actually found is returned.
|
||||
* If ret_action is non-NULL, a pointer to the next token is returned there.
|
||||
*
|
||||
**************************************************************************/
|
||||
int GetIntegerArguments(char *action, char **ret_action, int retvals[],int num)
|
||||
{
|
||||
int i;
|
||||
char *token;
|
||||
|
||||
for (i = 0; i < num && action; i++)
|
||||
{
|
||||
action = GetNextToken(action, &token);
|
||||
if (token == NULL)
|
||||
break;
|
||||
if (sscanf(token, "%d", &(retvals[i])) != 1)
|
||||
break;
|
||||
free(token);
|
||||
token = NULL;
|
||||
}
|
||||
if (token)
|
||||
free(token);
|
||||
if (ret_action != NULL)
|
||||
*ret_action = action;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This function tries to match a token with a list of strings and returns
|
||||
* the position of token in the array or -1 if no match is found. The last
|
||||
* entry in the list must be NULL.
|
||||
*
|
||||
* len = 0 : only exact matches
|
||||
* len < 0 : match, if token begins with one of the strings in list
|
||||
* len > 0 : match, if the first len characters do match
|
||||
*
|
||||
* if next is non-NULL, *next will be set to point to the first character
|
||||
* in token after the match.
|
||||
*
|
||||
**************************************************************************/
|
||||
int GetTokenIndex(char *token, char *list[], int len, char **next)
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int k;
|
||||
|
||||
if (!token || !list)
|
||||
{
|
||||
if (next)
|
||||
*next = NULL;
|
||||
return -1;
|
||||
}
|
||||
l = (len) ? len : strlen(token);
|
||||
for (i = 0; list[i] != NULL; i++)
|
||||
{
|
||||
k = strlen(list[i]);
|
||||
if (len < 0)
|
||||
l = k;
|
||||
if (len == 0 && k != l)
|
||||
continue;
|
||||
if (!strncasecmp(token, list[i], l))
|
||||
break;
|
||||
}
|
||||
if (next)
|
||||
{
|
||||
*next = (list[i]) ? token + l : token;
|
||||
}
|
||||
|
||||
return (list[i]) ? i : -1;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This function does roughly the same as GetTokenIndex but reads the
|
||||
* token from string action with GetNextToken. The index is returned
|
||||
* in *index. The return value is a pointer to the character after the
|
||||
* token (just like the return value of GetNextToken).
|
||||
*
|
||||
**************************************************************************/
|
||||
char *GetNextTokenIndex(char *action, char *list[], int len, int *index)
|
||||
{
|
||||
char *token;
|
||||
char *next;
|
||||
|
||||
if (!index)
|
||||
return action;
|
||||
|
||||
next = GetNextToken(action, &token);
|
||||
if (!token)
|
||||
{
|
||||
*index = -1;
|
||||
return action;
|
||||
}
|
||||
*index = GetTokenIndex(token, list, len, NULL);
|
||||
free(token);
|
||||
|
||||
return (*index == -1) ? action : next;
|
||||
}
|
||||
|
||||
|
||||
int GetRectangleArguments(char *action, int *width, int *height)
|
||||
{
|
||||
char *token;
|
||||
int n;
|
||||
|
||||
GetNextToken(action, &token);
|
||||
if (!token)
|
||||
return 0;
|
||||
/* now try MxN style number, specifically for DeskTopSize: */
|
||||
n = sscanf(token, "%d%*c%d", width, height);
|
||||
free(token);
|
||||
|
||||
return (n == 2) ? 2 : 0;
|
||||
}
|
||||
|
||||
/* unit_io is input as well as output. If action has a postfix 'p' or 'P',
|
||||
* *unit_io is set to 100, otherwise it is left untouched. */
|
||||
int GetOnePercentArgument(char *action, int *value, int *unit_io)
|
||||
{
|
||||
unsigned int len;
|
||||
char *token;
|
||||
int n;
|
||||
|
||||
*value = 0;
|
||||
if (!action)
|
||||
return 0;
|
||||
GetNextToken(action, &token);
|
||||
if (!token)
|
||||
return 0;
|
||||
|
||||
len = strlen(token);
|
||||
/* token never contains an empty string, so this is ok */
|
||||
if (token[len - 1] == 'p' || token[len - 1] == 'P')
|
||||
{
|
||||
*unit_io = 100;
|
||||
token[len - 1] = '\0';
|
||||
}
|
||||
n = sscanf(token, "%d", value);
|
||||
|
||||
free(token);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int GetTwoPercentArguments(char *action, int *val1, int *val2, int *val1_unit,
|
||||
int *val2_unit)
|
||||
{
|
||||
char *tok1, *tok2;
|
||||
int n = 0;
|
||||
|
||||
*val1 = 0;
|
||||
*val2 = 0;
|
||||
|
||||
action = GetNextToken(action, &tok1);
|
||||
if (!tok1)
|
||||
return 0;
|
||||
GetNextToken(action, &tok2);
|
||||
if (GetOnePercentArgument(tok2, val2, val2_unit) == 1 &&
|
||||
GetOnePercentArgument(tok1, val1, val1_unit) == 1)
|
||||
{
|
||||
free(tok1);
|
||||
free(tok2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* now try MxN style number, specifically for DeskTopSize: */
|
||||
n = GetRectangleArguments(tok1, val1, val2);
|
||||
free(tok1);
|
||||
if (tok2)
|
||||
free(tok2);
|
||||
return n;
|
||||
}
|
||||
482
app/fvwm/libs/Picture.c
Normal file
482
app/fvwm/libs/Picture.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/****************************************************************************
|
||||
* This module is all original code
|
||||
* by Rob Nation
|
||||
* Copyright 1993, Robert Nation
|
||||
* You may use this code for any purpose, as long as the original
|
||||
* copyright remains in the source code and all documentation
|
||||
****************************************************************************/
|
||||
/*
|
||||
Changed 02/12/97 by Dan Espen:
|
||||
- added routines to determine color closeness, for color use reduction.
|
||||
Some of the logic comes from pixy2, so the copyright is below.
|
||||
*/
|
||||
/*
|
||||
* $Id: Picture.c,v 1.1.1.1 2006/11/26 10:53:41 matthieu Exp $
|
||||
* Copyright 1996, Romano Giannetti. 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.
|
||||
*
|
||||
* Romano Giannetti - Dipartimento di Ingegneria dell'Informazione
|
||||
* via Diotisalvi, 2 PISA
|
||||
* mailto:romano@iet.unipi.it
|
||||
* http://www.iet.unipi.it/~romano
|
||||
*
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Routines to handle initialization, loading, and removing of xpm's or mono-
|
||||
* icon images.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef XPM
|
||||
/* static function prototypes */
|
||||
static void c100_init_base_table (); /* prototype */
|
||||
static void c200_substitute_color(char **,int); /* prototype */
|
||||
static void c300_color_to_rgb(char *, XColor *); /* prototype */
|
||||
static double c400_distance(XColor *, XColor *); /* prototype */
|
||||
#endif
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
|
||||
static Picture *PictureList=NULL;
|
||||
Colormap PictureCMap;
|
||||
Display *PictureSaveDisplay; /* Save area for display pointer */
|
||||
|
||||
/* This routine called during fvwm and some modules initialization */
|
||||
void InitPictureCMap(Display *dpy,Window Root)
|
||||
{
|
||||
XWindowAttributes root_attr;
|
||||
PictureSaveDisplay = dpy; /* save for latter */
|
||||
XGetWindowAttributes(dpy,Root,&root_attr);
|
||||
PictureCMap=root_attr.colormap;
|
||||
}
|
||||
|
||||
|
||||
Picture *LoadPicture(Display *dpy,Window Root,char *path, int color_limit)
|
||||
{
|
||||
int l;
|
||||
Picture *p;
|
||||
#ifdef XPM
|
||||
XpmAttributes xpm_attributes;
|
||||
int rc;
|
||||
XpmImage my_image = {0};
|
||||
#endif
|
||||
|
||||
p=(Picture*)safemalloc(sizeof(Picture));
|
||||
p->count=1;
|
||||
p->name=path;
|
||||
p->next=NULL;
|
||||
|
||||
#ifdef XPM
|
||||
/* Try to load it as an X Pixmap first */
|
||||
xpm_attributes.colormap=PictureCMap;
|
||||
xpm_attributes.closeness=40000; /* Allow for "similar" colors */
|
||||
xpm_attributes.valuemask=
|
||||
XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness;
|
||||
|
||||
rc =XpmReadFileToXpmImage(path, &my_image, NULL);
|
||||
if (rc == XpmSuccess) {
|
||||
color_reduce_pixmap(&my_image, color_limit);
|
||||
rc = XpmCreatePixmapFromXpmImage(dpy, Root, &my_image,
|
||||
&p->picture,&p->mask,
|
||||
&xpm_attributes);
|
||||
if (rc == XpmSuccess) {
|
||||
p->width = my_image.width;
|
||||
p->height = my_image.height;
|
||||
XpmFreeXpmImage(&my_image);
|
||||
p->depth = DefaultDepthOfScreen(DefaultScreenOfDisplay(dpy));
|
||||
return p;
|
||||
}
|
||||
XpmFreeXpmImage(&my_image);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If no XPM support, or XPM loading failed, try bitmap */
|
||||
if(XReadBitmapFile(dpy,Root,path,&p->width,&p->height,&p->picture,&l,&l)
|
||||
== BitmapSuccess)
|
||||
{
|
||||
p->depth = 0;
|
||||
p->mask = None;
|
||||
return p;
|
||||
}
|
||||
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Picture *GetPicture(Display *dpy,Window Root,char *IconPath,char *PixmapPath,
|
||||
char *name, int color_limit)
|
||||
{
|
||||
char *path;
|
||||
Picture *p;
|
||||
|
||||
if(!(path=findIconFile(name,PixmapPath,R_OK)))
|
||||
if(!(path=findIconFile(name,IconPath,R_OK)))
|
||||
return NULL;
|
||||
p = LoadPicture(dpy,Root,path, color_limit);
|
||||
if (!p)
|
||||
free(path);
|
||||
return p;
|
||||
}
|
||||
|
||||
Picture *CachePicture(Display *dpy,Window Root,char *IconPath,char *PixmapPath,
|
||||
char *name, int color_limit)
|
||||
{
|
||||
char *path;
|
||||
Picture *p=PictureList;
|
||||
|
||||
/* First find the full pathname */
|
||||
#ifdef XPM
|
||||
if(!(path=findIconFile(name,PixmapPath,R_OK)))
|
||||
if(!(path=findIconFile(name,IconPath,R_OK)))
|
||||
return NULL;
|
||||
#else
|
||||
/* Ignore the given pixmap path when compiled without XPM support */
|
||||
if(!(path=findIconFile(name,IconPath,R_OK)))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* See if the picture is already cached */
|
||||
while(p)
|
||||
{
|
||||
register char *p1, *p2;
|
||||
|
||||
for (p1=path, p2=p->name; *p1 && *p2; ++p1, ++p2)
|
||||
if (*p1 != *p2)
|
||||
break;
|
||||
|
||||
if(!*p1 && !*p2) /* We have found a picture with the wanted name */
|
||||
{
|
||||
p->count++; /* Put another weight on the picture */
|
||||
free(path);
|
||||
return p;
|
||||
}
|
||||
p=p->next;
|
||||
}
|
||||
|
||||
/* Not previously cached, have to load it ourself. Put it first in list */
|
||||
p=LoadPicture(dpy,Root,path, color_limit);
|
||||
if(p)
|
||||
{
|
||||
p->next=PictureList;
|
||||
PictureList=p;
|
||||
}
|
||||
else
|
||||
free(path);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void DestroyPicture(Display *dpy,Picture *p)
|
||||
{
|
||||
Picture *q=PictureList;
|
||||
|
||||
if (!p) /* bag out if NULL */
|
||||
return;
|
||||
if(--(p->count)>0) /* Remove a weight, still too heavy? */
|
||||
return;
|
||||
|
||||
/* Let it fly */
|
||||
if(p->name!=NULL)
|
||||
free(p->name);
|
||||
if(p->picture!=None)
|
||||
XFreePixmap(dpy,p->picture);
|
||||
if(p->mask!=None)
|
||||
XFreePixmap(dpy,p->mask);
|
||||
|
||||
/* Link it out of the list (it might not be there) */
|
||||
if(p==q) /* in head? simple */
|
||||
PictureList=p->next;
|
||||
else
|
||||
{
|
||||
while(q && q->next!=p) /* fast forward until end or found */
|
||||
q=q->next;
|
||||
if(q) /* not end? means we found it in there, possibly at end */
|
||||
q->next=p->next; /* link around it */
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Find the specified icon file somewhere along the given path.
|
||||
*
|
||||
* There is a possible race condition here: We check the file and later
|
||||
* do something with it. By then, the file might not be accessible.
|
||||
* Oh well.
|
||||
*
|
||||
****************************************************************************/
|
||||
char *findIconFile(char *icon, char *pathlist, int type)
|
||||
{
|
||||
char *path;
|
||||
char *dir_end;
|
||||
int l;
|
||||
size_t pathlen;
|
||||
|
||||
if (!icon)
|
||||
return NULL;
|
||||
|
||||
l = (pathlist) ? strlen(pathlist) : 0;
|
||||
pathlen = strlen(icon) + l + 10;
|
||||
path = safemalloc(pathlen);
|
||||
*path = '\0';
|
||||
if (*icon == '/' || pathlist == NULL || *pathlist == '\0')
|
||||
{
|
||||
/* No search if icon begins with a slash */
|
||||
/* No search if pathlist is empty */
|
||||
strlcpy(path, icon, pathlen);
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Search each element of the pathlist for the icon file */
|
||||
while ((pathlist)&&(*pathlist))
|
||||
{
|
||||
dir_end = strchr(pathlist, ':');
|
||||
if (dir_end != NULL)
|
||||
{
|
||||
strncpy(path, pathlist, dir_end - pathlist);
|
||||
path[dir_end - pathlist] = 0;
|
||||
}
|
||||
else
|
||||
strlcpy(path, pathlist, pathlen);
|
||||
|
||||
strlcat(path, "/", pathlen);
|
||||
strlcat(path, icon, pathlen);
|
||||
if (access(path, type) == 0)
|
||||
return path;
|
||||
strlcat(path, ".gz", pathlen);
|
||||
if (access(path, type) == 0)
|
||||
return path;
|
||||
|
||||
/* Point to next element of the path */
|
||||
if(dir_end == NULL)
|
||||
pathlist = NULL;
|
||||
else
|
||||
pathlist = dir_end + 1;
|
||||
}
|
||||
/* Hmm, couldn't find the file. Return NULL */
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XPM
|
||||
/* This structure is used to quickly access the RGB values of the colors */
|
||||
/* without repeatedly having to transform them. */
|
||||
typedef struct {
|
||||
char * c_color; /* Pointer to the name of the color */
|
||||
XColor rgb_space; /* rgb color info */
|
||||
} Color_Info;
|
||||
|
||||
/* First thing in base array are colors probably already in the color map
|
||||
because they have familiar names.
|
||||
I pasted them into a xpm and spread them out so that similar colors are
|
||||
spread out.
|
||||
Toward the end are some colors to fill in the gaps.
|
||||
Currently 61 colors in this list.
|
||||
*/
|
||||
static Color_Info base_array[] = {
|
||||
{"white"},
|
||||
{"black"},
|
||||
{"grey"},
|
||||
{"green"},
|
||||
{"blue"},
|
||||
{"red"},
|
||||
{"cyan"},
|
||||
{"yellow"},
|
||||
{"magenta"},
|
||||
{"DodgerBlue"},
|
||||
{"SteelBlue"},
|
||||
{"chartreuse"},
|
||||
{"wheat"},
|
||||
{"turquoise"},
|
||||
{"CadetBlue"},
|
||||
{"gray87"},
|
||||
{"CornflowerBlue"},
|
||||
{"YellowGreen"},
|
||||
{"NavyBlue"},
|
||||
{"MediumBlue"},
|
||||
{"plum"},
|
||||
{"aquamarine"},
|
||||
{"orchid"},
|
||||
{"ForestGreen"},
|
||||
{"lightyellow"},
|
||||
{"brown"},
|
||||
{"orange"},
|
||||
{"red3"},
|
||||
{"HotPink"},
|
||||
{"LightBlue"},
|
||||
{"gray47"},
|
||||
{"pink"},
|
||||
{"red4"},
|
||||
{"violet"},
|
||||
{"purple"},
|
||||
{"gray63"},
|
||||
{"gray94"},
|
||||
{"plum1"},
|
||||
{"PeachPuff"},
|
||||
{"maroon"},
|
||||
{"lavender"},
|
||||
{"salmon"}, /* for peachpuff, orange gap */
|
||||
{"blue4"}, /* for navyblue/mediumblue gap */
|
||||
{"PaleGreen4"}, /* for forestgreen, yellowgreen gap */
|
||||
{"#AA7700"}, /* brick, no close named color */
|
||||
{"#11EE88"}, /* light green, no close named color */
|
||||
{"#884466"}, /* dark brown, no close named color */
|
||||
{"#CC8888"}, /* light brick, no close named color */
|
||||
{"#EECC44"}, /* gold, no close named color */
|
||||
{"#AAAA44"}, /* dull green, no close named color */
|
||||
{"#FF1188"}, /* pinkish red */
|
||||
{"#992299"}, /* purple */
|
||||
{"#CCFFAA"}, /* light green */
|
||||
{"#664400"}, /* dark brown*/
|
||||
{"#AADD99"}, /* light green */
|
||||
{"#66CCFF"}, /* light blue */
|
||||
{"#CC2299"}, /* dark red */
|
||||
{"#FF11CC"}, /* bright pink */
|
||||
{"#11CC99"}, /* grey/green */
|
||||
{"#AA77AA"}, /* purple/red */
|
||||
{"#EEBB77"} /* orange/yellow */
|
||||
};
|
||||
|
||||
#define NColors (sizeof(base_array) / sizeof(Color_Info))
|
||||
|
||||
/* if c_color isn't set, copy it from one of the other colours */
|
||||
Bool xpmcolor_require_c_color(XpmColor *p)
|
||||
{
|
||||
if (p->c_color != NULL)
|
||||
return False;
|
||||
else if (p->g_color != NULL)
|
||||
p->c_color = strdup(p->g_color);
|
||||
else if (p->g4_color != NULL)
|
||||
p->c_color = strdup(p->g4_color);
|
||||
else if (p->m_color != NULL)
|
||||
p->c_color = strdup(p->m_color);
|
||||
else
|
||||
p->c_color = strdup("none");
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/* given an xpm, change colors to colors close to the
|
||||
subset above. */
|
||||
void
|
||||
color_reduce_pixmap(XpmImage *image,int color_limit) {
|
||||
int i;
|
||||
XpmColor *color_table_ptr;
|
||||
static char base_init = 'n';
|
||||
|
||||
if (color_limit > 0) { /* If colors to be limited */
|
||||
if (base_init == 'n') { /* if base table not created yet */
|
||||
c100_init_base_table(); /* init the base table */
|
||||
base_init = 'y'; /* remember that its set now. */
|
||||
} /* end base table init */
|
||||
color_table_ptr = image->colorTable; /* start of xpm color table */
|
||||
for(i=0; i<image->ncolors; i++) { /* all colors in the xpm */
|
||||
/* Theres an array for this in the xpm library, but it doesn't
|
||||
appear to be part of the API. Too bad. dje 01/09/00 */
|
||||
char **visual_color = 0;
|
||||
if (color_table_ptr->c_color) {
|
||||
visual_color = &color_table_ptr->c_color;
|
||||
} else if (color_table_ptr->g_color) {
|
||||
visual_color = &color_table_ptr->g_color;
|
||||
} else if (color_table_ptr->g4_color) {
|
||||
visual_color = &color_table_ptr->g4_color;
|
||||
} else { /* its got to be one of these */
|
||||
visual_color = &color_table_ptr->m_color;
|
||||
}
|
||||
c200_substitute_color(visual_color,color_limit);
|
||||
color_table_ptr +=1; /* counter for loop */
|
||||
} /* end all colors in xpm */
|
||||
} /* end colors limited */
|
||||
return; /* return, no rc! */
|
||||
}
|
||||
|
||||
/* from the color names in the base table, calc rgbs */
|
||||
static void
|
||||
c100_init_base_table () {
|
||||
int i;
|
||||
for (i=0; i<NColors; i++) { /* change all base colors to numbers */
|
||||
c300_color_to_rgb(base_array[i].c_color, &base_array[i].rgb_space);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Replace the color in my_color by the closest matching color
|
||||
from base_table */
|
||||
void c200_substitute_color(char **my_color, int color_limit) {
|
||||
int i, limit, minind;
|
||||
double mindst=1e20;
|
||||
double dst;
|
||||
XColor rgb; /* place to calc rgb for each color in xpm */
|
||||
size_t len;
|
||||
|
||||
if (!strcasecmp(*my_color,"none")) {
|
||||
return ; /* do not substitute the "none" color */
|
||||
}
|
||||
|
||||
c300_color_to_rgb(*my_color, &rgb); /* get rgb for a color in xpm */
|
||||
/* Loop over all base_array colors; find out which one is closest
|
||||
to my_color */
|
||||
minind = 0; /* Its going to find something... */
|
||||
limit = NColors; /* init to max */
|
||||
if (color_limit < NColors) { /* can't do more than I have */
|
||||
limit = color_limit; /* Do reduction using subset */
|
||||
} /* end reducing limit */
|
||||
for(i=0; i < limit; i++) { /* loop over base array */
|
||||
dst = c400_distance (&rgb, &base_array[i].rgb_space); /* distance */
|
||||
if (dst < mindst ) { /* less than min and better than last */
|
||||
mindst=dst; /* new minimum */
|
||||
minind=i; /* save loc of new winner */
|
||||
if (dst <= 100) { /* if close enough */
|
||||
break; /* done */
|
||||
} /* end close enough */
|
||||
} /* end new low distance */
|
||||
} /* end all base colors */
|
||||
/* Finally: replace the color string by the newly determined color string */
|
||||
free(*my_color); /* free old color */
|
||||
len = strlen(base_array[minind].c_color) + 1;
|
||||
*my_color = safemalloc(len); /* area for new color */
|
||||
strlcpy(*my_color,base_array[minind].c_color,len); /* put it there */
|
||||
return; /* all done */
|
||||
}
|
||||
|
||||
static void c300_color_to_rgb(char *c_color, XColor *rgb_space) {
|
||||
int rc;
|
||||
rc=XParseColor(PictureSaveDisplay, PictureCMap, c_color, rgb_space);
|
||||
if (rc==0) {
|
||||
fprintf(stderr,"color_to_rgb: can't parse color %s, rc %d\n", c_color, rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A macro for squaring things */
|
||||
#define SQUARE(X) ((X)*(X))
|
||||
/* RGB Color distance sum of square of differences */
|
||||
double c400_distance(XColor *target_ptr, XColor *base_ptr) {
|
||||
register double dst;
|
||||
dst = SQUARE((double)(base_ptr->red - target_ptr->red )/655.35)
|
||||
+ SQUARE((double)(base_ptr->green - target_ptr->green)/655.35)
|
||||
+ SQUARE((double)(base_ptr->blue - target_ptr->blue )/655.35);
|
||||
return dst;
|
||||
}
|
||||
#endif /* XPM */
|
||||
117
app/fvwm/libs/Strings.c
Normal file
117
app/fvwm/libs/Strings.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
** Strings.c: various routines for dealing with strings
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* Concatentates 3 strings
|
||||
*
|
||||
*************************************************************************/
|
||||
char CatS[256];
|
||||
|
||||
char *CatString3(char *a, char *b, char *c)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if(a != NULL)
|
||||
len += strlen(a);
|
||||
if(b != NULL)
|
||||
len += strlen(b);
|
||||
if(c != NULL)
|
||||
len += strlen(c);
|
||||
|
||||
if (len > 255)
|
||||
return NULL;
|
||||
|
||||
if(a == NULL)
|
||||
CatS[0] = 0;
|
||||
else
|
||||
strlcpy(CatS, a, sizeof(CatS));
|
||||
if(b != NULL)
|
||||
strlcat(CatS, b, sizeof(CatS));
|
||||
if(c != NULL)
|
||||
strlcat(CatS, c, sizeof(CatS));
|
||||
return CatS;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* A simple routine to copy a string, stripping spaces and mallocing
|
||||
* space for the new string
|
||||
***************************************************************************/
|
||||
void CopyString(char **dest, char *source)
|
||||
{
|
||||
int len;
|
||||
char *start;
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
*dest = NULL;
|
||||
return;
|
||||
}
|
||||
while(((isspace(*source))&&(*source != '\n'))&&(*source != 0))
|
||||
{
|
||||
source++;
|
||||
}
|
||||
len = 0;
|
||||
start = source;
|
||||
while((*source != '\n')&&(*source != 0))
|
||||
{
|
||||
len++;
|
||||
source++;
|
||||
}
|
||||
|
||||
source--;
|
||||
while((isspace(*source))&&(*source != 0)&&(len >0))
|
||||
{
|
||||
len--;
|
||||
source--;
|
||||
}
|
||||
*dest = safemalloc(len+1);
|
||||
strncpy(*dest,start,len);
|
||||
(*dest)[len]=0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copies a string into a new, malloc'ed string
|
||||
* Strips leading spaces and trailing spaces and new lines
|
||||
*
|
||||
****************************************************************************/
|
||||
char *stripcpy(char *source)
|
||||
{
|
||||
char *tmp,*ptr;
|
||||
int len;
|
||||
|
||||
if(source == NULL)
|
||||
return NULL;
|
||||
|
||||
while(isspace(*source))
|
||||
source++;
|
||||
len = strlen(source);
|
||||
tmp = source + len -1;
|
||||
while(((isspace(*tmp))||(*tmp == '\n'))&&(tmp >=source))
|
||||
{
|
||||
tmp--;
|
||||
len--;
|
||||
}
|
||||
ptr = safemalloc(len+1);
|
||||
strncpy(ptr,source,len);
|
||||
ptr[len]=0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int StrEquals(char *s1,char *s2)
|
||||
{
|
||||
if (!s1 && !s2)
|
||||
return 1;
|
||||
if (!s1 || !s2)
|
||||
return 0;
|
||||
return (strcasecmp(s1,s2)==0);
|
||||
}
|
||||
44
app/fvwm/libs/System.c
Normal file
44
app/fvwm/libs/System.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
** System.c: code for dealing with various OS system call variants
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_UNAME
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** just in case...
|
||||
*/
|
||||
#ifndef FD_SETSIZE
|
||||
#define FD_SETSIZE 2048
|
||||
#endif
|
||||
|
||||
|
||||
int GetFdWidth(void)
|
||||
{
|
||||
#if HAVE_SYSCONF
|
||||
return min(sysconf(_SC_OPEN_MAX),FD_SETSIZE);
|
||||
#else
|
||||
return min(getdtablesize(),FD_SETSIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return a string indicating the OS type (i.e. "Linux", "SINIX-D", ... ) */
|
||||
int getostype(char *buf, int max)
|
||||
{
|
||||
#if HAVE_UNAME
|
||||
struct utsname sysname;
|
||||
|
||||
if ( uname( &sysname ) >= 0 ) {
|
||||
strlcpy( buf, sysname.sysname, max);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
strlcpy (buf,"",max);
|
||||
return -1;
|
||||
}
|
||||
275
app/fvwm/libs/XResource.c
Normal file
275
app/fvwm/libs/XResource.c
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
** XResource.c:
|
||||
** These routines provide modules with an interface to parse all kinds of
|
||||
** configuration options (X resources, command line options and configuration
|
||||
** file lines) in the same way (Xrm database).
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* If you have a module MyModule and want to parse X resources as well as
|
||||
* command line options and a config file:
|
||||
*
|
||||
*** EXAMPLE ***************************************************************/
|
||||
#if 0
|
||||
#include <fvwmlib.h>
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
const char *MyName = "MyModule";
|
||||
XrmDatabase db = NULL;
|
||||
char *value;
|
||||
char *line;
|
||||
|
||||
/* our private options */
|
||||
const XrmOptionDescRec my_opts[] = {
|
||||
{ "-iconic", ".Iconic", XrmoptionNoArg, "any_string" },
|
||||
{ "-foo", "*bar", XrmoptionSepArg, NULL }
|
||||
};
|
||||
int opt_argc = argc - 6; /* options start at 6th argument for modules */
|
||||
char **opt_argv = argv + 6;
|
||||
|
||||
/* ... (open config file, etc.) */
|
||||
|
||||
/* Get global X resources */
|
||||
MergeXResources(NULL, &db, False);
|
||||
|
||||
/* config file descriptor in fd; config file takes precedence over X
|
||||
* resources (this may not be what you want). */
|
||||
for (GetConfigLine(fd, &line); line != NULL; GetConfigLine(fd, &line))
|
||||
{
|
||||
if (!MergeConfigLineResource(&db, line, MyName, '*'))
|
||||
{
|
||||
/* Parse other lines here (e.g. "IconPath") */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* You may still have to parse the line here yourself (e.g.
|
||||
* FvwmButtons may have multiple lines for the same resource). */
|
||||
}
|
||||
}
|
||||
|
||||
/* command line takes precedence over all */
|
||||
MergeCmdLineResources(&db, (XrmOptionDescList)my_opts, 2, MyName,
|
||||
&opt_argc, opt_argv, True /*no default options*/);
|
||||
|
||||
/* Now parse the database values: */
|
||||
if (GetResourceString(db, "iconic", MyName, &value))
|
||||
{
|
||||
/* Just see if there is *any* string and don't mind it's value. */
|
||||
/* flags |= ICONIC */
|
||||
}
|
||||
if (GetResourceString(db, "bar", MyName, &value))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ... */
|
||||
XrmDestroyDatabase(db);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** END OF EXAMPLE ********************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/* Default option table */
|
||||
static XrmOptionDescRec default_opts[] =
|
||||
{
|
||||
{ "-fg", "*Foreground", XrmoptionSepArg, NULL },
|
||||
{ "-bg", "*Background", XrmoptionSepArg, NULL },
|
||||
{ "-fn", "*Font", XrmoptionSepArg, NULL },
|
||||
{ "-geometry", "*Geometry", XrmoptionSepArg, NULL },
|
||||
{ "-title", "*Title", XrmoptionSepArg, NULL }
|
||||
/* Remember to update NUM_DEFAULT_OPTIONS if you change this list! */
|
||||
};
|
||||
#define NUM_DEFAULT_OPTS 5
|
||||
|
||||
|
||||
|
||||
/* internal function */
|
||||
static void DoMergeString(char *resource, XrmDatabase *ptarget, Bool override)
|
||||
{
|
||||
XrmDatabase db;
|
||||
|
||||
if (!resource)
|
||||
return;
|
||||
db = XrmGetStringDatabase(resource);
|
||||
XrmCombineDatabase(db, ptarget, override);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Merges all X resources for the display/screen into a Xrm database.
|
||||
* If the database does not exist (*pdb == NULL), a new database is created.
|
||||
* If override is True, existing entries of the same name are overwritten.
|
||||
*
|
||||
* Please remember to destroy the database with XrmDestroyDatabase(*pdb)
|
||||
* if you do not need it amymore.
|
||||
*
|
||||
***************************************************************************/
|
||||
void MergeXResources(Display *dpy, XrmDatabase *pdb, Bool override)
|
||||
{
|
||||
if (!*pdb)
|
||||
/* create new database */
|
||||
XrmPutStringResource(pdb, "", "");
|
||||
DoMergeString(XResourceManagerString(dpy), pdb, override);
|
||||
DoMergeString(XScreenResourceString(DefaultScreenOfDisplay(dpy)), pdb,
|
||||
override);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Parses the command line given through pargc/argv and puts recognized
|
||||
* entries into the Xrm database *pdb (if *pdb is NULL a new database is
|
||||
* created). The caller may provide an option list in XrmOptionDescList
|
||||
* format (see XrmParseCommand manpage) and/or parse only standard options
|
||||
* (fg, bg, geometry, fn, title). User given options have precedence over
|
||||
* standard options which are disabled if fNoDefaults is True. Existing
|
||||
* values are overwritten.
|
||||
*
|
||||
* All recognised options are removed from the command line (*pargc and
|
||||
* argv are updated accordingly).
|
||||
*
|
||||
* Please remember to destroy the database with XrmDestroyDatabase(*pdb)
|
||||
* if you do not need it amymore.
|
||||
*
|
||||
***************************************************************************/
|
||||
void MergeCmdLineResources(XrmDatabase *pdb, XrmOptionDescList opts,
|
||||
int num_opts, char *name, int *pargc, char **argv,
|
||||
Bool fNoDefaults)
|
||||
{
|
||||
if (opts && num_opts > 0)
|
||||
XrmParseCommand(pdb, opts, num_opts, name, pargc, argv);
|
||||
if (!fNoDefaults)
|
||||
XrmParseCommand(pdb, default_opts, NUM_DEFAULT_OPTS,
|
||||
name, pargc, argv);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Takes a line from a config file and puts a corresponding value into the
|
||||
* Xrm database *pdb (will be created if *pdb is NULL). 'prefix' is the
|
||||
* name of the module. A specific type of binding in the database must be
|
||||
* provided in bindstr (either "*" or "."). Leading unquoted whitespace are
|
||||
* stripped from value. Existing values in the database are overwritten.
|
||||
* True is returned if the line was indeed merged into the database (i.e. it
|
||||
* had the correct format) or False if not.
|
||||
*
|
||||
* Example: If prefix = "MyModule" and bindstr = "*", the line
|
||||
*
|
||||
* *MyModuleGeometry 80x25+0+0
|
||||
*
|
||||
* will be put into the database as if you had this line in your .Xdefaults:
|
||||
*
|
||||
* MyModule*Geometry: 80x25+0+0
|
||||
*
|
||||
* Please remember to destroy the database with XrmDestroyDatabase(*pdb)
|
||||
* if you do not need it amymore.
|
||||
*
|
||||
***************************************************************************/
|
||||
Bool MergeConfigLineResource(XrmDatabase *pdb, char *line, char *prefix,
|
||||
char *bindstr)
|
||||
{
|
||||
int len;
|
||||
char *end;
|
||||
char *value;
|
||||
char *myvalue;
|
||||
char *resource;
|
||||
size_t reslen;
|
||||
|
||||
/* translate "*(prefix)(suffix)" to "(prefix)(binding)(suffix)",
|
||||
* e.g. "*FvwmPagerGeometry" to "FvwmPager.Geometry" */
|
||||
if (!line || *line != '*')
|
||||
return False;
|
||||
|
||||
line++;
|
||||
len = (prefix) ? strlen(prefix) : 0;
|
||||
if (!prefix || strncasecmp(line, prefix, len))
|
||||
return False;
|
||||
|
||||
line += len;
|
||||
end = line;
|
||||
while (*end && !isspace(*end))
|
||||
end++;
|
||||
if (line == end)
|
||||
return False;
|
||||
value = end;
|
||||
while (*value && isspace(*value))
|
||||
value++;
|
||||
|
||||
/* prefix*suffix: value */
|
||||
reslen = len + (end - line) + 2;
|
||||
resource = (char *)safemalloc(reslen);
|
||||
strlcpy(resource, prefix,reslen);
|
||||
strlcat(resource, bindstr,reslen);
|
||||
strncat(resource, line, end - line);
|
||||
|
||||
len = strlen(value);
|
||||
myvalue = (char *)safemalloc(len + 1);
|
||||
strlcpy(myvalue, value,len+1);
|
||||
for (len--; len >= 0 && isspace(myvalue[len]); len--)
|
||||
myvalue[len] = 0;
|
||||
|
||||
/* merge string into database */
|
||||
XrmPutStringResource(pdb, resource, myvalue);
|
||||
|
||||
free(resource);
|
||||
free(myvalue);
|
||||
return True;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Reads the string-value for the pair prefix/resource from the Xrm database
|
||||
* db and returns a pointer to it. The string may only be read and must not
|
||||
* be freed by the caller. 'prefix' is the class name (usually the name of
|
||||
* the module). If no value is found in the database, *val will be NULL.
|
||||
* True is returned if a value was found, False if not. If you are only
|
||||
* interested if there is a string, but not it's value, you can set val to
|
||||
* NULL.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* GetResourceString(db, "Geometry", "MyModule", &s)
|
||||
*
|
||||
* returns the string value of the "Geometry" resource for MyModule in s.
|
||||
*
|
||||
***************************************************************************/
|
||||
Bool GetResourceString(XrmDatabase db, const char *resource,
|
||||
const char *prefix, char **val)
|
||||
{
|
||||
XrmValue xval = { 0, NULL };
|
||||
char *str_type;
|
||||
char *name;
|
||||
size_t len;
|
||||
|
||||
len = strlen(resource) + strlen(prefix) + 2;
|
||||
name = (char *)safemalloc(len);
|
||||
strlcpy(name, prefix,len);
|
||||
strlcat(name, ".",len);
|
||||
strlcat(name, resource,len);
|
||||
|
||||
if (!XrmGetResource(db, name, name, &str_type, &xval) || xval.addr == NULL)
|
||||
{
|
||||
free(name);
|
||||
if (val)
|
||||
*val = NULL;
|
||||
return False;
|
||||
}
|
||||
free(name);
|
||||
if (val)
|
||||
*val = xval.addr;
|
||||
|
||||
return True;
|
||||
}
|
||||
48
app/fvwm/libs/debug.c
Normal file
48
app/fvwm/libs/debug.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* File: debug.c
|
||||
*
|
||||
* Description:
|
||||
* Implement some debugging/log functions that can be used generically
|
||||
* by all of fvwm + modules.
|
||||
*
|
||||
* Created:
|
||||
* 6 Nov 1998 - Paul D. Smith <psmith@BayNetworks.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
#ifndef HAVE_VFPRINTF
|
||||
# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
|
||||
#else
|
||||
# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
|
||||
#endif
|
||||
|
||||
/* Don't put this into the #ifdef, since some compilers don't like completely
|
||||
* empty source files.
|
||||
*/
|
||||
int f_db_level = 0;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
struct f_db_info f_db_info;
|
||||
|
||||
void
|
||||
f_db_print(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%ld: ", f_db_info.filenm, f_db_info.lineno);
|
||||
|
||||
va_start(ap, fmt);
|
||||
VA_PRINTF(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
#endif
|
||||
318
app/fvwm/libs/envvar.c
Normal file
318
app/fvwm/libs/envvar.c
Normal file
@@ -0,0 +1,318 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* FILE envvar.c
|
||||
* MODULE OF fvwm
|
||||
*
|
||||
* DESCRIPTION Routines to expand environment-variables into strings.
|
||||
* Will understand both $ENV and ${ENV} -type variables.
|
||||
*
|
||||
* WRITTEN BY Sverre H. Huseby
|
||||
* sverrehu@ifi.uio.no
|
||||
*
|
||||
* CREATED 1995/10/3
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "fvwmlib.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P R I V A T E D A T A *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P R I V A T E F U N C T I O N S *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME strDel
|
||||
*
|
||||
* FUNCTION Delete characters from a string.
|
||||
*
|
||||
* INPUT s the string to delete characters from.
|
||||
* idx index of first character to delete.
|
||||
* n number of characters to delete.
|
||||
*
|
||||
* OUTPUT s string with characters deleted.
|
||||
*
|
||||
* DESCRIPTION Deletes characters from a string by moving following
|
||||
* characters back.
|
||||
*
|
||||
*/
|
||||
static void strDel(char *s, int idx, int n)
|
||||
{
|
||||
int l;
|
||||
char *p;
|
||||
|
||||
if (idx >= (l = strlen(s)))
|
||||
return;
|
||||
if (idx + n > l)
|
||||
n = l - idx;
|
||||
s += idx;
|
||||
p = s + n;
|
||||
do {
|
||||
*s++ = *p;
|
||||
} while (*p++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME strIns
|
||||
*
|
||||
* FUNCTION Insert a string into a string.
|
||||
*
|
||||
* INPUT s the string to insert into.
|
||||
* ins the string to insert.
|
||||
* idx index of where to insert the string.
|
||||
* maxstrlen max length of s, including '\0'.
|
||||
*
|
||||
* OUTPUT s string with characters inserted.
|
||||
*
|
||||
* DESCRIPTION The insertion will be done even if the string gets to
|
||||
* long, but characters will be sacrificed at the end of s.
|
||||
* The string is always '\0'-terminated.
|
||||
*
|
||||
*/
|
||||
static void strIns(char *s, const char *ins, int idx, int maxstrlen)
|
||||
{
|
||||
int l, li, move;
|
||||
char *p1, *p2;
|
||||
|
||||
if (idx > (l = strlen(s)))
|
||||
idx = l;
|
||||
li = strlen(ins);
|
||||
move = l - idx + 1; /* include '\0' in move */
|
||||
p1 = s + l;
|
||||
p2 = p1 + li;
|
||||
while (p2 >= s + maxstrlen) {
|
||||
--p1;
|
||||
--p2;
|
||||
--move;
|
||||
}
|
||||
while (move-- > 0)
|
||||
*p2-- = *p1--;
|
||||
p1 = s + idx;
|
||||
if (idx + li >= maxstrlen)
|
||||
li = maxstrlen - idx - 1;
|
||||
while (li--)
|
||||
*p1++ = *ins++;
|
||||
s[maxstrlen - 1] = '\0';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME findEnvVar
|
||||
*
|
||||
* FUNCTION Find first environment variable in a string.
|
||||
*
|
||||
* INPUT s the string to scan.
|
||||
*
|
||||
* OUTPUT len length of variable, including $ and { }.
|
||||
*
|
||||
* RETURNS Pointer to the $ that introduces the variable, or NULL
|
||||
* if no variable is found.
|
||||
*
|
||||
* DESCRIPTION Searches for matches like $NAME and ${NAME}, where NAME is
|
||||
* a sequence of characters, digits and underscores, of which
|
||||
* the first can not be a digit.
|
||||
*
|
||||
* NOTE This function will only return `legal' variables. There
|
||||
* may be $'s in the string that are not followed by what
|
||||
* is considered a legal variable name introducer. Such
|
||||
* occurrences are skipped.
|
||||
*
|
||||
*/
|
||||
static char *findEnvVar(const char *s, int *len)
|
||||
{
|
||||
int brace = 0;
|
||||
char *ret = NULL;
|
||||
const char *next;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
while (*s) {
|
||||
next = s + 1;
|
||||
if (*s == '$' && (isalpha(*next) || *next == '_' || *next == '{')) {
|
||||
ret = (char *) s++;
|
||||
if (*s == '{') {
|
||||
brace = 1;
|
||||
++s;
|
||||
}
|
||||
while (*s && (isalnum(*s) || *s == '_'))
|
||||
++s;
|
||||
*len = s - ret;
|
||||
if (brace) {
|
||||
if (*s == '}') {
|
||||
++*len;
|
||||
break;
|
||||
}
|
||||
ret = NULL;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME getEnv
|
||||
*
|
||||
* FUNCTION Look up environment variable.
|
||||
*
|
||||
* INPUT name name of environment variable to look up. This
|
||||
* may include $ and { }.
|
||||
*
|
||||
* RETURNS The variable contents, or "" if not found.
|
||||
*
|
||||
*/
|
||||
static const char *getEnv(const char *name)
|
||||
{
|
||||
static char *empty = "";
|
||||
char *ret, *tmp, *p, *p2;
|
||||
|
||||
if ((tmp = strdup(name)) == NULL)
|
||||
return empty; /* better than no test at all. */
|
||||
p = tmp;
|
||||
if (*p == '$')
|
||||
++p;
|
||||
if (*p == '{') {
|
||||
++p;
|
||||
if ((p2 = strchr(p, '}')) != NULL)
|
||||
*p2 = '\0';
|
||||
}
|
||||
if ((ret = getenv(p)) == NULL)
|
||||
ret = empty;
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P U B L I C F U N C T I O N S *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME envExpand
|
||||
*
|
||||
* FUNCTION Expand environment variables in a string.
|
||||
*
|
||||
* SYNOPSIS #include "envvar.h"
|
||||
* int envExpand(char *s, int maxstrlen);
|
||||
*
|
||||
* INPUT s string to expand environment variables in.
|
||||
* maxstrlen max length of string, including '\0'.
|
||||
*
|
||||
* OUTPUT s the string with environment variables expanded.
|
||||
*
|
||||
* RETURNS Number of changes done.
|
||||
*
|
||||
* NOTES A non-existing variable is substituted with the empty
|
||||
* string.
|
||||
*
|
||||
*/
|
||||
int envExpand(char *s, int maxstrlen)
|
||||
{
|
||||
char *var, *s2, save;
|
||||
const char *env;
|
||||
int len, ret = 0;
|
||||
|
||||
s2 = s;
|
||||
while ((var = findEnvVar(s2, &len)) != NULL) {
|
||||
++ret;
|
||||
save = var[len];
|
||||
var[len] = '\0';
|
||||
env = getEnv(var);
|
||||
var[len] = save;
|
||||
strDel(s, var - s, len);
|
||||
strIns(s, env, var - s, maxstrlen);
|
||||
s2 = var + strlen(env);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME envDupExpand
|
||||
*
|
||||
* FUNCTION Expand environment variables into a new string.
|
||||
*
|
||||
* SYNOPSIS #include "envvar.h"
|
||||
* char *envDupExpand(const char *s, int extra);
|
||||
*
|
||||
* INPUT s string to expand environment variables in.
|
||||
* extra number of extra bytes to allocate in the
|
||||
* string, in addition to the string contents
|
||||
* and the terminating '\0'.
|
||||
*
|
||||
* RETURNS A dynamically allocated string with environment
|
||||
* variables expanded.
|
||||
* Use free() to deallocate the buffer when it is no
|
||||
* longer needed.
|
||||
* NULL is returned if there is not enough memory.
|
||||
*
|
||||
* NOTES A non-existing variable is substituted with the empty
|
||||
* string.
|
||||
*
|
||||
*/
|
||||
char *envDupExpand(const char *s, int extra)
|
||||
{
|
||||
char *var, *ret, save;
|
||||
const char *env, *s2;
|
||||
int len, slen, elen, bufflen;
|
||||
|
||||
/*
|
||||
* calculate length needed.
|
||||
*/
|
||||
s2 = s;
|
||||
slen = strlen(s);
|
||||
bufflen = slen + 1 + extra;
|
||||
while ((var = findEnvVar(s2, &len)) != NULL) {
|
||||
save = var[len];
|
||||
var[len] = '\0';
|
||||
env = getEnv(var);
|
||||
var[len] = save;
|
||||
elen = strlen(env);
|
||||
/* need to make a buffer the maximum possible size, else we
|
||||
* may get trouble while expanding. */
|
||||
bufflen += len > elen ? len : elen;
|
||||
s2 = var + len;
|
||||
}
|
||||
if (bufflen < slen + 1)
|
||||
bufflen = slen + 1;
|
||||
|
||||
ret = safemalloc(bufflen);
|
||||
|
||||
/*
|
||||
* now do the real expansion.
|
||||
*/
|
||||
strlcpy(ret, s,bufflen);
|
||||
envExpand(ret, bufflen - extra);
|
||||
|
||||
return ret;
|
||||
}
|
||||
167
app/fvwm/libs/fvwmlib.h
Normal file
167
app/fvwm/libs/fvwmlib.h
Normal file
@@ -0,0 +1,167 @@
|
||||
#ifndef FVWMLIB_H
|
||||
#define FVWMLIB_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Intrinsic.h> /* needed for xpm.h and Pixel defn */
|
||||
#include <ctype.h>
|
||||
|
||||
/* Allow GCC extensions to work, if you have GCC */
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(__STRICT_ANSI__)
|
||||
# define __attribute__(x)
|
||||
# endif
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
||||
# define __format__ format
|
||||
# define __printf__ printf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Generic debugging
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef DEBUG
|
||||
# define DB(_x)
|
||||
#else
|
||||
# ifndef __FILE__
|
||||
# define __FILE__ "?"
|
||||
# define __LINE__ 0
|
||||
# endif
|
||||
# define DB(_x) do{f_db_info.filenm=__FILE__;f_db_info.lineno=__LINE__;\
|
||||
f_db_print _x;}while(0)
|
||||
struct f_db_info { const char *filenm; unsigned long lineno; };
|
||||
extern struct f_db_info f_db_info;
|
||||
extern void f_db_print(const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Routines for dealing with strings
|
||||
***********************************************************************/
|
||||
|
||||
char *CatString3(char *a, char *b, char *c);
|
||||
void CopyString(char **dest, char *source);
|
||||
char *stripcpy(char *source);
|
||||
int StrEquals(char *s1,char *s2);
|
||||
|
||||
int envExpand(char *s, int maxstrlen);
|
||||
char *envDupExpand(const char *s, int extra);
|
||||
|
||||
int matchWildcards(char *pattern, char *string);
|
||||
|
||||
/***********************************************************************
|
||||
* Stuff for consistent parsing
|
||||
***********************************************************************/
|
||||
#define EatWS(s) do { while ((s) && (isspace(*(s)) || *(s) == ',')) (s)++; } while (0)
|
||||
#define IsQuote(c) ((c) == '"' || (c) == '\'' || (c) =='`')
|
||||
#define IsBlockStart(c) ((c) == '[' || (c) == '{' || (c) == '(')
|
||||
#define IsBlockEnd(c,cs) (((c) == ']' && (cs) == '[') || ((c) == '}' && (cs) == '{') || ((c) == ')' && (cs) == '('))
|
||||
#define MAX_TOKEN_LENGTH 255
|
||||
|
||||
char *SkipQuote(char *s, const char *qlong, const char *qstart,
|
||||
const char *qend);
|
||||
char *GetQuotedString(char *sin, char **sout, const char *delims,
|
||||
const char *qlong, const char *qstart, const char *qend);
|
||||
char *PeekToken(const char *pstr);
|
||||
char *GetToken(char **pstr);
|
||||
int CmpToken(const char *pstr,char *tok);
|
||||
int MatchToken(const char *pstr,char *tok);
|
||||
void NukeToken(char **pstr);
|
||||
|
||||
/* old style parse routine: */
|
||||
char *DoGetNextToken(char *indata,char **token, char *spaces, char *delims,
|
||||
char *out_delim);
|
||||
char *GetNextToken(char *indata,char **token);
|
||||
char *GetNextOption(char *indata,char **token);
|
||||
char *SkipNTokens(char *indata, unsigned int n);
|
||||
char *GetModuleResource(char *indata, char **resource, char *module_name);
|
||||
int GetIntegerArguments(char *action, char**ret_action, int retvals[],int num);
|
||||
int GetTokenIndex(char *token, char *list[], int len, char **next);
|
||||
char *GetNextTokenIndex(char *action, char *list[], int len, int *index);
|
||||
int GetRectangleArguments(char *action, int *width, int *height);
|
||||
int GetOnePercentArgument(char *action, int *value, int *unit_io);
|
||||
int GetTwoPercentArguments(char *action, int *val1, int *val2, int *val1_unit,
|
||||
int *val2_unit);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Various system related utils
|
||||
***********************************************************************/
|
||||
|
||||
int GetFdWidth(void);
|
||||
int getostype(char *buf, int max);
|
||||
char *safemalloc(int);
|
||||
|
||||
/***********************************************************************
|
||||
* Stuff for modules to communicate with fvwm
|
||||
***********************************************************************/
|
||||
int ReadFvwmPacket(int fd, unsigned long *header, unsigned long **body);
|
||||
void SendText(int *fd,char *message,unsigned long window);
|
||||
#define SendInfo SendText
|
||||
void GetConfigLine(int *fd, char **tline);
|
||||
void SetMessageMask(int *fd, unsigned long mask);
|
||||
|
||||
/***********************************************************************
|
||||
* Stuff for dealing w/ bitmaps & pixmaps:
|
||||
***********************************************************************/
|
||||
typedef struct PictureThing
|
||||
{
|
||||
struct PictureThing *next;
|
||||
char *name;
|
||||
Pixmap picture;
|
||||
Pixmap mask;
|
||||
unsigned int depth;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int count;
|
||||
} Picture;
|
||||
|
||||
void InitPictureCMap(Display*,Window);
|
||||
Picture *GetPicture(Display* dpy, Window Root, char* IconPath,
|
||||
char* PixmapPath, char* name, int color_limit);
|
||||
Picture *CachePicture(Display*,Window,char *iconpath,
|
||||
char *pixmappath,char*,int);
|
||||
void DestroyPicture(Display*,Picture*);
|
||||
|
||||
char *findIconFile(char *icon, char *pathlist, int type);
|
||||
#ifdef XPM
|
||||
#include <X11/xpm.h> /* needed for next prototype */
|
||||
void color_reduce_pixmap(XpmImage *, int);
|
||||
#endif
|
||||
|
||||
Pixel GetShadow(Pixel); /* 3d.c */
|
||||
Pixel GetHilite(Pixel); /* 3d.c */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Wrappers around various X11 routines
|
||||
***********************************************************************/
|
||||
|
||||
XFontStruct *GetFontOrFixed(Display *disp, char *fontname);
|
||||
|
||||
void MyXGrabServer(Display *disp);
|
||||
void MyXUngrabServer(Display *disp);
|
||||
|
||||
void send_clientmessage (Display *disp, Window w, Atom a, Time timestamp);
|
||||
|
||||
/***********************************************************************
|
||||
* Wrappers around Xrm routines (XResources.c)
|
||||
***********************************************************************/
|
||||
void MergeXResources(Display *dpy, XrmDatabase *pdb, Bool override);
|
||||
void MergeCmdLineResources(XrmDatabase *pdb, XrmOptionDescList opts,
|
||||
int num_opts, char *name, int *pargc, char **argv,
|
||||
Bool fNoDefaults);
|
||||
Bool MergeConfigLineResource(XrmDatabase *pdb, char *line, char *prefix,
|
||||
char *bindstr);
|
||||
Bool GetResourceString(XrmDatabase db, const char *resource,
|
||||
const char *prefix, char **val);
|
||||
|
||||
|
||||
#endif
|
||||
53
app/fvwm/libs/gethostname.c
Normal file
53
app/fvwm/libs/gethostname.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/* gethostname emulation for SysV and POSIX.1.
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
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, 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 Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* David MacKenzie <djm@gnu.ai.mit.edu> */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNAME
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
/* Put up to LEN chars of the host name into NAME.
|
||||
Null terminate it if the name is shorter than LEN.
|
||||
Return 0 if ok, -1 if error. */
|
||||
|
||||
int
|
||||
gethostname (name, len)
|
||||
char *name;
|
||||
int len;
|
||||
{
|
||||
#ifdef HAVE_UNAME
|
||||
struct utsname uts;
|
||||
|
||||
if (uname (&uts) == -1)
|
||||
return -1;
|
||||
if (len > sizeof (uts.nodename))
|
||||
{
|
||||
/* More space than we need is available. */
|
||||
name[sizeof (uts.nodename)] = '\0';
|
||||
len = sizeof (uts.nodename);
|
||||
}
|
||||
strlcpy (name, uts.nodename, len);
|
||||
#else
|
||||
strlcpy (name, "", len); /* Hardcode your system name if you want. */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
18
app/fvwm/libs/lang-strings.h
Normal file
18
app/fvwm/libs/lang-strings.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/***************************************************************************
|
||||
* Please translate the strings into the language which you use for
|
||||
* your pop-up menus.
|
||||
*
|
||||
* Some decisions about where a function is prohibited (based on
|
||||
* mwm-function-hints) is based on a string comparison between the
|
||||
* menu item and the strings below.
|
||||
***************************************************************************/
|
||||
#define MOVE_STRING "move"
|
||||
#define RESIZE_STRING1 "size"
|
||||
#define RESIZE_STRING2 "resize"
|
||||
#define MINIMIZE_STRING "minimize"
|
||||
#define MINIMIZE_STRING2 "iconify"
|
||||
#define MAXIMIZE_STRING "maximize"
|
||||
#define CLOSE_STRING1 "close"
|
||||
#define CLOSE_STRING2 "delete"
|
||||
#define CLOSE_STRING3 "destroy"
|
||||
#define CLOSE_STRING4 "quit"
|
||||
27
app/fvwm/libs/safemalloc.c
Normal file
27
app/fvwm/libs/safemalloc.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Procedure:
|
||||
* safemalloc - mallocs specified space or exits if there's a
|
||||
* problem
|
||||
*
|
||||
***********************************************************************/
|
||||
char *safemalloc(int length)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if(length <= 0)
|
||||
length = 1;
|
||||
|
||||
ptr = malloc(length);
|
||||
if(ptr == (char *)0)
|
||||
{
|
||||
fprintf(stderr,"malloc of %d bytes failed. Exiting\n",length);
|
||||
exit(1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
75
app/fvwm/libs/wild.c
Normal file
75
app/fvwm/libs/wild.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Does `string' match `pattern'? '*' in pattern matches any sub-string
|
||||
* (including the null string) '?' matches any single char. For use
|
||||
* by filenameforall. Note that '*' matches across directory boundaries
|
||||
*
|
||||
* This code donated by Paul Hudson <paulh@harlequin.co.uk>
|
||||
* It is public domain, no strings attached. No guarantees either.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int matchWildcards(char *pattern, char *string)
|
||||
{
|
||||
if(string == NULL)
|
||||
{
|
||||
if(pattern == NULL)
|
||||
return TRUE;
|
||||
else if(strcmp(pattern,"*")==0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
if(pattern == NULL)
|
||||
return TRUE;
|
||||
|
||||
while (*string && *pattern)
|
||||
{
|
||||
if (*pattern == '?')
|
||||
{
|
||||
/* match any character */
|
||||
pattern += 1;
|
||||
string += 1;
|
||||
}
|
||||
else if (*pattern == '*')
|
||||
{
|
||||
/* see if the rest of the pattern matches any trailing substring
|
||||
of the string. */
|
||||
pattern += 1;
|
||||
if (*pattern == 0)
|
||||
{
|
||||
return TRUE; /* trailing * must match rest */
|
||||
}
|
||||
while (*string)
|
||||
{
|
||||
if (matchWildcards(pattern,string))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*pattern == '\\')
|
||||
pattern ++; /* has strange, but harmless effects if the last
|
||||
character is a '\\' */
|
||||
if (*pattern++ != *string++)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if((*pattern == 0)&&(*string == 0))
|
||||
return TRUE;
|
||||
if((*string == 0)&&(strcmp(pattern,"*")==0))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user