/*
* remote_cmd.cc
*
* Copyright (C) 1995-2001 Kenichi Kourai
*
* 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 qvwm; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef ALLOW_RMTCMD
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "main.h"
#include "remote_cmd.h"
#include "function.h"
#include "hash.h"
#include "qvwmrc.h"
#define TMP_DIR "/tmp/"
#define FIFO_PREFIX "qvwm-"
RemoteCommand::RemoteCommand()
{
char *dispName = DisplayString(display);
int dispLen = strlen(dispName);
int dirLen = strlen(TMP_DIR);
int prefixLen = strlen(FIFO_PREFIX);
m_fifoName = (char *)malloc(dirLen + prefixLen + dispLen + 1);
sprintf(m_fifoName, "%s%s%s", TMP_DIR, FIFO_PREFIX, dispName);
if (mknod(m_fifoName, S_IFIFO | 0600, 0) == -1) {
if (errno != EEXIST) {
QvwmError("RemoteCommand: mknod: %s", strerror(errno));
m_fd = -1;
return;
}
if (unlink(m_fifoName) == -1) {
QvwmError("'%s' exists but cannot be removed: %s",
m_fifoName, strerror(errno));
m_fd = -1;
return;
}
QvwmError("removed '%s'", m_fifoName);
if (mknod(m_fifoName, S_IFIFO | 0600, 0) == -1) {
QvwmError("mknod '%s': %s", m_fifoName, strerror(errno));
m_fd = -1;
return;
}
}
if ((m_fd = open(m_fifoName, O_RDWR | O_NONBLOCK)) == -1) {
QvwmError("open '%s': %s", m_fifoName, strerror(errno));
return;
}
}
RemoteCommand::~RemoteCommand()
{
if (m_fd != -1) {
close(m_fd);
if (unlink(m_fifoName) == -1)
QvwmError("RemoteCommand: unlink '%s': %s", m_fifoName, strerror(errno));
free(m_fifoName);
}
}
#define BUF_SIZE 256
void RemoteCommand::process()
{
char buf[BUF_SIZE];
char *cmd, *ptr;
int len;
if ((len = read(m_fd, buf, BUF_SIZE)) < 0) {
if (errno != EAGAIN)
QvwmError("RemoteCommand: read: %s", strerror(errno));
return;
}
cmd = ptr = buf;
while (len > 0) {
if (*ptr == '\n') {
*ptr = '\0';
interpret(cmd);
cmd = ptr + 1; // point to the next command
}
ptr++;
len--;
}
if (cmd != ptr) {
if (cmd == buf)
QvwmError("too long remote command; command must be terminated by '\n'");
else
QvwmError("incomplete remote command is discarded");
}
}
void RemoteCommand::interpret(char* cmd)
{
FuncNumber *fn;
char *ptr = cmd, *args;
while (*ptr != '\0') {
if (*ptr == ' ')
break;
ptr++;
}
*ptr = '\0';
args = ptr + 1;
if ((fn = QvFunction::funcHashTable->GetHashItem(cmd)) == NULL) {
QvwmError("invalid function name: '%s'", cmd);
return;
}
switch (*fn) {
case Q_NONE:
return;
case Q_EXIT:
{
Bool bakUseExitDialog = UseExitDialog;
Bool bakUseConfirmDialog = UseConfirmDialog;
// change to non-interructive mode
UseExitDialog = False;
UseConfirmDialog = False;
QvFunction::execFunction(Q_EXIT);
UseExitDialog = bakUseExitDialog;
UseConfirmDialog = bakUseConfirmDialog;
}
break;
case Q_RESTART:
// window focus
case Q_CHANGE_WINDOW:
case Q_CHANGE_WINDOW_BACK:
case Q_CHANGE_WINDOW_INSCR:
case Q_CHANGE_WINDOW_BACK_INSCR:
case Q_DESKTOP_FOCUS:
// window rearrangement
case Q_OVERLAP:
case Q_OVERLAP_INSCR:
case Q_TILE_HORZ:
case Q_TILE_HORZ_INSCR:
case Q_TILE_VERT:
case Q_TILE_VERT_INSCR:
case Q_MINIMIZE_ALL:
case Q_MINIMIZE_ALL_INSCR:
case Q_RESTORE_ALL:
case Q_RESTORE_ALL_INSCR:
case Q_CLOSE_ALL:
case Q_CLOSE_ALL_INSCR:
// menu
case Q_POPUP_START_MENU:
case Q_POPUP_DESKTOP_MENU:
case Q_POPDOWN_ALL_MENU:
// paging
case Q_LEFT_PAGING:
case Q_RIGHT_PAGING:
case Q_UP_PAGING:
case Q_DOWN_PAGING:
// taskbar
case Q_BOTTOM:
case Q_TOP:
case Q_LEFT:
case Q_RIGHT:
case Q_TOGGLE_AUTOHIDE:
case Q_ENABLE_AUTOHIDE:
case Q_DISABLE_AUTOHIDE:
case Q_TOGGLE_TASKBAR:
case Q_ENABLE_TASKBAR:
case Q_DISABLE_TASKBAR:
case Q_SHOW_TASKBAR:
case Q_HIDE_TASKBAR:
// pager
case Q_TOGGLE_PAGER:
case Q_ENABLE_PAGER:
case Q_DISABLE_PAGER:
// icon
case Q_LINEUP_ICON:
QvFunction::execFunction(*fn);
break;
case Q_MINIMIZE:
case Q_MAXIMIZE:
case Q_RESTORE:
case Q_EXPAND:
case Q_EXPAND_LEFT:
case Q_EXPAND_RIGHT:
case Q_EXPAND_UP:
case Q_EXPAND_DOWN:
case Q_RAISE:
case Q_LOWER:
case Q_CLOSE:
case Q_KILL:
case Q_TOGGLE_ONTOP:
case Q_ENABLE_ONTOP:
case Q_DISABLE_ONTOP:
case Q_TOGGLE_STICKY:
case Q_ENABLE_STICKY:
case Q_DISABLE_STICKY:
{
List<Qvwm>* qvwmList = &desktop.GetQvwmList();
List<Qvwm>::Iterator i(qvwmList);
Qvwm* qvWm;
int idx=0;
XClassHint wm_class; // STRING
for (qvWm = i.GetHead(); qvWm; qvWm = i.GetNext()) {
XGetClassHint(display, qvWm->GetWin(), &wm_class);
if ((!strncmp(args, wm_class.res_name, strlen(args))) ||
(!strncmp(args, wm_class.res_class, strlen(args)))) {
QvFunction::execFunction(*fn, qvWm);
}
}
break;
}
default:
QvwmError("not supported command '%s' as a remote command", cmd);
break;
}
}
#endif // ALLOW_RMTCMD
syntax highlighted by Code2HTML, v. 0.9.1