Blame utils/viewer-x.c

Packit 0ec9dd
/* viewer-x.c: Common code for X-based viewers
Packit 0ec9dd
 *
Packit 0ec9dd
 * Copyright (C) 1999,2004,2005 Red Hat, Inc.
Packit 0ec9dd
 * Copyright (C) 2001 Sun Microsystems
Packit 0ec9dd
 *
Packit 0ec9dd
 * This library is free software; you can redistribute it and/or
Packit 0ec9dd
 * modify it under the terms of the GNU Library General Public
Packit 0ec9dd
 * License as published by the Free Software Foundation; either
Packit 0ec9dd
 * version 2 of the License, or (at your option) any later version.
Packit 0ec9dd
 *
Packit 0ec9dd
 * This library is distributed in the hope that it will be useful,
Packit 0ec9dd
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0ec9dd
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit 0ec9dd
 * Library General Public License for more details.
Packit 0ec9dd
 *
Packit 0ec9dd
 * You should have received a copy of the GNU Library General Public
Packit 0ec9dd
 * License along with this library; if not, write to the
Packit 0ec9dd
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 0ec9dd
 * Boston, MA 02111-1307, USA.
Packit 0ec9dd
 */
Packit 0ec9dd
#include "config.h"
Packit 0ec9dd
#include <string.h>
Packit 0ec9dd
Packit 0ec9dd
#include "viewer-render.h"
Packit 0ec9dd
#include "viewer-x.h"
Packit 0ec9dd
Packit 0ec9dd
void
Packit 0ec9dd
x_view_init (gpointer           instance,
Packit 0ec9dd
	     const PangoViewer *klass G_GNUC_UNUSED)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *)instance;
Packit 0ec9dd
Packit 0ec9dd
  x->display = XOpenDisplay (NULL);
Packit 0ec9dd
  if (!x->display)
Packit 0ec9dd
    fail ("Cannot open display %s", XDisplayName (NULL));
Packit 0ec9dd
Packit 0ec9dd
  x->screen = DefaultScreen (x->display);
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
gpointer
Packit 0ec9dd
x_view_create (const PangoViewer *klass)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *instance;
Packit 0ec9dd
Packit 0ec9dd
  instance = g_slice_new (XViewer);
Packit 0ec9dd
Packit 0ec9dd
  x_view_init (instance, klass);
Packit 0ec9dd
Packit 0ec9dd
  return instance;
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
void
Packit 0ec9dd
x_view_destroy (gpointer instance)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *)instance;
Packit 0ec9dd
Packit 0ec9dd
  XCloseDisplay (x->display);
Packit 0ec9dd
Packit 0ec9dd
  g_slice_free (XViewer, instance);
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
gpointer
Packit 0ec9dd
x_view_create_surface (gpointer instance,
Packit 0ec9dd
		       int      width,
Packit 0ec9dd
		       int      height)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *) instance;
Packit 0ec9dd
  Pixmap pixmap;
Packit 0ec9dd
Packit 0ec9dd
  pixmap = XCreatePixmap (x->display, DefaultRootWindow (x->display), width, height,
Packit 0ec9dd
			  DefaultDepth (x->display, x->screen));
Packit 0ec9dd
Packit 0ec9dd
  return (gpointer) pixmap;
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
void
Packit 0ec9dd
x_view_destroy_surface (gpointer instance,
Packit 0ec9dd
			gpointer surface)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *) instance;
Packit 0ec9dd
  Pixmap pixmap = (Pixmap) surface;
Packit 0ec9dd
Packit 0ec9dd
  XFreePixmap (x->display, pixmap);
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
static void
Packit 0ec9dd
update (Display *display,
Packit 0ec9dd
	Pixmap   pixmap,
Packit 0ec9dd
	Window   window,
Packit 0ec9dd
	Region  *update_region)
Packit 0ec9dd
{
Packit 0ec9dd
  GC gc;
Packit 0ec9dd
  XRectangle extents;
Packit 0ec9dd
Packit 0ec9dd
  XClipBox (*update_region, &extents);
Packit 0ec9dd
Packit 0ec9dd
  gc = XCreateGC (display, pixmap, 0, NULL);
Packit 0ec9dd
Packit 0ec9dd
  XCopyArea (display, pixmap, window, gc,
Packit 0ec9dd
	     extents.x, extents.y,
Packit 0ec9dd
	     extents.width, extents.height,
Packit 0ec9dd
	     extents.x, extents.y);
Packit 0ec9dd
Packit 0ec9dd
  XFreeGC (display, gc);
Packit 0ec9dd
Packit 0ec9dd
  XDestroyRegion (*update_region);
Packit 0ec9dd
  *update_region = NULL;
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
static void
Packit 0ec9dd
expose (XExposeEvent *xev,
Packit 0ec9dd
	Region       *update_region)
Packit 0ec9dd
{
Packit 0ec9dd
  XRectangle  r;
Packit 0ec9dd
Packit 0ec9dd
  if (!*update_region)
Packit 0ec9dd
    *update_region = XCreateRegion ();
Packit 0ec9dd
Packit 0ec9dd
  r.x = xev->x;
Packit 0ec9dd
  r.y = xev->y;
Packit 0ec9dd
  r.width = xev->width;
Packit 0ec9dd
  r.height = xev->height;
Packit 0ec9dd
Packit 0ec9dd
  XUnionRectWithRegion (&r, *update_region, *update_region);
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
gpointer
Packit 0ec9dd
x_view_create_window (gpointer    instance,
Packit 0ec9dd
		      const char *title,
Packit 0ec9dd
		      int         width,
Packit 0ec9dd
		      int         height)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *) instance;
Packit 0ec9dd
  unsigned long bg;
Packit 0ec9dd
  Window window;
Packit 0ec9dd
  XSizeHints size_hints;
Packit 0ec9dd
Packit 0ec9dd
  bg = WhitePixel (x->display, x->screen);
Packit 0ec9dd
  window = XCreateSimpleWindow (x->display, DefaultRootWindow (x->display),
Packit 0ec9dd
				0, 0, width, height, 0,
Packit 0ec9dd
				bg, bg);
Packit 0ec9dd
Packit 0ec9dd
  XSelectInput (x->display, window, ExposureMask | KeyPressMask);
Packit 0ec9dd
Packit 0ec9dd
  XMapWindow (x->display, window);
Packit 0ec9dd
  XmbSetWMProperties (x->display, window,
Packit 0ec9dd
		      title,
Packit 0ec9dd
		      NULL, NULL, 0, NULL, NULL, NULL);
Packit 0ec9dd
Packit 0ec9dd
  memset ((char *)&size_hints, 0, sizeof (XSizeHints));
Packit 0ec9dd
  size_hints.flags = PSize | PMaxSize;
Packit 0ec9dd
  size_hints.width = width; size_hints.height = height; /* for compat only */
Packit 0ec9dd
  size_hints.max_width = width; size_hints.max_height = height;
Packit 0ec9dd
Packit 0ec9dd
  XSetWMNormalHints (x->display, window, &size_hints);
Packit 0ec9dd
Packit 0ec9dd
  return (gpointer) window;
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
void
Packit 0ec9dd
x_view_destroy_window (gpointer instance,
Packit 0ec9dd
		       gpointer window)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *) instance;
Packit 0ec9dd
  Window win = (Window) window;
Packit 0ec9dd
Packit 0ec9dd
  XDestroyWindow (x->display, win);
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
gpointer
Packit 0ec9dd
x_view_display (gpointer instance,
Packit 0ec9dd
		gpointer surface,
Packit 0ec9dd
		gpointer win,
Packit 0ec9dd
		int      width,
Packit 0ec9dd
		int      height,
Packit 0ec9dd
		gpointer state)
Packit 0ec9dd
{
Packit 0ec9dd
  XViewer *x = (XViewer *) instance;
Packit 0ec9dd
  Pixmap pixmap = (Pixmap) surface;
Packit 0ec9dd
  Window window = (Window) win;
Packit 0ec9dd
  XEvent xev;
Packit 0ec9dd
  XRectangle  r;
Packit 0ec9dd
  Region update_region;
Packit 0ec9dd
  unsigned int quit_keycode;
Packit 0ec9dd
  unsigned int annotate_keycode;
Packit 0ec9dd
Packit 0ec9dd
  /* force a full redraw */
Packit 0ec9dd
  update_region = XCreateRegion ();
Packit 0ec9dd
  r.x = 0;
Packit 0ec9dd
  r.y = 0;
Packit 0ec9dd
  r.width = width;
Packit 0ec9dd
  r.height = height;
Packit 0ec9dd
  XUnionRectWithRegion (&r, update_region, update_region);
Packit 0ec9dd
Packit 0ec9dd
  annotate_keycode = XKeysymToKeycode(x->display, 'B');
Packit 0ec9dd
  quit_keycode = XKeysymToKeycode(x->display, 'Q');
Packit 0ec9dd
Packit 0ec9dd
  while (1)
Packit 0ec9dd
    {
Packit 0ec9dd
      if (!XPending (x->display) && update_region)
Packit 0ec9dd
	update (x->display, pixmap, window, &update_region);
Packit 0ec9dd
Packit 0ec9dd
      XNextEvent (x->display, &xev);
Packit 0ec9dd
      switch (xev.xany.type) {
Packit 0ec9dd
      case KeyPress:
Packit 0ec9dd
	if (xev.xkey.keycode == quit_keycode)
Packit 0ec9dd
	  return GINT_TO_POINTER (-1);
Packit 0ec9dd
	else if (xev.xkey.keycode == annotate_keycode)
Packit 0ec9dd
	  {
Packit 0ec9dd
	    return GUINT_TO_POINTER (GPOINTER_TO_INT (state) + 1);
Packit 0ec9dd
	  }
Packit 0ec9dd
	break;
Packit 0ec9dd
      case Expose:
Packit 0ec9dd
	expose (&xev.xexpose, &update_region);
Packit 0ec9dd
	break;
Packit 0ec9dd
      }
Packit 0ec9dd
    }
Packit 0ec9dd
}
Packit 0ec9dd
Packit 0ec9dd
const PangoViewer x_viewer = {
Packit 0ec9dd
  "X",
Packit 0ec9dd
  NULL,
Packit 0ec9dd
  NULL,
Packit 0ec9dd
  x_view_create,
Packit 0ec9dd
  x_view_destroy,
Packit 0ec9dd
  NULL,
Packit 0ec9dd
  x_view_create_surface,
Packit 0ec9dd
  x_view_destroy_surface,
Packit 0ec9dd
  NULL,
Packit 0ec9dd
  NULL,
Packit 0ec9dd
  x_view_create_window,
Packit 0ec9dd
  x_view_destroy_window,
Packit 0ec9dd
  x_view_display
Packit 0ec9dd
};