rendered paste body/*************************************************************************//* _____________ *//* < yeahconsole > *//* ------------- *//* \ ^__^ *//* \ (oo)\_______ *//* (__)\ )\/\ *//* ||----w | *//* || || *//* *//* Copyright (C) knorke *//* *//* 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., 675 Mass Ave, Cambridge, MA 02139, USA. *//*************************************************************************/#include <X11/Xlib.h>#include <X11/keysym.h>#include <X11/Xutil.h>#include <X11/cursorfont.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "config.h"Display *dpy;Window root;Window win;Window termwin;Window last_focused;int revert_to;int screen;int opt_x, opt_width, opt_height, opt_delay, opt_bw, height;int opt_hideStep, opt_showStep;char *opt_color;KeySym opt_key;KeySym opt_key_smaller;KeySym opt_key_bigger;Cursor cursor;int resize_inc;void roll(int i);void get_defaults(void);KeySym grab_that_key(char *opt, unsigned int numlockmask);void init_win(void);void init_xterm(void);void resize(void);int handle_xerror(Display * display, XErrorEvent * e);int main(int argc, char *argv[]){ KeySym key; XEvent event; int hidden = 1; if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, " can not open dpy %s", XDisplayName(NULL)); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); XSetErrorHandler(handle_xerror); cursor = XCreateFontCursor(dpy, XC_double_arrow); get_defaults(); init_win(); init_xterm(); while (1) { XNextEvent(dpy, &event); switch (event.type) { case EnterNotify: XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); break; case LeaveNotify: if (last_focused && event.xcrossing.detail != NotifyInferior) XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); break; case KeyPress: key = XKeycodeToKeysym(dpy, event.xkey.keycode, 0); if (key == opt_key) { if (!hidden) { if (last_focused) XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); /* else XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); */ roll(0); hidden = 1; XSync(dpy, False); } else { XRaiseWindow(dpy, win); XGetInputFocus(dpy, &last_focused, &revert_to); XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); roll(-(height + opt_bw)); hidden = 0; } break; } if (!hidden) { if (key == opt_key_bigger) height += resize_inc; if (key == opt_key_smaller) height -= resize_inc; if (height < resize_inc) height = resize_inc; XResizeWindow(dpy, termwin, opt_width, height); XResizeWindow(dpy, win, opt_width, height + opt_bw); } break; case ButtonPress: resize(); break; case UnmapNotify: if (event.xunmap.window == termwin) { if (last_focused) XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XSync(dpy, False); exit(0); } break; } } return 0;}void roll(int i){ int x = opt_showStep; if (i == 0) x = -opt_hideStep; while (1) { i += x; if ( (x>0) && (i>0) ) i=0; if ( (x<0) && (i< -(height + opt_bw))) i=-(height + opt_bw); XMoveWindow(dpy, win, opt_x, i); XSync(dpy, False); usleep(opt_delay * 10); if (i == 0 || i == -(height + opt_bw)) break; }}void get_defaults(){ char *opt; XModifierKeymap *modmap; unsigned int numlockmask = 0; int i, j; char def_key []="ControlAlt+y"; char def_key_bigger[] = "Control+KP_Add"; char def_key_smaller[] = "Control+KP_Subtract"; /* key grabbing stuff taken from evilwm */ modmap = XGetModifierMapping(dpy); for (i = 0; i < 8; i++) { for (j = 0; j < modmap->max_keypermod; j++) { if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) { numlockmask = (1 << i); } } } XFreeModifiermap(modmap); opt = XGetDefault(dpy, "yeahconsole", "showStep"); opt_showStep = opt ? atoi(opt) : 1; opt = XGetDefault(dpy, "yeahconsole", "hideStep"); opt_hideStep = opt ? atoi(opt) : 1; opt = XGetDefault(dpy, "yeahconsole", "screenWidth"); opt_width = opt ? atoi(opt) : DisplayWidth(dpy, screen); opt = XGetDefault(dpy, "yeahconsole", "handleColor"); opt_color = opt ? opt : "grey70"; opt = XGetDefault(dpy, "yeahconsole", "handleWidth"); opt_bw = opt ? atoi(opt) : 3; opt = XGetDefault(dpy, "yeahconsole", "consoleHeight"); opt_height = opt ? atoi(opt) : 10; opt = XGetDefault(dpy, "yeahconsole", "xOffset"); opt_x = opt ? atoi(opt) : 0; opt = XGetDefault(dpy, "yeahconsole", "aniDelay"); opt_delay = opt ? atoi(opt) : 40; opt = XGetDefault(dpy, "yeahconsole", "toggleKey"); opt_key = opt ? grab_that_key(opt, numlockmask) : grab_that_key(def_key, numlockmask); opt = XGetDefault(dpy, "yeahconsole", "keySmaller"); opt_key_smaller = opt ? grab_that_key(opt, numlockmask) : grab_that_key(def_key_smaller, numlockmask); opt = XGetDefault(dpy, "yeahconsole", "keyBigger"); opt_key_bigger = opt ? grab_that_key(opt, numlockmask) : grab_that_key(def_key_bigger, numlockmask);}KeySym grab_that_key(char *opt, unsigned int numlockmask){ unsigned int modmask = 0; KeySym keysym; if (strstr(opt, "Control")) modmask = modmask | ControlMask; if (strstr(opt, "Alt")) modmask = modmask | Mod1Mask; if (strstr(opt, "Win")) modmask = modmask | Mod4Mask; if (strstr(opt, "None")) modmask = 0; if (strtok(opt, "+")) keysym = XStringToKeysym(strtok(NULL, "+")); XGrabKey(dpy, XKeysymToKeycode(dpy, keysym), modmask, root, True, GrabModeAsync, GrabModeAsync); XGrabKey(dpy, XKeysymToKeycode(dpy, keysym), LockMask | modmask, root, True, GrabModeAsync, GrabModeAsync); if (numlockmask) { XGrabKey(dpy, XKeysymToKeycode(dpy, keysym), numlockmask | modmask, root, True, GrabModeAsync, GrabModeAsync); XGrabKey(dpy, XKeysymToKeycode(dpy, keysym), numlockmask | LockMask | modmask, root, True, GrabModeAsync, GrabModeAsync); } return keysym;}void init_win(){ XSetWindowAttributes attrib; XColor color; XColor dummy_color; attrib.override_redirect = True; attrib.background_pixel = BlackPixel(dpy, screen); win = XCreateWindow(dpy, root, opt_x, -opt_height, opt_width, opt_height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackPixel, &attrib); XSelectInput(dpy, win, SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), opt_color, &color, &dummy_color); XSetWindowBackground(dpy, win, color.pixel); XMapWindow(dpy, win); /* printf("win:0x%x\n", win); */}void init_xterm(){ char cmd[20]; XEvent ev; long dummy; XSizeHints *size; sprintf(cmd, " %d ", (int) win); if (!fork()) { execlp("xterm", "xterm", "-name", "yeahconsole", "-b", "0", "-into", cmd, "-e", "~/.yeah/script.sh", NULL); fprintf(stderr, "Oops, no xterm found\n"); exit(1); } while (1) { XMaskEvent(dpy, SubstructureNotifyMask, &ev); if (ev.type == ReparentNotify && ev.xreparent.parent == win) { termwin = ev.xreparent.window; /* printf("termwin:0x%x\n", termwin); */ break; } } XSetWindowBorderWidth(dpy, termwin, 0); size = XAllocSizeHints(); XGetWMNormalHints(dpy, termwin, size, &dummy); resize_inc = size->height_inc; height = resize_inc * opt_height; XFree(size); XResizeWindow(dpy, termwin, opt_width, height); XMoveResizeWindow(dpy, win, opt_x, -(height + opt_bw), opt_width, height + opt_bw);}void resize(){ XEvent ev; if (!XGrabPointer (dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime) == GrabSuccess) return; for (;;) { XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | PointerMotionHintMask, &ev); switch (ev.type) { case MotionNotify: if (!(ev.xmotion.y % resize_inc) && ev.xmotion.y >= resize_inc) { height = ev.xmotion.y; XResizeWindow(dpy, termwin, opt_width, height); XResizeWindow(dpy, win, opt_width, height + opt_bw); XSync(dpy, False); break; case ButtonRelease: XUngrabPointer(dpy, CurrentTime); return; } } }}int handle_xerror(Display * display, XErrorEvent * e){ /* this function does nothing, we receive xerrors when the last_focused window gets lost.. */ /* fprintf(stderr, "XError caught\n"); */ return 0;}