1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
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/.
30 #include <sys/types.h>
32 #include <sys/ioctl.h>
40 #include "gdkprivate-fb.h"
41 #include "gdkinternals.h"
43 /* Private variable declarations
45 static int gdk_initialized = 0; /* 1 if the library is initialized,
50 static const GDebugKey gdk_debug_keys[] = {
51 {"misc", GDK_DEBUG_MISC},
52 {"events", GDK_DEBUG_EVENTS},
55 static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey);
57 #endif /* G_ENABLE_DEBUG */
59 GdkArgDesc _gdk_windowing_args[] = {
64 gdk_fb_display_new(const char *filename)
69 fd = open(filename, O_RDWR);
73 retval = g_new0(GdkFBDisplay, 1);
75 n = ioctl(fd, FBIOGET_FSCREENINFO, &retval->sinfo);
76 n |= ioctl(fd, FBIOGET_VSCREENINFO, &retval->modeinfo);
79 /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */
80 retval->fbmem = mmap(NULL, retval->modeinfo.yres * retval->sinfo.line_length,
81 PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
82 g_assert(retval->fbmem != MAP_FAILED);
84 if(retval->sinfo.visual == FB_VISUAL_PSEUDOCOLOR)
86 guint16 red[256], green[256], blue[256];
88 for(n = 0; n < 16; n++)
89 red[n] = green[n] = blue[n] = n << 12;
90 for(n = 16; n < 256; n++)
91 red[n] = green[n] = blue[n] = n << 8;
92 cmap.red = red; cmap.green = green; cmap.blue = blue; cmap.len = 256; cmap.start = 0;
93 ioctl(fd, FBIOPUTCMAP, &cmap);
96 if(retval->sinfo.visual == FB_VISUAL_TRUECOLOR)
98 retval->red_byte = retval->modeinfo.red.offset >> 3;
99 retval->green_byte = retval->modeinfo.green.offset >> 3;
100 retval->blue_byte = retval->modeinfo.blue.offset >> 3;
107 gdk_fb_display_destroy(GdkFBDisplay *fbd)
109 munmap(fbd->fbmem, fbd->modeinfo.yres * fbd->sinfo.line_length);
114 extern void keyboard_init(void);
117 _gdk_windowing_init_check (int argc, char **argv)
123 gdk_display = gdk_fb_display_new("/dev/fb");
130 gdk_initialized = TRUE;
136 *--------------------------------------------------------------
139 * Grabs the pointer to a specific window
142 * "window" is the window which will receive the grab
143 * "owner_events" specifies whether events will be reported as is,
144 * or relative to "window"
145 * "event_mask" masks only interesting events
146 * "confine_to" limits the cursor movement to the specified window
147 * "cursor" changes the cursor for the duration of the grab
148 * "time" specifies the time
153 * requires a corresponding call to gdk_pointer_ungrab
155 *--------------------------------------------------------------
159 gdk_pointer_grab (GdkWindow * window,
161 GdkEventMask event_mask,
162 GdkWindow * confine_to,
166 g_return_val_if_fail (window != NULL, 0);
167 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
168 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
170 if(_gdk_fb_pointer_grab_window)
171 gdk_pointer_ungrab(time);
174 _gdk_fb_pointer_grab_window = gdk_window_ref(window);
176 _gdk_fb_pointer_grab_confine = confine_to?gdk_window_ref(confine_to):NULL;
177 _gdk_fb_pointer_grab_events = event_mask;
178 _gdk_fb_pointer_grab_cursor = cursor?gdk_cursor_ref(cursor):NULL;
181 gdk_fb_cursor_reset();
183 return GDK_GRAB_SUCCESS;
187 *--------------------------------------------------------------
190 * Releases any pointer grab
198 *--------------------------------------------------------------
202 gdk_pointer_ungrab (guint32 time)
204 gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1;
206 if(_gdk_fb_pointer_grab_window)
207 gdk_window_unref(_gdk_fb_pointer_grab_window);
208 _gdk_fb_pointer_grab_window = NULL;
210 if(_gdk_fb_pointer_grab_confine)
211 gdk_window_unref(_gdk_fb_pointer_grab_confine);
212 _gdk_fb_pointer_grab_confine = NULL;
214 if(_gdk_fb_pointer_grab_cursor)
215 gdk_cursor_unref(_gdk_fb_pointer_grab_cursor);
216 _gdk_fb_pointer_grab_cursor = NULL;
219 gdk_fb_cursor_reset();
223 *--------------------------------------------------------------
224 * gdk_pointer_is_grabbed
226 * Tell wether there is an active x pointer grab in effect
234 *--------------------------------------------------------------
238 gdk_pointer_is_grabbed (void)
240 return _gdk_fb_pointer_grab_window != NULL;
244 *--------------------------------------------------------------
247 * Grabs the keyboard to a specific window
250 * "window" is the window which will receive the grab
251 * "owner_events" specifies whether events will be reported as is,
252 * or relative to "window"
253 * "time" specifies the time
258 * requires a corresponding call to gdk_keyboard_ungrab
260 *--------------------------------------------------------------
264 gdk_keyboard_grab (GdkWindow * window,
268 g_return_val_if_fail (window != NULL, 0);
269 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
271 if(_gdk_fb_pointer_grab_window)
272 gdk_keyboard_ungrab(time);
275 _gdk_fb_keyboard_grab_window = gdk_window_ref(window);
277 return GDK_GRAB_SUCCESS;
281 *--------------------------------------------------------------
282 * gdk_keyboard_ungrab
284 * Releases any keyboard grab
292 *--------------------------------------------------------------
296 gdk_keyboard_ungrab (guint32 time)
298 if(_gdk_fb_keyboard_grab_window)
299 gdk_window_unref(_gdk_fb_keyboard_grab_window);
300 _gdk_fb_keyboard_grab_window = NULL;
304 *--------------------------------------------------------------
307 * Return the width of the screen.
315 *--------------------------------------------------------------
319 gdk_screen_width (void)
321 return gdk_display->modeinfo.xres;
325 *--------------------------------------------------------------
328 * Return the height of the screen.
336 *--------------------------------------------------------------
340 gdk_screen_height (void)
342 return gdk_display->modeinfo.yres;
346 *--------------------------------------------------------------
347 * gdk_screen_width_mm
349 * Return the width of the screen in millimeters.
357 *--------------------------------------------------------------
361 gdk_screen_width_mm (void)
363 return 0.5 + gdk_screen_width () * (25.4 / 72.);
367 *--------------------------------------------------------------
370 * Return the height of the screen in millimeters.
378 *--------------------------------------------------------------
382 gdk_screen_height_mm (void)
384 return 0.5 + gdk_screen_height () * (25.4 / 72.);
388 *--------------------------------------------------------------
389 * gdk_set_sm_client_id
391 * Set the SM_CLIENT_ID property on the WM_CLIENT_LEADER window
392 * so that the window manager can save our state using the
393 * X11R6 ICCCM session management protocol. A NULL value should
394 * be set following disconnection from the session manager to
395 * remove the SM_CLIENT_ID property.
399 * "sm_client_id" specifies the client id assigned to us by the
400 * session manager or NULL to remove the property.
406 *--------------------------------------------------------------
410 gdk_set_sm_client_id (const gchar* sm_client_id)
415 gdk_key_repeat_disable (void)
420 gdk_key_repeat_restore (void)
430 extern void keyboard_shutdown(void);
433 gdk_windowing_exit (void)
435 gdk_fb_display_destroy(gdk_display); gdk_display = NULL;
443 gdk_keyval_name (guint keyval)
449 gdk_keyval_from_name (const gchar *keyval_name)
455 gdk_get_display(void)
457 return g_strdup("/dev/fb0");
462 gdk_event_make(GdkWindow *window, GdkEventType type, gboolean append_to_queue)
464 static const guint type_masks[] = {
465 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0, */
466 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1, */
467 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2, */
468 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3, */
469 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4, */
470 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5, */
471 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6, */
472 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7, */
473 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8, */
474 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9, */
475 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10, */
476 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11, */
477 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12, */
478 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13, */
479 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14, */
480 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15, */
481 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16, */
482 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17, */
483 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18, */
484 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19, */
485 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20, */
486 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21, */
487 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22, */
488 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23, */
489 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24, */
490 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25, */
491 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26, */
492 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27, */
493 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28, */
494 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29, */
495 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30, */
496 GDK_SCROLL_MASK /* GDK_SCROLL = 31 */
499 evmask = GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
501 if(evmask & GDK_BUTTON_MOTION_MASK)
503 evmask |= GDK_BUTTON1_MOTION_MASK|GDK_BUTTON2_MOTION_MASK|GDK_BUTTON3_MOTION_MASK;
506 if(evmask & (GDK_BUTTON1_MOTION_MASK|GDK_BUTTON2_MOTION_MASK|GDK_BUTTON3_MOTION_MASK))
509 GdkModifierType mask;
511 gdk_input_ps2_get_mouseinfo(&x, &y, &mask);
513 if(((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK))
514 || ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK))
515 || ((mask & GDK_BUTTON3_MASK) && (evmask & GDK_BUTTON3_MOTION_MASK)))
516 evmask |= GDK_POINTER_MOTION_MASK;
519 if(evmask & type_masks[type])
521 GdkEvent *event = gdk_event_new();
522 guint32 the_time = g_latest_time.tv_sec * 1000 + g_latest_time.tv_usec / 1000;
524 event->any.type = type;
525 event->any.window = gdk_window_ref(window);
526 event->any.send_event = FALSE;
529 case GDK_MOTION_NOTIFY:
530 event->motion.time = the_time;
531 event->motion.axes = NULL;
533 case GDK_BUTTON_PRESS:
534 case GDK_2BUTTON_PRESS:
535 case GDK_3BUTTON_PRESS:
536 case GDK_BUTTON_RELEASE:
537 event->button.time = the_time;
538 event->button.axes = NULL;
541 case GDK_KEY_RELEASE:
542 event->key.time = the_time;
544 case GDK_ENTER_NOTIFY:
545 case GDK_LEAVE_NOTIFY:
546 event->crossing.time = the_time;
549 case GDK_PROPERTY_NOTIFY:
550 event->property.time = the_time;
553 case GDK_SELECTION_CLEAR:
554 case GDK_SELECTION_REQUEST:
555 case GDK_SELECTION_NOTIFY:
556 event->selection.time = the_time;
558 case GDK_PROXIMITY_IN:
559 case GDK_PROXIMITY_OUT:
560 event->proximity.time = the_time;
564 case GDK_DRAG_MOTION:
565 case GDK_DRAG_STATUS:
567 case GDK_DROP_FINISHED:
568 event->dnd.time = the_time;
571 case GDK_FOCUS_CHANGE:
575 case GDK_CLIENT_EVENT:
576 case GDK_VISIBILITY_NOTIFY:
587 gdk_event_queue_append(event);
597 static gpointer mymem = NULL;
605 for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++)
606 arry[i] = malloc(i+1);
607 for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++)
614 typedef struct _GdkWindowPaint GdkWindowPaint;
616 struct _GdkWindowPaint
624 void RP(GdkDrawable *d)
627 if(GDK_DRAWABLE_TYPE(d) == GDK_DRAWABLE_PIXMAP)
629 if(!GDK_PIXMAP_FBDATA(d)->no_free_mem)
631 guchar *oldmem = GDK_DRAWABLE_FBDATA(d)->mem;
632 guint len = ((GDK_DRAWABLE_IMPL_FBDATA(d)->width * GDK_DRAWABLE_IMPL_FBDATA(d)->depth + 7) / 8) * GDK_DRAWABLE_IMPL_FBDATA(d)->height;
633 GDK_DRAWABLE_IMPL_FBDATA(d)->mem = g_malloc(len);
634 memcpy(GDK_DRAWABLE_IMPL_FBDATA(d)->mem, oldmem, len);
640 GSList *priv = GDK_WINDOW_P(d)->paint_stack;
641 for(; priv; priv = priv->next)
643 GdkWindowPaint *p = priv->data;