Changeset 14789 in project


Ignore:
Timestamp:
05/26/09 07:15:16 (10 years ago)
Author:
Ivan Raikov
Message:

updated ezxdisp to upstream ver 0.1.4

Location:
release/4/ezxdisp
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • release/4/ezxdisp/ezxdisp.h

    r7351 r14789  
    77#define _EZXDISP_H_
    88
    9 #include <X11/Xlib.h>
    10 #include <X11/Xutil.h>
     9#define EZX_NLAYER 8
    1110
    12 #define NLAYER 8
     11#define EZX_BUTTON_LEFT      1
     12#define EZX_BUTTON_MIDDLE    2
     13#define EZX_BUTTON_RIGHT     3
     14#define EZX_BUTTON_WHEELUP   4
     15#define EZX_BUTTON_WHEELDOWN 5
    1316
    14 typedef struct ezx_color {
     17#define EZX_KEY_HOME  0xff50
     18#define EZX_KEY_LEFT  0xff51
     19#define EZX_KEY_UP    0xff52
     20#define EZX_KEY_RIGHT 0xff53
     21#define EZX_KEY_DOWN  0xff54
     22
     23#define EZX_SHIFT_MASK   (1<<0)
     24#define EZX_CONTROL_MASK (1<<1)
     25#define EZX_BUTTON_LMASK (1<<2)
     26#define EZX_BUTTON_MMASK (1<<3)
     27#define EZX_BUTTON_RMASK (1<<4)
     28
     29typedef struct ezx_s ezx_t;
     30
     31typedef struct {
    1532  double r, g, b;
    16 } ezx_color;
     33} ezx_color_t;
    1734
    18 typedef struct ezx_t {
    19   unsigned int magic;
     35typedef struct {
     36  int x, y;
     37} ezx_point2d_t;
    2038
    21   Display     *display;
    22   int          size_x, size_y;
    23   Window       top;
    24   XFontStruct *fontst;
    25   GC           gc, gc2;
    26   int          basex, basey;
    27   Colormap     cmap;
    28   XColor       black, white, rgb;
    29   ezx_color    bgcolor;
    30   Pixmap       pixmap;
     39typedef struct {
     40  double x, y, z;
     41} ezx_point3d_t;
    3142
    32   XSizeHints   size_hints;
    33 
    34   int                 cur_layer;
    35   struct ezx_figures *froot;
    36   struct ezx_figures *layers[NLAYER];
    37 
    38   // 3d stuffs
    39   double scrdist, mag;
    40   double eye_x, eye_y, eye_z, eye_r;
    41   double cmat[3][3];
    42   double light_x, light_y, light_z;
    43 } ezx_t;
    44 
    45 typedef struct ezx_points_3d {
    46   double x, y, z;
    47 } ezx_points_3d;
    48 
    49 typedef struct ezx_figures {
    50   unsigned int magic;
    51 
    52   int          kind;
    53   double       x0, y0, z0, x1, y1, z1;
    54 
    55   double       r;
    56   char        *str;
    57   struct {
    58     ezx_points_3d *points;
    59     int    npoints;
    60     double gx, gy, gz;
    61     double hx, hy, hz;
    62   } poly;
    63 
    64   ezx_color           col;
    65   int                 width;
    66   struct ezx_figures *next;
    67 } ezx_figures;
    68 
    69 typedef struct ezx_pfigures {
    70   unsigned int magic;
    71 
    72   double               z;
    73   struct ezx_figures  *fig;
    74   struct ezx_pfigures *next;
    75 } ezx_pfigures;
    76 
    77 #define EzxKeyPress    KeyPress
    78 #define EzxButtonPress ButtonPress
    79 
    80 typedef struct _ezx_event_t {
    81   int  type;
    82   int  x, y;
    83   int  b;
    84   char k;
    85 } ezx_event_t;
    86 
    87 extern ezx_color ezx_black, ezx_white;
    88 extern ezx_color ezx_grey25, ezx_grey50, ezx_grey75;
    89 extern ezx_color ezx_blue, ezx_red, ezx_green, ezx_yellow;
    90 extern ezx_color ezx_purple, ezx_pink, ezx_cyan, ezx_brown, ezx_orange;
     43typedef enum ezx_event_type {
     44     EZX_BUTTON_PRESS,
     45     EZX_BUTTON_RELEASE,
     46     EZX_KEY_PRESS,
     47     EZX_KEY_RELEASE,
     48     EZX_MOTION_NOTIFY,
     49     EZX_CLOSE
     50} ezx_event_type_t;
     51 
     52extern const ezx_color_t ezx_black, ezx_white;
     53extern const ezx_color_t ezx_grey25, ezx_grey50, ezx_grey75;
     54extern const ezx_color_t ezx_blue, ezx_red, ezx_green, ezx_yellow;
     55extern const ezx_color_t ezx_purple, ezx_pink, ezx_cyan, ezx_brown, ezx_orange;
    9156
    9257ezx_t *ezx_init(int size_x, int size_y, char *window_name);
     
    9661void   ezx_wipe_layer(ezx_t *e, int lay);
    9762void   ezx_select_layer(ezx_t *e, int lay);
    98 void   ezx_set_background(ezx_t *e, ezx_color *col);
     63void   ezx_set_background(ezx_t *e, const ezx_color_t *col);
    9964void   ezx_window_name(ezx_t *e, char *window_name);
    100 void   ezx_raise_window(ezx_t *e);
     65int    ezx_isclosed(ezx_t *e);
    10166int    ezx_sensebutton(ezx_t *e, int *x, int *y);
    10267int    ezx_pushbutton(ezx_t *e, int *x, int *y);
    103 int   ezx_next_event(ezx_t *ezx, int *x, int *y, int *b, int *k);
    104 int    ezx_event_pending(ezx_t *ezx);
     68void   ezx_next_event(ezx_t *ezx, ezx_event_type_t *type, int *x, int *y, unsigned int *state, unsigned int *kb);
    10569
    106 // for 2D graphics
    107 void   ezx_line_2d(ezx_t *e, int x0, int y0, int x1, int y1, ezx_color *col,
     70// 2D graphics
     71void ezx_point_2d(ezx_t *e, int x, int y, const ezx_color_t *col);
     72void ezx_line_2d(ezx_t *e, int x0, int y0, int x1, int y1,
     73                 const ezx_color_t *col, int width);
     74void ezx_lines_2d(ezx_t *e, ezx_point2d_t *points, int npoints,
     75                  const ezx_color_t *col, int width);
     76void ezx_poly_2d(ezx_t *e,ezx_point2d_t *points, int npoints,
     77                 const ezx_color_t *col);
     78void ezx_str_2d(ezx_t *e, int x, int y, char *str, const ezx_color_t *col);
     79void ezx_rect_2d(ezx_t *e, int x0, int y0, int x1, int y1,
     80                 const ezx_color_t *col, int width);
     81void ezx_fillrect_2d(ezx_t *e, int x0, int y0, int x1, int y1,
     82                     const ezx_color_t *col);
     83void ezx_circle_2d(ezx_t *e, int x, int y, int r, const ezx_color_t *col,
    10884                   int width);
    109 void   ezx_str_2d(ezx_t *e, double x0, double y0, char *str, ezx_color *col);
    110 void   ezx_fillrect_2d(ezx_t *e, double x0, double y0, double x1, double y1,
    111                        ezx_color *col);
    112 void   ezx_fillcircle_2d(ezx_t *e, int x0, int y0, int r, ezx_color *col,
    113                          int width);
    114 void   ezx_circle_2d(ezx_t * e, int x0, int y0, int r, ezx_color *col,
    115                      int width);
     85void ezx_fillcircle_2d(ezx_t *e, int x, int y, int r, const ezx_color_t *col);
     86void ezx_arc_2d(ezx_t *e, int x, int y, int w, int h, double angle1,
     87                double angle2, const ezx_color_t *col, int width);
     88void ezx_fillarc_2d(ezx_t *e, int x, int y, int w, int h, double angle1,
     89                    double angle2, const ezx_color_t *col);
    11690
    117 // for 3D graphics
    118 void   ezx_c3d_to_2d(ezx_t *e, double sx, double sy, double sz, double *dx,
    119                      double *dy);
    120 void   ezx_line_3d(ezx_t *e, double x0, double y0, double z0, double x1,
    121                    double y1, double z1, ezx_color *col, int width);
    122 void   ezx_set_light_3d(ezx_t *e, double ex, double ey, double ez);
    123 void   ezx_set_view_3d(ezx_t *e, double ex, double ey, double ez, double vx,
    124                        double vy, double vz, double m);
    125 void   ezx_str_3d(ezx_t *e, double x0, double y0, double z0, char *str,
    126                   ezx_color *col, int width);
    127 void   ezx_poly_3d(ezx_t *e, ezx_points_3d *points, double hx, double hy,
    128                    double hz, int npoints, ezx_color *col);
    129 void   ezx_circle_3d(ezx_t *e, double x0, double y0, double z0, double r,
    130                      ezx_color *col);
     91// 3D graphics
     92void ezx_c3d_to_2d(ezx_t *e, double sx, double sy, double sz, double *dx,
     93                   double *dy);
     94void ezx_line_3d(ezx_t *e, double x0, double y0, double z0, double x1,
     95                 double y1, double z1, const ezx_color_t *col, int width);
     96void ezx_set_light_3d(ezx_t *e, double ex, double ey, double ez);
     97void ezx_set_view_3d(ezx_t *e, double ex, double ey, double ez, double vx,
     98                     double vy, double vz, double m);
     99void ezx_str_3d(ezx_t *e, double x0, double y0, double z0, char *str,
     100                const ezx_color_t *col);
     101void ezx_poly_3d(ezx_t *e, ezx_point3d_t *points, double hx, double hy,
     102                 double hz, int npoints, const ezx_color_t *col);
     103void ezx_circle_3d(ezx_t *e, double x0, double y0, double z0, double r,
     104                   const ezx_color_t *col);
    131105
    132106#endif
  • release/4/ezxdisp/ezxdisp.scm

    r14785 r14789  
    1515
    1616(define-record ezx ptr)
     17(define-record ezx-button-event ptr)
    1718
    1819#>?
    1920___declare(type, "ezxp;(pointer \"ezx_t\");ezx-ptr;make-ezx")
     21___declare(type, "ezxevbp;(pointer \"ezx_button_event_t\");ezx-button-event-ptr;make-ezx-button-event")
    2022___declare(substitute, "_;-")
     23___declare(substitute, "EZX;ezx")
     24
     25enum event_type {
     26    EZX_BUTTON_PRESS,
     27    EZX_BUTTON_RELEASE,
     28    EZX_KEY_PRESS,
     29    EZX_KEY_RELEASE,
     30    EZX_MOTION_NOTIFY,
     31    EZX_CLOSE
     32  } ;
     33
    2134
    2235ezxp ezx_init(int size_x, int size_y, char *window_name);
     
    2942void   ezx_window_name(ezxp e, char *window_name);
    3043void   ezx_raise_window(ezxp e);
     44int    ezx_isclosed(ezxp e);
    3145int    ezx_sensebutton(ezxp e, ___out int *x, ___out int *y);
    3246int    ezx_pushbutton(ezxp e, ___out int *x, ___out int *y);
     47void   ezx_next_event(ezxp e,  ___out int *type, ___out int *x, ___out int *y, ___out unsigned int *state, ___out unsigned int *kb);
    3348___bool ezx_event_pending(ezxp e);
    34 int ezx_next_event(ezxp e, ___out int *x, ___out int *y, ___out int *b, ___out int *k);
    3549
    3650// for 2D graphics
     51void   ezx_point_2d(ezxp e, int x, int y, double *col);
    3752void   ezx_line_2d(ezxp e, int x0, int y0, int x1, int y1, double *col, int width);
     53void   ezx_lines_2d(ezxp e, int *points, int npoints, double *col, int width);
     54void   ezx_poly_2d(ezxp e,int *points, int npoints, double *col);
    3855void   ezx_str_2d(ezxp e, double x0, double y0, char *str, double *col);
     56void   ezx_rect_2d(ezxp e, int x0, int y0, int x1, int y1, double *col, int width);
    3957void   ezx_fillrect_2d(ezxp e, double x0, double y0, double x1, double y1, double *col);
    40 void   ezx_fillcircle_2d(ezxp e, int x0, int y0, int r, double *col, int width);
    41 void   ezx_circle_2d(ezxp  e, int x0, int y0, int r, double *col, int width);
     58void   ezx_circle_2d(ezxp e, int x, int y, int r, double *col, int width);
     59void   ezx_fillcircle_2d(ezxp e, int x0, int y0, int r, double *col);
     60void   ezx_arc_2d(ezxp e, int x, int y, int w, int h, double angle1, double angle2, double *col, int width);
     61void   ezx_fillarc_2d(ezxp e, int x, int y, int w, int h, double angle1, double angle2, double *col);
    4262
    4363// for 3D graphics
     
    4666void   ezx_set_light_3d(ezxp e, double ex, double ey, double ez);
    4767void   ezx_set_view_3d(ezxp e, double ex, double ey, double ez, double vx, double vy, double vz, double m);
    48 void   ezx_str_3d(ezxp e, double x0, double y0, double z0, char *str, ezx_color *col, int width);
     68void   ezx_str_3d(ezxp e, double x0, double y0, double z0, char *str, double *col);
    4969void   ezx_poly_3d(ezxp e, double *points, double hx, double hy, double hz, int npoints, double *col);
    5070void   ezx_circle_3d(ezxp e, double x0, double y0, double z0, double r, double *col);
     71
    5172<#
    5273
  • release/4/ezxdisp/ezxdisp.setup

    r14785 r14789  
    1717 `( ,(dynld-name "ezxdisp") ,(dynld-name "ezxdisp.import") )
    1818
    19  '((version 1.4)
     19 '((version 2.0)
    2020   (examples "3d_clock.scm")
    2121   (documentation "ezxdisp.html")
  • release/4/ezxdisp/ezxdisp0.c

    r7351 r14789  
    11/*
    2  * ezxdisp.c
     2 * x11/ezxdisp.c
    33 * This file is part of the ezxdisp library.
    44 */
     
    66#include <stdio.h>
    77#include <stdlib.h>
     8#include <string.h>
     9#include <errno.h>
     10#include <stdarg.h>
     11#include <assert.h>
    812#include <math.h>
    913#include <X11/Xlib.h>
    1014#include <X11/Xutil.h>
    11 #include <string.h>
    12 #include <assert.h>
     15#include <X11/keysym.h>
    1316
    1417#include "ezxdisp.h"
    1518
    16 #define MAGIC1 0x2BA9E0BFUL
    17 #define MAGIC2 0xDE6B0FBFUL
    18 #define MAGIC3 0x356B047EUL
    19 
    20 #define FLINE           1
    21 #define FFILLEDCIRCLE   2
    22 #define FLINE3D         3
    23 #define FFILLEDCIRCLE3D 4
    24 #define FSTR3D          5
    25 #define FPOLY3D         6
    26 #define FSTR2D          7
    27 #define FFILLRECT2D     8
    28 #define FCIRCLE         9
    29 
    30 ezx_color ezx_black  = {0, 0, 0};
    31 ezx_color ezx_white  = {1, 1, 1};
    32 ezx_color ezx_grey25 = {0.25, 0.25, 0.25};
    33 ezx_color ezx_grey50 = {0.5, 0.5, 0.5};
    34 ezx_color ezx_grey75 = {0.75, 0.75, 0.75};
    35 ezx_color ezx_blue   = {0, 0, 1};
    36 ezx_color ezx_red    = {1, 0, 0};
    37 ezx_color ezx_green  = {0, 1, 0};
    38 ezx_color ezx_yellow = {1, 1, 0};
    39 ezx_color ezx_purple = {1, 0, 1};
    40 ezx_color ezx_pink   = {1, 0.5, 0.5};
    41 ezx_color ezx_cyan   = {0.5, 0.5, 1};
    42 ezx_color ezx_brown  = {0.5, 0, 0};
    43 ezx_color ezx_orange = {1, 0.5, 0};
    44 
    45 static char *fontname = "5x8";
    46 
    47 void ezx_wipe(ezx_t * e)
     19struct ezx_s {
     20  int size_x, size_y;
     21  ezx_color_t bgcolor;
     22  int closed;
     23
     24  Display     *display;
     25  Window       top;
     26  XFontStruct *fontst;
     27  GC           gc;
     28  Colormap     cmap;
     29  XColor       black, white, rgb;
     30  Pixmap       pixmap;
     31  XSizeHints   size_hints;
     32  Atom         wm_protocols, wm_delete_window;
     33
     34  int                 cur_layer;
     35  struct ezx_figures *fig_head[EZX_NLAYER];
     36  struct ezx_figures *fig_tail[EZX_NLAYER];
     37
     38  // 3d stuffs
     39  double scrdist, mag;
     40  double eye_x, eye_y, eye_z, eye_r;
     41  double cmat[3][3];
     42  double light_x, light_y, light_z;
     43
     44  struct color_table_s *color_table;
     45};
     46
     47typedef struct ezx_figures {
     48  enum {
     49    FPOINT2D,
     50    FLINE2D,
     51    FLINES2D,
     52    FLINE3D,
     53    FPOLY2D,
     54    FPOLY3D,
     55    FSTR2D,
     56    FSTR3D,
     57    FRECT2D,
     58    FFILLEDRECT2D,
     59    FCIRCLE2D,
     60    FFILLEDCIRCLE2D,
     61    FFILLEDCIRCLE3D,
     62    FARC2D,
     63    FFILLEDARC2D,
     64  } type;
     65
     66  int x0, y0, z0, x1, y1, z1, r;
     67  double dx0, dy0, dz0, dx1, dy1, dz1, dr;
     68  double angle1, angle2;
     69  char *str;
     70
     71  int npoints;
     72  ezx_point2d_t *points_2d;
     73  ezx_point3d_t *points_3d;
     74
     75  ezx_color_t         col;
     76  int                 width;
     77  struct ezx_figures *next;
     78} ezx_figures;
     79
     80typedef struct ezx_pfigures {
     81  double               z;
     82  struct ezx_figures  *fig;
     83  struct ezx_pfigures *next;
     84} ezx_pfigures;
     85
     86typedef struct color_table_entry_s {
     87  unsigned short red, green, blue;
     88  XColor *data;
     89} color_table_entry_t;
     90
     91typedef struct color_table_s {
     92  int size;
     93  int maxsize;
     94  struct color_table_entry_s *entry;
     95} color_table_t;
     96
     97const ezx_color_t ezx_black  = {0, 0, 0};
     98const ezx_color_t ezx_white  = {1, 1, 1};
     99const ezx_color_t ezx_grey25 = {0.25, 0.25, 0.25};
     100const ezx_color_t ezx_grey50 = {0.5, 0.5, 0.5};
     101const ezx_color_t ezx_grey75 = {0.75, 0.75, 0.75};
     102const ezx_color_t ezx_blue   = {0, 0, 1};
     103const ezx_color_t ezx_red    = {1, 0, 0};
     104const ezx_color_t ezx_green  = {0, 1, 0};
     105const ezx_color_t ezx_yellow = {1, 1, 0};
     106const ezx_color_t ezx_purple = {1, 0, 1};
     107const ezx_color_t ezx_pink   = {1, 0.5, 0.5};
     108const ezx_color_t ezx_cyan   = {0.5, 0.5, 1};
     109const ezx_color_t ezx_brown  = {0.5, 0, 0};
     110const ezx_color_t ezx_orange = {1, 0.5, 0};
     111
     112static const char * const fontname = "5x8";
     113
     114static void error_exit(const char *fmt, ...)
     115{
     116  va_list params;
     117
     118  fprintf(stderr, "ezxdisp: ");
     119  va_start(params, fmt);
     120  vfprintf(stderr, fmt, params);
     121  va_end(params);
     122  fprintf(stderr, "\n");
     123  fflush(stderr);
     124  exit(EXIT_FAILURE);
     125}
     126
     127static void sys_error_exit(const char *fmt, ...)
     128{
     129  int errno_save = errno;
     130  va_list params;
     131
     132  fprintf(stderr, "ezxdisp: ");
     133  va_start(params, fmt);
     134  vfprintf(stderr, fmt, params);
     135  va_end(params);
     136  fprintf(stderr, ": %s\n", strerror(errno_save));
     137  fflush(stderr);
     138  exit(EXIT_FAILURE);
     139}
     140
     141static inline void *xmalloc(size_t n)
     142{
     143  void *p;
     144
     145  p = malloc(n);
     146  if (!p) sys_error_exit("malloc failed");
     147 
     148  return p;
     149}
     150
     151static inline void *xcalloc(size_t n, size_t s)
     152{
     153  void *p;
     154
     155  p = calloc(n, s);
     156  if (!p) sys_error_exit("calloc failed");
     157
     158  return p;
     159}
     160
     161static color_table_t *color_table_new()
     162{
     163  int i;
     164  color_table_t *table;
     165
     166  table = xmalloc(sizeof(color_table_t));
     167  table->size = 0;
     168  table->maxsize = 8191;
     169  //table->maxsize = 32749;
     170  table->entry = xmalloc(sizeof(color_table_entry_t) * table->maxsize);
     171  for (i = 0; i < table->maxsize; i++)
     172    table->entry[i].data = NULL;
     173
     174  return table;
     175}
     176
     177static int color_hash(unsigned short red, unsigned short green,
     178                      unsigned short blue, int maxsize)
     179{
     180  long long hash = ((long long)red << 32) |
     181    ((long long)green << 16) | ((long long)blue);
     182  return hash % maxsize;
     183}
     184
     185static void color_table_insert(color_table_t *table, unsigned short red,
     186                               unsigned short green, unsigned short blue,
     187                               Display *display, XColor *col)
     188{
     189  int i = color_hash(red, green, blue, table->maxsize);
     190
     191  if (table->size == table->maxsize) {
     192    XFreeColors(display, DefaultColormap(display, DefaultScreen(display)),
     193                &(table->entry[i].data->pixel), 1, 0);
     194    free(table->entry[i].data);
     195    table->entry[i].data = NULL;
     196    table->size--;
     197  }
     198 
     199  while (table->entry[i].data) i = (i+1) % table->maxsize;
     200  table->entry[i].red = red;
     201  table->entry[i].green = green;
     202  table->entry[i].blue = blue;
     203  table->entry[i].data = col;
     204  table->size++;
     205}
     206
     207static XColor *color_table_search(color_table_t *table, unsigned short red,
     208                                  unsigned short green, unsigned short blue)
     209{
     210  int h, i;
     211
     212  h = i = color_hash(red, green, blue, table->maxsize);
     213
     214  while (table->entry[i].data) {
     215    if (table->entry[i].red == red &&
     216        table->entry[i].green == green &&
     217        table->entry[i].blue == blue)
     218      return table->entry[i].data;
     219    else i = (i+1) % table->maxsize;
     220   
     221    if (h == i) break;
     222  }
     223
     224  return NULL;
     225}
     226
     227static void color_table_free(color_table_t *table)
     228{
     229  int i;
     230 
     231  for (i = 0; i < table->maxsize; i++)
     232    if (table->entry[i].data) free(table->entry[i].data);
     233  free(table->entry);
     234  free(table);
     235}
     236
     237static void set_fgcolor(ezx_t *e, const ezx_color_t *col)
     238{
     239  XColor lc={0}, *c;
     240 
     241  lc.red = (unsigned short) (col->r * 65535);
     242  lc.green = (unsigned short) (col->g * 65535);
     243  lc.blue = (unsigned short) (col->b * 65535);
     244  lc.flags = DoRed | DoGreen | DoBlue;
     245 
     246  c = color_table_search(e->color_table, lc.red, lc.green, lc.blue);
     247  if (!c) {
     248    c = xmalloc(sizeof(XColor));
     249    *c = lc;
     250    XAllocColor(e->display, e->cmap, c);
     251    color_table_insert(e->color_table, lc.red, lc.green, lc.blue, e->display, c);
     252  }
     253 
     254  XSetForeground(e->display, e->gc, c->pixel);
     255}
     256
     257void ezx_wipe(ezx_t *e)
    48258{
    49259  int i;
    50260  ezx_figures *f, *nf;
    51261
    52   assert(e->magic == MAGIC1);
    53 
    54   for (i = 0; i < NLAYER; i++) {
    55     for (f = e->layers[i]; f != NULL; f = nf) {
    56       assert(f->magic == MAGIC2);
    57 
     262  for (i = 0; i < EZX_NLAYER; i++) {
     263    for (f = e->fig_head[i]; f != NULL; f = nf) {
    58264      nf = f->next;
    59       if (f->kind == FSTR3D)
    60         free(f->str);
    61       if (f->kind == FSTR2D)
    62         free(f->str);
    63       if (f->kind == FPOLY3D)
    64         free(f->poly.points);
    65       f->magic = 0;
     265      if (f->type == FSTR3D) free(f->str);
     266      if (f->type == FSTR2D) free(f->str);
    66267      free(f);
    67268    }
    68269
    69     e->layers[i] = NULL;
    70   }
    71 
    72   e->froot = NULL;
    73 }
    74 
    75 void ezx_wipe_layer(ezx_t * e, int lay)
     270    e->fig_head[i] = NULL;
     271    e->fig_tail[i] = NULL;
     272  }
     273}
     274
     275void ezx_wipe_layer(ezx_t *e, int lay)
    76276{
    77277  ezx_figures *f, *nf;
    78278
    79   assert(e->magic == MAGIC1);
    80 
    81   for (f = e->layers[lay]; f != NULL; f = nf) {
    82     assert(f->magic == MAGIC2);
    83 
     279  if (lay < 0 || EZX_NLAYER <= lay)
     280    error_exit("ezx_wipe_layer: invalid layer number %d", lay);
     281 
     282  for (f = e->fig_head[lay]; f != NULL; f = nf) {
    84283    nf = f->next;
    85     if (f->kind == FSTR3D)
    86       free(f->str);
    87     if (f->kind == FSTR2D)
    88       free(f->str);
    89     if (f->kind == FPOLY3D)
    90       free(f->poly.points);
    91     f->magic = 0;
     284    if (f->type == FSTR3D) free(f->str);
     285    if (f->type == FSTR2D) free(f->str);
    92286    free(f);
    93287  }
    94288
    95   e->layers[lay] = NULL;
    96 
    97   if (e->cur_layer == lay)
    98     e->froot = NULL;
    99 }
    100 
    101 void ezx_select_layer(ezx_t * e, int lay)
    102 {
    103   assert(e->magic == MAGIC1);
    104 
    105   if (lay < 0)
    106     lay = 0;
    107   if (lay >= NLAYER)
    108     lay = NLAYER - 1;
    109 
    110   e->layers[e->cur_layer] = e->froot;
    111   e->froot = e->layers[lay];
     289  e->fig_head[lay] = NULL;
     290  e->fig_tail[lay] = NULL;
     291}
     292
     293void ezx_select_layer(ezx_t *e, int lay)
     294{
     295  if (lay < 0 || EZX_NLAYER <= lay)
     296    error_exit("ezx_select_layer: invalid layer number %d", lay);
     297
    112298  e->cur_layer = lay;
    113299}
    114300
    115 void ezx_set_light_3d(ezx_t * e, double ex, double ey, double ez)
     301void ezx_set_light_3d(ezx_t *e, double ex, double ey, double ez)
    116302{
    117303  double s = sqrt(ex * ex + ey * ey + ez * ez);
    118 
    119   assert(e->magic == MAGIC1);
    120304
    121305  if (s != 0) {
     
    126310}
    127311
    128 void ezx_set_view_3d(ezx_t * e, double ex, double ey, double ez, double vx,
     312void ezx_set_view_3d(ezx_t *e, double ex, double ey, double ez, double vx,
    129313                     double vy, double vz, double m)
    130314{
     
    135319  double st, ct, sp, cp;
    136320
    137   assert(e->magic == MAGIC1);
    138 
    139321  e->mag = m;
    140322
     
    144326  e->eye_r = sqrt(x * x + y * y + z * z);
    145327
    146   if (tmp == 0)
    147     phi = M_PI / 2;
    148   else
    149     phi = acos(tmp / (sqrt(tmp) * e->eye_r));
    150 
    151   if (z < 0)
    152     phi = -phi;
    153 
    154   //cerr << "theta = " << theta / M_PI * 180 << "\n";
    155   //cerr << "phi   = " << phi / M_PI * 180 << "\n";
     328  if (tmp == 0) phi = M_PI / 2;
     329  else phi = acos(tmp / (sqrt(tmp) * e->eye_r));
     330
     331  if (z < 0) phi = -phi;
    156332
    157333  st = sin(theta);
     
    171347}
    172348
    173 static double getz(ezx_t * e, double sx, double sy, double sz)
    174 {
    175   assert(e->magic == MAGIC1);
    176 
     349static double getz(ezx_t *e, double sx, double sy, double sz)
     350{
    177351  sx -= e->eye_x;
    178352  sy -= e->eye_y;
     
    182356}
    183357
    184 void ezx_c3d_to_2d(ezx_t * e, double sx, double sy, double sz, double *dx,
     358void ezx_c3d_to_2d(ezx_t *e, double sx, double sy, double sz, double *dx,
    185359                   double *dy)
    186360{
    187361  double x2, y2, z2, rz;
    188 
    189   assert(e->magic == MAGIC1);
    190362
    191363  sx -= e->eye_x;
     
    197369  z2 = sx * e->cmat[0][2] + sy * e->cmat[1][2] + sz * e->cmat[2][2];
    198370
    199   //cerr << x2 << "," << y2 << "," << z2 << "\n";
    200   //cerr << "e->eye_r = " << e->eye_r << "\n";
    201   //cerr << "z2 = " << z2 << "\n";
    202 
    203371  rz = e->scrdist - z2;
    204372  *dx = e->mag * e->scrdist * x2 / rz;
     
    206374}
    207375
    208 static void clip_line(int *x0, int *y0, int *x1, int *y1, int width,
    209                       int height)
     376static void clip_line(int *x0, int *y0, int *x1, int *y1, int width, int height)
    210377{
    211378  if (*x0 > *x1) {
     
    248415}
    249416
    250 void ezx_line_2d(ezx_t * e, int x0, int y0, int x1, int y1,
    251                  ezx_color * col, int width)
    252 {
    253   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    254   ezx_figures **p;
    255 
    256   assert(e->magic == MAGIC1);
    257 
    258   nf->magic = MAGIC2;
    259   nf->kind = FLINE;
     417static void figure_list_add_tail(ezx_t *e, ezx_figures *nf)
     418{
     419  int lay = e->cur_layer;
     420 
     421  if (e->fig_head[lay] == NULL)
     422    e->fig_head[lay] = e->fig_tail[lay] = nf;
     423  else {
     424    e->fig_tail[lay]->next = nf;
     425    e->fig_tail[lay] = nf;
     426  }
     427}
     428
     429void ezx_point_2d(ezx_t *e, int x, int y, const ezx_color_t *col)
     430{
     431  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     432
     433  nf->type = FPOINT2D;
     434  nf->x0 = x;
     435  nf->y0 = y;
     436  nf->col = *col;
     437
     438  figure_list_add_tail(e, nf);
     439}
     440
     441void ezx_line_2d(ezx_t *e, int x0, int y0, int x1, int y1, const ezx_color_t *col,
     442                 int width)
     443{
     444  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     445
     446  nf->type = FLINE2D;
    260447  nf->x0 = x0;
    261448  nf->y0 = y0;
     
    264451  nf->col = *col;
    265452  nf->width = width;
    266 
    267   p = &e->froot;
    268   while (*p != NULL)
    269     p = &(*p)->next;
    270   *p = nf;
    271 }
    272 
    273 void ezx_line_3d(ezx_t * e, double x0, double y0, double z0, double x1,
    274                  double y1, double z1, ezx_color * col, int width)
    275 {
    276   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    277   ezx_figures **p;
    278 
    279   assert(e->magic == MAGIC1);
    280 
    281   nf->magic = MAGIC2;
    282   nf->kind = FLINE3D;
     453 
     454  figure_list_add_tail(e, nf);
     455}
     456
     457void ezx_lines_2d(ezx_t *e, ezx_point2d_t *points, int npoints,
     458                  const ezx_color_t *col, int width)
     459{
     460  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     461
     462  nf->type = FLINES2D;
     463  nf->points_2d = points;
     464  nf->npoints = npoints;
     465  nf->col = *col;
     466  nf->width = width;
     467 
     468  figure_list_add_tail(e, nf);
     469}
     470
     471void ezx_poly_2d(ezx_t *e,ezx_point2d_t *points, int npoints,
     472                 const ezx_color_t *col)
     473{
     474  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     475
     476  nf->type = FPOLY2D;
     477  nf->points_2d = points;
     478  nf->npoints = npoints;
     479  nf->col = *col;
     480 
     481  figure_list_add_tail(e, nf);
     482}
     483
     484void ezx_arc_2d(ezx_t *e, int x0, int y0, int w, int h, double angle1,
     485                double angle2, const ezx_color_t *col, int width)
     486{
     487  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     488
     489  nf->type = FARC2D;
    283490  nf->x0 = x0;
    284491  nf->y0 = y0;
    285   nf->z0 = z0;
    286   nf->x1 = x1;
    287   nf->y1 = y1;
    288   nf->z1 = z1;
     492  nf->x1 = w;
     493  nf->y1 = h;
     494  nf->angle1 = angle1;
     495  nf->angle2 = angle2;
     496  nf->col = *col;
     497  nf->width = width;
     498
     499  figure_list_add_tail(e, nf);
     500}
     501
     502void ezx_fillarc_2d(ezx_t *e, int x0, int y0, int w, int h, double angle1,
     503                    double angle2, const ezx_color_t *col)
     504{
     505  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     506
     507  nf->type = FFILLEDARC2D;
     508  nf->x0 = x0;
     509  nf->y0 = y0;
     510  nf->x1 = w;
     511  nf->y1 = h;
     512  nf->angle1 = angle1;
     513  nf->angle2 = angle2;
     514  nf->col = *col;
     515  nf->width = 0;
     516
     517  figure_list_add_tail(e, nf);
     518}
     519
     520void ezx_line_3d(ezx_t *e, double x0, double y0, double z0, double x1,
     521                 double y1, double z1, const ezx_color_t *col, int width)
     522{
     523  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     524
     525  nf->type = FLINE3D;
     526  nf->dx0 = x0;
     527  nf->dy0 = y0;
     528  nf->dz0 = z0;
     529  nf->dx1 = x1;
     530  nf->dy1 = y1;
     531  nf->dz1 = z1;
    289532  nf->col = *col;
    290533  nf->width = width;
    291534  nf->next = NULL;
    292535
    293   p = &e->froot;
    294   while (*p != NULL)
    295     p = &(*p)->next;
    296   *p = nf;
    297 }
    298 
    299 void ezx_str_3d(ezx_t * e, double x0, double y0, double z0, char *str,
    300                 ezx_color * col, int width)
    301 {
    302   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    303   ezx_figures **p;
    304 
    305   assert(e->magic == MAGIC1);
    306 
    307   nf->magic = MAGIC2;
    308   nf->kind = FSTR3D;
     536  figure_list_add_tail(e, nf);
     537}
     538
     539void ezx_str_3d(ezx_t *e, double x0, double y0, double z0, char *str,
     540                const ezx_color_t *col)
     541{
     542  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     543
     544  nf->type = FSTR3D;
     545  nf->dx0 = x0;
     546  nf->dy0 = y0;
     547  nf->dz0 = z0;
     548  nf->str = xcalloc(strlen(str) + 1, sizeof(char));
     549  strcpy(nf->str, str);
     550  nf->col = *col;
     551  nf->next = NULL;
     552
     553  figure_list_add_tail(e, nf);
     554}
     555
     556void ezx_str_2d(ezx_t *e, int x0, int y0, char *str, const ezx_color_t *col)
     557{
     558  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     559
     560  nf->type = FSTR2D;
    309561  nf->x0 = x0;
    310562  nf->y0 = y0;
    311   nf->z0 = z0;
    312   nf->str = calloc(strlen(str) + 1, sizeof(char));
    313   strcpy(nf->str, str);
    314   nf->col = *col;
    315   nf->width = width;
    316   nf->next = NULL;
    317 
    318   p = &e->froot;
    319   while (*p != NULL)
    320     p = &(*p)->next;
    321   *p = nf;
    322 }
    323 
    324 void ezx_str_2d(ezx_t * e, double x0, double y0, char *str,
    325                 ezx_color * col)
    326 {
    327   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    328   ezx_figures **p;
    329 
    330   assert(e->magic == MAGIC1);
    331 
    332   nf->magic = MAGIC2;
    333   nf->kind = FSTR2D;
    334   nf->x0 = x0;
    335   nf->y0 = y0;
    336   nf->str = calloc(strlen(str) + 1, sizeof(char));
     563  nf->str = xcalloc(strlen(str) + 1, sizeof(char));
    337564  strcpy(nf->str, str);
    338565  nf->col = *col;
     
    340567  nf->next = NULL;
    341568
    342   p = &e->froot;
    343   while (*p != NULL)
    344     p = &(*p)->next;
    345   *p = nf;
    346 }
    347 
    348 void ezx_fillrect_2d(ezx_t * e, double x0, double y0, double x1, double y1,
    349                      ezx_color * col)
    350 {
    351   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    352   ezx_figures **p;
    353 
    354   assert(e->magic == MAGIC1);
    355 
    356   nf->magic = MAGIC2;
    357   nf->kind = FFILLRECT2D;
     569  figure_list_add_tail(e, nf);
     570}
     571
     572void ezx_fillrect_2d(ezx_t *e, int x0, int y0, int x1, int y1,
     573                     const ezx_color_t *col)
     574{
     575  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     576
     577  nf->type = FFILLEDRECT2D;
    358578  nf->x0 = x0;
    359579  nf->y0 = y0;
     
    364584  nf->next = NULL;
    365585
    366   p = &e->froot;
    367   while (*p != NULL)
    368     p = &(*p)->next;
    369   *p = nf;
    370 }
    371 
    372 void ezx_poly_3d(ezx_t * e, ezx_points_3d * points, double hx, double hy,
    373                  double hz, int npoints, ezx_color * col)
    374 {
    375   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    376   ezx_figures **p;
     586  figure_list_add_tail(e, nf);
     587}
     588
     589void ezx_rect_2d(ezx_t *e, int x0, int y0, int x1, int y1, const ezx_color_t *col,
     590                 int width)
     591{
     592  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     593
     594  nf->type = FRECT2D;
     595  nf->x0 = x0;
     596  nf->y0 = y0;
     597  nf->x1 = x1;
     598  nf->y1 = y1;
     599  nf->col = *col;
     600  nf->width = width;
     601  nf->next = NULL;
     602
     603  figure_list_add_tail(e, nf);
     604}
     605
     606void ezx_poly_3d(ezx_t *e, ezx_point3d_t *points, double hx, double hy,
     607                 double hz, int npoints, const ezx_color_t *col)
     608{
     609  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
    377610  int i;
    378611
    379   assert(e->magic == MAGIC1);
    380 
    381   nf->magic = MAGIC2;
    382   nf->kind = FPOLY3D;
    383   nf->poly.points = points;
    384   nf->poly.npoints = npoints;
     612  nf->type = FPOLY3D;
     613  nf->points_3d = points;
     614  nf->npoints = npoints;
    385615  nf->col = *col;
    386616  nf->next = NULL;
    387   nf->poly.hx = hx;
    388   nf->poly.hy = hy;
    389   nf->poly.hz = hz;
    390 
    391   nf->poly.gx = nf->poly.gy = nf->poly.gz = 0;
     617  nf->dx0 = hx;
     618  nf->dy0 = hy;
     619  nf->dz0 = hz;
     620
     621  nf->dx1 = nf->dy1 = nf->dz1 = 0;
    392622  for (i = 0; i < npoints; i++) {
    393     nf->poly.gx += points[i].x;
    394     nf->poly.gy += points[i].y;
    395     nf->poly.gz += points[i].z;
    396   }
    397 
    398   nf->poly.gx /= npoints;
    399   nf->poly.gy /= npoints;
    400   nf->poly.gz /= npoints;
    401 
    402   p = &e->froot;
    403   while (*p != NULL)
    404     p = &(*p)->next;
    405   *p = nf;
    406 }
    407 
    408 void ezx_fillcircle_2d(ezx_t * e, int x0, int y0, int r, ezx_color * col,
    409                        int width)
    410 {
    411   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    412   ezx_figures **p;
    413 
    414   assert(e->magic == MAGIC1);
    415 
    416   nf->magic = MAGIC2;
    417   nf->kind = FFILLEDCIRCLE;
     623    nf->dx1 += points[i].x;
     624    nf->dy1 += points[i].y;
     625    nf->dz1 += points[i].z;
     626  }
     627
     628  nf->dx1 /= npoints;
     629  nf->dy1 /= npoints;
     630  nf->dz1 /= npoints;
     631
     632  figure_list_add_tail(e, nf);
     633}
     634
     635void ezx_fillcircle_2d(ezx_t *e, int x0, int y0, int r, const ezx_color_t *col)
     636{
     637  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     638
     639  nf->type = FFILLEDCIRCLE2D;
    418640  nf->x0 = x0;
    419641  nf->y0 = y0;
    420642  nf->r = r;
    421643  nf->col = *col;
    422   nf->width = width;
     644  nf->width = 0;
    423645  nf->next = NULL;
    424646
    425   p = &e->froot;
    426   while (*p != NULL)
    427     p = &(*p)->next;
    428   *p = nf;
    429 }
    430 
    431 void ezx_circle_2d(ezx_t * e, int x0, int y0, int r, ezx_color * col,
     647  figure_list_add_tail(e, nf);
     648}
     649
     650void ezx_circle_2d(ezx_t *e, int x0, int y0, int r, const ezx_color_t *col,
    432651                   int width)
    433652{
    434   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    435   ezx_figures **p;
    436 
    437   assert(e->magic == MAGIC1);
    438 
    439   nf->magic = MAGIC2;
    440   nf->kind = FCIRCLE;
     653  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     654
     655  nf->type = FCIRCLE2D;
    441656  nf->x0 = x0;
    442657  nf->y0 = y0;
     
    446661  nf->next = NULL;
    447662
    448   p = &e->froot;
    449   while (*p != NULL)
    450     p = &(*p)->next;
    451   *p = nf;
    452 }
    453 
    454 void ezx_circle_3d(ezx_t * e, double x0, double y0, double z0, double r,
    455                    ezx_color * col)
    456 {
    457   ezx_figures *nf = calloc(1, sizeof(ezx_figures));
    458   ezx_figures **p;
    459 
    460   assert(e->magic == MAGIC1);
    461 
    462   nf->magic = MAGIC2;
    463   nf->kind = FFILLEDCIRCLE3D;
    464   nf->x0 = x0;
    465   nf->y0 = y0;
    466   nf->z0 = z0;
    467   nf->r = r;
    468   nf->col = *col;
    469   //nf->width = width;
     663  figure_list_add_tail(e, nf);
     664}
     665
     666void ezx_circle_3d(ezx_t *e, double x0, double y0, double z0, double r,
     667                   const ezx_color_t *col)
     668{
     669  ezx_figures *nf = xcalloc(1, sizeof(ezx_figures));
     670
     671  nf->type = FFILLEDCIRCLE3D;
     672  nf->dx0 = x0;
     673  nf->dy0 = y0;
     674  nf->dz0 = z0;
     675  nf->dr = r;
     676  nf->col = *col;
    470677  nf->next = NULL;
    471678
    472   p = &e->froot;
    473   while (*p != NULL)
    474     p = &(*p)->next;
    475   *p = nf;
    476 }
    477 
    478 void ezx_set_background(ezx_t * e, ezx_color * col)
    479 {
    480   assert(e->magic == MAGIC1);
    481 
     679  figure_list_add_tail(e, nf);
     680}
     681
     682void ezx_set_background(ezx_t *e, const ezx_color_t *col)
     683{
    482684  e->bgcolor = *col;
    483685}
    484686
    485 void ezx_redraw(ezx_t * e)
     687void ezx_redraw(ezx_t *e)
    486688{
    487689  ezx_figures  *f;
     
    489691  ezx_pfigures *pf;
    490692
    491   assert(e->magic == MAGIC1);
    492 
    493   {
    494     XColor lc;
    495 
    496     lc.red = (unsigned short) (e->bgcolor.r * 65535);
    497     lc.green = (unsigned short) (e->bgcolor.g * 65535);
    498     lc.blue = (unsigned short) (e->bgcolor.b * 65535);
    499     lc.flags = DoRed | DoGreen | DoBlue;
    500 
    501     XAllocColor(e->display, e->cmap, &lc);
    502 
    503     XSetBackground(e->display, e->gc, e->black.pixel);
    504     XSetForeground(e->display, e->gc, lc.pixel);
    505 
    506     XFillRectangle(e->display, e->pixmap, e->gc, 0, 0, e->size_x,
    507                    e->size_y);
    508   }
     693  XSetBackground(e->display, e->gc, e->black.pixel);
     694  set_fgcolor(e, &e->bgcolor);
     695  XFillRectangle(e->display, e->pixmap, e->gc, 0, 0, e->size_x, e->size_y);
    509696
    510697  // z-sorting
    511698  pf = NULL;
    512 
    513   for (f = e->froot; f != NULL; f = f->next) {
     699  for (f = e->fig_head[e->cur_layer]; f != NULL; f = f->next) {
    514700    double z;
    515701    ezx_pfigures **p;
    516702
    517     if (f->kind != FPOLY3D)
    518       continue;
    519 
    520     z = getz(e, f->poly.gx, f->poly.gy, f->poly.gz);
     703    if (f->type != FPOLY3D) continue;
     704
     705    z = getz(e, f->dx1, f->dy1, f->dz1);
    521706
    522707    for (p = &pf; *p != NULL; p = &(*p)->next) {
    523708      ezx_pfigures *np;
    524709
    525       if (z <= (*p)->z)
    526         continue;
    527 
    528       np = malloc(sizeof(ezx_pfigures));
     710      if (z <= (*p)->z) continue;
     711
     712      np = xmalloc(sizeof(ezx_pfigures));
    529713      np->z = z;
    530714      np->fig = f;
     
    535719
    536720    if (*p == NULL) {
    537       ezx_pfigures *np = malloc(sizeof(ezx_pfigures));
     721      ezx_pfigures *np = xmalloc(sizeof(ezx_pfigures));
    538722      np->z = z;
    539723      np->fig = f;
     
    547731    double hx, hy, hz;
    548732    double cl, br;
    549     XColor lc;
    550733    XPoint *xp;
    551734    int i;
    552735
    553     XSetBackground(e->display, e->gc, e->black.pixel);
    554 
    555     if (f->poly.hx != 0 || f->poly.hy != 0 || f->poly.hz != 0) {
    556       hx = f->poly.hx;
    557       hy = f->poly.hy;
    558       hz = f->poly.hz;
    559 
    560       if (hx * (e->eye_x - f->poly.gx) +
    561           hy * (e->eye_y - f->poly.gy) +
    562           hz * (e->eye_z - f->poly.gz) < 0) {
     736    if (f->dx0 != 0 || f->dy0 != 0 || f->dz0 != 0) {
     737      hx = f->dx0;
     738      hy = f->dy0;
     739      hz = f->dz0;
     740
     741      if (hx * (e->eye_x - f->dx1) +
     742          hy * (e->eye_y - f->dy1) +
     743          hz * (e->eye_z - f->dz1) < 0) {
    563744        continue;
    564745      }
    565746    } else {
    566747      for (i = 2;; i++) {
    567         double x0 = f->poly.points[1].x - f->poly.points[0].x;
    568         double y0 = f->poly.points[1].y - f->poly.points[0].y;
    569         double z0 = f->poly.points[1].z - f->poly.points[0].z;
    570         double x1 = f->poly.points[i].x - f->poly.points[0].x;
    571         double y1 = f->poly.points[i].y - f->poly.points[0].y;
    572         double z1 = f->poly.points[i].z - f->poly.points[0].z;
     748        double x0 = f->points_3d[1].x - f->points_3d[0].x;
     749        double y0 = f->points_3d[1].y - f->points_3d[0].y;
     750        double z0 = f->points_3d[1].z - f->points_3d[0].z;
     751        double x1 = f->points_3d[i].x - f->points_3d[0].x;
     752        double y1 = f->points_3d[i].y - f->points_3d[0].y;
     753        double z1 = f->points_3d[i].z - f->points_3d[0].z;
    573754
    574755        hx = y0 * z1 - y1 * z0;
     
    576757        hz = x0 * y1 - x1 * y0;
    577758
    578         if (hx != 0 || hy != 0 || hz != 0)
    579           break;
     759        if (hx != 0 || hy != 0 || hz != 0) break;
    580760      }
    581761    }
    582762
    583     cl = (e->light_x * f->poly.hx + e->light_y * f->poly.hy +
    584           e->light_z * f->poly.hz) / sqrt(f->poly.hx * f->poly.hx +
    585                                           f->poly.hy * f->poly.hy +
    586                                           f->poly.hz * f->poly.hz);
     763    cl = (e->light_x * f->dx0 + e->light_y * f->dy0 +
     764          e->light_z * f->dz0) / sqrt(f->dx0 * f->dx0 +
     765                                          f->dy0 * f->dy0 +
     766                                          f->dz0 * f->dz0);
    587767    if (cl < 0) {
    588768      cl = -cl;
    589       f->poly.hx = -f->poly.hx;
    590       f->poly.hy = -f->poly.hy;
    591       f->poly.hz = -f->poly.hz;
     769      f->dx0 = -f->dx0;
     770      f->dy0 = -f->dy0;
     771      f->dz0 = -f->dz0;
    592772    }
    593     if (f->poly.hx * (e->eye_x - f->poly.gx) +
    594         f->poly.hy * (e->eye_y - f->poly.gy) +
    595         f->poly.hz * (e->eye_z - f->poly.gz) < 0)
     773    if (f->dx0 * (e->eye_x - f->dx1) +
     774        f->dy0 * (e->eye_y - f->dy1) +
     775        f->dz0 * (e->eye_z - f->dz1) < 0)
    596776      cl = 0;
    597777    br = cl * 0.6 + 0.3;
    598778
    599     //cerr << "br = " << br << "\n";
    600 
    601     lc.red = (unsigned short) (f->col.r * 65535 * br);
    602     lc.green = (unsigned short) (f->col.g * 65535 * br);
    603     lc.blue = (unsigned short) (f->col.b * 65535 * br);
    604     lc.flags = DoRed | DoGreen | DoBlue;
    605 
    606     XAllocColor(e->display, e->cmap, &lc);
    607 
    608     XSetForeground(e->display, e->gc, lc.pixel);
    609 
    610     xp = malloc(sizeof(XPoint) * f->poly.npoints);
    611     for (i = 0; i < f->poly.npoints; i++) {
     779    xp = xmalloc(sizeof(XPoint) * f->npoints);
     780    for (i = 0; i < f->npoints; i++) {
    612781      double sx0, sy0;
    613       ezx_c3d_to_2d(e, f->poly.points[i].x, f->poly.points[i].y,
    614                     f->poly.points[i].z, &sx0, &sy0);
    615       xp[i].x = (int) sx0 + (e->size_x / 2);
    616       xp[i].y = (int) sy0 + (e->size_y / 2);
     782      ezx_c3d_to_2d(e, f->points_3d[i].x, f->points_3d[i].y,
     783                    f->points_3d[i].z, &sx0, &sy0);
     784      xp[i].x = (int)sx0 + (e->size_x / 2);
     785      xp[i].y = (int)sy0 + (e->size_y / 2);
    617786    }
    618787
    619     XFillPolygon(e->display, e->pixmap, e->gc, xp, f->poly.npoints,
     788    set_fgcolor(e, &f->col);
     789   
     790    XFillPolygon(e->display, e->pixmap, e->gc, xp, f->npoints,
    620791                 Complex, CoordModeOrigin);
     792
    621793    free(xp);
    622794  }
     
    636808    int i;
    637809
    638     e->layers[e->cur_layer] = e->froot;
    639 
    640     for (i = 0; i < NLAYER; i++) {
    641       for (f = e->layers[i]; f != NULL; f = f->next) {
    642         XColor lc;
    643 
    644         assert(f->magic == MAGIC2);
    645 
    646         lc.red = (unsigned short) (f->col.r * 65535);
    647         lc.green = (unsigned short) (f->col.g * 65535);
    648         lc.blue = (unsigned short) (f->col.b * 65535);
    649         lc.flags = DoRed | DoGreen | DoBlue;
    650 
    651         XAllocColor(e->display, e->cmap, &lc);
    652 
    653         XSetBackground(e->display, e->gc, e->black.pixel);
    654         XSetForeground(e->display, e->gc, lc.pixel);
    655 
    656         switch (f->kind) {
    657         case FLINE:
    658           XSetLineAttributes(e->display, e->gc, f->width,
    659                              LineSolid, CapRound, JoinRound);
    660           XDrawLine(e->display, e->pixmap, e->gc, (int) f->x0,
    661                     (int) f->y0, (int) f->x1, (int) f->y1);
     810    for (i = 0; i < EZX_NLAYER; i++) {
     811      for (f = e->fig_head[i]; f != NULL; f = f->next) {
     812        set_fgcolor(e, &f->col);
     813
     814        switch (f->type) {
     815        case FPOINT2D:
     816          XDrawPoint(e->display, e->pixmap, e->gc, f->x0, f->y0);
     817          break;
     818        case FLINE2D:
     819          {
     820            int width = f->width;
     821            if (width <= 0) break;
     822            if (width == 1) width = 0;
     823            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     824                               CapRound, JoinRound);
     825            XDrawLine(e->display, e->pixmap, e->gc, f->x0, f->y0, f->x1, f->y1);
     826          }
     827          break;
     828        case FLINES2D:
     829          {
     830            int j, width = f->width;
     831            if (width <= 0) break;
     832            if (width == 1) width = 0;
     833            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     834                               CapRound, JoinRound);
     835            XPoint *xp = xmalloc(sizeof(XPoint) * f->npoints);
     836            for (j = 0; j < f->npoints; j++) {
     837              xp[j].x = f->points_2d[j].x;
     838              xp[j].y = f->points_2d[j].y;
     839            }
     840            XDrawLines(e->display, e->pixmap, e->gc, xp, f->npoints,
     841                       CoordModeOrigin);
     842            free(xp);
     843          }
     844          break;
     845        case FPOLY2D:
     846          {
     847            int j;
     848            XPoint *xp = xmalloc(sizeof(XPoint) * f->npoints);
     849            for (j = 0; j < f->npoints; j++) {
     850              xp[j].x = f->points_2d[j].x;
     851              xp[j].y = f->points_2d[j].y;
     852            }
     853            XFillPolygon(e->display, e->pixmap, e->gc, xp, f->npoints,
     854                         Complex, CoordModeOrigin);
     855            free(xp);
     856          }
    662857          break;
    663858        case FLINE3D:
    664859          {
     860            int width = f->width;
    665861            double sx0, sy0, sx1, sy1;
    666862            int x0, y0, x1, y1;
    667 
    668             ezx_c3d_to_2d(e, f->x0, f->y0, f->z0, &sx0, &sy0);
    669             ezx_c3d_to_2d(e, f->x1, f->y1, f->z1, &sx1, &sy1);
    670             x0 = sx0 + (e->size_x / 2);
    671             y0 = sy0 + (e->size_y / 2);
    672             x1 = sx1 + (e->size_x / 2);
    673             y1 = sy1 + (e->size_y / 2);
    674             clip_line(&x0, &y0, &x1, &y1, e->size_x,
    675                       e->size_y);
    676             XSetLineAttributes(e->display, e->gc, f->width,
    677                                LineSolid, CapRound, JoinRound);
    678             XDrawLine(e->display, e->pixmap, e->gc, x0, y0, x1,
    679                       y1);
    680             //cerr << "(" << sx0 << "," << sy0 << ") - (" << sx1 << "," << sy1 << ")\n";
     863            if (width <= 0) break;
     864            if (width == 1) width = 0;
     865            ezx_c3d_to_2d(e, f->dx0, f->dy0, f->dz0, &sx0, &sy0);
     866            ezx_c3d_to_2d(e, f->dx1, f->dy1, f->dz1, &sx1, &sy1);
     867            x0 = (int)sx0 + (e->size_x / 2);
     868            y0 = (int)sy0 + (e->size_y / 2);
     869            x1 = (int)sx1 + (e->size_x / 2);
     870            y1 = (int)sy1 + (e->size_y / 2);
     871            clip_line(&x0, &y0, &x1, &y1, e->size_x, e->size_y);
     872            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     873                               CapRound, JoinRound);
     874            XDrawLine(e->display, e->pixmap, e->gc, x0, y0, x1, y1);
    681875          }
    682876          break;
    683         case FFILLEDCIRCLE:
    684           XSetLineAttributes(e->display, e->gc, f->width,
    685                              LineSolid, CapRound, JoinRound);
    686           XFillArc(e->display, e->pixmap, e->gc,
    687                    (int) (f->x0 - f->r), (int) (f->y0 - f->r),
    688                    (int) f->r * 2, (int) f->r * 2, 0, 64 * 360);
     877        case FCIRCLE2D:
     878          {
     879            int width = f->width;
     880            if (width <= 0) break;
     881            if (width == 1) width = 0;
     882            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     883                               CapRound, JoinRound);
     884            XDrawArc(e->display, e->pixmap, e->gc, f->x0 - f->r, f->y0 - f->r,
     885                     f->r * 2, f->r * 2, 0, 64 * 360);
     886          }
     887          break;
     888        case FFILLEDCIRCLE2D:
     889          XFillArc(e->display, e->pixmap, e->gc, f->x0 - f->r, f->y0 - f->r,
     890                   f->r * 2, f->r * 2, 0, 64 * 360);
    689891          break;
    690892        case FFILLEDCIRCLE3D:
    691893          {
    692894            double sx0, sy0;
    693             ezx_c3d_to_2d(e, f->x0, f->y0, f->z0, &sx0, &sy0);
    694             XSetLineAttributes(e->display, e->gc, f->width,
    695                                LineSolid, CapRound, JoinRound);
     895            ezx_c3d_to_2d(e, f->dx0, f->dy0, f->dz0, &sx0, &sy0);
    696896            XFillArc(e->display, e->pixmap, e->gc,
    697                      (int) sx0 + (e->size_x / 2) - (int) f->r,
    698                      (int) sy0 + (e->size_y / 2) - (int) f->r,
    699                      (int) f->r * 2, (int) f->r * 2, 0,
    700                      64 * 360);
     897                     (int)sx0 + (e->size_x / 2) - (int)f->dr,
     898                     (int)sy0 + (e->size_y / 2) - (int)f->dr,
     899                     (int)f->dr * 2, (int)f->dr * 2, 0, 64 * 360);
    701900          }
     901          break;
     902        case FSTR2D:
     903          XDrawString(e->display, e->pixmap, e->gc, f->x0, f->y0, f->str,
     904                      strlen(f->str));
    702905          break;
    703906        case FSTR3D:
    704907          {
    705908            double sx0, sy0;
    706             ezx_c3d_to_2d(e, f->x0, f->y0, f->z0, &sx0, &sy0);
     909            ezx_c3d_to_2d(e, f->dx0, f->dy0, f->dz0, &sx0, &sy0);
    707910            XDrawString(e->display, e->pixmap, e->gc,
    708                         (int) sx0 + (e->size_x / 2),
    709                         (int) sy0 + (e->size_y / 2), f->str,
    710                         strlen(f->str));
     911                        (int)sx0 + (e->size_x / 2), (int)sy0 + (e->size_y / 2),
     912                        f->str, strlen(f->str));
    711913          }
    712914          break;
    713         case FSTR2D:
    714           XDrawString(e->display, e->pixmap, e->gc, (int) f->x0,
    715                       (int) f->y0, f->str, strlen(f->str));
    716           break;
    717         case FFILLRECT2D:
    718           XSetLineAttributes(e->display, e->gc, 0, LineSolid,
    719                              CapRound, JoinRound);
    720           XFillRectangle(e->display, e->pixmap, e->gc,
    721                          (int) f->x0, (int) f->y0,
    722                          (int) (f->x1 - f->x0 + 1),
    723                          (int) (f->y1 - f->y0 + 1));
    724           break;
    725         case FCIRCLE:
    726           XSetLineAttributes(e->display, e->gc, f->width,
    727                              LineSolid, CapRound, JoinRound);
    728           XDrawArc(e->display, e->pixmap, e->gc,
    729                    (int) (f->x0 - f->r), (int) (f->y0 - f->r),
    730                    (int) f->r * 2, (int) f->r * 2, 0, 64 * 360);
     915        case FRECT2D:
     916          {
     917            int width = f->width;
     918            if (width <= 0) break;
     919            if (width == 1) width = 0;
     920            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     921                               CapRound, JoinRound);
     922            XDrawRectangle(e->display, e->pixmap, e->gc, f->x0, f->y0,
     923                           f->x1 - f->x0, f->y1 - f->y0);
     924          }
     925          break;
     926        case FFILLEDRECT2D:
     927          XFillRectangle(e->display, e->pixmap, e->gc, f->x0, f->y0,
     928                         f->x1 - f->x0, f->y1 - f->y0);
     929          break;
     930        case FARC2D:
     931          {
     932            int width = f->width;
     933            if (width <= 0) break;
     934            if (width == 1) width = 0;
     935            XSetLineAttributes(e->display, e->gc, width, LineSolid,
     936                               CapRound, JoinRound);
     937            XDrawArc(e->display, e->pixmap, e->gc, f->x0 - f->x1/2, f->y0 - f->y1/2,
     938                     f->x1, f->y1, f->angle1 * 64, f->angle2 * 64);
     939          }
     940          break;
     941        case FFILLEDARC2D:
     942          XFillArc(e->display, e->pixmap, e->gc, f->x0 - f->x1/2, f->y0 - f->y1/2,
     943                   f->x1, f->y1, f->angle1 * 64, f->angle2 * 64);
     944          break;
     945        case FPOLY3D:
    731946          break;
    732947        }
     
    735950  }
    736951
    737   //XCopyGC(e->display,e->gc,0,e->gc2);
    738   XCopyArea(e->display, e->pixmap, e->top, e->gc, 0, 0, e->size_x,
    739             e->size_y, 0, 0);
     952  XCopyArea(e->display, e->pixmap, e->top, e->gc, 0, 0, e->size_x, e->size_y,
     953            0, 0);
     954
    740955  XFlush(e->display);
    741956}
    742957
    743 void ezx_window_name(ezx_t * e, char *window_name)
    744 {
    745   assert(e->magic == MAGIC1);
    746 
    747   XStoreName(e->display, e->top, window_name);
    748 }
    749 
    750 void ezx_raise_window(ezx_t * e)
    751 {
    752   assert(e->magic == MAGIC1);
    753 
    754   XRaiseWindow(e->display, e->top);
    755 }
    756 
    757 void ezx_quit(ezx_t * e)
    758 {
    759   assert(e->magic == MAGIC1);
    760 
     958void ezx_window_name(ezx_t *e, char *window_name)
     959{
     960  if (window_name != NULL)
     961    XStoreName(e->display, e->top, window_name);
     962}
     963
     964int ezx_isclosed(ezx_t *e)
     965{
     966  XEvent event;
     967
     968  if (!e->closed &&
     969      XCheckTypedWindowEvent(e->display, e->top, ClientMessage, &event) != 0) {
     970    if (event.xclient.message_type == e->wm_protocols &&
     971        event.xclient.data.l[0] == e->wm_delete_window) {
     972      e->closed = 1;
     973    }     
     974  }
     975
     976  return e->closed;
     977}
     978
     979void ezx_quit(ezx_t *e)
     980{
    761981  ezx_wipe(e);
     982
    762983  XFreeFont(e->display, e->fontst);
    763984  XFreeGC(e->display, e->gc);
    764   XFreeGC(e->display, e->gc2);
    765985  XCloseDisplay(e->display);
    766   e->magic = 0;
     986
     987  color_table_free(e->color_table);
    767988
    768989  free(e);
     
    775996  XSetWindowAttributes atr;
    776997
    777   e = calloc(1, sizeof(ezx_t));
    778 
    779   e->magic = MAGIC1;
     998  e = xcalloc(1, sizeof(ezx_t));
    780999
    7811000  server = (char *)getenv("DISPLAY");
    782 
    783   if (server == NULL)
    784     server = "localhost:0.0";
     1001  if (server == NULL) server = "localhost:0.0";
    7851002
    7861003  e->display = XOpenDisplay(server);
    787 
    788   if (e->display == NULL) {
    789     fprintf(stderr, "can't open display %s.\n", server);
    790     exit(EXIT_FAILURE);
    791   }
     1004  if (e->display == NULL) error_exit("can't open display \"%s\"", server);
    7921005
    7931006  e->size_x = size_x;
    7941007  e->size_y = size_y;
     1008  e->closed = 0;
     1009  e->scrdist = 100;
     1010  e->mag = 20;
    7951011  e->cmap = DefaultColormap(e->display, DefaultScreen(e->display));
     1012
     1013  e->color_table = color_table_new();
    7961014
    7971015  XAllocNamedColor(e->display, e->cmap, "black", &e->black, &e->rgb);
    7981016  XAllocNamedColor(e->display, e->cmap, "white", &e->white, &e->rgb);
     1017
     1018  e->fontst = XLoadQueryFont(e->display, fontname);
     1019  if (e->fontst == NULL) error_exit("can't load font \"%s\"", fontname);
    7991020
    8001021  e->top =
    8011022    XCreateSimpleWindow(e->display, DefaultRootWindow(e->display), 0,
    8021023                        0, e->size_x, e->size_y, 2,
    803                         BlackPixel(e->display,
    804                                    DefaultScreen(e->display)),
    805                         WhitePixel(e->display,
    806                                    DefaultScreen(e->display)));
     1024                        BlackPixel(e->display, DefaultScreen(e->display)),
     1025                        WhitePixel(e->display, DefaultScreen(e->display)));
    8071026
    8081027  if (window_name != NULL)
    8091028    XStoreName(e->display, e->top, window_name);
     1029
     1030  e->pixmap = XCreatePixmap(e->display, e->top, e->size_x, e->size_y,
     1031                            DefaultDepth(e->display, DefaultScreen(e->display)));
     1032 
     1033  e->gc = XCreateGC(e->display, e->top, 0, 0);
     1034  XSetGraphicsExposures(e->display, e->gc, False);
     1035
     1036  e->wm_protocols = XInternAtom(e->display, "WM_PROTOCOLS", True);
     1037  e->wm_delete_window = XInternAtom(e->display, "WM_DELETE_WINDOW", True);
     1038  XSetWMProtocols(e->display, e->top, &e->wm_delete_window, 1);
    8101039 
    8111040  e->size_hints.flags = PMinSize | PMaxSize;
     
    8171046
    8181047  atr.backing_store = WhenMapped;
    819 
    8201048  XChangeWindowAttributes(e->display, e->top, CWBackingStore, &atr);
    8211049
    822   XSelectInput(e->display, e->top, ExposureMask | ButtonPressMask |
    823                KeyPressMask);
    824 
    825   e->gc2 = XCreateGC(e->display, e->top, 0, 0);
    826 
    827   e->fontst = XLoadQueryFont(e->display, fontname);
    828 
    829   if (e->fontst == NULL) {
    830     fprintf(stderr, "can't load font.\n");
    831     exit(EXIT_FAILURE);
    832   }
     1050  XSetWindowBackgroundPixmap(e->display, e->top, e->pixmap);
     1051
     1052  XSelectInput(e->display, e->top,
     1053               ExposureMask | KeyPressMask | KeyReleaseMask | ButtonMotionMask |
     1054               OwnerGrabButtonMask | ButtonPressMask | ButtonReleaseMask);
    8331055
    8341056  XResizeWindow(e->display, e->top, e->size_x, e->size_y);
     
    8361058  XMapWindow(e->display, e->top);
    8371059
    838   e->scrdist = 100;
    839   e->mag = 20;
     1060  XFlush(e->display);
    8401061
    8411062  {
    842     unsigned int depth, dummy;
    843     Window dwin;
    844 
    845     XGetGeometry(e->display, e->top, &dwin, &dummy, &dummy, &dummy,
    846                  &dummy, &dummy, &depth);
    847 
    848     e->pixmap =
    849       XCreatePixmap(e->display, e->top, e->size_x, e->size_y, depth);
    850   }
    851 
    852   e->gc = XCreateGC(e->display, e->pixmap, 0, 0);
    853 
    854 
    855   //XFlush(display);
     1063    XEvent ev;
     1064    do {
     1065      XNextEvent(e->display, &ev);
     1066    } while (ev.type != Expose);
     1067  }
     1068
     1069  ezx_set_background(e, &ezx_white);
    8561070  ezx_set_view_3d(e, 1000, 0, 0, 0, 0, 0, 5);
    8571071  ezx_set_light_3d(e, 1000, 900, 800);
    858 
     1072  ezx_redraw(e);
     1073 
    8591074  return e;
    8601075}
    8611076
    862 int ezx_sensebutton(ezx_t * e, int *x, int *y)
     1077static inline unsigned int get_state_mask(unsigned int xstate)
     1078{
     1079  unsigned int state = 0;
     1080
     1081  if (xstate & ShiftMask) state |= EZX_SHIFT_MASK;
     1082  if (xstate & ControlMask) state |= EZX_CONTROL_MASK;
     1083  if (xstate & Button1Mask) state |= EZX_BUTTON_LMASK;
     1084  if (xstate & Button2Mask) state |= EZX_BUTTON_MMASK;
     1085  if (xstate & Button3Mask) state |= EZX_BUTTON_RMASK;
     1086
     1087  return state;
     1088}
     1089
     1090int ezx_sensebutton(ezx_t *e, int *x, int *y)
    8631091{
    8641092  Window root, child;
    8651093  int root_x, root_y, win_x, win_y;
    866   unsigned int b, k;
    867 
    868   assert(e->magic == MAGIC1);
    869 
    870   if (x == NULL)
    871     x = &win_x;
    872   if (y == NULL)
    873     y = &win_y;
    874 
    875   XQueryPointer(e->display, e->top, &root, &child, &root_x, &root_y, x,
    876                 y, &k);
    877   b = 0;
    878   if (k & Button1Mask)
    879     b = 1;
    880   else if (k & Button2Mask)
    881     b = 2;
    882   else if (k & Button3Mask)
    883     b = 3;
    884   if (k & ShiftMask)
    885     b |= 8;
    886   if (k & ControlMask)
    887     b |= 16;
    888   return b;
     1094  unsigned int s;
     1095
     1096  if (x == NULL) x = &win_x;
     1097  if (y == NULL) y = &win_y;
     1098
     1099  XQueryPointer(e->display, e->top, &root, &child, &root_x, &root_y, x, y, &s);
     1100 
     1101  return get_state_mask(s);
    8891102}
    8901103
    8911104int ezx_pushbutton(ezx_t *e, int *x, int *y)
    8921105{
    893   XEvent event;
    894 
    895   assert(e->magic == MAGIC1);
     1106  XEvent xevent;
    8961107
    8971108  for (;;) {
    898     XNextEvent(e->display, &event);
    899     if (event.type == Expose) {
    900       ezx_redraw(e);
    901       continue;
    902     }
    903     if (event.type == ButtonPress) {
    904       Window       root, child;
    905       int          root_x, root_y, win_x, win_y;
    906       unsigned int keys_buttons;
    907       int          b;
    908 
    909       XQueryPointer(e->display, e->top, &root, &child, &root_x, &root_y,
    910                     &win_x, &win_y, &keys_buttons);
    911       if (x != NULL)
    912         *x = ((XButtonEvent *)&event)->x;
    913       if (y != NULL)
    914         *y = ((XButtonEvent *)&event)->y;
    915       b = ((XButtonEvent *)&event)->button;
    916       if (keys_buttons & ShiftMask)
    917         b |= 8;
    918       if (keys_buttons & ControlMask)
    919         b |= 16;
    920 
    921       return b;
    922     }
    923   }
    924 }
    925 
    926 int ezx_next_event(ezx_t *ezx, int *x, int *y, int *b, int *k)
    927 {
    928   XEvent xevent;
    929 
    930   assert(ezx->magic == MAGIC1);
    931 
    932   for (;;) {
    933     XNextEvent(ezx->display, &xevent);
     1109    XMaskEvent(e->display, ExposureMask | ButtonPressMask, &xevent);
    9341110   
    9351111    if (xevent.type == Expose) {
    936       ezx_redraw(ezx);
    937       continue;
     1112      ezx_redraw(e);
     1113    } else if (xevent.type == ButtonPress) {
     1114      if (x) *x = xevent.xbutton.x;
     1115      if (y) *y = xevent.xbutton.y;
     1116      return xevent.xbutton.button;
    9381117    }
    939 
    940     if (xevent.type == ButtonPress) {
    941       Window       root, child;
    942       int          root_x, root_y, win_x, win_y;
    943       unsigned int keys_buttons;
    944 
    945       XQueryPointer(ezx->display, ezx->top, &root, &child, &root_x, &root_y,
    946                     &win_x, &win_y, &keys_buttons);
    947       *x = ((XButtonEvent *)&xevent)->x;
    948       *y = ((XButtonEvent *)&xevent)->y;
    949       *b = ((XButtonEvent *)&xevent)->button;
    950       if (keys_buttons & ShiftMask)
    951         *b |= 8;
    952       if (keys_buttons & ControlMask)
    953         *b |= 16;
    954       *k = 0;
    955       return EzxButtonPress;
     1118  }
     1119}
     1120
     1121void ezx_next_event(ezx_t *e, ezx_event_type_t *type, int *x, int *y, unsigned int *state, unsigned int *kb)
     1122{
     1123  XEvent xevent;
     1124
     1125  for (;;) {
     1126    XNextEvent(e->display, &xevent);
     1127   
     1128    if (xevent.type == Expose) {
     1129      ezx_redraw(e);
     1130    } else if (xevent.type == ButtonPress || xevent.type == ButtonRelease) {
     1131         {
     1132              if (xevent.type == ButtonPress) *type = EZX_BUTTON_PRESS;
     1133              else *type = EZX_BUTTON_RELEASE;
     1134              *x = xevent.xbutton.x;
     1135              *y = xevent.xbutton.y;
     1136              *state = get_state_mask(xevent.xbutton.state);
     1137              *kb = xevent.xbutton.button;
     1138         }
     1139         break;
     1140    } else if (xevent.type == KeyPress || xevent.type == KeyRelease) {
     1141      int ret;
     1142      char c;
     1143      KeySym keysym;
     1144      if ((ret=XLookupString((XKeyEvent *)&xevent, &c, 1, &keysym, NULL)) == 1 ||
     1145          (XK_Home <= keysym && keysym <= XK_Down)) {
     1146           {
     1147                if (xevent.type == KeyPress) *type = EZX_KEY_PRESS;     
     1148                else *type = EZX_KEY_RELEASE;
     1149                if (ret == 1) *kb = c;
     1150                else *kb = keysym;
     1151                *x = xevent.xkey.x;
     1152                *y = xevent.xkey.y;
     1153                *state = get_state_mask(xevent.xkey.state);
     1154           }
     1155        break;
     1156      }
     1157    } else if (xevent.type == MotionNotify) {
     1158         {
     1159              *type = EZX_MOTION_NOTIFY;
     1160              *x = xevent.xmotion.x;
     1161              *y = xevent.xmotion.y;
     1162              *state = get_state_mask(xevent.xmotion.state);
     1163         }
     1164      break;
     1165    } else if (xevent.type == ClientMessage) {
     1166         if (xevent.xclient.message_type == e->wm_protocols &&
     1167             xevent.xclient.data.l[0] == e->wm_delete_window) {
     1168              e->closed = 1;
     1169              *type = EZX_CLOSE;
     1170              break;
     1171         }
    9561172    }
    957 
    958     if (xevent.type == KeyPress) {
    959       char s[10];
    960       if (XLookupString((XKeyEvent *)&xevent, s, 10, NULL, NULL) == 1) {
    961         *b = 0;
    962         *k    = s[0];
    963         *x     = xevent.xkey.x;
    964         *y     = xevent.xkey.y;
    965         return EzxKeyPress;
    966       }
    967     }
    9681173  }
    9691174}
     
    9711176int ezx_event_pending(ezx_t *ezx)
    9721177{
    973   assert(ezx->magic == MAGIC1);
    974 
    975   return XPending(ezx->display) > 0;
    976 }
     1178     return (XPending(ezx->display) > 0);
     1179}
  • release/4/ezxdisp/hello.scm

    r14785 r14789  
    33(define ezx (ezx-init 100 100 "Hello, ezxdisp"))
    44(ezx-set-background ezx (make-ezx-color 1 1 1))
    5 (ezx-fillcircle-2d ezx 50 50 25 (make-ezx-color 1 0 0) 1)
     5(ezx-fillcircle-2d ezx 50 50 25 (make-ezx-color 1 0 0))
    66(ezx-redraw ezx)
    77
Note: See TracChangeset for help on using the changeset viewer.