/* * remote_cmd.cc * * Copyright (C) 1995, 1996, 1997, 1997, 1998, 1999, 2000, 2001, 2002 Kenichi Kourai * Copyright (C) 1999, 2000, 2001, 2002 Luiz Blanes * * 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 blwm; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef ALLOW_RMTCMD #include #include #include #include #include #include #include #include #include #include #include "main.h" #include "remote_cmd.h" #include "function.h" #include "hash.h" #include "blwmrc.h" #define TMP_DIR "/tmp/" #define FIFO_PREFIX "blwm-" 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) { BlwmError("RemoteCommand: mknod: %s", strerror(errno)); m_fd = -1; return; } if (unlink(m_fifoName) == -1) { BlwmError("'%s' exists but cannot be removed: %s", m_fifoName, strerror(errno)); m_fd = -1; return; } BlwmError("removed '%s'", m_fifoName); if (mknod(m_fifoName, S_IFIFO | 0600, 0) == -1) { BlwmError("mknod '%s': %s", m_fifoName, strerror(errno)); m_fd = -1; return; } } if ((m_fd = open(m_fifoName, O_RDWR | O_NONBLOCK)) == -1) { BlwmError("open '%s': %s", m_fifoName, strerror(errno)); return; } } RemoteCommand::~RemoteCommand() { if (m_fd != -1) { close(m_fd); if (unlink(m_fifoName) == -1) BlwmError("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) BlwmError("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) BlwmError("too long remote command; command must be terminated by '\n'"); else BlwmError("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 = BlFunction::funcHashTable->GetHashItem(cmd)) == NULL) { BlwmError("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; BlFunction::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: BlFunction::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* blwmList = &desktop.GetBlwmList(); List::Iterator i(blwmList); Blwm* blWm; int idx=0; XClassHint wm_class; // STRING for (blWm = i.GetHead(); blWm; blWm = i.GetNext()) { XGetClassHint(display, blWm->GetWin(), &wm_class); if ((!strncmp(args, wm_class.res_name, strlen(args))) || (!strncmp(args, wm_class.res_class, strlen(args)))) { BlFunction::execFunction(*fn, blWm); } } break; } default: BlwmError("not supported command '%s' as a remote command", cmd); break; } } #endif // ALLOW_RMTCMD