Logo Search packages:      
Sourcecode: octave-matcompat version File versions

gtext.cc

/*
## Copyright (C) 2000 Paul Kienzle
##
## This program is free software and may be used for any purpose.  This
## copyright notice must be maintained.  Paul Kienzle is not responsible
## for the consequences of using this software.
 */
#include <octave/oct.h>
#include <octave/toplev.h>
#include <octave/parse.h>
#include <octave/lo-mappers.h>
extern "C" {
#include <X11/Xlib.h>
}

/* Recursively search the window heirarchy for a window of the given name */
Window find_window(Display *display, Window top, char *name)
{
  Window root, parent, *children, found;
  char *window_name;
  unsigned int N, i;

  /* Check if we've already got it */
  XFetchName(display, top, &window_name);
  if (!window_name==None && strcmp(window_name, name) == 0) {
    XFree(window_name);
    return top;
  }

  /* If not, recursively check all children */
  if (!XQueryTree(display, top, &root, &parent, &children, &N))
    return 0;
  found = 0;
  for (i=0; i < N; i++) {
    found = find_window(display, children[i], name);
    if (found) break;
  }
  XFree(children);
  return found;
}


DEFUN_DLD(gtext, args, ,"gtext('text' [, figure])\n\
Click where you want the text.\n\
Use left button for left-justified text, middle button for centered\n\
text, or right button for right-justified text.\n\
\nI'm not clever enough to determine the current figure from\n\
gnupot, so if it is not 0, then give a figure number on the call\n\
to gtext.  Also, I'm using screen coordinates rather than graph\n\
coordinates to position the text, so expect it to shift from screen\n\
to print version.  If you want a good solution, get the mouse support\n\
patches for gnuplot.\n\
\nNote that gtext() doesn't work with multiplot().")
{
  int nargin = args.length ();
  if (nargin < 1 || nargin > 2) {
    print_usage ("gtext");
    return octave_value();
  }

#if 0
  /* Ask gnuplot for current figure */
  octave_value_list gargs;
  gargs(0) = "term";
  feval ("gshow", gargs, 0);
  shows: "terminal type is x11 %d", with %d assumed to be 0 if absent
#else
  /* Get current figure from the parameter list. */
  int current_figure = 0;
  if (nargin == 2)
    {
      double dval = args(1).double_value ();
      if (xisnan (dval))
        error ("gtext: NaN is invalid as the figure numbe");
      else
        current_figure = NINT (dval);
    }
#endif

  /* Identify current figure window title */
  char name[21]; /* Big enough to hold "Gnuplot " + 12 digit number */
  if (current_figure > 0)
    sprintf(name, "Gnuplot %d", current_figure);
  else
    strcpy(name, "Gnuplot");

  /* Find plot window from title */
  Display *display = XOpenDisplay(NULL);
  int screen = DefaultScreen(display);
  Window root = RootWindow(display, screen);
  Window window = find_window(display, root, name);
  if (window == 0) {
    error("Plot window not found.");
    return octave_value();
  }

  /* Make sure we can capture the clicks */
  XWindowAttributes wattr;
  XGetWindowAttributes(display, window, &wattr);
  if (wattr.all_event_masks & ButtonPressMask) {
    warning("gtext: could not capture button events");
    return octave_value();
  }

  /* Set cross-hairs cursor */
  Cursor cursor;
  cursor = XCreateFontCursor (display, 0x82);
  XDefineCursor(display, window, cursor);

  /* Watch for key/button press (among others) */
  unsigned int button;
  int x, y;
  XSelectInput(display, window, ButtonPressMask|KeyPressMask);
  for (;;) {
    XEvent event;

    XNextEvent (display, &event);
    if (event.type == ButtonPress) {
      XButtonEvent *bev = (XButtonEvent *)&event;
      button = bev->button;
      x = bev->x;
      y = bev->y;
      break;
    }
  }
  XSelectInput(display, window, 0);

  /* Restore cursor */
  XUndefineCursor(display, window);

  /* Determine click position */
  Window wroot;
  int wx, wy;
  unsigned int width, height, bw, dp;
  XGetGeometry(display, window, &wroot, &wx, &wy, &width, &height, &bw, &dp);
  double rel_x = (double)x/double(width);
  double rel_y = (double)(height-y)/double(height);

  /* do the text call */
  octave_value_list fargs;
  fargs(0) = rel_x;
  fargs(1) = rel_y;
  fargs(2) = args(0);
  fargs(3) = "Units";
  fargs(4) = "Screen";
  fargs(5) = "HorizontalAlignment";
  switch (button) {
  default: fargs(6) = "left"; break;
  case 2: fargs(6) = "center"; break;
  case 3: fargs(6) = "right"; break;
  }
  feval ("text", fargs, 0);

  /* automatically replot */
  octave_value_list rargs;
  rargs(0) = "replot";
  feval ("eval", rargs, 0);

  XCloseDisplay (display);
  return octave_value();
}

Generated by  Doxygen 1.6.0   Back to index