summaryrefslogtreecommitdiff
path: root/app/xterm/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/xterm/screen.c')
-rw-r--r--app/xterm/screen.c238
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 */