]> Pileus Git - ~andy/gtk/blob - gdk/linux-fb/gdkimage-fb.c
Do implicit button grabs, even if the window doesn't want the event.
[~andy/gtk] / gdk / linux-fb / gdkimage-fb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <config.h>
28
29 #include <stdlib.h>
30 #include <sys/types.h>
31 #include <string.h>
32
33 #include "gdk.h"
34 #include "gdkimage.h"
35 #include "gdkprivate.h"
36 #include "gdkprivate-fb.h"
37
38 static gpointer parent_class = NULL;
39
40 #define GDK_IMAGE_PRIVATE_DATA(image) ((GdkImagePrivateFB *) GDK_IMAGE (image)->windowing_data)
41
42 void
43 _gdk_windowing_image_init (void)
44 {
45 }
46
47 static void
48 gdk_image_init (GdkImage *image)
49 {
50   image->windowing_data = g_new0 (GdkImagePrivateFB, 1);
51 }
52
53 static void
54 gdk_image_finalize (GObject *object)
55 {
56   GdkImage *image = GDK_IMAGE (object);
57
58   g_free (image->windowing_data);
59   image->windowing_data = NULL;
60   
61   g_free (image->mem);
62   image->mem = NULL;
63
64   G_OBJECT_CLASS (parent_class)->finalize (object);
65 }
66
67 static void
68 gdk_image_class_init (GdkImageClass *klass)
69 {
70   GObjectClass *object_class = G_OBJECT_CLASS (klass);
71
72   parent_class = g_type_class_peek_parent (klass);
73
74   object_class->finalize = gdk_image_finalize;
75 }
76
77 GType
78 gdk_image_get_type (void)
79 {
80   static GType object_type = 0;
81
82   if (!object_type)
83     {
84       static const GTypeInfo object_info =
85       {
86         sizeof (GdkImageClass),
87         (GBaseInitFunc) NULL,
88         (GBaseFinalizeFunc) NULL,
89         (GClassInitFunc) gdk_image_class_init,
90         NULL,           /* class_finalize */
91         NULL,           /* class_data */
92         sizeof (GdkImage),
93         0,              /* n_preallocs */
94         (GInstanceInitFunc) gdk_image_init,
95       };
96       
97       object_type = g_type_register_static (G_TYPE_OBJECT,
98                                             "GdkImage",
99                                             &object_info,
100                                             0);
101     }
102   
103   return object_type;
104 }
105
106 GdkImage *
107 gdk_image_new_bitmap(GdkVisual *visual,
108                      gpointer data,
109                      gint w,
110                      gint h)
111 {
112   GdkImage *image;
113   GdkImagePrivateFB *private;
114   
115   image = g_object_new (gdk_image_get_type (), NULL);
116   private = GDK_IMAGE_PRIVATE_DATA (image);
117   
118   image->type = GDK_IMAGE_NORMAL;
119   image->visual = visual;
120   image->width = w;
121   image->height = h;
122   image->depth = 1;
123
124   image->byte_order = 1 /* MSBFirst */;
125   image->bpp = 1;
126   image->bpl = (w+7)/8;
127   image->mem = g_malloc (image->bpl * h / 8);
128
129   return image;
130 }
131
132 GdkImage*
133 gdk_image_new (GdkImageType  type,
134                GdkVisual    *visual,
135                gint          width,
136                gint          height)
137 {
138   GdkImage *image;
139   GdkImagePrivateFB *private;
140
141   image = g_object_new (gdk_image_get_type (), NULL);
142   private = GDK_IMAGE_PRIVATE_DATA (image);
143
144   image->type = 0;
145   image->visual = visual;
146   image->width = width;
147   image->height = height;
148   image->depth = visual->depth;
149   
150   image->byte_order = 0;
151   image->bpp = image->depth/8;
152   image->bpl = (width * image->depth + 7) / 8;
153   image->mem = g_malloc (image->bpl * height);
154
155   return image;
156 }
157
158 GdkImage*
159 _gdk_fb_get_image (GdkDrawable *drawable,
160                    gint       x,
161                    gint       y,
162                    gint       width,
163                    gint       height)
164 {
165   GdkImage *image;
166   GdkImagePrivateFB *private;
167   gint bits_per_pixel = GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->depth;
168   GdkPixmapFBData fbd;
169
170   g_return_val_if_fail (drawable != NULL, NULL);
171
172   image = g_object_new (gdk_image_get_type (), NULL);
173   private = GDK_IMAGE_PRIVATE_DATA (image);
174
175   image->type = GDK_IMAGE_NORMAL;
176   image->visual = gdk_drawable_get_visual (drawable);
177   image->width = width;
178   image->height = height;
179   image->depth = bits_per_pixel;
180
181   if (bits_per_pixel <= 8)
182     image->bpp = 1;
183   else if (bits_per_pixel <= 16)
184     image->bpp = 2;
185   else if (bits_per_pixel <= 24)
186     image->bpp = 3;
187   else
188     image->bpp = 4;
189   image->byte_order = 1;
190
191   image->bpl = (image->width * image->depth + 7) / 8; /* Packed pixels */
192   image->mem = g_malloc (image->bpl * image->height);
193   
194   /* Fake its existence as a pixmap */
195   memset (&fbd, 0, sizeof(fbd));
196   fbd.drawable_data.mem = image->mem;
197   fbd.drawable_data.rowstride = image->bpl;
198   fbd.drawable_data.width = fbd.drawable_data.lim_x = image->width;
199   fbd.drawable_data.height = fbd.drawable_data.lim_y = image->height;
200   fbd.drawable_data.depth = image->depth;
201   fbd.drawable_data.window_type = GDK_DRAWABLE_PIXMAP;
202
203   gdk_fb_draw_drawable_2 ((GdkPixmap *)&fbd,
204                           _gdk_fb_screen_gc,
205                           drawable,
206                           x, y,
207                           0, 0,
208                           width, height,
209                           TRUE, TRUE);
210
211   return image;
212 }
213
214 guint32
215 gdk_image_get_pixel (GdkImage *image,
216                      gint x,
217                      gint y)
218 {
219   GdkImagePrivateFB *private;
220
221   g_return_val_if_fail (image != NULL, 0);
222
223   private = GDK_IMAGE_PRIVATE_DATA (image);
224
225   switch (image->depth)
226     {
227     case 8:
228       return ((guchar *)image->mem)[x + y * image->bpl];
229       break;
230     case 16:
231       return *((guint16 *)&((guchar *)image->mem)[x*2 + y*image->bpl]);
232       break;
233     case 24:
234     case 32:
235       {
236         guchar *smem = &(((guchar *)image->mem)[x*image->bpp + y*image->bpl]);
237         return smem[0]|(smem[1]<<8)|(smem[2]<<16);
238       }
239       break;
240     }
241
242   return 0;
243 }
244
245 void
246 gdk_image_put_pixel (GdkImage *image,
247                      gint x,
248                      gint y,
249                      guint32 pixel)
250 {
251   guchar *ptr = image->mem;
252
253   g_return_if_fail (image != NULL);
254
255   switch (image->depth)
256     {
257     case 8:
258       ptr[x + y * image->bpl] = pixel;
259       break;
260     case 16:
261       {
262         guint16 *p16 = (guint16 *)&ptr[x*2 + y*image->bpl];
263         *p16 = pixel;
264       }
265       break;
266     case 24:
267       {
268         guchar *smem = &ptr[x*3 + y*image->bpl];
269         smem[0] = (pixel & 0xFF);
270         smem[1] = (pixel & 0xFF00) >> 8;
271         smem[2] = (pixel & 0xFF0000) >> 16;
272       }
273       break;
274     case 32:
275       {
276         guint32 *smem = (guint32 *)&ptr[x*4 + y*image->bpl];
277         *smem = pixel;
278       }
279       break;
280     default:
281       g_assert_not_reached ();
282       break;
283     }
284 }
285
286 void
287 gdk_image_exit(void)
288 {
289 }