2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 #define GDK_ENABLE_BROKEN
23 #include <gdk/gdkkeysyms.h>
27 #if !defined(GDK_Book) || !defined(GDK_Calendar)
28 #include <X11/XF86keysym.h>
47 #include "navit/font/freetype/font_freetype.h"
51 #define GDK_Book XF86XK_Book
54 #define GDK_Calendar XF86XK_Calendar
58 struct graphics_priv {
59 GdkEventButton button_event;
64 GdkDrawable *drawable;
65 GdkDrawable *background;
67 GdkColormap *colormap;
77 int overlay_autodisabled;
80 struct graphics_priv *parent;
81 struct graphics_priv *overlays;
82 struct graphics_priv *next;
83 struct graphics_gc_priv *background_gc;
84 enum draw_mode_num mode;
85 struct callback_list *cbl;
86 struct font_freetype_methods freetype_methods;
89 struct timeval button_press[8];
90 struct timeval button_release[8];
96 struct graphics_gc_priv {
99 struct graphics_priv *gr;
101 unsigned char r,g,b,a;
104 struct graphics_image_priv {
111 graphics_destroy(struct graphics_priv *gr)
116 gc_destroy(struct graphics_gc_priv *gc)
118 g_object_unref(gc->gc);
123 gc_set_linewidth(struct graphics_gc_priv *gc, int w)
125 gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
129 gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
131 gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n);
132 gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
136 gc_set_color(struct graphics_gc_priv *gc, struct color *c, int fg)
143 gdk_colormap_alloc_color(gc->gr->colormap, &gdkc, FALSE, TRUE);
144 gdk_colormap_query_color(gc->gr->colormap, gdkc.pixel, &gdkc);
146 gc->g=gdkc.green >> 8;
147 gc->b=gdkc.blue >> 8;
150 gdk_gc_set_foreground(gc->gc, &gdkc);
151 gc->level=(c->r+c->g+c->b)/3;
153 gdk_gc_set_background(gc->gc, &gdkc);
157 gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
159 gc_set_color(gc, c, 1);
163 gc_set_background(struct graphics_gc_priv *gc, struct color *c)
165 gc_set_color(gc, c, 0);
169 gc_set_stipple(struct graphics_gc_priv *gc, struct graphics_image_priv *img)
171 char data[2]={0x2,0x1};
172 gdk_gc_set_fill(gc->gc, GDK_STIPPLED);
173 gc->pixmap=gdk_bitmap_create_from_data(gc->gr->widget->window, data, 2, 2);
174 gdk_gc_set_stipple(gc->gc, gc->pixmap);
177 static struct graphics_gc_methods gc_methods = {
186 static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
188 struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1);
191 gc->gc=gdk_gc_new(gr->widget->window);
196 static struct graphics_image_priv *
197 image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot, int rotation)
200 struct graphics_image_priv *ret;
203 if (*w == -1 && *h == -1)
204 pixbuf=gdk_pixbuf_new_from_file(name, NULL);
206 pixbuf=gdk_pixbuf_new_from_file_at_size(name, *w, *h, NULL);
223 tmp=gdk_pixbuf_rotate_simple(pixbuf, rotation);
224 g_object_unref(pixbuf);
230 ret=g_new0(struct graphics_image_priv, 1);
232 ret->w=gdk_pixbuf_get_width(pixbuf);
233 ret->h=gdk_pixbuf_get_height(pixbuf);
237 option=gdk_pixbuf_get_option(pixbuf, "x_hot");
242 option=gdk_pixbuf_get_option(pixbuf, "y_hot");
252 image_free(struct graphics_priv *gr, struct graphics_image_priv *priv)
255 g_object_unref(priv->pixbuf);
260 draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
262 if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
263 gdk_draw_lines(gr->drawable, gc->gc, (GdkPoint *)p, count);
264 if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
265 gdk_draw_lines(gr->widget->window, gc->gc, (GdkPoint *)p, count);
269 draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
271 if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
272 gdk_draw_polygon(gr->drawable, gc->gc, TRUE, (GdkPoint *)p, count);
273 if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
274 gdk_draw_polygon(gr->widget->window, gc->gc, TRUE, (GdkPoint *)p, count);
278 draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
280 gdk_draw_rectangle(gr->drawable, gc->gc, TRUE, p->x, p->y, w, h);
284 draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
286 if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
287 gdk_draw_arc(gr->drawable, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
288 if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
289 gdk_draw_arc(gr->widget->window, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
293 display_text_draw(struct font_freetype_text *text, struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct point *p)
296 struct font_freetype_glyph *g, **gp;
297 unsigned char *shadow;
298 struct color transparent={0x0,0x0,0x0,0x0};
299 struct color white={0xffff,0xffff,0xffff,0xffff};
308 if (g->w && g->h && bg ) {
310 shadow=g_malloc((g->w+2)*(g->h+2));
311 if (gr->freetype_methods.get_shadow(g, shadow, 8, g->w+2, &white, &transparent))
312 gdk_draw_gray_image(gr->drawable, bg->gc, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, g->w+2, g->h+2, GDK_RGB_DITHER_NONE, shadow, g->w+2);
317 shadow=malloc(stride*(g->h+2));
319 gr->freetype_methods.get_shadow(g, shadow, 1, stride);
320 image=gdk_image_new_bitmap(gdk_visual_get_system(),shadow,g->w+2, g->h+2);
321 gdk_draw_image(gr->drawable, bg->gc, image, 0, 0, ((x+g->x)>>6)-1, ((y+g->y)>>6)-1, g->w+2, g->h+2);
322 g_object_unref(image);
337 gdk_draw_gray_image(gr->drawable, fg->gc, (x+g->x)>>6, (y+g->y)>>6, g->w, g->h, GDK_RGB_DITHER_NONE, g->pixmap, g->w);
344 draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
346 struct font_freetype_text *t;
350 dbg(0,"no font, returning\n");
353 #if 0 /* Temporarily disabled because it destroys text rendering of overlays and in gui internal in some places */
355 This needs an improvement, no one checks if the strings are visible
357 if (p->x > gr->width-50 || p->y > gr->height-50) {
360 if (p->x < -50 || p->y < -50) {
366 if (bg->level > 32767) {
367 gdk_gc_set_function(fg->gc, GDK_AND_INVERT);
368 gdk_gc_set_function(bg->gc, GDK_OR);
370 gdk_gc_set_function(fg->gc, GDK_OR);
371 gdk_gc_set_function(bg->gc, GDK_AND_INVERT);
375 t=gr->freetype_methods.text_new(text, (struct font_freetype_font *)font, dx, dy);
376 display_text_draw(t, gr, fg, bg, p);
377 gr->freetype_methods.text_destroy(t);
379 gdk_gc_set_function(fg->gc, GDK_COPY);
380 gdk_gc_set_function(bg->gc, GDK_COPY);
386 gr->freetype_methods.get_text_bbox(gr, font, text, dx, dy, pnt, 1);
387 for (i = 0 ; i < 4 ; i++) {
392 gdk_draw_lines(gr->drawable, fg->gc, (GdkPoint *)pnt, 5);
398 draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
400 gdk_draw_pixbuf(gr->drawable, fg->gc, img->pixbuf, 0, 0, p->x, p->y,
401 img->w, img->h, GDK_RGB_DITHER_NONE, 0, 0);
406 draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
410 dbg(1,"draw_image_warp data=%s\n", data);
411 image = imlib_load_image(data);
412 imlib_context_set_display(gdk_x11_drawable_get_xdisplay(gr->widget->window));
413 imlib_context_set_colormap(gdk_x11_colormap_get_xcolormap(gtk_widget_get_colormap(gr->widget)));
414 imlib_context_set_visual(gdk_x11_visual_get_xvisual(gtk_widget_get_visual(gr->widget)));
415 imlib_context_set_drawable(gdk_x11_drawable_get_xid(gr->drawable));
416 imlib_context_set_image(image);
417 w = imlib_image_get_width();
418 h = imlib_image_get_height();
422 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y);
427 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y);
433 imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x-w/2, p[0].y-h/2, w, 0, 0, h);
440 overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, int clean, GdkRectangle *r)
443 r->x=overlay->pclean.x;
444 r->y=overlay->pclean.y;
449 r->width=overlay->width;
450 r->height=overlay->height;
451 if (!overlay->wraparound)
454 r->x += parent->width;
456 r->y += parent->height;
458 r->width += parent->width;
460 r->height += parent->height;
464 overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRectangle *r, GdkPixmap *pixmap, GdkGC *gc)
466 GdkPixbuf *pixbuf,*pixbuf2;
467 guchar *pixels1, *pixels2, *p1, *p2;
469 int rowstride1,rowstride2;
470 int n_channels1,n_channels2;
472 struct graphics_gc_priv *bg=overlay->background_gc;
474 if (parent->overlay_disabled || overlay->overlay_disabled || overlay->overlay_autodisabled)
476 dbg(1,"r->x=%d r->y=%d r->width=%d r->height=%d\n", r->x, r->y, r->width, r->height);
477 overlay_rect(parent, overlay, 0, &or);
478 dbg(1,"or.x=%d or.y=%d or.width=%d or.height=%d\n", or.x, or.y, or.width, or.height);
479 if (! gdk_rectangle_intersect(r, &or, &ir))
483 pixbuf=gdk_pixbuf_get_from_drawable(NULL, overlay->drawable, NULL, 0, 0, 0, 0, or.width, or.height);
484 pixbuf2=gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf), TRUE, gdk_pixbuf_get_bits_per_sample(pixbuf),
485 or.width, or.height);
486 rowstride1 = gdk_pixbuf_get_rowstride (pixbuf);
487 rowstride2 = gdk_pixbuf_get_rowstride (pixbuf2);
488 pixels1=gdk_pixbuf_get_pixels (pixbuf);
489 pixels2=gdk_pixbuf_get_pixels (pixbuf2);
490 n_channels1 = gdk_pixbuf_get_n_channels (pixbuf);
491 n_channels2 = gdk_pixbuf_get_n_channels (pixbuf2);
492 for (y = 0 ; y < or.height ; y++) {
493 for (x = 0 ; x < or.width ; x++) {
494 p1 = pixels1 + y * rowstride1 + x * n_channels1;
495 p2 = pixels2 + y * rowstride2 + x * n_channels2;
499 if (bg && p1[0] == bg->r && p1[1] == bg->g && p1[2] == bg->b)
505 gdk_draw_pixbuf(pixmap, gc, pixbuf2, 0, 0, or.x, or.y, or.width, or.height, GDK_RGB_DITHER_NONE, 0, 0);
506 g_object_unref(pixbuf);
507 g_object_unref(pixbuf2);
511 draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
513 GtkWidget *widget=gr->widget;
514 gdk_draw_drawable(widget->window,
515 widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
517 p->x, p->y, p->x, p->y, w, h);
522 draw_drag(struct graphics_priv *gr, struct point *p)
538 background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
540 gr->background_gc=gc;
544 gtk_drawing_area_draw(struct graphics_priv *gr, GdkRectangle *r)
547 GtkWidget *widget=gr->widget;
548 GdkGC *gc=widget->style->fg_gc[GTK_WIDGET_STATE(widget)];
549 struct graphics_priv *overlay;
553 pixmap = gdk_pixmap_new(widget->window, r->width, r->height, -1);
554 if ((gr->p.x || gr->p.y) && gr->background_gc)
555 gdk_draw_rectangle(pixmap, gr->background_gc->gc, TRUE, 0, 0, r->width, r->height);
556 gdk_draw_drawable(pixmap, gc, gr->drawable, r->x, r->y, gr->p.x, gr->p.y, r->width, r->height);
557 overlay=gr->overlays;
559 overlay_draw(gr,overlay,r,pixmap,gc);
560 overlay=overlay->next;
562 gdk_draw_drawable(widget->window, gc, pixmap, 0, 0, r->x, r->y, r->width, r->height);
563 g_object_unref(pixmap);
567 draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
570 struct graphics_priv *overlay;
572 if (mode == draw_mode_begin) {
573 if (! gr->parent && gr->background_gc)
574 gdk_draw_rectangle(gr->drawable, gr->background_gc->gc, TRUE, 0, 0, gr->width, gr->height);
577 if (mode == draw_mode_end && gr->mode != draw_mode_cursor) {
580 overlay_rect(gr->parent, gr, 1, &r);
581 gtk_drawing_area_draw(gr->parent, &r);
584 overlay_rect(gr->parent, gr, 0, &r);
585 gtk_drawing_area_draw(gr->parent, &r);
591 gtk_drawing_area_draw(gr, &r);
592 overlay=gr->overlays;
595 overlay=overlay->next;
605 configure(GtkWidget * widget, GdkEventConfigure * event, gpointer user_data)
607 struct graphics_priv *gra=user_data;
610 if (gra->drawable != NULL) {
611 g_object_unref(gra->drawable);
613 if(gra->background_ready && gra->background != NULL) {
614 g_object_unref(gra->background);
615 gra->background_ready = 0;
618 dbg(1,"window=%d\n", GDK_WINDOW_XID(widget->window));
620 gra->width=widget->allocation.width;
621 gra->height=widget->allocation.height;
622 gra->drawable = gdk_pixmap_new(widget->window, gra->width, gra->height, -1);
623 callback_list_call_attr_2(gra->cbl, attr_resize, GINT_TO_POINTER(gra->width), GINT_TO_POINTER(gra->height));
628 expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
630 struct graphics_priv *gra=user_data;
634 configure(widget, NULL, user_data);
635 gtk_drawing_area_draw(gra, &event->area);
637 gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
638 gra->drawable, event->area.x, event->area.y,
639 event->area.x, event->area.y,
640 event->area.width, event->area.height);
648 button_timeout(gpointer user_data)
651 struct container *co=user_data;
652 int x=co->gra->gra->button_event.x;
653 int y=co->gra->gra->button_event.y;
654 int button=co->gra->gra->button_event.button;
656 co->gra->gra->button_timeout=0;
657 popup(co, x, y, button);
665 tv_delta(struct timeval *old, struct timeval *new)
667 if (new->tv_sec-old->tv_sec >= INT_MAX/1000)
669 return (new->tv_sec-old->tv_sec)*1000+(new->tv_usec-old->tv_usec)/1000;
673 button_press(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
675 struct graphics_priv *this=user_data;
680 gettimeofday(&tv, &tz);
682 if (event->button < 8) {
683 if (tv_delta(&this->button_press[event->button], &tv) < this->timeout)
685 this->button_press[event->button]= tv;
686 this->button_release[event->button].tv_sec=0;
687 this->button_release[event->button].tv_usec=0;
691 callback_list_call_attr_3(this->cbl, attr_button, GINT_TO_POINTER(1), GINT_TO_POINTER(event->button), (void *)&p);
696 button_release(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
698 struct graphics_priv *this=user_data;
703 gettimeofday(&tv, &tz);
705 if (event->button < 8) {
706 if (tv_delta(&this->button_release[event->button], &tv) < this->timeout)
708 this->button_release[event->button]= tv;
709 this->button_press[event->button].tv_sec=0;
710 this->button_press[event->button].tv_usec=0;
714 callback_list_call_attr_3(this->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER(event->button), (void *)&p);
721 scroll(GtkWidget * widget, GdkEventScroll * event, gpointer user_data)
723 struct graphics_priv *this=user_data;
729 switch (event->direction) {
733 case GDK_SCROLL_DOWN:
741 callback_list_call_attr_3(this->cbl, attr_button, GINT_TO_POINTER(1), GINT_TO_POINTER(button), (void *)&p);
742 callback_list_call_attr_3(this->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER(button), (void *)&p);
748 motion_notify(GtkWidget * widget, GdkEventMotion * event, gpointer user_data)
750 struct graphics_priv *this=user_data;
755 callback_list_call_attr_1(this->cbl, attr_motion, (void *)&p);
760 * * Exit navit (X pressed)
761 * * @param widget active widget
762 * * @param event the event (delete_event)
763 * * @param user_data Pointer to private data structure
767 delete(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
769 struct graphics_priv *this=user_data;
770 dbg(0,"enter this->win=%p\n",this->win);
771 if (this->delay & 2) {
775 navit_destroy(this->nav);
781 keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
783 struct graphics_priv *this=user_data;
786 ucode=gdk_keyval_to_unicode(event->keyval);
787 len=g_unichar_to_utf8(ucode, key);
790 switch (event->keyval) {
796 key[0]=NAVIT_KEY_DOWN;
800 key[0]=NAVIT_KEY_LEFT;
804 key[0]=NAVIT_KEY_RIGHT;
808 key[0]=NAVIT_KEY_BACKSPACE;
813 key[0]=NAVIT_KEY_RETURN;
820 key[0]=NAVIT_KEY_ZOOM_IN;
827 key[0]=NAVIT_KEY_ZOOM_OUT;
832 callback_list_call_attr_1(this->cbl, attr_keypress, (void *)key);
834 dbg(0,"keyval 0x%x\n", event->keyval);
839 static struct graphics_priv *graphics_gtk_drawing_area_new_helper(struct graphics_methods *meth);
842 overlay_disable(struct graphics_priv *gr, int disabled)
844 gr->overlay_disabled=disabled;
848 overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int alpha, int wraparound)
866 if (this->width != w2) {
871 if (this->height != h2) {
876 this->a = alpha >> 8;
877 this->wraparound = wraparound;
880 // Set the drawables to the right sizes
881 g_object_unref(this->drawable);
882 g_object_unref(this->background);
884 this->drawable=gdk_pixmap_new(this->parent->widget->window, w2, h2, -1);
885 this->background=gdk_pixmap_new(this->parent->widget->window, w2, h2, -1);
887 if ((w == 0) || (h == 0)) {
888 this->overlay_autodisabled = 1;
890 this->overlay_autodisabled = 0;
893 callback_list_call_attr_2(this->cbl, attr_resize, GINT_TO_POINTER(this->width), GINT_TO_POINTER(this->height));
898 get_data_window(struct graphics_priv *this, unsigned int xid)
901 this->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
903 this->win = gtk_plug_new(xid);
904 if (!gtk_widget_get_parent(this->widget))
905 gtk_widget_ref(this->widget);
906 gtk_window_set_default_size(GTK_WINDOW(this->win), this->win_w, this->win_h);
907 dbg(1,"h= %i, w= %i\n",this->win_h, this->win_w);
908 gtk_window_set_title(GTK_WINDOW(this->win), "Navit");
909 gtk_window_set_wmclass (GTK_WINDOW (this->win), "navit", "Navit");
910 gtk_widget_realize(this->win);
911 if (gtk_widget_get_parent(this->widget))
912 gtk_widget_reparent(this->widget, this->win);
914 gtk_container_add(GTK_CONTAINER(this->win), this->widget);
915 gtk_widget_show_all(this->win);
916 GTK_WIDGET_SET_FLAGS (this->widget, GTK_CAN_FOCUS);
917 gtk_widget_set_sensitive(this->widget, TRUE);
918 gtk_widget_grab_focus(this->widget);
919 g_signal_connect(G_OBJECT(this->widget), "key-press-event", G_CALLBACK(keypress), this);
920 g_signal_connect(G_OBJECT(this->win), "delete_event", G_CALLBACK(delete), this);
924 set_attr(struct graphics_priv *gr, struct attr *attr)
927 switch (attr->type) {
929 get_data_window(gr, attr->u.num);
936 static struct graphics_priv *
937 overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound)
940 struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
941 this->colormap=gr->colormap;
942 this->widget=gr->widget;
948 /* If either height or width is 0, we set it to 1 to avoid warnings, and
949 * disable the overlay. */
962 this->background=gdk_pixmap_new(gr->widget->window, w2, h2, -1);
963 this->drawable=gdk_pixmap_new(gr->widget->window, w2, h2, -1);
965 if ((w == 0) || (h == 0)) {
966 this->overlay_autodisabled = 1;
968 this->overlay_autodisabled = 0;
971 this->next=gr->overlays;
973 this->wraparound=wraparound;
979 static char **gtk_argv={NULL};
983 graphics_gtk_drawing_area_fullscreen(struct window *w, int on)
985 struct graphics_priv *gr=w->priv;
987 gtk_window_fullscreen(GTK_WINDOW(gr->win));
989 gtk_window_unfullscreen(GTK_WINDOW(gr->win));
994 graphics_gtk_drawing_area_disable_suspend(struct window *w)
996 struct graphics_priv *gr=w->priv;
1000 kill(gr->pid, SIGWINCH);
1002 dbg(1, "failed to kill() under Windows\n");
1008 get_data(struct graphics_priv *this, char *type)
1011 if (!strcmp(type,"gtk_widget"))
1012 return this->widget;
1014 if (!strcmp(type,"xwindow_id"))
1015 return (void *)GDK_WINDOW_XID(this->widget->window);
1017 if (!strcmp(type,"window")) {
1018 char *cp = getenv("NAVIT_XID");
1021 xid = strtol(cp, NULL, 0);
1022 if (!(this->delay & 1))
1023 get_data_window(this, xid);
1024 this->window.fullscreen=graphics_gtk_drawing_area_fullscreen;
1025 this->window.disable_suspend=graphics_gtk_drawing_area_disable_suspend;
1026 this->window.priv=this;
1027 #if !defined(_WIN32) && !defined(__CEGCC__)
1028 f=popen("pidof /usr/bin/ipaq-sleep","r");
1030 fscanf(f,"%d",&this->pid);
1031 dbg(1,"ipaq_sleep pid=%d\n", this->pid);
1035 return &this->window;
1040 static struct graphics_methods graphics_methods = {
1069 static struct graphics_priv *
1070 graphics_gtk_drawing_area_new_helper(struct graphics_methods *meth)
1072 struct font_priv * (*font_freetype_new)(void *meth);
1073 font_freetype_new=plugin_get_font_type("freetype");
1074 if (!font_freetype_new)
1076 struct graphics_priv *this=g_new0(struct graphics_priv,1);
1077 font_freetype_new(&this->freetype_methods);
1078 *meth=graphics_methods;
1079 meth->font_new=(struct graphics_font_priv *(*)(struct graphics_priv *, struct graphics_font_methods *, char *, int, int))this->freetype_methods.font_new;
1080 meth->get_text_bbox=this->freetype_methods.get_text_bbox;
1085 static struct graphics_priv *
1086 graphics_gtk_drawing_area_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl)
1092 if (! event_request_system("glib","graphics_gtk_drawing_area_new"))
1095 draw=gtk_drawing_area_new();
1096 struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
1100 if ((attr=attr_search(attrs, NULL, attr_w)))
1101 this->win_w=attr->u.num;
1103 if ((attr=attr_search(attrs, NULL, attr_h)))
1104 this->win_h=attr->u.num;
1106 if ((attr=attr_search(attrs, NULL, attr_timeout)))
1107 this->timeout=attr->u.num;
1109 if ((attr=attr_search(attrs, NULL, attr_delay)))
1110 this->delay=attr->u.num;
1112 this->colormap=gdk_colormap_new(gdk_visual_get_system(),FALSE);
1113 gtk_widget_set_events(draw, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_KEY_PRESS_MASK);
1114 g_signal_connect(G_OBJECT(draw), "expose_event", G_CALLBACK(expose), this);
1115 g_signal_connect(G_OBJECT(draw), "configure_event", G_CALLBACK(configure), this);
1116 g_signal_connect(G_OBJECT(draw), "button_press_event", G_CALLBACK(button_press), this);
1117 g_signal_connect(G_OBJECT(draw), "button_release_event", G_CALLBACK(button_release), this);
1118 g_signal_connect(G_OBJECT(draw), "scroll_event", G_CALLBACK(scroll), this);
1119 g_signal_connect(G_OBJECT(draw), "motion_notify_event", G_CALLBACK(motion_notify), this);
1120 g_signal_connect(G_OBJECT(draw), "delete_event", G_CALLBACK(delete), nav);
1122 for (i = 0; i < 8; i++) {
1123 this->button_press[i].tv_sec = 0;
1124 this->button_press[i].tv_usec = 0;
1125 this->button_release[i].tv_sec = 0;
1126 this->button_release[i].tv_usec = 0;
1135 gtk_init(>k_argc, >k_argv);
1137 plugin_register_graphics_type("gtk_drawing_area", graphics_gtk_drawing_area_new);