/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/****************************************************************************
* 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
****************************************************************************/
/*
* ********************************************************************
*
* code for processing module configuration commands
*
* Modification History
*
* Created 09/23/98 by Dan Espen:
*
* - Some of this Logic used to reside in "read.c", preceeded by a
* comment about whether it belonged there. Time tells.
*
* - Added logic to execute module config commands by passing to the
* modules that want "active command pipes".
*
* ********************************************************************
*/
#include "config.h"
#include <stdio.h>
#include "libs/fvwmlib.h"
#include "fvwm.h"
#include "externs.h"
#include "cursor.h"
#include "functions.h"
#include "bindings.h"
#include "misc.h"
#include "screen.h"
#include "module_interface.h"
#include "libs/Colorset.h"
#include "libs/FScreen.h"
extern unsigned long *PipeMask; /* in module.c */
extern int nColorsets; /* in libs/Colorset.c */
#define MODULE_CONFIG_DELIM ':'
struct moduleInfoList
{
char *data;
unsigned char alias_len;
struct moduleInfoList *next;
};
struct moduleInfoList *modlistroot = NULL;
static struct moduleInfoList *AddToModList(char *tline);
static void SendConfigToModule(
int module, const struct moduleInfoList *entry, char *match, int match_len);
/*
* ModuleConfig handles commands starting with "*".
*
* Each command is added to a list from which modules request playback
* thru "sendconfig".
*
* Some modules request that module config commands be sent to them
* as the commands are entered. Send to modules that want it.
*/
void ModuleConfig(char *action) {
int module, end;
struct moduleInfoList *new_entry;
end = strlen(action) - 1;
if (action[end] == '\n')
action[end] = '\0';
new_entry = AddToModList(action); /* save for config request */
for (module = 0; module < npipes; module++) /* look at all possible pipes */
{
if (PipeMask[module] & M_SENDCONFIG) /* does module want config cmds */
{
extern char **pipeName;
char *name = pipeName[module];
#ifndef WITHOUT_KILLMODULE_ALIAS_SUPPORT
extern char **pipeAlias;
if (pipeAlias[module]) name = pipeAlias[module];
#endif
SendConfigToModule(module, new_entry, CatString2("*", name), 0);
}
}
}
static struct moduleInfoList *AddToModList(char *tline)
{
struct moduleInfoList *t, *prev, *this;
char *rline = tline;
char *alias_end = skipModuleAliasToken(tline + 1);
/* Find end of list */
t = modlistroot;
prev = NULL;
while(t != NULL)
{
prev = t;
t = t->next;
}
this = (struct moduleInfoList *)safemalloc(sizeof(struct moduleInfoList));
this->alias_len = 0;
if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM)
{
/* migo (01-Sep-2000): construct an old-style config line */
char *conf_start = alias_end + 1;
while (isspace(*conf_start)) conf_start++;
*alias_end = '\0';
rline = CatString2(tline, conf_start);
*alias_end = MODULE_CONFIG_DELIM;
this->alias_len = alias_end - tline;
}
this->data = (char *)safemalloc(strlen(rline)+1);
strcpy(this->data, rline);
this->next = NULL;
if(prev == NULL)
{
modlistroot = this;
}
else
prev->next = this;
return this;
}
/**************************************************************/
/* delete from module configuration */
/**************************************************************/
void CMD_DestroyModuleConfig(F_CMD_ARGS)
{
struct moduleInfoList *current, *next, *prev;
char *info; /* info to be deleted - may contain wildcards */
char *mi;
char *alias_end;
int alias_len = 0;
while (isspace(*action)) action++;
alias_end = skipModuleAliasToken(action);
if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM)
{
/* migo: construct an old-style config line */
char *conf_start = alias_end + 1;
while (isspace(*conf_start)) conf_start++;
*alias_end = '\0';
GetNextToken(conf_start, &conf_start);
if (conf_start == NULL)
return;
info = stripcpy(CatString2(action, conf_start));
*alias_end = MODULE_CONFIG_DELIM;
alias_len = alias_end - action + 1; /* +1 for a leading '*' */
free(conf_start);
}
else
{
GetNextToken(action, &info);
if (info == NULL)
return;
}
current = modlistroot;
prev = NULL;
while (current != NULL)
{
GetNextToken(current->data, &mi);
next = current->next;
if ((!alias_len || !current->alias_len || alias_len == current->alias_len)
&& matchWildcards(info, mi+1))
{
free(current->data);
free(current);
if( prev )
{
prev->next = next;
}
else
{
modlistroot = next;
}
}
else
{
prev = current;
}
current = next;
if (mi)
free(mi);
}
free(info);
}
static void send_xinerama_state(int modnum)
{
SendName(modnum, M_CONFIG_INFO, 0, 0, 0, FScreenGetConfiguration());
return;
}
void CMD_Send_ConfigInfo(F_CMD_ARGS)
{
struct moduleInfoList *t;
char *message, msg2[32];
char *match; /* matching criteria for module cmds */
int match_len = 0; /* get length once for efficiency */
int n;
char *ImagePath = GetImagePath();
GetNextToken(action, &match);
if (match) {
match_len = strlen(match);
}
/* send desktop geometry */
sprintf(msg2,"DesktopSize %d %d\n", Scr.VxMax / Scr.MyDisplayWidth + 1,
Scr.VyMax / Scr.MyDisplayHeight + 1);
SendName(*Module,M_CONFIG_INFO,0,0,0,msg2);
/* send ImagePath and ColorLimit first */
if (ImagePath && strlen(ImagePath))
{
message=safemalloc(strlen(ImagePath)+12);
sprintf(message,"ImagePath %s\n",ImagePath);
SendName(*Module,M_CONFIG_INFO,0,0,0,message);
free(message);
}
#ifdef XPM
{
sprintf(msg2,"ColorLimit %d\n",Scr.ColorLimit);
SendName(*Module,M_CONFIG_INFO,0,0,0,msg2);
}
#endif
send_xinerama_state(*Module);
/* now dump the colorsets (0 first as others copy it) */
for (n = 0; n < nColorsets; n++)
SendName(*Module, M_CONFIG_INFO, 0, 0, 0, DumpColorset(n, &Colorset[n]));
/* Dominik Vogt (8-Nov-1998): Scr.ClickTime patch to set ClickTime to
* 'not at all' during InitFunction and RestartFunction. */
sprintf(msg2,"ClickTime %d\n", (Scr.ClickTime < 0) ?
-Scr.ClickTime : Scr.ClickTime);
SendName(*Module,M_CONFIG_INFO,0,0,0,msg2);
sprintf(msg2,"MoveThreshold %d\n", Scr.MoveThreshold);
SendName(*Module,M_CONFIG_INFO,0,0,0,msg2);
for (t = modlistroot; t != NULL; t = t->next)
{
SendConfigToModule(*Module, t, match, match_len);
}
SendPacket(*Module,M_END_CONFIG_INFO,0,0,0,0,0,0,0,0);
free(match);
}
static void SendConfigToModule(
int module, const struct moduleInfoList *entry, char *match, int match_len)
{
if (match)
{
if (match_len == 0)
match_len = strlen(match);
if (entry->alias_len > 0 && entry->alias_len != match_len)
return;
/* migo: this should be strncmp not strncasecmp probably. */
if (strncasecmp(entry->data, match, match_len) != 0)
return;
}
SendName(module, M_CONFIG_INFO, 0, 0, 0, entry->data);
}
syntax highlighted by Code2HTML, v. 0.9.1