WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / RNAforester / g2-0.70 / src / X11 / g2_X11.c
diff --git a/binaries/src/ViennaRNA/RNAforester/g2-0.70/src/X11/g2_X11.c b/binaries/src/ViennaRNA/RNAforester/g2-0.70/src/X11/g2_X11.c
new file mode 100644 (file)
index 0000000..d2f14f2
--- /dev/null
@@ -0,0 +1,797 @@
+/*****************************************************************************
+**  Copyright (C) 1998-2001  Ljubomir Milanovic & Horst Wagner
+**  This file is part of the g2 library
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "g2.h"
+#include "g2_device.h"
+#include "g2_util.h"
+#include "g2_X11_P.h"
+#include "g2_X11.h"
+#include "g2_X11_funix.h"
+#include "g2_config.h"
+
+
+static int N_X11=0;
+static g2_X11_device *g2_X11_dev=NULL;
+
+/**
+ * \ingroup physdev
+ * \defgroup X11 X11
+ */
+
+
+/**
+ *
+ * Open a simple X11 window (physical device device).
+ *
+ * \param width window width
+ * \param height window height
+ * \return physical device id
+ *
+ * \ingroup X11
+ */
+int g2_open_X11(int width, int height)
+{
+    return g2_open_X11X(width, height,
+                       10, 10,
+                       NULL, NULL,
+                       NULL, -1, -1);
+}
+
+
+
+/**
+ *
+ * Open a X11 window (physical device device). If \a icon_width or \a
+ * icon_height is smaller than 0, the \a icon_data is interpreted as a
+ * file name.
+ *
+ * \param width window width
+ * \param height window height
+ * \param x x position on screen
+ * \param y y position on screen
+ * \param window_name hint for window manager
+ * \param icon_name hint for window manager
+ * \param icon_data icon bitmap (\a icon_width * \a icon_height bits) or file name containing bitmap
+ *                  (if \a icon_width <= 0 or \a icon_height <= 0) 
+ * \param icon_width icon width
+ * \param icon_height icon height
+ * \return physical device id
+ *
+ * \ingroup X11
+ */
+int g2_open_X11X(int width, int height,
+                int x, int y,
+                char *window_name, char *icon_name,
+                char *icon_data, int icon_width, int icon_height)
+{
+    g2_X11_device *xout=NULL;
+    int pid=-1, i;
+    char name[32];
+    int vid;
+    
+    if(g2_X11_dev==NULL) {
+       g2_X11_dev=g2_malloc(sizeof(g2_X11_device));
+       N_X11=1;                                  /* first X11 device */
+       xout=&g2_X11_dev[N_X11-1];
+       pid=0;
+    } else {
+       for(i=0;i<N_X11;i++)                      /* find free place */
+           if(g2_X11_dev[i].display==NULL) {
+               xout=&g2_X11_dev[i];
+               pid=i;
+               break;
+           }
+       if(i==N_X11) {
+           N_X11++;
+           g2_X11_dev=g2_realloc(g2_X11_dev,
+                                 sizeof(g2_X11_device)*N_X11);
+           xout=&g2_X11_dev[N_X11-1];
+           pid=N_X11-1;
+       }
+    }
+    
+    xout->width=width;                   /* set window size */
+    xout->height=height;
+    
+    xout->NofInks=0;                     /* reset inks */
+    xout->inks=NULL;
+    
+    vid = g2_register_physical_device(pid, NULL,
+                                     g2_IntCoor, g2_X11_funix,
+                                     1.0, -1.0,
+                                     0.0, height-1);
+    
+    sprintf(name, "g2: %d", vid);         /* set window and icon names */
+    if(window_name==NULL)
+       window_name=name;
+    if(icon_name==NULL)
+       icon_name=name;
+    
+    g2_X11_init_X11X(pid, width, height,
+                    x, y,
+                    window_name, icon_name,
+                    icon_data, icon_width, icon_height);
+    
+    
+                                           /* g2 calls */
+    g2_allocate_basic_colors(vid);
+    g2_set_background(vid, 0);
+    g2_pen(vid, 1);
+    
+    return vid;
+}
+
+     
+
+
+/*
+ *
+ * Extended version of the InitX11
+ *                      
+ */
+int g2_X11_init_X11X(int pid, int width, int height,
+                    int xposition, int yposition,
+                    char *window_name, char *icon_name,
+                    char *icon_data,
+                    unsigned int icon_width, unsigned int icon_height)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    Window root;
+    XSetWindowAttributes wattr;
+    XEvent event;
+    Pixmap iconPixmap;
+    XSizeHints sizehints;
+    int xhot, yhot, rv;
+    XColor w_scr, w_exa, r_scr, r_exa;
+    XClassHint class_hint;
+
+    if((xout->display=XOpenDisplay(NULL))==NULL) { 
+       g2_log(Error, "g2: can't open display\n");
+       exit(-1);
+    }
+
+
+    xout->root=RootWindow(xout->display, DefaultScreen(xout->display));
+    root=xout->root;
+    
+    wattr.event_mask=ExposureMask;
+    xout->window=XCreateWindow(xout->display, root,
+                              xposition, yposition,
+                              width, height,
+                              0,
+                              CopyFromParent, InputOutput, CopyFromParent,
+                              CWEventMask,
+                              &wattr);
+
+    xout->gc=XCreateGC(xout->display, xout->window,
+                      0lu, NULL);
+
+    xout->colormap=DefaultColormap(xout->display,
+                                  DefaultScreen(xout->display));
+        
+    XAllocNamedColor(xout->display, xout->colormap,
+                    "red", &r_scr, &r_exa);
+    XAllocNamedColor(xout->display, xout->colormap,
+                    "white", &w_scr, &w_exa);
+
+
+    
+    if(icon_data!=NULL) {
+       if(icon_width<=0 || icon_height<=0) {     /* read icon from file */
+           rv=XReadBitmapFile(xout->display, xout->window,
+                              icon_data, &icon_width, &icon_height,
+                              &iconPixmap, &xhot, &yhot);
+       } else {                                  /* icon is bitmap */
+           iconPixmap=XCreatePixmapFromBitmapData(xout->display,
+                                                  xout->window,
+                                                  icon_data,
+                                                  icon_width, icon_height,
+                                                  1ul, 0ul, 1);
+           rv=BitmapSuccess;
+       }
+       switch(rv) {
+         case BitmapOpenFailed:
+           fputs("g2(OpenXX): bitmap file open failed\n",stderr);
+           break;
+         case BitmapFileInvalid:
+           fputs("g2(OpenXX): bitmap file invalid\n",stderr);
+           break;
+         case BitmapNoMemory:
+           fputs("g2(OpenXX): no enough memeory for bitmap\n",stderr);
+           break;
+       }
+    } else {                                     /* no icon data avail. */
+       unsigned char bitmapData[] = {
+           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+           0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0xe0,
+           0x0d,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,0x00,0x20,0x18,
+           0x00,0x00,0x00,0x00,0x10,0x00,0xf8,0xe3,0x07,0x08,0x00,
+           0xfe,0xfa,0x07,0x0c,0x00,0xbf,0x6e,0x07,0x06,0x80,0x0f,
+           0xf5,0x00,0x01,0x80,0x05,0x34,0x80,0x09,0xc0,0x03,0x78,
+           0xe0,0x18,0x80,0x00,0x70,0xe0,0x1e,0xc0,0x01,0x70,0x70,
+           0x1b,0xc0,0x01,0x50,0x00,0x00,0xc0,0x01,0x70,0x00,0x00,
+           0xc0,0x00,0x70,0x00,0x00,0x40,0x03,0x38,0x00,0x00,0x80,
+           0x05,0x50,0x00,0x00,0x80,0x0a,0x6e,0x00,0x00,0x00,0xfe,
+           0x37,0x00,0x00,0x00,0x6a,0x59,0x00,0x00,0x00,0xbc,0x57,
+           0x00,0x00,0x00,0xe0,0x50,0x00,0x00,0x00,0x00,0x60,0x00,
+           0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,
+           0x00,0x7c,0x2b,0x00,0x00,0x00,0xa4,0x1d,0x00,0x00,0x00,
+           0xb8,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+           0x00,0x00};
+       iconPixmap=XCreatePixmapFromBitmapData(xout->display, xout->window,
+                                              (char*)bitmapData,
+                                              40u, 40u,
+                                              w_scr.pixel, r_scr.pixel,
+                                              1ul);
+    }
+
+    sizehints.x = xposition;
+    sizehints.y = yposition;
+    sizehints.min_width = width;
+    sizehints.max_width = width;
+    sizehints.min_height = height;
+    sizehints.max_height = height;
+    sizehints.flags = PPosition | PMinSize | PMaxSize;
+    XSetStandardProperties(xout->display, xout->window,
+                          window_name, icon_name, iconPixmap,
+                          (char **)NULL, 0, &sizehints);
+    
+    class_hint.res_name =  "g2";
+    class_hint.res_class = "G2";
+    XSetClassHint(xout->display, xout->window, &class_hint);
+
+    XMapRaised(xout->display, xout->window);
+    
+    /*    XSetWindowBackground(xout->display, xout->window, w_scr.pixel); */
+    XClearWindow(xout->display,xout->window);
+    
+    g2_X11_paper(pid, NULL, 0);
+    g2_X11_set_font_size(pid, NULL, 12);
+                                                 /* wait expose event */
+                                                 /* (no back. store) */
+    while(!XCheckWindowEvent(xout->display,xout->window,
+                            ExposureMask,&event))
+       ;
+
+
+    wattr.event_mask=NoEventMask;                /* set NoEventMask */
+    wattr.backing_store=Always;                          /* set backing store */
+    XChangeWindowAttributes(xout->display, xout->window,
+                           CWEventMask|CWBackingStore,
+                           &wattr);
+
+    xout->dest = xout->window;
+
+    xout->backing_pixmap = None;
+
+    if(XDoesBackingStore(XDefaultScreenOfDisplay(xout->display))!=Always) {
+       if(g2_EmulateBackingStore) {
+           g2_log(Warning, "g2: Warning! Backing store is not available. Allocating pixmap instead.\n");
+
+           xout->backing_pixmap = XCreatePixmap(xout->display, xout->window,
+                                                xout->width, xout->height,
+                                                DefaultDepth(xout->display, DefaultScreen(xout->display)));
+           XSetWindowBackgroundPixmap(xout->display, xout->window,
+                                      xout->backing_pixmap);
+         
+           XSetForeground (xout->display, xout->gc, w_scr.pixel);
+          
+           XFillRectangle(xout->display, xout->backing_pixmap, xout->gc,
+                          0, 0, xout->width, xout->height);
+           xout->dest = xout->backing_pixmap;
+       } else {
+               g2_log(Warning, "g2: Warning! Backing store is not available.\n");
+       }
+    }
+
+    XFlush(xout->display);
+    return 0;
+}
+
+
+
+
+int g2_X11_delete(int pid, void *pdp)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XUnmapWindow(xout->display, xout->window);
+    if (xout->backing_pixmap != None)
+       XFreePixmap(xout->display,xout->backing_pixmap);
+    XDestroyWindow(xout->display, xout->window);
+    XDestroyWindow(xout->display, xout->root);
+    XFreeGC(xout->display, xout->gc);
+    XFreeColormap(xout->display, xout->colormap);
+    XCloseDisplay(xout->display);
+    if(xout->inks!=NULL)
+       g2_free(xout->inks);
+    xout->width=xout->height=0;
+    xout->display=NULL;
+    return 0;
+}
+
+
+
+int g2_X11_clear(int pid, void *pdp)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    
+    if (xout->backing_pixmap == None) {
+       XClearWindow(xout->display,xout->window);
+    } else {
+       XSetForeground (xout->display, xout->gc,
+                       xout->background);
+       XFillRectangle(xout->display, xout->dest, xout->gc,
+                      0, 0, xout->width, xout->height);
+    }
+    g2_X11_flush(pid, pdp);
+    return 0;
+}
+
+
+
+int g2_X11_flush(int pid, void *pdp)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    if( xout->backing_pixmap != None ) {
+       XCopyArea(xout->display, xout->dest, xout->window, xout->gc,
+                 0, 0, xout->width, xout->height, 0, 0);
+    }
+    XFlush(xout->display);
+    return 0;
+}
+
+
+
+int g2_X11_ink(int pid, void *pdp,
+              double red, double green, double blue)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XColor color;
+
+    color.flags=DoRed|DoGreen|DoBlue;
+    color.red   = (int)(red   * USHRT_MAX);
+    color.green = (int)(green * USHRT_MAX);
+    color.blue  = (int)(blue  * USHRT_MAX);
+    if(XAllocColor(xout->display,xout->colormap,&color)) {
+       xout->NofInks++;
+       if(xout->inks==NULL)
+           xout->inks=
+             (unsigned long *)g2_malloc(xout->NofInks*sizeof(unsigned long));
+       else
+           xout->inks=
+             (unsigned long *)g2_realloc((void *)xout->inks,
+                                         xout->NofInks*sizeof(unsigned long));
+       if(xout->inks==NULL) {
+           fputs("g2: not enough memory\n",stderr);
+           return -1;
+       }
+       xout->inks[xout->NofInks-1]=color.pixel;
+       return xout->NofInks-1;
+    } else {
+       fputs("g2: color is not available\n",stderr);
+       return -1;
+    }
+}
+
+
+int g2_X11_clear_palette(int pid, void *pdp)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XFreeColors(xout->display,xout->colormap,
+               xout->inks,xout->NofInks,0x0ul);
+    xout->NofInks=0;
+    if(xout->inks!=NULL)
+        free(xout->inks);
+    xout->inks=NULL;
+    return 0;
+}
+
+
+int g2_X11_set_background(int pid, void *pdp, int color)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    if(color>=xout->NofInks || color<0)
+       return -1;
+    if (xout->backing_pixmap == None)
+      {
+        XSetWindowBackground(xout->display,xout->dest,
+                        xout->inks[color]);
+      }
+    else
+      {
+       xout->background = xout->inks[color];
+      }
+    g2_X11_clear(pid,pdp);
+    return 0;
+}
+
+
+int g2_X11_pen(int pid, void *pdp, int color)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    if(color>=xout->NofInks || color<0)
+       return -1;
+    XSetForeground(xout->display, xout->gc, xout->inks[color]);
+    return 0;
+}
+
+
+
+int g2_X11_paper(int pid, void *pdp, int color)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    if(color>=xout->NofInks || color<0)
+       return -1;
+    XSetBackground(xout->display, xout->gc, xout->inks[color]);
+    return 0;
+}
+
+
+int g2_X11_set_line_width(int pid, void *pdp, int w)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XGCValues val;
+    
+    val.line_width=w;
+    XChangeGC(xout->display, xout->gc, GCLineWidth, &val);
+    return 0;
+}
+
+
+int g2_X11_set_dash(int pid, void *pdp, int n, int *data)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XGCValues val;
+    int i;
+    
+    if(n<=0 || data==NULL) {
+       val.line_style=LineSolid;
+       XChangeGC(xout->display, xout->gc, GCLineStyle,&val);
+    } else {
+       char *ch_data;
+       ch_data=g2_malloc(n*sizeof(char));
+       val.line_style=LineOnOffDash;
+       for(i=0;i<n;i++)
+           if(data[i]>0)
+               ch_data[i]=(char)data[i];
+           else
+               ch_data[i]=1;
+       XChangeGC(xout->display, xout->gc, GCLineStyle, &val);
+       XSetDashes(xout->display, xout->gc, 0, ch_data, n);
+       g2_free(ch_data);
+    }
+    return 0;
+}
+
+
+int g2_X11_set_font_size(int pid, void *pdp, int size)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XFontStruct *fnt_str;
+    char font_name[256];
+    int sizei, d, n;
+    
+    sizei=dtoi(size);
+
+    if(sizei<=0)
+       sizei=1;                                  /* set to smallest size */
+    
+    for(n=1;n<32;n++) {
+       d=((n&0x01)? -1:1)*(n>>1);
+       sprintf(font_name, g2_X11Font, sizei+d);
+       fnt_str=XLoadQueryFont(xout->display, font_name);
+       if(fnt_str==NULL) {
+           if(!d)
+               fprintf(stderr,"g2: can not load font: '%s'\n",font_name);
+       } else {
+           XSetFont(xout->display,xout->gc,fnt_str->fid);
+           if(d)
+               fprintf(stderr,"g2: using '%s' instead\n",font_name);
+           return 0;
+       }
+    }
+    fprintf(stderr, "g2: are you sure about %d point size\n", size);
+    return -1;
+}
+
+
+int g2_X11_plot(int pid, void *pdp, int x, int y)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawPoint(xout->display, xout->dest, xout->gc,
+              x, y);
+    return 0;
+}
+
+
+int g2_X11_line(int pid, void *pdp, int x1, int y1, int x2, int y2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawLine(xout->display,xout->dest,xout->gc,
+             x1, y1, x2, y2);
+    return 0;
+}
+
+
+int g2_X11_poly_line(int pid, void *pdp, int N, int *p)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XPoint *points;
+    int i;
+    points=g2_malloc(N*sizeof(XPoint));
+    for(i=0;i<N;i++) {
+       points[i].x=(short)p[i*2];
+       points[i].y=(short)p[i*2+1];
+    }
+    XDrawLines(xout->display,xout->dest,xout->gc,
+              points, N,
+              CoordModeOrigin);
+    g2_free(points);
+    return 0;
+}
+
+
+int g2_X11_polygon(int pid, void *pdp, int N, int *p)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XPoint *points;
+    int i;
+    points=g2_malloc((N+1)*sizeof(XPoint));
+    for(i=0;i<N;i++) {
+       points[i].x=(short)p[i*2];
+       points[i].y=(short)p[i*2+1];
+    }
+    points[N].x=(short)p[0];
+    points[N].y=(short)p[1];
+    XDrawLines(xout->display,xout->dest,xout->gc,
+              points, N+1,
+              CoordModeOrigin);
+    g2_free(points);
+    return 0;
+}
+
+
+int g2_X11_filled_polygon(int pid, void *pdp, int N, int *p)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XPoint *points;
+    int i;
+    points=g2_malloc((N+1)*sizeof(XPoint));
+    for(i=0;i<N;i++) {
+       points[i].x=(short)p[i*2];
+       points[i].y=(short)p[i*2+1];
+    }
+    points[N].x=(short)p[0];
+    points[N].y=(short)p[1];
+    XFillPolygon(xout->display,xout->dest,xout->gc,
+                points, N+1,
+                Complex, CoordModeOrigin);
+    g2_free(points);
+    return 0;
+}
+
+
+int g2_X11_triangle(int pid, void *pdp,
+                   int x1, int y1,
+                   int x2, int y2,
+                   int x3, int y3)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XPoint points[4];
+    points[0].x=x1; points[0].y=y1; 
+    points[1].x=x2; points[1].y=y2; 
+    points[2].x=x3; points[2].y=y3; 
+    points[3].x=x1; points[3].y=y1; 
+    XDrawLines(xout->display,xout->dest,xout->gc,
+              points, 4, CoordModeOrigin);
+    return 0;
+}
+
+
+int g2_X11_filled_triangle(int pid, void *pdp,
+                          int x1, int y1,
+                          int x2, int y2,
+                          int x3, int y3)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XPoint points[4];
+    points[0].x=x1; points[0].y=y1; 
+    points[1].x=x2; points[1].y=y2; 
+    points[2].x=x3; points[2].y=y3; 
+    points[3].x=x1; points[3].y=y1; 
+    XFillPolygon(xout->display,xout->dest,xout->gc,
+                points, 4, Convex, CoordModeOrigin);
+    return 0;
+}
+
+
+int g2_X11_rectangle(int pid, void *pdp, int x1, int y1, int x2, int y2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawRectangle(xout->display,xout->dest,xout->gc,
+                  x1, y1, x2-x1, y2-y1);
+    return 0;
+}
+
+
+
+int g2_X11_filled_rectangle(int pid, void *pdp, int x1, int y1, int x2, int y2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawRectangle(xout->display,xout->dest,xout->gc,
+                  x1, y1, x2-x1, y2-y1);
+    XFillRectangle(xout->display,xout->dest,xout->gc,
+                  x1, y1, x2-x1, y2-y1);
+    return 0;
+}
+
+
+int g2_X11_arc(int pid, void *pdp, int x, int y,
+              int r1, int r2, double a1, double a2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    double a0, d;
+
+    a0=fmod(a1, 360.) + (a1<0? 360:0);   /* map a1 to [0, 360) */
+    d=a2>a1? a2-a1:a2-a1+360;
+     
+    XDrawArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            (int)(a0*64.), (int)(d*64.));
+    return 0;
+}
+
+int g2_X11_filled_arc(int pid, void *pdp, int x, int y,
+                     int r1, int r2, double a1, double a2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    double a0, d;
+    
+    a0=fmod(a1, 360.) + (a1<0? 360:0);   /* map a1 to [0, 360) */
+    d=a2>a1? a2-a1:a2-a1+360;
+    
+    XDrawArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            (int)(a0*64.), (int)(d*64.));
+    XFillArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            (int)(a0*64.), (int)(d*64.));
+    return 0;
+}
+
+int g2_X11_ellipse(int pid, void *pdp, int x, int y, int r1, int r2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            0,360*64);
+    return 0;
+}
+
+
+int g2_X11_filled_ellipse(int pid, void *pdp, int x, int y, int r1, int r2)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            0,360*64);
+    XFillArc(xout->display,xout->dest,xout->gc,
+            x-r1, y-r2,
+            r1*2, r2*2,
+            0,360*64);
+    XFlush(xout->display);
+    return 0;
+}
+
+int g2_X11_draw_string(int pid, void *pdp, int x, int y, const char *text)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XDrawString(xout->display,xout->dest,xout->gc,
+               x, y, text, strlen(text));
+    return 0;
+}
+
+
+int g2_X11_image(int pid, void *pdp,
+                int x, int y, int width, int height, int *pen_array)
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    XImage *image=NULL;
+    Screen *screen;
+    unsigned long *ink_array;
+    int i;
+
+    ink_array=malloc(sizeof(unsigned long)*width*height);
+    for(i=0;i<width*height;i++)
+       ink_array[i]=xout->inks[pen_array[i]];
+
+    screen=DefaultScreenOfDisplay(xout->display);
+    image=XCreateImage(xout->display,
+                      DefaultVisualOfScreen(screen),
+                      DefaultDepthOfScreen(screen),
+                      ZPixmap,
+                      0,                         /* offset */
+                      (char *)ink_array,
+                      width, height,
+                      sizeof(unsigned long)*8,   /* bitmap pad */
+                      0);                        /* bytes per line */
+    /* XInitImage(image); problems with AIX ?!! */
+    XPutImage(xout->display, xout->dest, xout->gc,
+             image,
+             0, 0,
+             x, y, width, height);
+       
+    XDestroyImage(image);
+    free(ink_array);
+    return 0;
+}
+
+
+int g2_X11_query_pointer(int pid, void *pdp,
+                        int *x, int *y, unsigned int *button)
+{
+    Bool rv;
+    g2_X11_device *xout=&g2_X11_dev[pid];
+    Window root, child;
+    int rx, ry;
+
+    rv = XQueryPointer(xout->display, xout->window,
+                      &root, &child, &rx, &ry,
+                      x, y, button);
+
+    if(rv)
+       return 0;
+    else
+       return 1;
+}
+
+
+
+int g2_X11_get_pd_handles(int pid, void *pdp, void *handles[G2_PD_HANDLES_SIZE])
+{
+    g2_X11_device *xout=&g2_X11_dev[pid];
+
+    handles[0]=xout->display;
+    handles[1]=&xout->window;
+    handles[2]=&xout->root;
+    handles[3]=&xout->colormap;
+    handles[4]=&xout->gc;
+    handles[5]=&xout->dest;
+    return 0;
+}