diff options
Diffstat (limited to 'app/xterm/screen.c')
-rw-r--r-- | app/xterm/screen.c | 238 |
1 files changed, 230 insertions, 8 deletions
diff --git a/app/xterm/screen.c b/app/xterm/screen.c index 952a584bc..14ae746d1 100644 --- a/app/xterm/screen.c +++ b/app/xterm/screen.c @@ -1,7 +1,7 @@ -/* $XTermId: screen.c,v 1.426 2010/10/11 00:46:05 tom Exp $ */ +/* $XTermId: screen.c,v 1.436 2011/02/20 00:48:23 tom Exp $ */ /* - * Copyright 1999-2009,2010 by Thomas E. Dickey + * Copyright 1999-2010,2011 by Thomas E. Dickey * * All Rights Reserved * @@ -61,11 +61,14 @@ #include <xcharmouse.h> #include <xterm_io.h> +#include <X11/Xatom.h> + #if OPT_WIDE_CHARS #include <fontutils.h> -#include <menu.h> #endif +#include <menu.h> + #include <assert.h> #include <signal.h> @@ -119,12 +122,12 @@ value = (value | (unsigned) AlignMask()) + 1 #define SetupScrnPtr(dst,src,type) \ - dst = (type *) src; \ + dst = (type *) (void *) src; \ assert(IsAligned(dst)); \ src += skipNcol##type -#define ScrnBufAddr(ptrs, offset) (ScrnBuf) ((char *) (ptrs) + (offset)) -#define LineDataAddr(ptrs, offset) (LineData *) ((char *) (ptrs) + (offset)) +#define ScrnBufAddr(ptrs, offset) (ScrnBuf) ((void *) ((char *) (ptrs) + (offset))) +#define LineDataAddr(ptrs, offset) (LineData *) ((void *) ((char *) (ptrs) + (offset))) #if OPT_TRACE > 1 static void @@ -580,6 +583,43 @@ ReallocateBufOffsets(XtermWidget xw, TRACE(("ReallocateBufOffsets %dx%d ->%p\n", nrow, ncol, *sbufaddr)); } +#if OPT_FIFO_LINES +/* + * Allocate a new FIFO index. + */ +static void +ReallocateFifoIndex(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + + if (screen->savelines > 0 && screen->saveBuf_index != 0) { + ScrnBuf newBufHead; + LineData *dstPtrs; + LineData *srcPtrs; + unsigned i; + unsigned old_jump = scrnHeadSize(screen, 1); + unsigned new_jump; + + screen->wide_chars = True; + newBufHead = allocScrnHead(screen, (unsigned) screen->savelines); + new_jump = scrnHeadSize(screen, 1); + + srcPtrs = (LineData *) screen->saveBuf_index; + dstPtrs = (LineData *) newBufHead; + + for (i = 0; i < (unsigned) screen->savelines; ++i) { + memcpy(dstPtrs, srcPtrs, SizeOfLineData); + srcPtrs = LineDataAddr(srcPtrs, old_jump); + dstPtrs = LineDataAddr(dstPtrs, new_jump); + } + + screen->wide_chars = False; + free(screen->saveBuf_index); + screen->saveBuf_index = newBufHead; + } +} +#endif + /* * This function dynamically adds support for wide-characters. */ @@ -611,7 +651,9 @@ ChangeToWide(XtermWidget xw) SwitchBufPtrs(screen, 0); #if OPT_SAVE_LINES -#if !OPT_FIFO_LINES +#if OPT_FIFO_LINES + ReallocateFifoIndex(xw); +#else ReallocateBufOffsets(xw, &screen->saveBuf_index, &screen->saveBuf_data, @@ -1254,7 +1296,7 @@ void ShowWrapMarks(XtermWidget xw, int row, LineData * ld) { TScreen *screen = TScreenOf(xw); - Boolean set = LineTstWrapped(ld); + Boolean set = (Boolean) LineTstWrapped(ld); CgsEnum cgsId = set ? gcVTcursFilled : gcVTcursReverse; VTwin *currentWin = WhichVWin(screen); int y = row * FontHeight(screen) + screen->border; @@ -2339,6 +2381,7 @@ ScrnCopyRectangle(XtermWidget xw, XTermRect * source, int nparam, int *params) (j * wide) + k, ld, col); } else { + /* EMPTY */ /* FIXME - clear the target cell? */ } ld->attribs[col] |= CHARDRAWN; @@ -2532,3 +2575,182 @@ ScrnWipeRectangle(XtermWidget xw, } } #endif /* OPT_DEC_RECTOPS */ + +#if OPT_MAXIMIZE + +static void +set_resize_increments(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + int min_width = (2 * screen->border) + screen->fullVwin.sb_info.width; + int min_height = (2 * screen->border); + XSizeHints sizehints; + + memset(&sizehints, 0, sizeof(XSizeHints)); + sizehints.width_inc = FontWidth(screen); + sizehints.height_inc = FontHeight(screen); + sizehints.flags = PResizeInc; + XSetWMNormalHints(screen->display, VShellWindow(xw), &sizehints); + + XtVaSetValues(SHELL_OF(xw), + XtNbaseWidth, min_width, + XtNbaseHeight, min_height, + XtNminWidth, min_width + FontWidth(screen), + XtNminHeight, min_height + FontHeight(screen), + XtNwidthInc, FontWidth(screen), + XtNheightInc, FontHeight(screen), + (XtPointer) 0); + + XFlush(XtDisplay(xw)); +} + +static void +unset_resize_increments(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + XSizeHints sizehints; + + memset(&sizehints, 0, sizeof(XSizeHints)); + sizehints.width_inc = 1; + sizehints.height_inc = 1; + sizehints.flags = PResizeInc; + XSetWMNormalHints(screen->display, VShellWindow(xw), &sizehints); + + XtVaSetValues(SHELL_OF(xw), + XtNwidthInc, 1, + XtNheightInc, 1, + (XtPointer) 0); + + XFlush(XtDisplay(xw)); +} + +static void +netwm_fullscreen(XtermWidget xw, int operation) +{ + TScreen *screen = TScreenOf(xw); + XEvent e; + Display *dpy = screen->display; + Window window = VShellWindow(xw); + Atom atom_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + Atom atom_state = XInternAtom(dpy, "_NET_WM_STATE", False); + + memset(&e, 0, sizeof(e)); + e.xclient.type = ClientMessage; + e.xclient.message_type = atom_state; + e.xclient.display = dpy; + e.xclient.window = window; + e.xclient.format = 32; + e.xclient.data.l[0] = operation; + e.xclient.data.l[1] = (long) atom_fullscreen; + + XSendEvent(dpy, DefaultRootWindow(dpy), False, + SubstructureRedirectMask, &e); +} + +/* + * Check if the "fullscreen" property is supported on the root window. + * The XGetWindowProperty function returns a list of Atom's which corresponds + * to the output of xprop. The actual list (ignore the manpage, which refers + * to an array of 32-bit values) is constructed by _XRead32, which uses long + * as a datatype. + * + * Alternatively, we could check _NET_WM_ALLOWED_ACTIONS on the application's + * window. + */ +static Boolean +probe_netwm_fullscreen_capability(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + Display *dpy = screen->display; + Atom atom_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + Atom atom_supported = XInternAtom(dpy, "_NET_SUPPORTED", False); + Atom actual_type; + int actual_format; + long long_offset = 0; + long long_length = 128; /* number of items to ask for at a time */ + unsigned int i; + unsigned long nitems, bytes_after; + unsigned char *args; + long *ldata; + Boolean netwm_fullscreen_capability = False; + int rc; + + while (!netwm_fullscreen_capability) { + rc = XGetWindowProperty(dpy, + DefaultRootWindow(dpy), + atom_supported, + long_offset, + long_length, + False, /* do not delete */ + AnyPropertyType, /* req_type */ + &actual_type, /* actual_type_return */ + &actual_format, /* actual_format_return */ + &nitems, /* nitems_return */ + &bytes_after, /* bytes_after_return */ + &args /* prop_return */ + ); + if (rc != Success + || actual_type != XA_ATOM) { + break; + } + ldata = (long *) (void *) args; + for (i = 0; i < nitems; i++) { + if ((Atom) ldata[i] == atom_fullscreen) { + netwm_fullscreen_capability = True; + break; + } + } + XFree(ldata); + + if (!netwm_fullscreen_capability) { + if (bytes_after != 0) { + long remaining = (long) (bytes_after / sizeof(long)); + if (long_length > remaining) + long_length = remaining; + long_offset += (long) nitems; + } else { + break; + } + } + } + + return netwm_fullscreen_capability; +} + +/* + * Enable/disable fullscreen mode for the xterm widget, if the window manager + * supports that feature. + */ +void +FullScreen(XtermWidget xw, Bool enabled) +{ + TScreen *screen = TScreenOf(xw); + + static Boolean initialized = False; + static Boolean netwm_fullscreen_capability = False; + + TRACE(("FullScreen %s\n", BtoS(enabled))); + + if (resource.fullscreen == esNever) { + initialized = True; + netwm_fullscreen_capability = False; + } else if (!initialized) { + initialized = True; + netwm_fullscreen_capability = probe_netwm_fullscreen_capability(xw); + } + + if (netwm_fullscreen_capability) { + if (enabled) { + unset_resize_increments(xw); + netwm_fullscreen(xw, 1); + } else { + set_resize_increments(xw); + netwm_fullscreen(xw, 0); + } + screen->fullscreen = (Boolean) enabled; + update_fullscreen(); + } else { + Bell(xw, XkbBI_MinorError, 100); + } +} +#endif /* OPT_MAXIMIZE */ |