/*----------------------------------------------------------------------* * File: rxvttoolkit.h - provide toolkit-functionality for rxvt. *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 2003-2011 Marc Lehmann * Copyright (c) 2011 Emanuele Giaquinta * * 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 3 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. *----------------------------------------------------------------------*/ #ifndef RXVT_TOOLKIT_H #define RXVT_TOOLKIT_H #include #if XFT # include #endif #include "ev_cpp.h" #include "rxvtutil.h" #include "callback.h" // see rxvttoolkit.C:xa_names, which must be kept in sync enum { XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING, XA_MULTIPLE, XA_TARGETS, XA_TIMESTAMP, XA_VT_SELECTION, XA_INCR, XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW, XA_CLIPBOARD, XA_AVERAGE_WIDTH, XA_WEIGHT_NAME, XA_SLANT, XA_CHARSET_REGISTRY, XA_CHARSET_ENCODING, #if ENABLE_FRILLS XA_MOTIF_WM_HINTS, #endif #if ENABLE_EWMH XA_NET_WM_PID, XA_NET_WM_NAME, XA_NET_WM_ICON_NAME, XA_NET_WM_PING, XA_NET_WM_ICON, #endif #if USE_XIM XA_WM_LOCALE_NAME, XA_XIM_SERVERS, #endif #if HAVE_IMG || ENABLE_PERL XA_XROOTPMAP_ID, XA_ESETROOT_PMAP_ID, #endif #if ENABLE_XEMBED XA_XEMBED, XA_XEMBED_INFO, #endif #if !ENABLE_MINIMAL // these are usually allocated by other subsystems, but we do it // here to avoid a server roundtrip. XA_SCREEN_RESOURCES, XA_XDCCC_LINEAR_RGB_CORRECTION, XA_XDCCC_LINEAR_RGB_MATRICES, XA_WM_COLORMAP_WINDOWS, XA_WM_STATE, XA_cursor, # if USE_XIM // various selection targets used by XIM XA_TRANSPORT, XA_LOCALES, XA__XIM_PROTOCOL, XA__XIM_XCONNECT, XA__XIM_MOREDATA, # endif #endif NUM_XA }; struct rxvt_term; struct rxvt_display; struct im_watcher; struct xevent_watcher; template struct event_vec : vector { void erase_unordered (unsigned int pos) { watcher *w = (*this)[this->size () - 1]; this->pop_back (); if (!this->empty ()) if (((*this)[pos] = w)) // '=' is correct! w->active = pos + 1; } }; struct rxvt_watcher { int active; /* 0 == inactive, else index into respective vector */ bool is_active () { return active; } rxvt_watcher () : active (0) { } }; struct refcounted { int referenced; char *id; refcounted (const char *id); bool ref_init () { return false; } void ref_next () { } ~refcounted (); }; template struct refcache : vector { T *get (const char *id); void put (T *obj); void clear (); ~refcache () { clear (); } }; ///////////////////////////////////////////////////////////////////////////// struct rxvt_screen; struct rxvt_drawable { rxvt_screen *screen; Drawable drawable; operator Drawable() { return drawable; } #if XFT XftDraw *xftdrawable; operator XftDraw *(); #endif rxvt_drawable (rxvt_screen *screen, Drawable drawable) : screen(screen), #if XFT xftdrawable(0), #endif drawable(drawable) { } #if XFT ~rxvt_drawable (); #endif }; ///////////////////////////////////////////////////////////////////////////// #if USE_XIM struct rxvt_xim : refcounted { void destroy (); rxvt_display *display; //public XIM xim; rxvt_xim (const char *id) : refcounted (id) { } bool ref_init (); ~rxvt_xim (); }; #endif struct rxvt_screen { rxvt_display *display; Display *dpy; int depth; Visual *visual; Colormap cmap; #if XFT // scratch pixmap rxvt_drawable *scratch_area; int scratch_w, scratch_h; rxvt_drawable &scratch_drawable (int w, int h); rxvt_screen (); #endif void set (rxvt_display *disp); void select_visual (int id); void select_depth (int bitdepth); // select visual by depth void clear (); }; enum { DISPLAY_HAS_RENDER = 1 << 0, DISPLAY_HAS_RENDER_CONV = 1 << 1, }; struct rxvt_display : refcounted { event_vec xw; ev::prepare flush_ev; void flush_cb (ev::prepare &w, int revents); ev::io x_ev ; void x_cb (ev::io &w, int revents); #if USE_XIM refcache xims; vector imw; void im_change_cb (); void im_change_check (); #endif //public Display *dpy; int screen; Window root; rxvt_term *selection_owner; rxvt_term *clipboard_owner; Atom xa[NUM_XA]; bool is_local; #ifdef POINTER_BLANK Cursor blank_cursor; #endif uint8_t flags; rxvt_display (const char *id); XrmDatabase get_resources (bool refresh); bool ref_init (); void ref_next (); ~rxvt_display (); void flush () { flush_ev.start (); } Atom atom (const char *name); Pixmap get_pixmap_property (Atom property); void set_selection_owner (rxvt_term *owner, bool clipboard); void reg (xevent_watcher *w); void unreg (xevent_watcher *w); #if USE_XIM void reg (im_watcher *w); void unreg (im_watcher *w); rxvt_xim *get_xim (const char *locale, const char *modifiers); void put_xim (rxvt_xim *xim); #endif }; #if USE_XIM struct im_watcher : rxvt_watcher, callback { void start (rxvt_display *display) { display->reg (this); } void stop (rxvt_display *display) { display->unreg (this); } }; #endif struct xevent_watcher : rxvt_watcher, callback { Window window; void start (rxvt_display *display, Window window) { this->window = window; display->reg (this); } void stop (rxvt_display *display) { display->unreg (this); } }; extern refcache displays; ///////////////////////////////////////////////////////////////////////////// typedef unsigned long Pixel; struct rgba { uint16_t r, g, b, a; enum { MIN_CC = 0x0000, MAX_CC = 0xffff }; rgba () { } rgba (uint16_t r, uint16_t g, uint16_t b, uint16_t a = MAX_CC) : r(r), g(g), b(b), a(a) { } }; struct rxvt_color { #if XFT XftColor c; #else XColor c; #endif operator Pixel () const { return c.pixel; } bool operator == (const rxvt_color &b) const { return Pixel (*this) == Pixel (b); } bool operator != (const rxvt_color &b) const { return Pixel (*this) != Pixel (b); } bool is_opaque () const { #if XFT return c.color.alpha == rgba::MAX_CC; #else return 1; #endif } bool alloc (rxvt_screen *screen, const rgba &color); void free (rxvt_screen *screen); operator rgba () const { rgba c; get (c); return c; } void get (rgba &color) const; void get (XColor &color) const; bool set (rxvt_screen *screen, const char *name); bool set (rxvt_screen *screen, const rgba &color); void fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to = rgba (0, 0, 0)); }; #define Sel_normal 0x01 /* normal selection */ #define Sel_incr 0x02 /* incremental selection */ #define Sel_Primary 0x01 #define Sel_Secondary 0x02 #define Sel_Clipboard 0x03 #define Sel_whereMask 0x0f #define Sel_CompoundText 0x10 /* last request was COMPOUND_TEXT */ #define Sel_UTF8String 0x20 /* last request was UTF8_STRING */ struct rxvt_selection { rxvt_selection (rxvt_display *disp, int selnum, Time tm, Window win, Atom prop, rxvt_term *term); void run (); void finish (char *data = 0, unsigned int len = 0); ~rxvt_selection (); rxvt_term *term; // terminal to paste to, may be 0 void *cb_sv; // managed by perl rxvt_display *display; Time request_time; Window request_win; Atom request_prop; private: unsigned char selection_wait; unsigned char selection_type; char *incr_buf; size_t incr_buf_size, incr_buf_fill; void timer_cb (ev::timer &w, int revents); ev::timer timer_ev; void x_cb (XEvent &xev); xevent_watcher x_ev; void stop (); bool request (Atom target, int selnum); void handle_selection (Window win, Atom prop, bool delete_prop); }; #endif