1 /* picture.c: GTK routines to draw the keyboard picture
2    Copyright (c) 2002-2005 Philip Kendall
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
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.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 
18    Author contact information:
19 
20    E-mail: philip-fuse@shadowmagic.org.uk
21 
22 */
23 
24 #include <config.h>
25 
26 #include <gtk/gtk.h>
27 
28 #include "gtkinternals.h"
29 #include "ui/ui.h"
30 #include "utils.h"
31 
32 static int dialog_created = 0;
33 
34 static GtkWidget *dialog;
35 static GdkPixbuf *pixbuf = NULL;
36 
37 #if GTK_CHECK_VERSION( 3, 0, 0 )
38 
39 static GdkPixbuf *scaled_pixbuf = NULL;
40 
41 static gint
picture_size_allocate(GtkWidget * widget GCC_UNUSED,GdkRectangle * allocation,gpointer data GCC_UNUSED)42 picture_size_allocate( GtkWidget *widget GCC_UNUSED, GdkRectangle *allocation,
43                        gpointer data GCC_UNUSED )
44 {
45   float scale_x, scale_y, scale_factor;
46   int scaled_width, scaled_height;
47 
48   scale_x = (float)allocation->width / gdk_pixbuf_get_width( pixbuf );
49   scale_y = (float)allocation->height / gdk_pixbuf_get_height( pixbuf );
50   scale_factor = scale_x < scale_y ? scale_x : scale_y;
51 
52   scaled_width = gdk_pixbuf_get_width( pixbuf ) * scale_factor;
53   scaled_height = gdk_pixbuf_get_height( pixbuf ) * scale_factor;
54 
55   if( scaled_pixbuf != NULL ) g_object_unref( scaled_pixbuf );
56   scaled_pixbuf = gdk_pixbuf_scale_simple( pixbuf, scaled_width, scaled_height,
57                                            GDK_INTERP_BILINEAR );
58 
59   return FALSE;
60 }
61 
62 static gboolean
picture_draw(GtkWidget * widget,cairo_t * cr,gpointer user_data GCC_UNUSED)63 picture_draw( GtkWidget *widget, cairo_t *cr, gpointer user_data GCC_UNUSED )
64 {
65   int offset_x, offset_y;
66   int scaled_width, scaled_height;
67   int allocated_width, allocated_height;
68 
69   allocated_width = gtk_widget_get_allocated_width( widget );
70   allocated_height = gtk_widget_get_allocated_height( widget );
71 
72   scaled_width = gdk_pixbuf_get_width( scaled_pixbuf );
73   scaled_height = gdk_pixbuf_get_height( scaled_pixbuf );
74 
75   offset_x = ( allocated_width - scaled_width ) / 2;
76   offset_y = ( allocated_height - scaled_height ) / 2;
77 
78   gdk_cairo_set_source_pixbuf( cr, scaled_pixbuf, offset_x, offset_y );
79   cairo_paint(cr);
80 
81   return FALSE;
82 }
83 
84 #endif                /* #if GTK_CHECK_VERSION( 3, 0, 0 ) */
85 
86 int
gtkui_picture(const char * filename,int border GCC_UNUSED)87 gtkui_picture( const char *filename, int border GCC_UNUSED )
88 {
89   GtkWidget *content_area;
90 
91   if( !dialog_created ) {
92 
93     char path[PATH_MAX];
94 
95     if( utils_find_file_path( filename, path, UTILS_AUXILIARY_LIB ) ) return 1;
96 
97     pixbuf = gdk_pixbuf_new_from_file( path, NULL );
98     if( pixbuf == NULL ) {
99       ui_error( UI_ERROR_ERROR, "Failed to load keyboard image" );
100       return 1;
101     }
102 
103     dialog = gtkstock_dialog_new( "Fuse - Keyboard",
104 				  G_CALLBACK( gtk_widget_hide ) );
105 
106     content_area = gtk_dialog_get_content_area( GTK_DIALOG( dialog ) );
107 
108 #if !GTK_CHECK_VERSION( 3, 0, 0 )
109 
110     GtkWidget *image = gtk_image_new();
111     gtk_image_set_from_pixbuf( GTK_IMAGE( image ), pixbuf );
112     gtk_container_add( GTK_CONTAINER( content_area ), image );
113 
114     /* Stop users resizing this window */
115     gtk_window_set_resizable( GTK_WINDOW( dialog ), FALSE );
116 
117 #else
118 
119     GtkWidget *box = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 );
120     gtk_container_add( GTK_CONTAINER( content_area ), box );
121 
122     GtkWidget *drawing_area = gtk_drawing_area_new();
123     gtk_widget_set_vexpand( drawing_area, TRUE );
124     gtk_box_pack_start( GTK_BOX( box ), drawing_area, TRUE, TRUE, 0 );
125 
126     g_signal_connect( G_OBJECT( drawing_area ), "draw",
127                       G_CALLBACK( picture_draw ), NULL );
128     g_signal_connect( G_OBJECT( drawing_area ), "size-allocate",
129                       G_CALLBACK( picture_size_allocate ), NULL );
130 
131     gtk_widget_set_size_request( GTK_WIDGET( drawing_area ),
132                                  gdk_pixbuf_get_width( pixbuf ),
133                                  gdk_pixbuf_get_height( pixbuf ) );
134 
135 #endif                /* #if !GTK_CHECK_VERSION( 3, 0, 0 ) */
136 
137     gtkstock_create_close( dialog, NULL, G_CALLBACK( gtk_widget_hide ),
138                            FALSE );
139 
140     dialog_created = 1;
141   }
142 
143   gtk_widget_show_all( dialog );
144 
145   return 0;
146 }
147