Commit 8621807a authored by Mikael Magnusson's avatar Mikael Magnusson

plug-ins: imagemap, port to cairo

parent e012caf1
......@@ -39,8 +39,8 @@
static gboolean circle_is_valid(Object_t *obj);
static Object_t *circle_clone(Object_t *obj);
static void circle_assign(Object_t *obj, Object_t *des);
static void circle_draw(Object_t* obj, GdkWindow *window, GdkGC* gc);
static void circle_draw_sashes(Object_t* obj, GdkWindow *window, GdkGC* gc);
static void circle_draw(Object_t* obj, cairo_t *cr);
static void circle_draw_sashes(Object_t* obj, cairo_t *cr);
static MoveSashFunc_t circle_near_sash(Object_t *obj, gint x, gint y);
static gboolean circle_point_is_on(Object_t *obj, gint x, gint y);
static void circle_get_dimensions(Object_t *obj, gint *x, gint *y,
......@@ -128,20 +128,20 @@ circle_assign(Object_t *obj, Object_t *des)
}
static void
circle_draw(Object_t *obj, GdkWindow *window, GdkGC *gc)
circle_draw(Object_t *obj, cairo_t *cr)
{
Circle_t *circle = ObjectToCircle(obj);
draw_circle(window, gc, FALSE, circle->x, circle->y, circle->r);
draw_circle(cr, circle->x, circle->y, circle->r);
}
static void
circle_draw_sashes(Object_t *obj, GdkWindow *window, GdkGC *gc)
circle_draw_sashes(Object_t *obj, cairo_t *cr)
{
Circle_t *circle = ObjectToCircle(obj);
draw_sash(window, gc, circle->x - circle->r, circle->y - circle->r);
draw_sash(window, gc, circle->x + circle->r, circle->y - circle->r);
draw_sash(window, gc, circle->x - circle->r, circle->y + circle->r);
draw_sash(window, gc, circle->x + circle->r, circle->y + circle->r);
draw_sash(cr, circle->x - circle->r, circle->y - circle->r);
draw_sash(cr, circle->x + circle->r, circle->y - circle->r);
draw_sash(cr, circle->x - circle->r, circle->y + circle->r);
draw_sash(cr, circle->x + circle->r, circle->y + circle->r);
}
static gint sash_x;
......
......@@ -132,7 +132,7 @@ gimp_guides_ok_cb(gpointer data)
}
subcommand_end();
redraw_preview();
preview_redraw();
}
static GimpGuidesDialog_t*
......
......@@ -78,7 +78,7 @@ insert_point_command_execute(Command_t *parent)
command->edge);
command->position = command->edge;
}
redraw_preview();
preview_redraw();
return CMD_APPEND;
}
......@@ -92,5 +92,5 @@ insert_point_command_undo(Command_t *parent)
g_free(p->data);
polygon->points = g_list_remove_link(polygon->points, p);
redraw_preview(); /* Fix me! */
preview_redraw(); /* Fix me! */
}
......@@ -103,8 +103,6 @@ button_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
if (command->moved_first_time) {
command->moved_first_time = FALSE;
command->cursor = preview_set_cursor(command->preview, GDK_FLEUR);
gdk_gc_set_function(command->preferences->normal_gc, GDK_XOR);
gdk_gc_set_function(command->preferences->selected_gc, GDK_XOR);
hide_url();
}
......@@ -118,14 +116,15 @@ button_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
dy = command->image_height - command->obj_height - command->obj_y;
if (dx || dy) {
command->start_x = get_real_coord((gint) event->x);
command->start_y = get_real_coord((gint) event->y);
command->obj_x += dx;
command->obj_y += dy;
object_draw(obj, gtk_widget_get_window (widget));
object_move(obj, dx, dy);
object_draw(obj, gtk_widget_get_window (widget));
preview_redraw ();
}
}
......@@ -141,8 +140,6 @@ button_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
if (!command->moved_first_time) {
preview_set_cursor(command->preview, command->cursor);
gdk_gc_set_function(command->preferences->normal_gc, GDK_COPY);
gdk_gc_set_function(command->preferences->selected_gc, GDK_COPY);
show_url();
}
command->obj_x -= command->obj_start_x;
......
......@@ -105,10 +105,10 @@ sash_move(GtkWidget *widget, GdkEventMotion *event, gpointer data)
command->x = x;
command->y = y;
object_draw(obj, gtk_widget_get_window (widget));
command->sash_func(obj, dx, dy);
object_emit_geometry_signal(obj);
object_draw(obj, gtk_widget_get_window (widget));
preview_redraw ();
}
static void
......@@ -123,8 +123,8 @@ sash_end(GtkWidget *widget, GdkEventButton *event, gpointer data)
sash_end, data);
if (obj->class->normalize)
object_normalize(obj);
gdk_gc_set_function(get_preferences()->selected_gc, GDK_COPY);
preview_thaw();
preview_unset_tmp_obj(command->obj);
preview_redraw();
show_url();
}
......@@ -134,12 +134,11 @@ move_sash_command_execute(Command_t *parent)
MoveSashCommand_t *command = (MoveSashCommand_t*) parent;
hide_url();
preview_freeze();
g_signal_connect(command->widget, "button-release-event",
G_CALLBACK (sash_end), command);
g_signal_connect(command->widget, "motion-notify-event",
G_CALLBACK (sash_move), command);
gdk_gc_set_function(get_preferences()->selected_gc, GDK_XOR);
preview_set_tmp_obj(command->obj);
return CMD_APPEND;
}
......@@ -83,13 +83,14 @@ select_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
SelectRegionCommand_t *command = (SelectRegionCommand_t*) data;
Object_t *obj = command->obj;
Rectangle_t *rectangle = ObjectToRectangle(obj);
gint x = get_real_coord((gint) event->x);
gint y = get_real_coord((gint) event->y);
object_draw(obj, gtk_widget_get_window (widget));
rectangle->width = x - rectangle->x;
rectangle->height = y - rectangle->y;
object_draw(obj, gtk_widget_get_window (widget));
preview_redraw ();
}
static void
......@@ -106,9 +107,7 @@ select_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
g_signal_handlers_disconnect_by_func(widget,
select_release, data);
object_draw(obj, gtk_widget_get_window (widget));
object_normalize(obj);
gdk_gc_set_function(get_preferences()->normal_gc, GDK_COPY);
id = object_list_add_select_cb(command->list, select_one_object, command);
count = object_list_select_region(command->list, rectangle->x, rectangle->y,
......@@ -121,7 +120,9 @@ select_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
if (command->unselect_command->sub_commands)
command_list_add(&command->parent);
}
object_unref(obj);
preview_unset_tmp_obj (command->obj);
preview_redraw ();
}
static CmdExecuteValue_t
......@@ -130,12 +131,12 @@ select_region_command_execute(Command_t *parent)
SelectRegionCommand_t *command = (SelectRegionCommand_t*) parent;
command->obj = create_rectangle(command->x, command->y, 0, 0);
preview_set_tmp_obj (command->obj);
g_signal_connect(command->widget, "button-release-event",
G_CALLBACK (select_release), command);
g_signal_connect(command->widget, "motion-notify-event",
G_CALLBACK (select_motion), command);
gdk_gc_set_function(get_preferences()->normal_gc, GDK_XOR);
return CMD_IGNORE;
}
......@@ -394,7 +394,7 @@ edit_area_apply_cb(gpointer data)
update_shape(obj);
if (object_was_changed(param))
redraw_preview();
preview_redraw();
}
static void
......@@ -429,7 +429,7 @@ edit_area_cancel_cb(gpointer data)
object_unref(dialog->clone);
if (changed)
redraw_preview();
preview_redraw();
}
static void
......
......@@ -60,7 +60,6 @@ typedef struct {
} GridDialog_t;
static GdkGC *grid_gc;
static gboolean grid_snap = FALSE;
static gint grid_width = 15;
static gint grid_height = 15;
......@@ -88,7 +87,7 @@ grid_settings_ok_cb(gpointer data)
grid_snap = new_snap;
menu_check_grid(grid_snap);
}
redraw_preview();
preview_redraw();
}
static void
......@@ -109,7 +108,7 @@ type_toggled_cb(GtkWidget *widget, gpointer data)
if (gtk_widget_get_state (widget) & GTK_STATE_SELECTED)
{
grid_type = GPOINTER_TO_INT (data);
redraw_preview();
preview_redraw();
}
}
......@@ -118,7 +117,7 @@ toggle_preview_cb(GtkWidget *widget, GridDialog_t *param)
{
param->enable_preview =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
redraw_preview();
preview_redraw();
}
static void
......@@ -127,7 +126,7 @@ grid_assign_value(GtkWidget *widget, gpointer data, gint *value)
GridDialog_t *dialog = (GridDialog_t*) data;
if (dialog->enable_preview) {
*value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
redraw_preview(); /* Fix me! */
preview_redraw(); /* Fix me! */
}
}
......@@ -326,56 +325,47 @@ do_grid_settings_dialog(void)
}
static void
draw_lines(GdkWindow *window, GdkGC* gc, gint width, gint height)
draw_lines(cairo_t *cr, gint width, gint height)
{
gint x, y;
gdouble dash = 4.;
for (x = grid_left; x < width; x += grid_width)
draw_line(window, grid_gc, x, 1, x, height);
for (y = grid_top; y < height; y += grid_height)
draw_line(window, grid_gc, 1, y, width, y);
cairo_set_dash (cr, &dash, 1, 0.);
for (x = grid_left % grid_width; x < width; x += grid_width)
draw_line(cr, x, 1, x, height);
for (y = grid_top % grid_height; y < height; y += grid_height)
draw_line(cr, 1, y, width, y);
}
static void
draw_crosses(GdkWindow *window, GdkGC* gc, gint width, gint height)
draw_crosses(cairo_t *cr, gint width, gint height)
{
gint x, y;
for (x = grid_left; x < width; x += grid_width) {
for (y = grid_top; y < height; y += grid_height) {
draw_line(window, gc, x - 3, y, x + 3, y);
draw_line(window, gc, x, y - 3, x, y + 3);
}
}
gdouble dash[4] = { 7., grid_height - 7., 7., grid_width - 7. };
cairo_set_dash (cr, dash, 2, 4.5 - grid_top);
for (x = grid_left % grid_width; x < width; x += grid_width)
draw_line(cr, x, 1, x, height);
cairo_set_dash (cr, dash+2, 2, 4.5 - grid_left);
for (y = grid_top % grid_height; y < height; y += grid_height)
draw_line(cr, 1, y, width, y);
}
void
draw_grid(GtkWidget *preview)
draw_grid(cairo_t *cr, gint width, gint height)
{
if (grid_snap && grid_type != GRID_HIDDEN)
{
gint width = preview_get_width(preview);
gint height = preview_get_height(preview);
if (!grid_gc)
{
grid_gc = gdk_gc_new(gtk_widget_get_window (preview));
gdk_gc_set_line_attributes(grid_gc, 1, GDK_LINE_ON_OFF_DASH,
GDK_CAP_BUTT, GDK_JOIN_BEVEL);
}
cairo_save (cr);
if (grid_type == GRID_LINES)
{
draw_lines(gtk_widget_get_window (preview), grid_gc, width, height);
draw_lines(cr, width, height);
}
else
{
GtkStyle *style = gtk_widget_get_style (preview);
draw_crosses(gtk_widget_get_window (preview), style->black_gc, width,
height);
draw_crosses(cr, width, height);
}
cairo_restore (cr);
}
}
......@@ -383,7 +373,7 @@ void
toggle_grid(void)
{
grid_snap = !grid_snap;
redraw_preview();
preview_redraw();
}
static gint
......
......@@ -24,7 +24,7 @@
#define _IMAP_GRID_H
void do_grid_settings_dialog (void);
void draw_grid (GtkWidget *preview);
void draw_grid (cairo_t *cr, gint width, gint height);
void toggle_grid (void);
void round_to_grid (gint *x, gint *y);
......
......@@ -204,8 +204,8 @@ get_preferences(void)
static void
init_preferences(void)
{
GdkColormap *colormap = gdk_drawable_get_colormap(gtk_widget_get_window (_dlg));
ColorSelData_t *colors = &_preferences.colors;
GdkColormap *colormap = gdk_drawable_get_colormap(gtk_widget_get_window (_dlg));
ColorSelData_t *colors = &_preferences.colors;
colors->normal_fg.red = 0;
colors->normal_fg.green = 0xFFFF;
......@@ -223,6 +223,14 @@ init_preferences(void)
colors->selected_bg.green = 0;
colors->selected_bg.blue = 0xFFFF;
colors->interactive_fg.red = 0xFFFF;
colors->interactive_fg.green = 0;
colors->interactive_fg.blue = 0xFFFF;
colors->interactive_bg.red = 0xFFFF;
colors->interactive_bg.green = 0xFFFF;
colors->interactive_bg.blue = 0;
preferences_load(&_preferences);
gdk_colormap_alloc_color(colormap, &colors->normal_fg, FALSE, TRUE);
......@@ -230,20 +238,6 @@ init_preferences(void)
gdk_colormap_alloc_color(colormap, &colors->selected_fg, FALSE, TRUE);
gdk_colormap_alloc_color(colormap, &colors->selected_bg, FALSE, TRUE);
_preferences.normal_gc = gdk_gc_new(gtk_widget_get_window (_preview->preview));
_preferences.selected_gc = gdk_gc_new(gtk_widget_get_window (_preview->preview));
gdk_gc_set_line_attributes(_preferences.normal_gc, 1, GDK_LINE_DOUBLE_DASH,
GDK_CAP_BUTT, GDK_JOIN_BEVEL);
gdk_gc_set_line_attributes(_preferences.selected_gc, 1,
GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT,
GDK_JOIN_BEVEL);
gdk_gc_set_foreground(_preferences.normal_gc, &colors->normal_fg);
gdk_gc_set_background(_preferences.normal_gc, &colors->normal_bg);
gdk_gc_set_foreground(_preferences.selected_gc, &colors->selected_fg);
gdk_gc_set_background(_preferences.selected_gc, &colors->selected_bg);
mru_set_size(_mru, _preferences.mru_size);
command_list_set_undo_level(_preferences.undo_levels);
}
......@@ -309,76 +303,44 @@ get_real_coord(gint coord)
}
void
draw_line(GdkWindow *window, GdkGC *gc, gint x1, gint y1, gint x2, gint y2)
draw_line(cairo_t *cr, gint x1, gint y1, gint x2, gint y2)
{
gdk_draw_line(window, gc, ZOOMED(x1), ZOOMED(y1), ZOOMED(x2), ZOOMED(y2));
cairo_move_to (cr, ZOOMED (x1) + .5, ZOOMED (y1) + .5);
cairo_line_to (cr, ZOOMED (x2) + .5, ZOOMED (y2) + .5);
cairo_stroke (cr);
}
void
draw_rectangle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y,
gint width, gint height)
{
gdk_draw_rectangle(window, gc, filled, ZOOMED(x), ZOOMED(y),
ZOOMED(width), ZOOMED(height));
}
void
draw_arc(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
gint width, gint height, gint angle1, gint angle2)
{
gdk_draw_arc(window, gc, filled, ZOOMED(x), ZOOMED(y),
ZOOMED(width), ZOOMED(height), angle1, angle2);
cairo_rectangle (cr, ZOOMED (x) + (filled ? 0. : .5),
ZOOMED (y) + (filled ? 0. : .5),
ZOOMED (width), ZOOMED (height));
if (filled)
cairo_fill (cr);
else
cairo_stroke (cr);
}
void
draw_circle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y, gint r)
draw_circle(cairo_t *cr, gint x, gint y, gint r)
{
draw_arc(window, gc, filled, x - r, y - r, 2 * r, 2 * r, 0, 360 * 64);
cairo_arc (cr, ZOOMED (x), ZOOMED (y), ZOOMED (r), 0., 2 * M_PI);
cairo_stroke (cr);
}
void
draw_polygon(GdkWindow *window, GdkGC *gc, GList *list)
draw_polygon(cairo_t *cr, GList *list)
{
gint npoints = g_list_length(list);
GdkPoint *points = g_new(GdkPoint, npoints);
GdkPoint *des = points;
GList *p;
for (p = list; p; p = p->next, des++) {
for (p = list; p; p = p->next) {
GdkPoint *src = (GdkPoint*) p->data;
des->x = ZOOMED(src->x);
des->y = ZOOMED(src->y);
cairo_line_to (cr, ZOOMED (src->x) + .5, ZOOMED (src->y) + .5);
}
gdk_draw_polygon(window, gc, FALSE, points, npoints);
g_free(points);
}
static gboolean _preview_redraw_blocked = FALSE;
static gboolean _pending_redraw = FALSE;
void
preview_freeze(void)
{
_preview_redraw_blocked = TRUE;
}
void
preview_thaw(void)
{
_preview_redraw_blocked = FALSE;
if (_pending_redraw) {
_pending_redraw = FALSE;
redraw_preview();
}
}
void
redraw_preview(void)
{
if (_preview_redraw_blocked)
_pending_redraw = TRUE;
else
preview_redraw(_preview);
cairo_close_path (cr);
cairo_stroke (cr);
}
void
......@@ -389,6 +351,12 @@ set_preview_color (GtkRadioAction *action, GtkRadioAction *current,
set_zoom(_zoom_factor);
}
void
preview_redraw(void)
{
gtk_widget_queue_draw(_preview->preview);
}
void
set_zoom_factor (GtkRadioAction *action, GtkRadioAction *current,
gpointer user_data)
......@@ -625,10 +593,9 @@ do_zoom_out(void)
}
void
draw_shapes(GtkWidget *preview)
draw_shapes(cairo_t *cr)
{
if (!_preview_redraw_blocked)
object_list_draw(_shapes, gtk_widget_get_window (preview));
object_list_draw(_shapes, cr);
}
static void
......@@ -685,7 +652,7 @@ close_current(void)
clear_map_info();
main_set_title(NULL);
set_all_sensitivities();
redraw_preview();
preview_redraw();
object_list_clear_changed(_shapes);
command_list_remove_all();
}
......@@ -719,21 +686,19 @@ do_quit(void)
void
do_undo(void)
{
preview_freeze();
selection_freeze(_selection);
last_command_undo();
selection_thaw(_selection);
preview_thaw();
preview_redraw();
}
void
do_redo(void)
{
preview_freeze();
selection_freeze(_selection);
last_command_redo();
selection_thaw(_selection);
preview_thaw();
preview_redraw();
}
void
......@@ -900,7 +865,7 @@ do_image_size_changed_dialog(void)
object_list_resize(_shapes, per_x, per_y);
}
preview_thaw();
preview_redraw();
gtk_widget_destroy (dialog);
}
......@@ -917,7 +882,6 @@ really_load(gpointer data)
_map_info.map_format = CSIM;
if (_image_width != _map_info.old_image_width ||
_image_height != _map_info.old_image_height) {
preview_freeze();
do_image_size_changed_dialog();
}
} else if (load_ncsa(filename)) {
......@@ -936,7 +900,7 @@ really_load(gpointer data)
selection_thaw(_selection);
main_set_title(filename);
object_list_clear_changed(_shapes);
redraw_preview();
preview_redraw();
}
void
......@@ -1027,13 +991,9 @@ move_sash_selected_objects(gint dx, gint dy, gboolean fast)
dy *= 5;
}
gdk_gc_set_function(_preferences.normal_gc, GDK_XOR);
gdk_gc_set_function(_preferences.selected_gc, GDK_XOR);
object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
object_list_move_sash_selected(_shapes, dx, dy);
object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
gdk_gc_set_function(_preferences.normal_gc, GDK_COPY);
gdk_gc_set_function(_preferences.selected_gc, GDK_COPY);
preview_redraw ();
}
static void
......@@ -1046,13 +1006,9 @@ move_selected_objects(gint dx, gint dy, gboolean fast)
_dx += dx;
_dy += dy;
gdk_gc_set_function(_preferences.normal_gc, GDK_XOR);
gdk_gc_set_function(_preferences.selected_gc, GDK_XOR);
object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
object_list_move_selected(_shapes, dx, dy);
object_list_draw_selected(_shapes, gtk_widget_get_window (_preview->preview));
gdk_gc_set_function(_preferences.normal_gc, GDK_COPY);
gdk_gc_set_function(_preferences.selected_gc, GDK_COPY);
preview_redraw ();
}
static gboolean
......@@ -1067,7 +1023,7 @@ key_timeout_cb(gpointer data)
_dx = _dy = 0;
break;
}
preview_thaw();
preview_redraw();
return FALSE;
}
......@@ -1079,34 +1035,34 @@ key_press_cb(GtkWidget *widget, GdkEventKey *event)
gboolean ctrl = event->state & GDK_CONTROL_MASK;
Command_t *command;
preview_freeze();
if (_timeout)
g_source_remove(_timeout);
_timeout = 0;
switch (event->keyval) {
case GDK_Left:
if (ctrl)
if (ctrl)
move_sash_selected_objects(-1, 0, shift);
else
move_selected_objects(-1, 0, shift);
handled = TRUE;
break;
case GDK_Right:
if (ctrl)
if (ctrl)
move_sash_selected_objects(1, 0, shift);
else
move_selected_objects(1, 0, shift);
handled = TRUE;
break;
case GDK_Up:
if (ctrl)
if (ctrl)
move_sash_selected_objects(0, -1, shift);
else
move_selected_objects(0, -1, shift);
handled = TRUE;
break;
case GDK_Down:
if (ctrl)
if (ctrl)
move_sash_selected_objects(0, 1, shift);
else
move_selected_objects(0, 1, shift);
......@@ -1138,13 +1094,13 @@ key_release_cb(GtkWidget *widget, GdkEventKey *event)
static void
geometry_changed(Object_t *obj, gpointer data)
{
redraw_preview();
preview_redraw();
}
static void
data_changed(Object_t *obj, gpointer data)
{
redraw_preview();
preview_redraw();
set_all_sensitivities();
}
......@@ -1310,10 +1266,14 @@ dialog(GimpDrawable *drawable)
gtk_box_pack_start(GTK_BOX(hbox), tools, FALSE, FALSE, 0);
_preview = make_preview(drawable);
add_preview_motion_event(_preview, G_CALLBACK (preview_move));
add_enter_notify_event(_preview, G_CALLBACK (preview_enter));
add_leave_notify_event(_preview, G_CALLBACK (preview_leave));
add_preview_button_press_event(_preview, G_CALLBACK (button_press));
g_signal_connect(_preview->preview, "motion-notify-event",
G_CALLBACK(preview_move), NULL);
g_signal_connect(_preview->preview, "enter-notify-event",
G_CALLBACK(preview_enter), NULL);
g_signal_connect(_preview->preview, "leave-notify-event",
G_CALLBACK(preview_leave), NULL);
g_signal_connect(_preview->preview, "button-press-event",
G_CALLBACK(button_press), NULL);
gtk_container_add(GTK_CONTAINER(hbox), _preview->window);
object_list_add_geometry_cb(_shapes, geometry_changed, NULL);
......
......@@ -26,6 +26,7 @@
#include "imap_mru.h"
#include "imap_object.h"
#include "imap_preferences.h"
#include "imap_preview.h"
#define PLUG_IN_PROC "plug-in-imagemap"
#define PLUG_IN_BINARY "imagemap"
......@@ -65,15 +66,13 @@ void main_toolbar_set_grid(gboolean active);
void set_zoom(gint zoom_factor);
gint get_real_coord(gint coord);
void draw_line(GdkWindow *window, GdkGC *gc, gint x1, gint y1, gint x2,
void draw_line(cairo_t *cr, gint x1, gint y1, gint x2,
gint y2);
void draw_rectangle(GdkWindow *window, GdkGC *gc, gint filled, gint x, gint y,
void draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y,
gint width, gint height);
void draw_arc(GdkWindow *window, GdkGC