head 1.11; access; symbols; locks; strict; comment @ * @; 1.11 date 2005.07.09.23.40.55; author keithp; state Exp; branches; next 1.10; commitid 13c342d060824567; 1.10 date 2005.07.07.08.09.21; author keithp; state Exp; branches; next 1.9; commitid 1de242cce3254567; 1.9 date 2005.05.18.06.21.15; author keithp; state Exp; branches; next 1.8; commitid 431d428aded64567; 1.8 date 2005.05.02.20.24.38; author keithp; state Exp; branches; next 1.7; commitid 416842768c824567; 1.7 date 2005.02.11.21.15.46; author keithp; state Exp; branches; next 1.6; 1.6 date 2004.12.24.09.00.10; author keithp; state Exp; branches; next 1.5; 1.5 date 2004.12.24.00.09.24; author keithp; state Exp; branches; next 1.4; 1.4 date 2004.12.23.22.39.40; author keithp; state Exp; branches; next 1.3; 1.3 date 2004.12.17.02.09.45; author keithp; state Exp; branches; next 1.2; 1.2 date 2004.12.15.07.04.50; author keithp; state Exp; branches; next 1.1; 1.1 date 2004.12.14.08.34.27; author keithp; state Exp; branches; next ; desc @@ 1.11 log @2005-07-09 Keith Packard * cairo-5c.h: * cairo.c: (cairo_5c_get): * examples/animate.5c: * gtk.c: (configure_event), (expose_event), (delete_drawing_area), (gtk_repaint), (gtk_tool_free), (cairo_5c_tool_create), (cairo_5c_tool_destroy): * surface.c: (create_cairo_window): Pass GtkPixmap objects around as they are reference counted. Use proposed new cairo_xlib_surface_set_drawable API to deal with window back-buffer resize issue. @ text @/* $Id: gtk.c,v 1.10 2005/07/07 08:09:21 keithp Exp $ * * Copyright © 2004 Keith Packard * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is Keith Packard * * Contributor(s): * Keith Packard */ #include "cairo-5c.h" #include typedef struct _gtk_global { DataType *data; Display *dpy; pthread_t gtk_thread; } gtk_global_t; struct _cairo_5c_tool { DataType *data; gtk_global_t *global; int dirty; int disable; GtkWidget *window; GtkWidget *drawing_area; }; static gtk_global_t *gtk_global; /* * This part runs in the gtk thread, so it must not refer to or use * any memory managed by nickle. Called from signal handler with * gdk lock held. */ static gboolean configure_event (GtkWidget *widget, GdkEventConfigure *event) { GdkPixmap *pixmap; cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; c5s->width = widget->allocation.width; c5s->height = widget->allocation.height; pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); if (c5s->u.window.pixmap) { gdk_draw_drawable (pixmap, widget->style->white_gc, c5s->u.window.pixmap, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height); gdk_drawable_unref (c5s->u.window.pixmap); } c5s->u.window.pixmap = pixmap; return TRUE; } /* * Called from signal handler with gdk lock held */ static gboolean expose_event( GtkWidget *widget, GdkEventExpose *event ) { cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], c5s->u.window.pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE; } /* * Called from delete_event with gdk lock held */ static void delete_drawing_area (GtkWidget *widget, gpointer data) { cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; cairo_5c_tool_t *tool = c5s->u.window.tool; if (c5s->u.window.send_events) { gdk_threads_leave (); fprintf (c5s->u.window.send_events, "%d delete\n", 0); fflush (c5s->u.window.send_events); gdk_threads_enter (); } tool->drawing_area = NULL; tool->window = NULL; if (c5s->u.window.pixmap) { gdk_drawable_unref (c5s->u.window.pixmap); c5s->u.window.pixmap = NULL; } c5s->u.window.pixmap = None; } /* * Called from signal handler with lock held */ static gboolean delete_event( GtkWidget *widget, GdkEventAny *event ) { gtk_container_foreach (GTK_CONTAINER(widget), delete_drawing_area, NULL); return FALSE; } /* * Called from signal handler with lock held */ static gboolean motion_notify_event( GtkWidget *widget, GdkEventMotion *event ) { cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; if (c5s->u.window.send_events) { gdk_threads_leave (); fprintf (c5s->u.window.send_events, "%d motion %g %g\n", event->time, event->x, event->y); fflush (c5s->u.window.send_events); gdk_threads_enter (); } return FALSE; } /* * Called from signal handler with lock held */ static gboolean button_press_event( GtkWidget *widget, GdkEventButton *event ) { cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; if (c5s->u.window.send_events) { gdk_threads_leave (); fprintf (c5s->u.window.send_events, "%d press %d %g %g\n", event->time, event->button, event->x, event->y); fflush (c5s->u.window.send_events); gdk_threads_enter (); } return FALSE; } /* * Called from signal handler with lock held */ static gboolean button_release_event( GtkWidget *widget, GdkEventButton *event ) { cairo_5c_surface_t *c5s = GTK_DRAWING_AREA (widget)->draw_data; if (c5s->u.window.send_events) { gdk_threads_leave (); fprintf (c5s->u.window.send_events, "%d release %d %g %g\n", event->time, event->button, event->x, event->y); fflush (c5s->u.window.send_events); gdk_threads_enter (); } return FALSE; } /* * Called from signal handler with lock held */ static void gtk_repaint (cairo_5c_surface_t *c5s, int x, int y, int w, int h) { cairo_5c_tool_t *tool = c5s->u.window.tool; GtkWidget *widget = tool->drawing_area; GdkPixmap *pixmap = c5s->u.window.pixmap; if (widget && pixmap) { Window xwin = GDK_WINDOW_XID (widget->window); Pixmap xpix = GDK_PIXMAP_XID (pixmap); Display *dpy = tool->global->dpy; GC xgc = GDK_GC_XGC(widget->style->white_gc); if (xwin && xpix && xgc) { if (w == 0) w = c5s->width - x; if (h == 0) h = c5s->height - y; XCopyArea (dpy, xpix, xwin, xgc, x, y, w, h, x, y); XFlush (dpy); } } } /* * Called from timeout with gdk lock not held */ static gboolean gtk_repaint_timeout (gpointer data) { gdk_threads_enter (); { cairo_5c_surface_t *c5s = data; cairo_5c_tool_t *tool = c5s->u.window.tool; if (tool->disable == 0) { tool->dirty = 0; gtk_repaint (c5s, 0, 0, 0, 0); } } gdk_threads_leave (); return FALSE; } static void * gtk_thread_main (void *closure) { gdk_threads_enter (); gtk_main (); gdk_threads_leave (); return 0; } /* * Manage the gtk_global object, starting the thread and such */ static void gtk_global_mark (void *object) { } static int gtk_global_free (void *object) { gtk_global_t *gg = object; gdk_threads_enter (); gtk_main_quit (); if (gg == gtk_global) gtk_global = NULL; gdk_threads_leave (); return 1; } static DataType gtk_global_type = { gtk_global_mark, gtk_global_free, "GtkGlobal" }; static gtk_global_t * create_gtk_global (void) { ENTER (); static int been_here = 0; static int argc = 1; static char *args[] = { "nickle", 0 }; static char **argv = args; gtk_global_t *gg; if (!been_here) { XInitThreads (); g_thread_init (NULL); gdk_threads_init (); been_here = 1; } gdk_threads_enter (); if (!gtk_init_check (&argc, &argv)) { const char *display_name_arg = gdk_get_display_arg_name (); RaiseStandardException (exception_open_error, "cannot open X display", 0, NewStrString (display_name_arg)); RETURN (Void); } gg = ALLOCATE (>k_global_type, sizeof (gtk_global_t)); gg->dpy = gdk_x11_get_default_xdisplay (); pthread_create (&gg->gtk_thread, 0, gtk_thread_main, gg); if (!gtk_global) gtk_global = gg; gdk_threads_leave (); RETURN (gg); } /* * manage a the gtk piece of an xlib surface */ static void gtk_tool_mark (void *object) { cairo_5c_tool_t *tool = object; MemReference (tool->global); } /* * Called from nickle with gdk lock not held */ static int gtk_tool_free (void *object) { cairo_5c_tool_t *tool = object; gdk_threads_enter (); if (tool->window) { gtk_widget_destroy (tool->window); tool->window = NULL; tool->drawing_area = NULL; } gdk_threads_leave (); return 1; } static DataType gtk_tool_type = { gtk_tool_mark, gtk_tool_free, "GtkTool" }; /* * Called from nickle with gdk lock not held */ Bool cairo_5c_tool_create (cairo_5c_surface_t *c5s, char *name, int width, int height) { ENTER (); gtk_global_t *gg = gtk_global ? gtk_global : create_gtk_global (); cairo_5c_tool_t *tool; Display *dpy; if (aborting) { EXIT (); return False; } tool = ALLOCATE (>k_tool_type, sizeof (cairo_5c_tool_t)); gdk_threads_enter (); dpy = gg->dpy; tool->global = gg; tool->dirty = 0; tool->disable = 0; c5s->dirty = False; c5s->recv_events = Void; c5s->u.window.curpix = 0; c5s->u.window.pixmap = 0; c5s->u.window.send_events = 0; c5s->u.window.tool = tool; if (!width) width = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3; if (!height) height = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3; tool->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW(tool->window), width, height); gtk_window_set_title (GTK_WINDOW (tool->window), name); tool->drawing_area = gtk_drawing_area_new (); GTK_DRAWING_AREA (tool->drawing_area)->draw_data = c5s; gtk_container_add (GTK_CONTAINER(tool->window), tool->drawing_area); g_signal_connect (GTK_OBJECT (tool->drawing_area), "expose_event", (GtkSignalFunc) expose_event, NULL); g_signal_connect (GTK_OBJECT(tool->drawing_area),"configure_event", (GtkSignalFunc) configure_event, NULL); g_signal_connect (GTK_OBJECT (tool->window), "delete_event", (GtkSignalFunc) delete_event, NULL); g_signal_connect (GTK_OBJECT (tool->drawing_area), "motion_notify_event", (GtkSignalFunc) motion_notify_event, NULL); g_signal_connect (GTK_OBJECT (tool->drawing_area), "button_press_event", (GtkSignalFunc) button_press_event, NULL); g_signal_connect (GTK_OBJECT (tool->drawing_area), "button_release_event", (GtkSignalFunc) button_release_event, NULL); gtk_widget_set_events (tool->drawing_area, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); gtk_widget_realize (tool->window); gtk_widget_realize (tool->drawing_area); gdk_window_set_back_pixmap (GTK_WIDGET(tool->drawing_area)->window, NULL, FALSE); gtk_widget_show (tool->drawing_area); gtk_widget_show (tool->window); /* create the pixmap */ configure_event (tool->drawing_area, 0); gdk_threads_leave (); EXIT (); return True; } /* * called from nickle with the gdk lock not held */ Bool cairo_5c_tool_destroy (cairo_5c_surface_t *c5s) { cairo_5c_tool_t *tool = c5s->u.window.tool; gdk_threads_enter (); gtk_widget_hide (tool->window); if (c5s->u.window.pixmap) { gdk_drawable_unref (c5s->u.window.pixmap); c5s->u.window.pixmap = NULL; } gdk_threads_leave (); /* let nickle allocator free it */ return True; } void cairo_5c_tool_mark (cairo_5c_surface_t *c5s) { MemReference (c5s->u.window.tool); } void cairo_5c_tool_dirty (cairo_5c_surface_t *c5s) { cairo_5c_tool_t *tool = c5s->u.window.tool; if (!tool->dirty) { tool->dirty = 1; if (tool->disable == 0) { g_timeout_add (16, gtk_repaint_timeout, c5s); } } } Bool cairo_5c_tool_disable (cairo_5c_surface_t *c5s) { cairo_5c_tool_t *tool = c5s->u.window.tool; ++tool->disable; return True; } /* * Called from nickle with gdk lock not held. As no gtk/gdk * functions are called, I don't think we need to grab it. */ Bool cairo_5c_tool_enable (cairo_5c_surface_t *c5s) { cairo_5c_tool_t *tool = c5s->u.window.tool; if (!tool->disable) return False; --tool->disable; if (!tool->disable && tool->dirty) g_timeout_add (0, gtk_repaint_timeout, c5s); return True; } Display * cairo_5c_tool_display (cairo_5c_surface_t *c5s) { cairo_5c_tool_t *tool = c5s->u.window.tool; return tool->global->dpy; } @ 1.10 log @2005-07-07 Keith Packard * cairo-5c.h: * cairo.c: (do_Cairo_status_to_string): * examples/fob.5c: * gtk.c: (create_gtk_global): * init.c: (nickle_init): * pattern.c: (do_Cairo_Pattern_add_color_stop_rgba), (do_Cairo_Pattern_add_color_stop_rgb), (do_Cairo_Pattern_set_matrix), (do_Cairo_Pattern_set_extend), (do_Cairo_Pattern_set_filter): Match current cairo API. Use XInitThreads, as it's necessary for stable operation. Requires at least one bug fix not yet in Xlib CVS to work @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.9 2005/05/18 06:21:15 keithp Exp $ a35 1 #define GTK_DISABLE_DEPRECATED a36 2 #include #include a51 1 GdkPixmap *pixmap; a65 1 cairo_5c_tool_t *tool = c5s->u.window.tool; d79 1 a79 1 if (tool->pixmap) d82 1 a82 1 tool->pixmap, 0, 0, 0, 0, d85 1 a85 1 gdk_drawable_unref (tool->pixmap); d87 1 a87 2 tool->pixmap = pixmap; c5s->u.window.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(tool->pixmap)); d98 1 a98 1 cairo_5c_tool_t *tool = c5s->u.window.tool; d102 1 a102 1 tool->pixmap, d127 1 a127 1 if (tool->pixmap) d129 2 a130 2 gdk_drawable_unref (tool->pixmap); tool->pixmap = NULL; d211 1 a211 1 GdkPixmap *pixmap = tool->pixmap; a349 5 if (tool->pixmap) { gdk_drawable_unref (tool->pixmap); tool->pixmap = NULL; } a380 1 tool->pixmap = 0; d384 3 a432 3 /* fill in the c5s window structure */ c5s->u.window.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(tool->pixmap)); d448 5 @ 1.9 log @2005-05-17 Keith Packard * cairo-5c.h: * cairo.5c: * cairo.c: (cairo_5c_get), (do_Cairo_create), (cairo_5c_dirty), (cairo_5c_enable), (cairo_5c_disable), (do_Cairo_get_target): * draw.c: (do_Cairo_paint), (do_Cairo_paint_with_alpha), (do_Cairo_mask), (do_Cairo_mask_surface), (do_Cairo_fill_preserve), (do_Cairo_stroke_preserve), (path_elt_new), (path_array), (do_Cairo_copy_path), (do_Cairo_copy_path_flat), (do_Cairo_append_path): * event.c: (do_Cairo_Surface_open_event): * examples/animate.5c: * examples/draw.5c: * examples/fob.5c: * examples/metrics.5c: * examples/sin.5c: * examples/spin.5c: * examples/spinman.5c: * examples/test.5c: * gstate.c: (do_Cairo_set_source_surface), (do_Cairo_identity_matrix), (do_Cairo_transform), (do_Cairo_user_to_device), (do_Cairo_user_to_device_distance), (do_Cairo_device_to_user), (do_Cairo_device_to_user_distance), (do_Cairo_reset_clip), (do_Cairo_clip_preserve): * gtk.c: (create_gtk_global): * init.c: (init_types), (nickle_init): * pattern.c: (do_Cairo_Pattern_create_for_surface), (do_Cairo_Pattern_add_color_stop_rgba), (do_Cairo_Pattern_add_color_stop_rgb): * surface.c: (cairo_5c_surface_get), (cairo_5c_surface_mark), (cairo_5c_surface_destroy), (do_Cairo_Surface_write_to_png), (do_Cairo_Surface_write_to_png_file), (do_Cairo_Surface_set_device_offset), (do_Cairo_Surface_create_similar), (do_Cairo_Surface_finish), (do_Cairo_Surface_destroy), (do_Cairo_Surface_width), (do_Cairo_Surface_height), (do_Cairo_Image_surface_create), (do_Cairo_Image_surface_create_from_png), (do_Cairo_Image_surface_create_from_png_file), (do_Cairo_Pdf_surface_create): * text.c: (do_Cairo_select_font_face), (do_Cairo_get_font_matrix): Another round of API changes for cairo 0.5, the putative final API structure. @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.8 2005/05/02 20:24:38 keithp Exp $ a302 1 /* trust to gdk to lock the display; Xlib is horribly broken */ @ 1.8 log @2005-05-02 Keith Packard * cairo-5c.h: * cairo.5c: * cairo.c: (cairo_5c_dirty), (cairo_5c_enable), (cairo_5c_disable), (do_Cairo_get_target_surface): * event.c: (do_Cairo_Surface_open_event): * gstate.c: (do_Cairo_set_source_rgb), (do_Cairo_set_source_rgba), (do_Cairo_get_matrix), (do_Cairo_concat_matrix), (do_Cairo_set_matrix), (do_Cairo_get_operator), (do_Cairo_get_tolerance), (do_Cairo_get_current_point), (do_Cairo_get_fill_rule), (do_Cairo_get_line_width), (do_Cairo_get_line_cap), (do_Cairo_get_line_join), (do_Cairo_get_miter_limit): * gtk.c: (delete_drawing_area), (motion_notify_event), (button_press_event), (button_release_event), (gtk_repaint_timeout), (gtk_thread_main), (gtk_global_free), (create_gtk_global), (cairo_5c_tool_dirty), (cairo_5c_tool_enable): * init.c: (init_types), (nickle_init): * matrix.c: (cairo_matrix_part), (new_cairo_matrix): * pattern.c: (do_Cairo_set_source), (do_Cairo_get_source), (do_Cairo_Pattern_set_matrix), (do_Cairo_Pattern_get_matrix): * surface.c: (cairo_5c_surface_get), (cairo_5c_surface_mark), (cairo_5c_surface_destroy), (do_Cairo_Surface_create_image), (do_Cairo_Surface_write_to_png): * text.c: (do_Cairo_set_font), (do_Cairo_set_font_size), (do_Cairo_set_font_matrix), (do_Cairo_font_extents): Match cairo API as of today. * examples/draw.5c: * examples/fob.5c: * examples/graph.5c: * examples/grid.5c: * examples/led.5c: * examples/pie-new.5c: * examples/pie.5c: * examples/rottext.5c: * examples/sin.5c: * examples/spin-cairo.5c: * examples/spin.5c: * examples/spinman.5c: * examples/test.5c: * examples/text45.5c: Update examples to match API changes @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.7 2005/02/11 21:15:46 keithp Exp $ d304 1 a304 1 /* XInitThreads (); */ @ 1.7 log @2005-01-02 Keith Packard * cairo-5c.h: Add do_Cairo_copy_page and do_Cairo_show_page. Track whether copy_page/show_page have ever been called so that they can be when the surface is destroyed. * cairo.c: (cairo_5c_free), (cairo_5c_dirty): * draw.c: (do_Cairo_arc), (do_Cairo_arc_negative), (do_Cairo_copy_page), (do_Cairo_show_page): Fix arc arguments * event.c: (do_Cairo_Surface_open_event): * gtk.c: (cairo_5c_tool_destroy): * init.c: (nickle_init): * surface.c: (cairo_5c_surface_mark), (cairo_5c_surface_destroy), (cairo_5c_surface_free), (do_Cairo_Surface_create_window), (do_Cairo_Surface_create_png), (do_Cairo_Surface_create_ps), (do_Cairo_Surface_create_similar), (do_Cairo_Surface_destroy): dunno @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.6 2004/12/24 09:00:10 keithp Exp $ d62 2 a63 1 * any memory managed by nickle d97 3 d115 3 d126 1 d129 1 d141 3 d151 3 d161 1 d165 1 d171 3 d181 1 d185 1 d190 3 d200 1 d204 1 d209 3 d238 3 d244 1 a244 4 cairo_5c_surface_t *c5s = data; cairo_5c_tool_t *tool = c5s->u.window.tool; if (tool->disable == 0) d246 8 a253 2 tool->dirty = 0; gtk_repaint (c5s, 0, 0, 0, 0); d255 1 d262 1 a282 1 gdk_threads_leave (); d285 1 d303 2 a304 1 XInitThreads (); d309 1 a309 1 d326 1 d342 3 d368 4 d451 3 a481 1 gdk_threads_enter (); a482 1 gdk_threads_leave (); d496 4 a508 2 { gdk_threads_enter (); a509 2 gdk_threads_leave (); } @ 1.6 log @2004-12-24 Keith Packard * cairo-5c.h: * cairo.5c: * cairo.c: (do_Cairo_set_target_surface): * gtk.c: (delete_drawing_area), (gtk_tool_free), (cairo_5c_tool_create), (cairo_5c_tool_destroy): * init.c: (nickle_init): * surface.c: (create_cairo_window), (cairo_5c_surface_get), (do_Cairo_Surface_create_window): Handle window delete more gracefully; report exception on drawing, report 'delete' event to event reader. Have default surface creation code re-create a surface when the old default surface has been destroyed. @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.5 2004/12/24 00:09:24 keithp Exp $ d407 5 @ 1.5 log @2004-12-23 Keith Packard * examples/grid.5c: Destroy context to flush file * gtk.c: (gtk_thread_main): call gdk_threads_leave on thread exit to release mutex @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.4 2004/12/23 22:39:40 keithp Exp $ d115 1 d122 8 d312 1 d326 1 a326 1 cairo_5c_tool_create (cairo_5c_surface_t *c5s, int width, int height) d361 1 d407 1 a407 14 cairo_5c_tool_t *tool = c5s->u.window.tool; gdk_threads_enter (); if (tool->window) { gtk_widget_destroy (tool->window); tool->window = NULL; } if (tool->pixmap) { gdk_drawable_unref (tool->pixmap); tool->pixmap = NULL; } gdk_threads_leave (); @ 1.4 log @2004-12-23 Keith Packard * Makefile.am: * cairo-5c.h: * cairo.5c: * cairo.c: (cairo_5c_get), (cairo_5c_mark), (cairo_5c_free), (cairo_foreign_mark), (cairo_foreign_free), (do_Cairo_create), (cairo_5c_dirty), (cairo_5c_enable), (cairo_5c_disable), (do_Cairo_set_target_surface), (do_Cairo_current_target_surface), (do_Cairo_destroy), (do_Cairo_copy), (do_Cairo_status), (do_Cairo_status_string), (do_Cairo_enable), (do_Cairo_disable): * draw.c: (do_Cairo_new_path), (do_Cairo_move_to), (do_Cairo_line_to), (do_Cairo_curve_to), (do_Cairo_arc), (do_Cairo_arc_negative), (do_Cairo_rel_move_to), (do_Cairo_rel_line_to), (do_Cairo_rel_curve_to), (do_Cairo_rectangle), (do_Cairo_close_path), (do_Cairo_fill), (do_Cairo_stroke), (do_Cairo_in_stroke), (do_Cairo_in_fill), (do_Cairo_stroke_extents), (do_Cairo_fill_extents), (do_Cairo_current_path_list), (do_Cairo_current_path_flat_list): * event.c: (do_Cairo_Surface_open_event): * examples/draw.5c: * examples/graph.5c: * examples/grid.5c: * examples/rottext.5c: * gstate.c: (do_Cairo_save), (do_Cairo_restore), (do_Cairo_set_operator), (do_Cairo_set_rgb_color), (do_Cairo_set_alpha), (do_Cairo_set_tolerance), (do_Cairo_set_fill_rule), (do_Cairo_set_line_width), (do_Cairo_set_line_cap), (do_Cairo_set_line_join), (do_Cairo_set_dash), (do_Cairo_set_miter_limit), (do_Cairo_identity_matrix), (do_Cairo_default_matrix), (do_Cairo_translate), (do_Cairo_scale), (do_Cairo_rotate), (do_Cairo_current_matrix), (do_Cairo_concat_matrix), (do_Cairo_set_matrix), (do_Cairo_transform_point), (do_Cairo_transform_distance), (do_Cairo_inverse_transform_point), (do_Cairo_inverse_transform_distance), (do_Cairo_init_clip), (do_Cairo_clip), (do_Cairo_current_operator), (do_Cairo_current_rgb_color), (do_Cairo_current_alpha), (do_Cairo_current_tolerance), (do_Cairo_current_point), (do_Cairo_current_fill_rule), (do_Cairo_current_line_width), (do_Cairo_current_line_cap), (do_Cairo_current_line_join), (do_Cairo_current_miter_limit): * gtk.c: (configure_event), (expose_event), (delete_drawing_area), (delete_event), (motion_notify_event), (button_press_event), (button_release_event), (gtk_repaint), (gtk_repaint_timeout), (gtk_global_mark), (gtk_global_free), (create_gtk_global), (gtk_tool_mark), (gtk_tool_free), (cairo_5c_tool_create), (cairo_5c_tool_destroy), (cairo_5c_tool_mark), (cairo_5c_tool_dirty), (cairo_5c_tool_disable), (cairo_5c_tool_enable), (cairo_5c_tool_display): * init.c: (init_types), (nickle_init): * pattern.c: (mark_cairo_pattern), (make_pattern_value), (do_Cairo_set_pattern), (do_Cairo_current_pattern), (do_Cairo_Pattern_create_for_surface): * surface.c: (create_cairo_window), (cairo_5c_surface_get), (cairo_5c_surface_mark), (cairo_5c_surface_free), (cairo_surface_foreign_mark), (cairo_surface_foreign_free), (do_Cairo_Surface_create_window), (do_Cairo_Surface_create_png), (do_Cairo_Surface_create_ps), (do_Cairo_Surface_create_similar), (do_Cairo_Surface_destroy), (do_Cairo_Surface_width), (do_Cairo_Surface_height): * text.c: (do_Cairo_select_font), (do_Cairo_set_font), (do_Cairo_scale_font), (do_Cairo_transform_font), (do_Cairo_current_font_extents), (do_Cairo_show_text), (do_Cairo_text_path), (do_Cairo_text_extents): Split cairo_t and cairo_surface_t functions apart, permitting more complex programs to be written that use more than a single window. Switch allocations around to mostly use the nickle memory allocator now. Requires updated nickle bits that expose this change in the foreign object API. @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.3 2004/12/17 02:09:45 keithp Exp $ d217 1 @ 1.3 log @2004-12-16 Keith Packard * Makefile.am: * autogen.sh: * cairo.5c: * configure.in: Add cairo.5c and install it to nickle libary * cairo-5c.h: * draw.c: (do_Cairo_rectangle), (do_Cairo_in_stroke), (do_Cairo_in_fill), (do_Cairo_stroke_extents), (do_Cairo_fill_extents), (cairo_5c_move_to), (do_Cairo_current_path), (do_Cairo_current_path_flat): * gstate.c: (do_Cairo_set_operator), (do_Cairo_set_fill_rule), (do_Cairo_set_line_cap), (do_Cairo_set_line_join), (do_Cairo_set_dash), (do_Cairo_set_miter_limit), (do_Cairo_default_matrix), (do_Cairo_transform_point), (do_Cairo_transform_distance), (do_Cairo_inverse_transform_point), (do_Cairo_inverse_transform_distance), (do_Cairo_init_clip), (do_Cairo_clip), (do_Cairo_current_operator), (do_Cairo_current_rgb_color), (do_Cairo_current_alpha), (do_Cairo_current_tolerance), (do_Cairo_current_point), (do_Cairo_current_fill_rule), (do_Cairo_current_line_width), (do_Cairo_current_line_cap), (do_Cairo_current_line_join), (do_Cairo_current_miter_limit): * init.c: (make_typedef), (init_types), (EnumIntPart), (IntToEnum), (nickle_init): * text.c: (do_Cairo_select_font), (do_Cairo_text_extents), (do_Cairo_select_ft_font): Add a bunch more bindings. Still more to do, especially the path walkers. Switch from int constants to enums for enumerated types. * gtk.c: (motion_notify_event), (button_press_event), (button_release_event), (cairo_5c_window_new): * surface.c: (do_Cairo_new): Add mouse input support. * examples/animate.5c: * examples/cairo.5c: * examples/draw.5c: * examples/graph.5c: * examples/pie.5c: * examples/rottext.5c: * examples/sin.5c: * examples/test.5c: Change examples to use cairo.5c file with autoimport @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.2 2004/12/15 07:04:50 keithp Exp $ d42 15 d58 1 a58 8 typedef struct _cairo_5c_gtk { cairo_5c_x_t x; int dirty; int disable; GtkWidget *window; GtkWidget *drawing_area; GdkPixmap *pixmap; } cairo_5c_gtk_t; d60 4 d68 2 a69 1 cairo_5c_gtk_t *c5cg = GTK_DRAWING_AREA (widget)->draw_data; d71 2 a72 2 c5cg->x.width = widget->allocation.width; c5cg->x.height = widget->allocation.height; d83 1 a83 1 if (c5cg->pixmap) d86 1 a86 1 c5cg->pixmap, 0, 0, 0, 0, d89 1 a89 1 gdk_pixmap_unref (c5cg->pixmap); d91 2 a92 2 c5cg->pixmap = pixmap; c5cg->x.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(c5cg->pixmap)); d99 2 a100 1 cairo_5c_gtk_t *c5cg = GTK_DRAWING_AREA (widget)->draw_data; d104 1 a104 1 c5cg->pixmap, d108 14 d123 4 d133 1 a133 1 cairo_5c_gtk_t *c5cg = GTK_DRAWING_AREA (widget)->draw_data; d135 1 a135 1 if (c5cg->x.send_events) d137 1 a137 1 fprintf (c5cg->x.send_events, "%d motion %g %g\n", d139 1 a139 1 fflush (c5cg->x.send_events); d148 1 a148 1 cairo_5c_gtk_t *c5cg = GTK_DRAWING_AREA (widget)->draw_data; d150 1 a150 1 if (c5cg->x.send_events) d152 1 a152 1 fprintf (c5cg->x.send_events, "%d press %d %g %g\n", d154 1 a154 1 fflush (c5cg->x.send_events); d162 1 a162 1 cairo_5c_gtk_t *c5cg = GTK_DRAWING_AREA (widget)->draw_data; d164 1 a164 1 if (c5cg->x.send_events) d166 1 a166 1 fprintf (c5cg->x.send_events, "%d release %d %g %g\n", d168 1 a168 1 fflush (c5cg->x.send_events); d173 2 a174 3 static cairo_5c_gtk_t * cairo_5c_window_new (int width, int height) d176 3 a178 14 cairo_5c_gtk_t *c5cg = malloc (sizeof (cairo_5c_gtk_t)); Display *dpy; c5cg->pixmap = 0; c5cg->x.send_events = 0; c5cg->x.dpy = gdk_x11_get_default_xdisplay (); dpy = c5cg->x.dpy; if (!width) width = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3; if (!height) height = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3; c5cg->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW(c5cg->window), width, height); d180 6 a185 1 c5cg->drawing_area = gtk_drawing_area_new (); d187 9 a195 50 GTK_DRAWING_AREA (c5cg->drawing_area)->draw_data = c5cg; gtk_container_add (GTK_CONTAINER(c5cg->window), c5cg->drawing_area); g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "expose_event", (GtkSignalFunc) expose_event, NULL); g_signal_connect (GTK_OBJECT(c5cg->drawing_area),"configure_event", (GtkSignalFunc) configure_event, NULL); g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "motion_notify_event", (GtkSignalFunc) motion_notify_event, NULL); g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "button_press_event", (GtkSignalFunc) button_press_event, NULL); g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "button_release_event", (GtkSignalFunc) button_release_event, NULL); gtk_widget_set_events (c5cg->drawing_area, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); gtk_widget_realize (c5cg->window); gtk_widget_realize (c5cg->drawing_area); gdk_window_set_back_pixmap (GTK_WIDGET(c5cg->drawing_area)->window, NULL, FALSE); gtk_widget_show (c5cg->drawing_area); gtk_widget_show (c5cg->window); configure_event (c5cg->drawing_area, 0); return c5cg; } void repaint_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h) { cairo_5c_gtk_t *c5cg = (cairo_5c_gtk_t *) c5cx; GtkWidget *widget = c5cg->drawing_area; Window xwin = GDK_WINDOW_XID (widget->window); GdkPixmap *pixmap = c5cg->pixmap; Pixmap xpix = GDK_PIXMAP_XID (pixmap); Display *dpy = gdk_x11_get_default_xdisplay (); GC xgc = GDK_GC_XGC(widget->style->white_gc); if (xwin && xpix && xgc) { if (w == 0) w = c5cg->x.width - x; if (h == 0) h = c5cg->x.height - y; XCopyArea (dpy, xpix, xwin, xgc, x, y, w, h, x, y); XFlush (dpy); d202 2 a203 1 cairo_5c_gtk_t *c5cg = data; d205 1 a205 1 if (c5cg->disable == 0) d207 2 a208 2 c5cg->dirty = 0; repaint_x (&c5cg->x, 0, 0, 0, 0); d220 22 a241 1 static cairo_5c_gtk_t *c5cg; d243 2 a244 2 cairo_5c_x_t * start_x (int width, int height) d246 2 a247 1 pthread_t gtk_thread; d251 1 d253 1 a253 1 if (!c5cg) d258 63 a320 2 gtk_init (&argc, &argv); c5cg = cairo_5c_window_new (width, height); d322 4 a325 1 pthread_create (>k_thread, 0, gtk_thread_main, c5cg); d327 83 a409 1 return &c5cg->x; d413 1 a413 1 dirty_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h) d415 2 a416 1 cairo_5c_gtk_t *c5cg = (cairo_5c_gtk_t *) c5cx; d418 6 a423 1 if (!c5cg->dirty) d425 2 a426 2 c5cg->dirty = 1; if (c5cg->disable == 0) d429 1 a429 1 g_timeout_add (16, gtk_repaint_timeout, c5cg); d436 1 a436 1 disable_x (cairo_5c_x_t *c5cx) d438 1 a438 1 cairo_5c_gtk_t *c5cg = (cairo_5c_gtk_t *) c5cx; d440 1 a440 1 ++c5cg->disable; d445 1 a445 1 enable_x (cairo_5c_x_t *c5cx) d447 1 a447 1 cairo_5c_gtk_t *c5cg = (cairo_5c_gtk_t *) c5cx; d449 1 a449 1 if (!c5cg->disable) d451 2 a452 2 --c5cg->disable; if (!c5cg->disable && c5cg->dirty) d455 1 a455 1 g_timeout_add (0, gtk_repaint_timeout, c5cg); d460 8 @ 1.2 log @2004-12-14 Keith Packard * cairo-5c.h: * gtk.c: (gtk_repaint_timeout), (dirty_x), (disable_x), (enable_x): * init.c: (nickle_init): * surface.c: (enable_cairo_5c), (disable_cairo_5c), (do_Cairo_enable), (do_Cairo_disable): Add enable/disable to take advantage of double buffering for smooth animation. * examples/animate.5c: Use enable/disable to smooth this animation out @ text @d1 1 a1 1 /* $Id: gtk.c,v 1.1 2004/12/14 08:34:27 keithp Exp $ d98 44 d149 1 d170 6 a175 6 #if 0 gtk_signal_connect (GTK_OBJECT (c5cg->drawing_area), "motion_notify_event", (GtkSignalFunc) motion_notify_event, NULL); gtk_signal_connect (GTK_OBJECT (c5cg->drawing_area), "button_press_event", (GtkSignalFunc) button_press_event, NULL); #endif d180 2 a181 2 | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); @ 1.1 log @2004-12-14 Keith Packard * .cvsignore: * Makefile.am: * cairo-5c.h: * configure.in: * draw.c: (do_Cairo_fill), (do_Cairo_stroke): * gtk.c: (configure_event), (expose_event), (cairo_5c_window_new), (repaint_x), (gtk_repaint_timeout), (gtk_thread_main), (start_x), (dirty_x): * init.c: (nickle_init): * surface.c: (get_cairo_5c), (free_cairo_5c), (dirty_cairo_5c), (do_Cairo_new): * text.c: (do_Cairo_show_text): Replace lame Xlib-based output with more capable gtk+ based output, including backing storage and resize handling. Input still isn't hooked up. * gstate.c: (do_Cairo_current_matrix), (do_Cairo_set_matrix): Add current_matrix and set_matrix functions; these only do affine matrices. * examples/animate.5c: * examples/pie.5c: * examples/rottext.5c: * examples/sin.5c: * examples/test.5c: Update examples to use installed library @ text @d1 1 a1 1 /* $Id: $ d46 1 d175 5 a179 2 c5cg->dirty = 0; repaint_x (&c5cg->x, 0, 0, 0, 0); d221 28 d250 1 a250 1 g_timeout_add (16, gtk_repaint_timeout, c5cg); d253 1 @