x.c 12.8 KB
Newer Older
1 2 3 4
#include "x.h"
#include "x_defs.h"
#include "gui_defs.h"
#include <X11/Xlib.h>
Cedric Roux's avatar
Cedric Roux committed
5
#include <X11/Xutil.h>
6 7 8 9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
10
int x_connection_fd(x_connection *_x) {
11 12 13 14
  struct x_connection *x = _x;
  return ConnectionNumber(x->d);
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
15
static GC create_gc(Display *d, char *color) {
16 17 18 19
  GC ret = XCreateGC(d, DefaultRootWindow(d), 0, NULL);
  XGCValues gcv;
  XColor rcol, scol;
  XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, ret);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
20

21
  if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
22
                       color, &scol, &rcol)) {
23 24 25 26 27 28 29
    gcv.foreground = scol.pixel;
    XChangeGC(d, ret, GCForeground, &gcv);
  } else ERR("X: could not allocate color '%s'\n", color);

  return ret;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
30
int x_new_color(x_connection *_x, char *color) {
31 32 33
  struct x_connection *x = _x;
  x->ncolors++;
  x->colors = realloc(x->colors, x->ncolors * sizeof(GC));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
34

35
  if (x->colors == NULL) OOM;
Cedric Roux's avatar
Cedric Roux committed
36

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
37
  x->colors[x->ncolors-1] = create_gc(x->d, color);
Cedric Roux's avatar
Cedric Roux committed
38
  x->xft_colors = realloc(x->xft_colors, x->ncolors * sizeof(XftColor));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
39

Cedric Roux's avatar
Cedric Roux committed
40
  if (x->xft_colors == NULL) OOM;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
41

Cedric Roux's avatar
Cedric Roux committed
42
  if (XftColorAllocName(x->d, DefaultVisual(x->d, DefaultScreen(x->d)),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
43 44
                        DefaultColormap(x->d, DefaultScreen(x->d)),
                        color, &x->xft_colors[x->ncolors-1]) == False)
Cedric Roux's avatar
Cedric Roux committed
45 46
    ERR("could not allocate color '%s'\n", color);

47 48 49
  return x->ncolors - 1;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
50
int x_new_font(x_connection *_x, char *font) {
Cedric Roux's avatar
Cedric Roux committed
51 52 53 54
  struct x_connection *x = _x;
  /* TODO: allocate fonts only once */
  x->nfonts++;
  x->fonts = realloc(x->fonts, x->nfonts * sizeof(XftFont *));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
55

Cedric Roux's avatar
Cedric Roux committed
56
  if (x->fonts == NULL) OOM;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
57

Cedric Roux's avatar
Cedric Roux committed
58
  x->fonts[x->nfonts-1] = XftFontOpenName(x->d, DefaultScreen(x->d), font);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
59

Cedric Roux's avatar
Cedric Roux committed
60 61
  if (x->fonts[x->nfonts-1] == NULL)
    ERR("failed allocating font '%s'\n", font);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
62

Cedric Roux's avatar
Cedric Roux committed
63 64 65
  return x->nfonts - 1;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
66
x_connection *x_open(void) {
67 68
  struct x_connection *ret;
  ret = calloc(1, sizeof(struct x_connection));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
69

70 71 72
  if (ret == NULL) OOM;

  ret->d = XOpenDisplay(0);
Cedric Roux's avatar
Cedric Roux committed
73
  LOGD("XOpenDisplay display %p return x_connection %p\n", ret->d, ret);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
74

75 76 77 78
  if (ret->d == NULL) ERR("error calling XOpenDisplay: no X? you root?\n");

  x_new_color(ret, "white");    /* background color */
  x_new_color(ret, "black");    /* foreground color */
Cedric Roux's avatar
Cedric Roux committed
79
  x_new_font(ret, "sans-8");
80 81 82 83
  return ret;
}

x_window *x_create_window(x_connection *_x, int width, int height,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
84
                          char *title) {
85 86 87
  struct x_connection *x = _x;
  struct x_window *ret;
  ret = calloc(1, sizeof(struct x_window));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
88

89 90 91
  if (ret == NULL) OOM;

  ret->w = XCreateSimpleWindow(x->d, DefaultRootWindow(x->d), 0, 0,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
92 93
                               width, height, 0, WhitePixel(x->d, DefaultScreen(x->d)),
                               WhitePixel(x->d, DefaultScreen(x->d)));
94 95 96 97
  ret->width = width;
  ret->height = height;
  XStoreName(x->d, ret->w, title);
  ret->p = XCreatePixmap(x->d, ret->w, width, height,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
98
                         DefaultDepth(x->d, DefaultScreen(x->d)));
99
  XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
100
                 0, 0, width, height);
Cedric Roux's avatar
Cedric Roux committed
101
  ret->xft = XftDrawCreate(x->d, ret->p,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
102 103 104
                           DefaultVisual(x->d, DefaultScreen(x->d)),
                           DefaultColormap(x->d, DefaultScreen(x->d)));

Cedric Roux's avatar
Cedric Roux committed
105 106
  if (ret->xft == NULL) ERR("XftDrawCreate failed\n");

107 108 109 110 111 112 113
  /* enable backing store */
  {
    XSetWindowAttributes att;
    att.backing_store = Always;
    XChangeWindowAttributes(x->d, ret->w, CWBackingStore, &att);
  }
  XSelectInput(x->d, ret->w,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
114 115 116 117 118 119
               KeyPressMask      |
               ButtonPressMask   |
               ButtonReleaseMask |
               PointerMotionMask |
               ExposureMask      |
               StructureNotifyMask);
120 121 122 123
  XMapWindow(x->d, ret->w);
  return ret;
}

Cedric Roux's avatar
Cedric Roux committed
124
x_image *x_create_image(x_connection *_x, unsigned char *data,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
125
                        int width, int height) {
Cedric Roux's avatar
Cedric Roux committed
126 127 128 129 130 131 132
  struct x_connection *x = _x;
  struct x_image *ret;
  XImage *ximage;
  XVisualInfo *vs;
  XVisualInfo template;
  int nvs;
  Visual *v;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
133
  ret = calloc(1, sizeof(struct x_image));
Cedric Roux's avatar
Cedric Roux committed
134

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
135
  if (ret == NULL) OOM;
Cedric Roux's avatar
Cedric Roux committed
136 137

  template.class = TrueColor;
138
  template.depth = 24;
Cedric Roux's avatar
Cedric Roux committed
139 140 141 142 143
  template.red_mask = 0xff0000;
  template.green_mask = 0x00ff00;
  template.blue_mask = 0x0000ff;
  template.bits_per_rgb = 8;
  vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
144 145
                      VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
                      VisualBitsPerRGBMask, &template, &nvs);
146 147 148 149 150

  if (vs == NULL) {
    /* try again with 32 bpp */
    template.depth = 32;
    vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask |
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
151 152
                        VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask |
                        VisualBitsPerRGBMask, &template, &nvs);
153 154 155 156
  }

  if (vs == NULL) ERR("no good visual found\n");

Cedric Roux's avatar
Cedric Roux committed
157 158 159
  v = vs[0].visual;
  XFree(vs);
  ximage = XCreateImage(x->d, v, 24, ZPixmap, 0,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
160 161
                        (char *)data, width, height, 32, 0);

Cedric Roux's avatar
Cedric Roux committed
162 163 164 165
  if (ximage == NULL) ERR("image creation failed\n");

  ret->p = XCreatePixmap(x->d, DefaultRootWindow(x->d), width, height, 24);
  XPutImage(x->d, ret->p, DefaultGC(x->d, DefaultScreen(x->d)),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
166
            ximage, 0, 0, 0, 0, width, height);
Cedric Roux's avatar
Cedric Roux committed
167 168 169 170 171 172 173 174
  /* TODO: be sure it's fine to set data to NULL */
  ximage->data = NULL;
  XDestroyImage(ximage);
  ret->width = width;
  ret->height = height;
  return ret;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
175
static struct toplevel_window_widget *find_x_window(struct gui *g, Window id) {
176 177 178 179
  struct widget_list *cur;
  struct toplevel_window_widget *w;
  struct x_window *xw;
  cur = g->toplevel;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
180

181 182 183
  while (cur) {
    w = (struct toplevel_window_widget *)cur->item;
    xw = w->x;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
184

185
    if (xw->w == id) return w;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
186

187 188
    cur = cur->next;
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
189

190 191 192
  return NULL;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
193
void x_events(gui *_gui) {
194 195 196 197
  struct gui *g = _gui;
  struct widget_list *cur;
  struct x_connection *x = g->x;
  struct toplevel_window_widget *w;
Cedric Roux's avatar
Cedric Roux committed
198
  LOGD("x_events START\n");
199 200
  /* preprocessing (to "compress" events) */
  cur = g->toplevel;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
201

202 203 204 205 206 207 208 209 210 211 212 213 214
  while (cur) {
    struct x_window *xw;
    w = (struct toplevel_window_widget *)cur->item;
    xw = w->x;
    xw->redraw = 0;
    xw->repaint = 0;
    xw->resize = 0;
    cur = cur->next;
  }

  while (XPending(x->d)) {
    XEvent ev;
    XNextEvent(x->d, &ev);
Cedric Roux's avatar
Cedric Roux committed
215
    LOGD("XEV %d\n", ev.type);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
216

217
    switch (ev.type) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
      case MapNotify:
      case Expose:
        if ((w = find_x_window(g, ev.xexpose.window)) != NULL) {
          struct x_window *xw = w->x;
          xw->redraw = 1;
        }

        break;

      case ConfigureNotify:
        if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) {
          struct x_window *xw = w->x;
          xw->resize = 1;
          xw->new_width = ev.xconfigure.width;
          xw->new_height = ev.xconfigure.height;

          if (xw->new_width < 10) xw->new_width = 10;

          if (xw->new_height < 10) xw->new_height = 10;

          LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height);
        }

        break;

      case ButtonPress:
        if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
          int key_modifiers = 0;

          if (ev.xbutton.state & ShiftMask)   key_modifiers |= KEY_SHIFT;

          if (ev.xbutton.state & Mod1Mask)    key_modifiers |= KEY_ALT;

          if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;

          w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
                           ev.xbutton.button, 0);
        }

        break;

      case ButtonRelease:
        if ((w = find_x_window(g, ev.xbutton.window)) != NULL) {
          int key_modifiers = 0;

          if (ev.xbutton.state & ShiftMask)   key_modifiers |= KEY_SHIFT;

          if (ev.xbutton.state & Mod1Mask)    key_modifiers |= KEY_ALT;

          if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL;

          w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers,
                           ev.xbutton.button, 1);
        }

        break;

      default:
        if (gui_logd) WARN("TODO: X event type %d\n", ev.type);

        break;
279 280 281 282
    }
  }

  /* postprocessing */
Cedric Roux's avatar
Cedric Roux committed
283
  LOGD("post processing\n");
284
  cur = g->toplevel;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
285

286 287
  while (cur) {
    struct toplevel_window_widget *w =
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
288
      (struct toplevel_window_widget *)cur->item;
289
    struct x_window *xw = w->x;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
290

291
    if (xw->resize) {
Cedric Roux's avatar
Cedric Roux committed
292
      LOGD("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw->new_height);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
293

294 295 296 297
      if (xw->width != xw->new_width || xw->height != xw->new_height) {
        w->common.allocate(g, w, 0, 0, xw->new_width, xw->new_height);
        xw->width = xw->new_width;
        xw->height = xw->new_height;
Cedric Roux's avatar
Cedric Roux committed
298
        XftDrawDestroy(xw->xft);
299 300
        XFreePixmap(x->d, xw->p);
        xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
301
                              DefaultDepth(x->d, DefaultScreen(x->d)));
302
        XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
303
                       0, 0, xw->width, xw->height);
Cedric Roux's avatar
Cedric Roux committed
304
        xw->xft = XftDrawCreate(x->d, xw->p,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
305 306 307
                                DefaultVisual(x->d, DefaultScreen(x->d)),
                                DefaultColormap(x->d, DefaultScreen(x->d)));

Cedric Roux's avatar
Cedric Roux committed
308 309
        if (xw->xft == NULL) ERR("XftDrawCreate failed\n");

310 311 312
        //xw->repaint = 1;
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
313

314 315 316 317
    if (xw->repaint) {
      w->common.paint(g, w);
      xw->redraw = 1;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
318

319 320
    if (xw->redraw) {
      struct x_connection *x = g->x;
Cedric Roux's avatar
Cedric Roux committed
321
      LOGD("XCopyArea w h %d %d\n", xw->width, xw->height);
322
      XCopyArea(x->d, xw->p, xw->w, x->colors[1],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
323
                0, 0, xw->width, xw->height, 0, 0);
324
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
325

326 327
    cur = cur->next;
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
328

Cedric Roux's avatar
Cedric Roux committed
329
  LOGD("x_events DONE\n");
330 331
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
332
void x_flush(x_connection *_x) {
333 334 335 336
  struct x_connection *x = _x;
  XFlush(x->d);
}

Cedric Roux's avatar
Cedric Roux committed
337
void x_text_get_dimensions(x_connection *_c, int font, const char *t,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
338
                           int *width, int *height, int *baseline) {
339
  struct x_connection *c = _c;
Cedric Roux's avatar
Cedric Roux committed
340
  XGlyphInfo ext;
Cedric Roux's avatar
Cedric Roux committed
341
  XftTextExtentsUtf8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext);
Cedric Roux's avatar
Cedric Roux committed
342 343 344
  *width = ext.width;
  *height = c->fonts[font]->height;
  *baseline = c->fonts[font]->ascent;
345 346 347 348 349 350 351
}

/***********************************************************************/
/*                    public drawing functions                         */
/***********************************************************************/

void x_draw_line(x_connection *_c, x_window *_w, int color,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
352
                 int x1, int y1, int x2, int y2) {
353 354 355 356 357 358
  struct x_connection *c = _c;
  struct x_window *w = _w;
  XDrawLine(c->d, w->p, c->colors[color], x1, y1, x2, y2);
}

void x_draw_rectangle(x_connection *_c, x_window *_w, int color,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
359
                      int x, int y, int width, int height) {
360 361 362 363 364 365
  struct x_connection *c = _c;
  struct x_window *w = _w;
  XDrawRectangle(c->d, w->p, c->colors[color], x, y, width, height);
}

void x_fill_rectangle(x_connection *_c, x_window *_w, int color,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
366
                      int x, int y, int width, int height) {
367 368 369 370 371
  struct x_connection *c = _c;
  struct x_window *w = _w;
  XFillRectangle(c->d, w->p, c->colors[color], x, y, width, height);
}

Cedric Roux's avatar
Cedric Roux committed
372
void x_draw_string(x_connection *_c, x_window *_w, int font, int color,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
373
                   int x, int y, const char *t) {
374 375 376
  struct x_connection *c = _c;
  struct x_window *w = _w;
  int tlen = strlen(t);
Cedric Roux's avatar
Cedric Roux committed
377
  XftDrawStringUtf8(w->xft, &c->xft_colors[color], c->fonts[font],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
378
                    x, y, (const unsigned char *)t, tlen);
379 380
}

Cedric Roux's avatar
Cedric Roux committed
381
void x_draw_clipped_string(x_connection *_c, x_window *_w, int font,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
382 383
                           int color, int x, int y, const char *t,
                           int clipx, int clipy, int clipwidth, int clipheight) {
Cedric Roux's avatar
Cedric Roux committed
384
  struct x_window *w = _w;
385
  XRectangle clip = { clipx, clipy, clipwidth, clipheight };
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
386

Cedric Roux's avatar
Cedric Roux committed
387
  if (XftDrawSetClipRectangles(w->xft, 0, 0, &clip, 1) == False) abort();
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
388

Cedric Roux's avatar
Cedric Roux committed
389
  x_draw_string(_c, _w, font, color, x, y, t);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
390

Cedric Roux's avatar
Cedric Roux committed
391
  if (XftDrawSetClip(w->xft, NULL) == False) abort();
392 393
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
394
void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y) {
Cedric Roux's avatar
Cedric Roux committed
395 396 397 398
  struct x_connection *c = _c;
  struct x_window *w = _w;
  struct x_image *img = _img;
  XCopyArea(c->d, img->p, w->p, DefaultGC(c->d, DefaultScreen(c->d)),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
399
            0, 0, img->width, img->height, x, y);
Cedric Roux's avatar
Cedric Roux committed
400 401
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
402
void x_draw(x_connection *_c, x_window *_w) {
403 404
  struct x_connection *c = _c;
  struct x_window *w = _w;
Cedric Roux's avatar
Cedric Roux committed
405
  LOGD("x_draw XCopyArea w h %d %d display %p window %d pixmap %d\n", w->width, w->height, c->d, (int)w->w, (int)w->p);
406 407
  XCopyArea(c->d, w->p, w->w, c->colors[1], 0, 0, w->width, w->height, 0, 0);
}
408 409 410 411

/* those two special functions are to plot many points
 * first call x_add_point many times then x_plot_points once
 */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
412
void x_add_point(x_connection *_c, int x, int y) {
413 414 415 416 417
  struct x_connection *c = _c;

  if (c->pts_size == c->pts_maxsize) {
    c->pts_maxsize += 65536;
    c->pts = realloc(c->pts, c->pts_maxsize * sizeof(XPoint));
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
418

419 420 421 422 423 424 425 426
    if (c->pts == NULL) OOM;
  }

  c->pts[c->pts_size].x = x;
  c->pts[c->pts_size].y = y;
  c->pts_size++;
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
427
void x_plot_points(x_connection *_c, x_window *_w, int color) {
428
  struct x_connection *c = _c;
Cedric Roux's avatar
Cedric Roux committed
429
  LOGD("x_plot_points %d points\n", c->pts_size);
430 431
  struct x_window *w = _w;
  XDrawPoints(c->d, w->p, c->colors[color], c->pts, c->pts_size,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
432
              CoordModeOrigin);
433 434
  c->pts_size = 0;
}