From 8a836c07cfcfdab1028943ac145bf0054a0c1fee Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Sat, 6 May 2000 11:57:31 +0000 Subject: [PATCH] Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro * gdk/nanox/*: nano-X port work in progress. * gdk/simple.c: simple test for Gdk. * README.nanox: notes about the port: read this first! * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile with nano-X. --- ChangeLog | 8 + ChangeLog.pre-2-0 | 8 + ChangeLog.pre-2-10 | 8 + ChangeLog.pre-2-2 | 8 + ChangeLog.pre-2-4 | 8 + ChangeLog.pre-2-6 | 8 + ChangeLog.pre-2-8 | 8 + README.nanox | 154 ++++ gdk/nanox/Makefile.am | 51 ++ gdk/nanox/gdkcc-nanox.c | 119 +++ gdk/nanox/gdkcolor-nanox.c | 238 +++++ gdk/nanox/gdkcursor-nanox.c | 26 + gdk/nanox/gdkdnd-nanox.c | 121 +++ gdk/nanox/gdkdrawable-nanox.c | 271 ++++++ gdk/nanox/gdkevents-nanox.c | 441 ++++++++++ gdk/nanox/gdkfont-nanox.c | 146 ++++ gdk/nanox/gdkgc-nanox.c | 103 +++ gdk/nanox/gdkglobals-nanox.c | 0 gdk/nanox/gdkim-nanox.c | 0 gdk/nanox/gdkimage-nanox.c | 118 +++ gdk/nanox/gdkinput-none.c | 79 ++ gdk/nanox/gdkinput.c | 282 ++++++ gdk/nanox/gdkmain-nanox.c | 250 ++++++ gdk/nanox/gdkpixmap-nanox.c | 149 ++++ gdk/nanox/gdkpolyreg-generic.c | 616 +++++++++++++ gdk/nanox/gdkproperty-nanox.c | 55 ++ gdk/nanox/gdkregion-generic.c | 1505 ++++++++++++++++++++++++++++++++ gdk/nanox/gdkregion-nanox.c | 107 +++ gdk/nanox/gdkselection-nanox.c | 89 ++ gdk/nanox/gdkvisual-nanox.c | 95 ++ gdk/nanox/gdkwindow-nanox.c | 600 +++++++++++++ gtk/gtkdnd.c | 2 + gtk/gtkplug.c | 2 + gtk/gtkselection.c | 2 + gtk/gtkwindow.c | 2 + 35 files changed, 5679 insertions(+) create mode 100644 README.nanox create mode 100644 gdk/nanox/Makefile.am create mode 100644 gdk/nanox/gdkcc-nanox.c create mode 100644 gdk/nanox/gdkcolor-nanox.c create mode 100644 gdk/nanox/gdkcursor-nanox.c create mode 100644 gdk/nanox/gdkdnd-nanox.c create mode 100644 gdk/nanox/gdkdrawable-nanox.c create mode 100644 gdk/nanox/gdkevents-nanox.c create mode 100644 gdk/nanox/gdkfont-nanox.c create mode 100644 gdk/nanox/gdkgc-nanox.c create mode 100644 gdk/nanox/gdkglobals-nanox.c create mode 100644 gdk/nanox/gdkim-nanox.c create mode 100644 gdk/nanox/gdkimage-nanox.c create mode 100644 gdk/nanox/gdkinput-none.c create mode 100644 gdk/nanox/gdkinput.c create mode 100644 gdk/nanox/gdkmain-nanox.c create mode 100644 gdk/nanox/gdkpixmap-nanox.c create mode 100644 gdk/nanox/gdkpolyreg-generic.c create mode 100644 gdk/nanox/gdkproperty-nanox.c create mode 100644 gdk/nanox/gdkregion-generic.c create mode 100644 gdk/nanox/gdkregion-nanox.c create mode 100644 gdk/nanox/gdkselection-nanox.c create mode 100644 gdk/nanox/gdkvisual-nanox.c create mode 100644 gdk/nanox/gdkwindow-nanox.c diff --git a/ChangeLog b/ChangeLog index d7f288f319..fa32644a9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d7f288f319..fa32644a9f 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,11 @@ +Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro + + * gdk/nanox/*: nano-X port work in progress. + * gdk/simple.c: simple test for Gdk. + * README.nanox: notes about the port: read this first! + * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile + with nano-X. + Fri May 5 11:18:47 2000 Owen Taylor * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move diff --git a/README.nanox b/README.nanox new file mode 100644 index 0000000000..8c75896148 --- /dev/null +++ b/README.nanox @@ -0,0 +1,154 @@ +Gtk port to nano-X + +STATUS + +Once upon a time I got a few apps working, then started merging +the new features added by Owen (32 bit sizes for windows and buffering). +Since then I haven't found the time to work on it:-/ + + +TODO + +Finish internal window manager abstraction or add proper support in nano-X. +Fix event polling. +Implement GdkImage, GdkRgb stuff. +Put generic region code in generic gdk and/or use the region code from nano-X. +Fix ugly automake stuff for make dist. + +TODO in nano-X + +We need to be able to clip and change the background of windows at runtime +for apps to not look so ugly! +Fonts: wait for better nano-X font implementation. +Properties on windows. + + +If you want to work on this port or get additional informnation, get in +touch with me. +To get the beast to compile you also need to apply the patch below +(any auto* wizard here?): the issue of having two gtk libraries in the +system needs to be addressed too, maybe use libgtk-x11-1.4.so and +libgtk-nanox-1.4.so ... + +Paolo Molaro +lupus@linuxcare.com + + +Index: acconfig.h +=================================================================== +RCS file: /cvs/gnome/gtk+/acconfig.h,v +retrieving revision 1.16 +diff -u -r1.16 acconfig.h +--- acconfig.h 1999/03/20 00:52:29 1.16 ++++ acconfig.h 2000/05/06 11:52:38 +@@ -49,6 +49,8 @@ + /* Most machines will be happy with int or void. IRIX requires '...' */ + #undef SIGNAL_ARG_TYPE + ++#undef USE_NANOX ++ + /* #undef PACKAGE */ + /* #undef VERSION */ + +Index: configure.in +=================================================================== +RCS file: /cvs/gnome/gtk+/configure.in,v +retrieving revision 1.142 +diff -u -r1.142 configure.in +--- configure.in 2000/05/04 00:29:46 1.142 ++++ configure.in 2000/05/06 11:52:38 +@@ -99,6 +99,8 @@ + AC_ARG_WITH(locale, [ --with-locale=LOCALE locale name you want to use ]) + + AC_ARG_WITH(xinput, [ --with-xinput=[no/gxi/xfree] support XInput ]) ++AC_ARG_ENABLE(nanox, [ --enable-nanox use nano-X instead of X11 [default=no]], ++ , enable_nanox="no") + + if test "x$enable_debug" = "xyes"; then + test "$cflags_set" = set || CFLAGS="$CFLAGS -g" +@@ -322,6 +324,8 @@ + saved_cflags="$CFLAGS" + saved_ldflags="$LDFLAGS" + ++if text "x$enable_nanox" = "xno"; then ++ + CFLAGS="$CFLAGS $X_CFLAGS" + LDFLAGS="$LDFLAGS $X_LDFLAGS $X_LIBS" + +@@ -465,6 +469,13 @@ + GTK_LOCALE_FLAGS="-DX_LOCALE" + fi + ++else ++AC_CHECK_LIB(nano-X, GrOpen) ++LIBS="-lnano-X $LIBS" ++ AC_DEFINE(USE_NANOX) ++AM_CONDITIONAL(USE_NANOX, test x$enable_nanox = xyes) ++fi # if enable_nanox ++ + # Checks for header files. + AC_HEADER_STDC + +@@ -602,8 +613,13 @@ + esac + ],[ + # Currently we always use X11 on those systems where we run configure... ++if test x$enable_nanox = xno; then + gdk_windowing=' + #define GDK_WINDOWING_X11' ++else ++gdk_windowing=' ++#define GDK_WINDOWING_NANOX' ++fi + if test x$gdk_wchar_h = xyes; then + gdk_wc=' + #define GDK_HAVE_WCHAR_H 1' +@@ -629,6 +645,7 @@ + docs/Makefile + gdk/Makefile + gdk/x11/Makefile ++gdk/nanox/Makefile + gdk/win32/Makefile + gtk/Makefile + gtk/gtkfeatures.h +Index: gdk/Makefile.am +=================================================================== +RCS file: /cvs/gnome/gtk+/gdk/Makefile.am,v +retrieving revision 1.41 +diff -u -r1.41 Makefile.am +--- gdk/Makefile.am 2000/04/05 04:11:10 1.41 ++++ gdk/Makefile.am 2000/05/06 11:52:38 +@@ -1,6 +1,10 @@ + ## Makefile.am for gtk+/gdk + ++if USE_NANOX ++SUBDIRS=win32 nanox ++else + SUBDIRS=x11 win32 ++endif + + EXTRA_DIST = \ + gdkconfig.h.win32 \ +@@ -36,8 +40,13 @@ + -lm \ + @STRIP_END@ + ++if USE_NANOX + libgdk_la_LIBADD = \ ++ nanox/libgdk-nanox.la ++else ++libgdk_la_LIBADD = \ + x11/libgdk-x11.la ++endif + + # + # setup source file variables +@@ -138,3 +147,8 @@ + @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \ + echo $$p; \ + done ++ ++noinst_PROGRAMS = simple ++simple_DEPENDENCIES = libgdk.la simple.c ++simple_LDADD = libgdk.la ++ diff --git a/gdk/nanox/Makefile.am b/gdk/nanox/Makefile.am new file mode 100644 index 0000000000..fc3d1a568a --- /dev/null +++ b/gdk/nanox/Makefile.am @@ -0,0 +1,51 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = @STRIP_BEGIN@ \ + -DG_LOG_DOMAIN=\"Gdk\" \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gdk \ + @GTK_DEBUG_FLAGS@ \ + @GTK_XIM_FLAGS@ \ + @GTK_LOCALE_FLAGS@ \ + @GLIB_CFLAGS@ \ + @x_cflags@ \ +@STRIP_END@ + +LDADDS = @STRIP_BEGIN@ \ + @x_ldflags@ \ + @x_libs@ \ + @GLIB_LIBS@ \ + -lm \ +@STRIP_END@ + +noinst_LTLIBRARIES = libgdk-nanox.la + +xinput_sources = \ + gdkinput-none.c + +libgdk_nanox_la_SOURCES = \ + gdkcc-nanox.c \ + gdkcolor-nanox.c \ + gdkcursor-nanox.c \ + gdkdnd-nanox.c \ + gdkdrawable-nanox.c \ + gdkevents-nanox.c \ + gdkfont-nanox.c \ + gdkgc-nanox.c \ + gdkglobals-nanox.c \ + gdkim-nanox.c \ + gdkimage-nanox.c \ + gdkinput.c \ + gdkmain-nanox.c \ + gdkpixmap-nanox.c \ + gdkpolyreg-generic.c \ + gdkproperty-nanox.c \ + gdkregion-generic.c \ + gdkselection-nanox.c \ + gdkvisual-nanox.c \ + gdkwindow-nanox.c \ + gdknanox.h \ + gdkprivate-nanox.h \ + gdkinput-none.c + + diff --git a/gdk/nanox/gdkcc-nanox.c b/gdk/nanox/gdkcc-nanox.c new file mode 100644 index 0000000000..3589924346 --- /dev/null +++ b/gdk/nanox/gdkcc-nanox.c @@ -0,0 +1,119 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +GdkColorContext * +gdk_color_context_new (GdkVisual *visual, + GdkColormap *colormap) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkColorContext * +gdk_color_context_new_mono (GdkVisual *visual, + GdkColormap *colormap) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +void +gdk_color_context_free (GdkColorContext *cc) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +gulong +gdk_color_context_get_pixel (GdkColorContext *cc, + gushort red, + gushort green, + gushort blue, + gint *failed) +{ + return RGB2PIXEL(red, green, blue); +} + +void +gdk_color_context_get_pixels (GdkColorContext *cc, + gushort *reds, + gushort *greens, + gushort *blues, + gint ncolors, + gulong *colors, + gint *nallocated) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_color_context_get_pixels_incremental (GdkColorContext *cc, + gushort *reds, + gushort *greens, + gushort *blues, + gint ncolors, + gint *used, + gulong *colors, + gint *nallocated) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +gint +gdk_color_context_query_color (GdkColorContext *cc, + GdkColor *color) +{ + return gdk_color_context_query_colors (cc, color, 1); +} + +gint +gdk_color_context_query_colors (GdkColorContext *cc, + GdkColor *colors, + gint num_colors) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +gint +gdk_color_context_add_palette (GdkColorContext *cc, + GdkColor *palette, + gint num_palette) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void +gdk_color_context_init_dither (GdkColorContext *cc) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_color_context_free_dither (GdkColorContext *cc) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +gulong +gdk_color_context_get_pixel_from_palette (GdkColorContext *cc, + gushort *red, + gushort *green, + gushort *blue, + gint *failed) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +guchar +gdk_color_context_get_index_from_palette (GdkColorContext *cc, + gint *red, + gint *green, + gint *blue, + gint *failed) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} diff --git a/gdk/nanox/gdkcolor-nanox.c b/gdk/nanox/gdkcolor-nanox.c new file mode 100644 index 0000000000..e0fb65be85 --- /dev/null +++ b/gdk/nanox/gdkcolor-nanox.c @@ -0,0 +1,238 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" +#include +#include + +GdkColormap* +gdk_colormap_new (GdkVisual *visual, + gboolean private_cmap) +{ + GdkColormap *colormap; + GdkColormapPrivateX *private; + int size; + int i; + + g_return_val_if_fail (visual != NULL, NULL); + + private = g_new (GdkColormapPrivateX, 1); + colormap = (GdkColormap*) private; + + private->base.visual = visual; + private->base.ref_count = 1; + + colormap->size = visual->colormap_size; + colormap->colors = NULL; + + return colormap; +} + +void +_gdk_colormap_real_destroy (GdkColormap *colormap) +{ +} + + +void +gdk_colormap_sync (GdkColormap *colormap, + gboolean force) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +GdkColormap* +gdk_colormap_get_system (void) +{ + return gdk_colormap_new(gdk_visual_get_system(), 0); +} + + +gint +gdk_colormap_get_system_size (void) +{ + GR_PALETTE palette; + + GrGetSystemPalette(&palette); + return palette.count; +} + +void +gdk_colormap_change (GdkColormap *colormap, + gint ncolors) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +gboolean +gdk_colors_alloc (GdkColormap *colormap, + gboolean contiguous, + gulong *planes, + gint nplanes, + gulong *pixels, + gint npixels) +{ + g_message("unimplemented %s", __FUNCTION__); + return 1; +} + +static struct cspec { + char *name; + int red, green, blue; +} cnames [] = { + {"white", 0xffff, 0xffff, 0xffff}, + {"black", 0, 0, 0}, + {"red", 0xffff, 0, 0}, + {"green", 0, 0xffff, 0}, + {"blue", 0, 0, 0xffff}, + {NULL} +}; + +gboolean +gdk_color_parse (const gchar *spec, + GdkColor *color) +{ + int size, csize, i, j, shift; + double dval; + gchar *end; + int scale[] = {0, 4096, 256, 16, 1}; + int add[] = {0, 4095, 255, 15, 1}; + + g_return_val_if_fail(spec != NULL, 0); + g_return_val_if_fail(color != NULL, 0); + + g_message("color parsing %s", spec); + + if (*spec == '#') { + spec++; + size = strlen(spec); + csize = size/3; + shift = 16-csize*4; + if (size > 12 || size % 3) + return 0; + j = spec[csize]; + spec[csize] = 0; + color->red = strtol(spec, &end, 16) << shift; + if (end == spec || *end != '\0') + return 0; + spec[csize] = j; + spec += csize; + /* green */ + j = spec[csize]; + spec[csize] = 0; + color->green = strtol(spec, &end, 16) << shift; + if (end == spec || *end != '\0') + return 0; + spec[csize] = j; + spec += csize; + /* blue */ + color->blue = strtol(spec, &end, 16) << shift; + if (end == spec || *end != '\0') + return 0; + return 1; + } else if (!strncmp(spec, "rgb:", 4)) { + spec += 4; + color->red = strtol(spec, &end, 16); + if (end == spec || *end != '/') + return 0; + csize = end-spec; + color->red *= scale[csize]; + color->red += add[csize]; + spec += csize + 1; + /* green */ + color->green = strtol(spec, &end, 16); + if (end == spec || *end != '/') + return 0; + csize = end-spec; + color->green *= scale[csize]; + color->green += add[csize]; + spec += csize + 1; + /* blue */ + color->blue = strtol(spec, &end, 16); + if (end == spec || *end != '\0') + return 0; + csize = end-spec; + color->blue *= scale[csize]; + color->blue += add[csize]; + return 1; + } else if (!strncmp(spec, "rgbi:", 5)) { + spec += 5; + dval = strtod(spec, &end); + if (end == spec || *end != '/' || dval > 1.0 || dval < 0) + return 0; + color->red = dval*0xffff; + spec += end-spec + 1; + /* green */ + dval = strtod(spec, &end); + if (end == spec || *end != '/' || dval > 1.0 || dval < 0) + return 0; + color->green = dval*0xffff; + spec += end-spec + 1; + /* blue */ + dval = strtod(spec, &end); + if (end == spec || *end != '0' || dval > 1.0 || dval < 0) + return 0; + color->blue = dval*0xffff; + return 1; + } else { + /* use a cdb database, instead, later */ + for (i=0; cnames[i].name; ++i) { + if (strcmp(cnames[i].name, spec)) + continue; + color->red = cnames[i].red; + color->green = cnames[i].green; + color->blue = cnames[i].blue; + return 1; + } + if (spec[0] == 'g' && spec[1] == 'r' && (spec[2] == 'a' || spec[2] == 'e') && spec[3] == 'y') { + dval = strtol(spec+4, NULL, 10)/100; + color->red = color->green = color->blue = 255 * dval; + return 1; + } + } + + return 0; +} + +void +gdk_colors_free (GdkColormap *colormap, + gulong *in_pixels, + gint in_npixels, + gulong planes) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_colormap_free_colors (GdkColormap *colormap, + GdkColor *colors, + gint ncolors) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +gint +gdk_colormap_alloc_colors (GdkColormap *colormap, + GdkColor *colors, + gint ncolors, + gboolean writeable, + gboolean best_match, + gboolean *success) +{ + int i; + + for (i=0; i < ncolors;++i) + colors[i].pixel = RGB2PIXEL(colors[i].red>>8, colors[i].green>>8, colors[i].blue>>8); + success = 1; + return 1; +} + + +gboolean +gdk_color_change (GdkColormap *colormap, + GdkColor *color) +{ + g_message("unimplemented %s", __FUNCTION__); + return 1; +} + + diff --git a/gdk/nanox/gdkcursor-nanox.c b/gdk/nanox/gdkcursor-nanox.c new file mode 100644 index 0000000000..a3b7fb0ca1 --- /dev/null +++ b/gdk/nanox/gdkcursor-nanox.c @@ -0,0 +1,26 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +GdkCursor* +gdk_cursor_new (GdkCursorType cursor_type) { + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkCursor* +gdk_cursor_new_from_pixmap (GdkPixmap *source, + GdkPixmap *mask, + GdkColor *fg, + GdkColor *bg, + gint x, + gint y) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +void +_gdk_cursor_destroy (GdkCursor *cursor) +{ +} + diff --git a/gdk/nanox/gdkdnd-nanox.c b/gdk/nanox/gdkdnd-nanox.c new file mode 100644 index 0000000000..d9fc05537b --- /dev/null +++ b/gdk/nanox/gdkdnd-nanox.c @@ -0,0 +1,121 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + + +GdkDragContext * +gdk_drag_context_new (void) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +void +gdk_drag_context_ref (GdkDragContext *context) +{ +} + +void +gdk_drag_context_unref (GdkDragContext *context) +{ +} + +void +gdk_dnd_init (void) +{ +} + +GdkDragContext * +gdk_drag_begin (GdkWindow *window, + GList *targets) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +guint32 +gdk_drag_get_protocol (guint32 xid, + GdkDragProtocol *protocol) +{ + *protocol = GDK_DRAG_PROTO_NONE; + return 0; +} + +void +gdk_drag_find_window (GdkDragContext *context, + GdkWindow *drag_window, + gint x_root, + gint y_root, + GdkWindow **dest_window, + GdkDragProtocol *protocol) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +gboolean +gdk_drag_motion (GdkDragContext *context, + GdkWindow *dest_window, + GdkDragProtocol protocol, + gint x_root, + gint y_root, + GdkDragAction suggested_action, + GdkDragAction possible_actions, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_drag_drop (GdkDragContext *context, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_drag_abort (GdkDragContext *context, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_drag_status (GdkDragContext *context, + GdkDragAction action, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_drop_reply (GdkDragContext *context, + gboolean ok, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_drop_finish (GdkDragContext *context, + gboolean success, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_register_dnd (GdkWindow *window) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +GdkAtom +gdk_drag_get_selection (GdkDragContext *context) +{ + return GDK_NONE; +} + + diff --git a/gdk/nanox/gdkdrawable-nanox.c b/gdk/nanox/gdkdrawable-nanox.c new file mode 100644 index 0000000000..10c67049b3 --- /dev/null +++ b/gdk/nanox/gdkdrawable-nanox.c @@ -0,0 +1,271 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +static void gdk_nanox_drawable_destroy (GdkDrawable *drawable); + +static void gdk_nanox_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_nanox_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_nanox_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints); +static void gdk_nanox_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); +static void gdk_nanox_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); +static void gdk_nanox_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_nanox_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_nanox_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_nanox_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); + +GdkDrawableClass _gdk_nanox_drawable_class = { + gdk_nanox_drawable_destroy, + _gdk_nanox_gc_new, + gdk_nanox_draw_rectangle, + gdk_nanox_draw_arc, + gdk_nanox_draw_polygon, + gdk_nanox_draw_text, + gdk_nanox_draw_text_wc, + gdk_nanox_draw_drawable, + gdk_nanox_draw_points, + gdk_nanox_draw_segments, + gdk_nanox_draw_lines +}; + +GdkColormap* +gdk_drawable_get_colormap (GdkDrawable *drawable) +{ + GdkDrawablePrivate *drawable_private; + + g_return_val_if_fail (drawable != NULL, NULL); + drawable_private = (GdkDrawablePrivate*) drawable; + + if (!GDK_DRAWABLE_DESTROYED (drawable)) + { + if (drawable_private->colormap == NULL && + GDK_IS_WINDOW (drawable)) + { + /*XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (drawable), + GDK_DRAWABLE_XID (drawable), + &window_attributes); + drawable_private->colormap = gdk_colormap_lookup (window_attributes.colormap);*/ + } + + return drawable_private->colormap; + } + + return NULL; +} + +void +gdk_drawable_set_colormap (GdkDrawable *drawable, + GdkColormap *colormap) +{ + GdkDrawablePrivate *drawable_private; + GdkColormapPrivateX *colormap_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (colormap != NULL); + + drawable_private = (GdkDrawablePrivate *)drawable; + colormap_private = (GdkColormapPrivateX *)colormap; + + if (!GDK_DRAWABLE_DESTROYED (drawable)) + { + if (GDK_IS_WINDOW (drawable)) + { + g_return_if_fail (colormap_private->base.visual != + ((GdkColormapPrivate *)(drawable_private->colormap))->visual); + + } + + if (drawable_private->colormap) + gdk_colormap_unref (drawable_private->colormap); + drawable_private->colormap = colormap; + gdk_colormap_ref (drawable_private->colormap); + + if (GDK_IS_WINDOW (drawable) && + drawable_private->window_type != GDK_WINDOW_TOPLEVEL) + /*gdk_window_add_colormap_windows (drawable);*/; + } +} + +static void +gdk_nanox_drawable_destroy (GdkDrawable *drawable) +{ + +} + +static void +gdk_nanox_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height) +{ + if (filled) + GrFillRect (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width, height); + else + GrRect (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width, height); +} + +static void +gdk_nanox_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + /* this is not an arc, obviously */ + if (filled) + GrFillEllipse (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width/2, height/2); + else + GrEllipse (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width/2, height/2); +} + +static void +gdk_nanox_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints) +{ + GR_POINT *new_points = g_new(GR_POINT, npoints); + int i; + for (i=0; i < npoints;++i) { + new_points[i].x = points[i].x; + new_points[i].y = points[i].y; + } + if (filled) + { + GrFillPoly (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), npoints, new_points); + } + else + { + GrPoly (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), npoints, new_points); + } + g_free(new_points); +} + +static void +gdk_nanox_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(font)); + GrText (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, text, text_length, TF_UTF8|TF_BASELINE); +} + +static void +gdk_nanox_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(font)); + GrText (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, text, text_length, TF_UC32|TF_BASELINE); +} + +static void +gdk_nanox_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GrCopyArea(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), xdest, ydest, + width, height, GDK_DRAWABLE_XID(src), xsrc, ysrc, 0); +} + +static void +gdk_nanox_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + int i; + for (i=0; i < npoints; ++i) + GrPoint(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), points[i].x, points[i].y); +} + +static void +gdk_nanox_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + int i; + for (i=0; i < nsegs; ++i) + GrLine(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); +} + +static void +gdk_nanox_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + int i; + for (i=0; i < npoints-1; ++i) + GrLine(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), points[i].x, points[i].y, points[i+1].x, points[i+1].y); +} + diff --git a/gdk/nanox/gdkevents-nanox.c b/gdk/nanox/gdkevents-nanox.c new file mode 100644 index 0000000000..81d9cb4bc7 --- /dev/null +++ b/gdk/nanox/gdkevents-nanox.c @@ -0,0 +1,441 @@ +#include "gdk.h" +#include "gdkinternals.h" +#include "gdkprivate-nanox.h" + +typedef struct _GdkEventPrivate GdkEventPrivate; + +#define DOUBLE_CLICK_TIME 250 +#define TRIPLE_CLICK_TIME 500 +#define DOUBLE_CLICK_DIST 5 +#define TRIPLE_CLICK_DIST 5 + +#define GR_BUTTON_TO_GDK(b) b&LBUTTON? 1: (b&MBUTTON? 2: (b&RBUTTON? 3: 0)) + +static guint gr_mod_to_gdk(guint mods, guint buttons) { + guint res=0; + if (mods & GR_MODIFIER_SHIFT) + res |= GDK_SHIFT_MASK; + if (mods & GR_MODIFIER_CTRL) + res |= GDK_CONTROL_MASK; + if (mods & GR_MODIFIER_META) + res |= GDK_MOD1_MASK; + if (buttons & LBUTTON) + res |= GDK_BUTTON1_MASK; + if (buttons & MBUTTON) + res |= GDK_BUTTON2_MASK; + if (buttons & RBUTTON) + res |= GDK_BUTTON3_MASK; + return res; +} + +static gboolean gdk_event_prepare (gpointer source_data, + GTimeVal *current_time, + gint *timeout, + gpointer user_data); +static gboolean gdk_event_check (gpointer source_data, + GTimeVal *current_time, + gpointer user_data); +static gboolean gdk_event_dispatch (gpointer source_data, + GTimeVal *current_time, + gpointer user_data); + +typedef enum +{ + /* Following flag is set for events on the event queue during + * translation and cleared afterwards. + */ + GDK_EVENT_PENDING = 1 << 0 +} GdkEventFlags; + +struct _GdkEventPrivate +{ + GdkEvent event; + guint flags; +}; + + +static GSourceFuncs event_funcs = { + gdk_event_prepare, + gdk_event_check, + gdk_event_dispatch, + (GDestroyNotify)g_free +}; + +GPollFD event_poll_fd; +extern int sock; +static guint serial_value = 1; + +static int +events_idle () { + gdk_events_queue(); + return TRUE; +} + +void +gdk_events_init (void) +{ + g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL); + + event_poll_fd.fd = sock; + event_poll_fd.events = G_IO_IN; + + g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS); + + g_idle_add(events_idle, NULL); + +} + +static gboolean +gdk_event_prepare (gpointer source_data, + GTimeVal *current_time, + gint *timeout, + gpointer user_data) +{ + gboolean retval; + + GDK_THREADS_ENTER (); + + *timeout = -1; + + retval = (gdk_event_queue_find_first () != NULL); + + GDK_THREADS_LEAVE (); + + return retval; +} + +static gboolean +gdk_event_check (gpointer source_data, + GTimeVal *current_time, + gpointer user_data) +{ + gboolean retval; + + GDK_THREADS_ENTER (); + + if (event_poll_fd.revents & G_IO_IN) + //retval = (gdk_event_queue_find_first () != NULL); + retval = 1; + else + retval = FALSE; + + GDK_THREADS_LEAVE (); + + return retval; +} + +static gboolean +gdk_event_dispatch (gpointer source_data, + GTimeVal *current_time, + gpointer user_data) +{ + GdkEvent *event; + + GDK_THREADS_ENTER (); + + gdk_events_queue(); + event = gdk_event_unqueue(); + + if (event) + { + if (gdk_event_func) + (*gdk_event_func) (event, gdk_event_data); + + gdk_event_free (event); + } + + GDK_THREADS_LEAVE (); + + return TRUE; +} + + +gboolean +gdk_events_pending (void) +{ + return gdk_event_queue_find_first(); +} + +GdkEvent* +gdk_event_get_graphics_expose (GdkWindow *window) +{ + return NULL; +} + +static gint gdk_event_translate (GdkEvent *event, GR_EVENT *xevent) { + GdkWindow *window=NULL; + GdkWindowPrivate *window_private=NULL; + gint return_val = FALSE; + static int lastx=0, lasty=0, lastrootx=0, lastrooty=0; + + if (xevent->type == GR_EVENT_TYPE_FDINPUT) + return 0; + window = gdk_window_lookup (xevent->general.wid); + /* FIXME: window might be a GdkPixmap!!! */ + + window_private = (GdkWindowPrivate *) window; + + if (window != NULL) + gdk_window_ref (window); + + event->any.window = window; + event->any.send_event = FALSE; + + if (window_private && GDK_DRAWABLE_DESTROYED (window)) + { + return FALSE; + } + else + { + /* Check for filters for this window + */ + GdkFilterReturn result = GDK_FILTER_CONTINUE; + /*result = gdk_event_apply_filters (xevent, event, + window_private + ?window_private->filters + :gdk_default_filters); + */ + if (result != GDK_FILTER_CONTINUE) + { + return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + } + } + + return_val = TRUE; + + //g_message("got event (%p) %d", window, xevent->type); + switch (xevent->type) + { + case GR_EVENT_TYPE_KEY_DOWN: + event->key.keyval = xevent->keystroke.ch; + event->key.type = GDK_KEY_PRESS; + event->key.window = window; + event->key.time = serial_value++; + event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons); + event->key.string = g_strdup_printf ("%c", xevent->keystroke.ch); + event->key.length = 1; + + break; + case GR_EVENT_TYPE_KEY_UP: + event->key.keyval = xevent->keystroke.ch; + event->key.type = GDK_KEY_RELEASE; + event->key.window = window; + event->key.time = serial_value++; + event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons)|GDK_RELEASE_MASK; + event->key.string = NULL; + event->key.length = 0; + + break; + case GR_EVENT_TYPE_BUTTON_DOWN: + event->button.type = GDK_BUTTON_PRESS; + event->button.window = window; + event->button.time = serial_value++; + event->button.x = xevent->button.x; + event->button.y = xevent->button.y; + event->button.x_root = (gfloat)xevent->button.rootx; + event->button.y_root = (gfloat)xevent->button.rooty; + event->button.pressure = 0.5; + event->button.xtilt = 0; + event->button.ytilt = 0; + event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons); + event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons); + event->button.source = GDK_SOURCE_MOUSE; + event->button.deviceid = GDK_CORE_POINTER; + g_message("button down: %d", event->button.button); + gdk_event_button_generate (event); + break; + case GR_EVENT_TYPE_BUTTON_UP: + event->button.type = GDK_BUTTON_RELEASE; + event->button.window = window; + event->button.time = serial_value++; + event->button.x = xevent->button.x; + event->button.y = xevent->button.y; + event->button.x_root = (gfloat)xevent->button.rootx; + event->button.y_root = (gfloat)xevent->button.rooty; + event->button.pressure = 0.5; + event->button.xtilt = 0; + event->button.ytilt = 0; + event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons)|GDK_RELEASE_MASK; + event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons); + event->button.source = GDK_SOURCE_MOUSE; + event->button.deviceid = GDK_CORE_POINTER; + g_message("button up: %d", event->button.button); + gdk_event_button_generate (event); + break; + case GR_EVENT_TYPE_MOUSE_MOTION: + event->motion.type = GDK_MOTION_NOTIFY; + event->motion.window = window; + event->motion.time = serial_value++; + event->motion.x = xevent->mouse.x; + event->motion.y = xevent->mouse.y; + event->motion.x_root = (gfloat)xevent->mouse.rootx; + event->motion.y_root = (gfloat)xevent->mouse.rooty; + event->motion.pressure = 0.5; + event->motion.xtilt = 0; + event->motion.ytilt = 0; + event->motion.state = gr_mod_to_gdk(xevent->mouse.modifiers, xevent->mouse.buttons); + event->motion.is_hint = 0; + event->motion.source = GDK_SOURCE_MOUSE; + event->motion.deviceid = GDK_CORE_POINTER; + + break; + case GR_EVENT_TYPE_MOUSE_POSITION: + return_val = FALSE; + break; + case GR_EVENT_TYPE_MOUSE_ENTER: + event->crossing.type = GDK_ENTER_NOTIFY; + event->crossing.window = window; + event->crossing.subwindow = NULL; + event->crossing.time = serial_value++; + event->crossing.detail = GDK_NOTIFY_UNKNOWN; + //g_message("subwindow 1: %p", event->crossing.subwindow); + /* other stuff here , x, y, x_root, y_root */ + break; + case GR_EVENT_TYPE_MOUSE_EXIT: + event->crossing.type = GDK_LEAVE_NOTIFY; + event->crossing.window = window; + event->crossing.subwindow = NULL; + event->crossing.time = serial_value++; + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_UNKNOWN; + //g_message("subwindow 2: %p", event->crossing.subwindow); + /* other stuff here , x, y, x_root, y_root */ + break; + case GR_EVENT_TYPE_FOCUS_IN: + case GR_EVENT_TYPE_FOCUS_OUT: + event->focus_change.type = GDK_FOCUS_CHANGE; + event->focus_change.window = window; + event->focus_change.in = (xevent->general.type == GR_EVENT_TYPE_FOCUS_IN); + + break; + case GR_EVENT_TYPE_UPDATE: + case GR_EVENT_TYPE_CHLD_UPDATE: + if (xevent->update.utype == GR_UPDATE_MAP) { + event->any.type = GDK_MAP; + event->any.window = window; + + } else if (xevent->update.utype == GR_UPDATE_UNMAP) { + event->any.type = GDK_UNMAP; + event->any.window = window; + + if (gdk_xgrab_window == window_private) + gdk_xgrab_window = NULL; + } else { + if (!window || GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_CHILD) + return_val = FALSE; + else + { + event->configure.type = GDK_CONFIGURE; + event->configure.window = window; + event->configure.width = xevent->update.width; + event->configure.height = xevent->update.height; + event->configure.x = xevent->update.x; + event->configure.y = xevent->update.y; + window_private->x = event->configure.x; + window_private->y = event->configure.y; + window_private->drawable.width = event->configure.width; + window_private->drawable.height = event->configure.height; + if (window_private->resize_count > 1) + window_private->resize_count -= 1; + } + } + break; + case GR_EVENT_TYPE_EXPOSURE: + + event->expose.type = GDK_EXPOSE; + event->expose.window = window; + event->expose.area.x = xevent->exposure.x; + event->expose.area.y = xevent->exposure.y; + event->expose.area.width = xevent->exposure.width; + event->expose.area.height = xevent->exposure.height; + event->expose.count = 0; + + break; + case GR_EVENT_TYPE_FDINPUT: + case GR_EVENT_TYPE_NONE: + return_val = FALSE; + break; + default: + return_val = FALSE; + g_message("event %d not handled\n", xevent->type); + } + if (return_val) + { + if (event->any.window) + gdk_window_ref (event->any.window); + if (((event->any.type == GDK_ENTER_NOTIFY) || + (event->any.type == GDK_LEAVE_NOTIFY)) && + (event->crossing.subwindow != NULL)) + gdk_window_ref (event->crossing.subwindow); + } + else + { + /* Mark this event as having no resources to be freed */ + event->any.window = NULL; + event->any.type = GDK_NOTHING; + } + + if (window) + gdk_window_unref (window); + + return return_val; +} + +void +gdk_events_queue (void) +{ + GList *node; + GdkEvent *event; + GR_EVENT xevent; + + while (!gdk_event_queue_find_first()) + { + GrCheckNextEvent (&xevent); + if (!xevent.type) + return; + + event = gdk_event_new (); + + event->any.type = GDK_NOTHING; + event->any.window = NULL; + event->any.send_event = FALSE; + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + gdk_event_queue_append (event); + node = gdk_queued_tail; + + if (gdk_event_translate (event, &xevent)) + { + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + //g_message("got event: %d", event->type); + } + else + { + gdk_event_queue_remove_link (node); + g_list_free_1 (node); + gdk_event_free (event); + } + } +} + +gboolean +gdk_event_send_client_message (GdkEvent *event, guint32 xid) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void +gdk_event_send_clientmessage_toall (GdkEvent *event) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_flush (void) +{ + GrFlush(); +} + + diff --git a/gdk/nanox/gdkfont-nanox.c b/gdk/nanox/gdkfont-nanox.c new file mode 100644 index 0000000000..19818b5ebf --- /dev/null +++ b/gdk/nanox/gdkfont-nanox.c @@ -0,0 +1,146 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +static GR_GC_ID gc_for_width = 0; + +#define ENSURE_GC if (!gc_for_width) gc_for_width = GrNewGC(); + +GdkFont* +gdk_font_load (const gchar *font_name) +{ + GdkFont *font; + GdkFontPrivateX *private; + GR_FONTID xfont; + + g_return_val_if_fail (font_name != NULL, NULL); + + xfont = GrCreateFont("System", 0, 0); + if (xfont == 0) + return NULL; + + { + private = g_new (GdkFontPrivateX, 1); + private->xfont = xfont; + private->base.ref_count = 1; + + font = (GdkFont*) private; + font->type = GDK_FONT_FONT; + font->ascent = 8; + font->descent = 4; + + } + + return font; +} + +GdkFont* +gdk_fontset_load (const gchar *fontset_name) +{ + return gdk_font_load(fontset_name); +} + +void +_gdk_font_destroy (GdkFont *font) +{ + GrUnloadFont(GDK_FONT_XFONT(font)); +} + +gint +_gdk_font_strlen (GdkFont *font, + const gchar *str) +{ + return strlen(str); +} + +gint +gdk_font_id (const GdkFont *font) +{ + return GDK_FONT_XFONT(font); +} + +gboolean +gdk_font_equal (const GdkFont *fonta, + const GdkFont *fontb) +{ + return GDK_FONT_XFONT(fonta) == GDK_FONT_XFONT(fontb); +} + +gint +gdk_text_width (GdkFont *font, + const gchar *text, + gint text_length) +{ + gint width, height, base; + ENSURE_GC; + GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font)); + GrGetGCTextSize(gc_for_width, text, text_length, TF_UTF8, &width, &height, &base); + return width; +} + +gint +gdk_text_width_wc (GdkFont *font, + const GdkWChar *text, + gint text_length) +{ + gint width, height, base; + ENSURE_GC; + GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font)); + GrGetGCTextSize(gc_for_width, text, text_length, TF_UC32, &width, &height, &base); + return width; +} + + +void +gdk_text_extents (GdkFont *font, + const gchar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ + gint mwidth, height, base; + ENSURE_GC; + GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font)); + GrGetGCTextSize(gc_for_width, text, text_length, TF_UTF8, &mwidth, &height, &base); + if (width) + *width = mwidth; + if (lbearing) + *lbearing = 0; + if (rbearing) + *rbearing = 0; + if (ascent) + *ascent = base; + if (descent) + *descent = height - base; + +} + +void +gdk_text_extents_wc (GdkFont *font, + const GdkWChar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ + gint mwidth, height, base; + ENSURE_GC; + GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font)); + GrGetGCTextSize(gc_for_width, text, text_length, TF_UC32, &mwidth, &height, &base); + if (width) + *width = mwidth; + if (lbearing) + *lbearing = 0; + if (rbearing) + *rbearing = 0; + if (ascent) + *ascent = base; + if (descent) + *descent = height - base; +} + + diff --git a/gdk/nanox/gdkgc-nanox.c b/gdk/nanox/gdkgc-nanox.c new file mode 100644 index 0000000000..78246a3dc0 --- /dev/null +++ b/gdk/nanox/gdkgc-nanox.c @@ -0,0 +1,103 @@ +#include "gdkprivate-nanox.h" + +static void gdk_nanox_gc_destroy (GdkGC *gc); +static void gdk_nanox_gc_get_values (GdkGC *gc, + GdkGCValues *values); +static void gdk_nanox_gc_set_values (GdkGC *gc, + GdkGCValues *values, + GdkGCValuesMask values_mask); +static void gdk_nanox_gc_set_dashes (GdkGC *gc, + gint dash_offset, + gchar dash_list[], + gint n); + +static GdkGCClass gdk_nanox_gc_class = { + gdk_nanox_gc_destroy, + gdk_nanox_gc_get_values, + gdk_nanox_gc_set_values, + gdk_nanox_gc_set_dashes +}; + +GdkGC * +_gdk_nanox_gc_new (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + + GdkGC *gc; + GdkGCPrivate *private; + + gc = gdk_gc_alloc (); + private = (GdkGCPrivate *)gc; + + private->klass = &gdk_nanox_gc_class; + private->klass_data = g_new (GdkGCXData, 1); + + GDK_GC_XDATA(gc)->xgc = GrNewGC(); + GrSetGCUseBackground(GDK_GC_XDATA(gc)->xgc, 0); + GrSetGCForeground(GDK_GC_XDATA(gc)->xgc, RGB2PIXEL(0,0,0)); + GrSetGCBackground(GDK_GC_XDATA(gc)->xgc, RGB2PIXEL(0,0,0)); + g_message("created GC: %d", GDK_GC_XDATA(gc)->xgc); + return gc; +} + + +static void +gdk_nanox_gc_destroy (GdkGC *gc) +{ + GrDestroyGC (GDK_GC_XGC (gc)); + g_free (GDK_GC_XDATA (gc)); +} + +static void +gdk_nanox_gc_get_values (GdkGC *gc, + GdkGCValues *values) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +static void +gdk_nanox_gc_set_values (GdkGC *gc, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + if (values_mask & GDK_GC_FOREGROUND) + GrSetGCForeground(GDK_GC_XGC(gc), values->foreground.pixel); + else if (values_mask & GDK_GC_BACKGROUND) + GrSetGCBackground(GDK_GC_XGC(gc), values->background.pixel); + else if (values_mask & GDK_GC_FONT) + GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(values->font)); +} + +static void +gdk_nanox_gc_set_dashes (GdkGC *gc, + gint dash_offset, + gchar dash_list[], + gint n) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_gc_set_clip_rectangle (GdkGC *gc, + GdkRectangle *rectangle) +{ + //g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_gc_set_clip_region (GdkGC *gc, + GdkRegion *region) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc) +{ + GDK_GC_XDATA(dst_gc)->xgc = GrCopyGC(GDK_GC_XGC(src_gc)); +} + + diff --git a/gdk/nanox/gdkglobals-nanox.c b/gdk/nanox/gdkglobals-nanox.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gdk/nanox/gdkim-nanox.c b/gdk/nanox/gdkim-nanox.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gdk/nanox/gdkimage-nanox.c b/gdk/nanox/gdkimage-nanox.c new file mode 100644 index 0000000000..e0b580ac42 --- /dev/null +++ b/gdk/nanox/gdkimage-nanox.c @@ -0,0 +1,118 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +static void +gdk_nanox_image_destroy (GdkImage *image); + +static void +gdk_image_put_normal (GdkImage *image, + GdkDrawable *drawable, + GdkGC *gc, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); + +static GdkImageClass image_class_normal = { + gdk_nanox_image_destroy, + gdk_image_put_normal +}; + +void +gdk_image_exit (void) +{ +} + + +GdkImage * +gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +void +gdk_image_init (void) +{ +} + + +GdkImage* +gdk_image_new (GdkImageType type, + GdkVisual *visual, + gint width, + gint height) +{ + GdkImage *image; + GdkImagePrivateX *private; + + private = g_new (GdkImagePrivateX, 1); + image = (GdkImage*) private; + + private->base.ref_count = 1; + image->type = type; + image->visual = visual; + image->width = width; + image->height = height; + image->depth = visual->depth; + + private->base.klass = &image_class_normal; + //private->ximage = NULL; + /* more: implement as a pixmap? */ + return image; +} + + +GdkImage* +gdk_image_get (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + + +guint32 +gdk_image_get_pixel (GdkImage *image, + gint x, + gint y) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void +gdk_image_put_pixel (GdkImage *image, + gint x, + gint y, + guint32 pixel) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +static void +gdk_nanox_image_destroy (GdkImage *image) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +static void +gdk_image_put_normal (GdkImage *image, + GdkDrawable *drawable, + GdkGC *gc, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + g_message("unimplemented %s", __FUNCTION__); +} + diff --git a/gdk/nanox/gdkinput-none.c b/gdk/nanox/gdkinput-none.c new file mode 100644 index 0000000000..d3aba3dd93 --- /dev/null +++ b/gdk/nanox/gdkinput-none.c @@ -0,0 +1,79 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gdkinputprivate.h" + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +static void gdk_input_none_get_pointer (GdkWindow *window, + guint32 deviceid, + gdouble *x, + gdouble *y, + gdouble *pressure, + gdouble *xtilt, + gdouble *ytilt, + GdkModifierType *mask); + +void +gdk_input_init (void) +{ + gdk_input_vtable.set_mode = NULL; + gdk_input_vtable.set_axes = NULL; + gdk_input_vtable.set_key = NULL; + gdk_input_vtable.motion_events = NULL; + gdk_input_vtable.get_pointer = gdk_input_none_get_pointer; + gdk_input_vtable.grab_pointer = NULL; + gdk_input_vtable.ungrab_pointer = NULL; + gdk_input_vtable.configure_event = NULL; + gdk_input_vtable.enter_event = NULL; + gdk_input_vtable.other_event = NULL; + gdk_input_vtable.window_none_event = NULL; + gdk_input_vtable.enable_window = NULL; + gdk_input_vtable.disable_window = NULL; + + gdk_input_devices = g_list_append (NULL, (GdkDeviceInfo *) &gdk_input_core_info); + + gdk_input_ignore_core = FALSE; +} + +static void +gdk_input_none_get_pointer (GdkWindow *window, + guint32 deviceid, + gdouble *x, + gdouble *y, + gdouble *pressure, + gdouble *xtilt, + gdouble *ytilt, + GdkModifierType *mask) +{ + gint x_int, y_int; + + gdk_window_get_pointer (window, &x_int, &y_int, mask); + + if (x) *x = x_int; + if (y) *y = y_int; + if (pressure) *pressure = 0.5; + if (xtilt) *xtilt = 0; + if (ytilt) *ytilt = 0; +} diff --git a/gdk/nanox/gdkinput.c b/gdk/nanox/gdkinput.c new file mode 100644 index 0000000000..6dd0195746 --- /dev/null +++ b/gdk/nanox/gdkinput.c @@ -0,0 +1,282 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" +#include "gdkinputprivate.h" + +static const GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y }; + +const GdkDeviceInfo gdk_input_core_info = +{ + GDK_CORE_POINTER, + "Core Pointer", + GDK_SOURCE_MOUSE, + GDK_MODE_SCREEN, + TRUE, + 2, + gdk_input_core_axes +}; + +/* Global variables */ + +GdkInputVTable gdk_input_vtable; +/* information about network port and host for gxid daemon */ +gchar *gdk_input_gxid_host; +gint gdk_input_gxid_port; +gint gdk_input_ignore_core; + +GList *gdk_input_devices; +GList *gdk_input_windows; + +GList * +gdk_input_list_devices (void) +{ + return gdk_input_devices; +} + +void +gdk_input_set_source (guint32 deviceid, GdkInputSource source) +{ + GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid); + g_return_if_fail (gdkdev != NULL); + + gdkdev->info.source = source; +} + +gboolean +gdk_input_set_mode (guint32 deviceid, GdkInputMode mode) +{ + if (deviceid == GDK_CORE_POINTER) + return FALSE; + + if (gdk_input_vtable.set_mode) + return gdk_input_vtable.set_mode(deviceid,mode); + else + return FALSE; +} + +void +gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes) +{ + if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes) + gdk_input_vtable.set_axes (deviceid, axes); +} + +void gdk_input_set_key (guint32 deviceid, + guint index, + guint keyval, + GdkModifierType modifiers) +{ + if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key) + gdk_input_vtable.set_key (deviceid, index, keyval, modifiers); +} + +GdkTimeCoord * +gdk_input_motion_events (GdkWindow *window, + guint32 deviceid, + guint32 start, + guint32 stop, + gint *nevents_return) +{ + GdkTimeCoord *coords; + int i; + + g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (GDK_DRAWABLE_DESTROYED (window)) + return NULL; + + if (deviceid == GDK_CORE_POINTER) + { + return NULL; + } + else + { + if (gdk_input_vtable.motion_events) + { + return gdk_input_vtable.motion_events(window, + deviceid, start, stop, + nevents_return); + } + else + { + *nevents_return = 0; + return NULL; + } + } +} + +gint +gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + if (gdk_input_vtable.enable_window) + return gdk_input_vtable.enable_window (window, gdkdev); + else + return TRUE; +} + +gint +gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + if (gdk_input_vtable.disable_window) + return gdk_input_vtable.disable_window(window,gdkdev); + else + return TRUE; +} + + +GdkInputWindow * +gdk_input_window_find(GdkWindow *window) +{ + GList *tmp_list; + + for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next) + if (((GdkInputWindow *)(tmp_list->data))->window == window) + return (GdkInputWindow *)(tmp_list->data); + + return NULL; /* Not found */ +} + +/* FIXME: this routine currently needs to be called between creation + and the corresponding configure event (because it doesn't get the + root_relative_geometry). This should work with + gtk_window_set_extension_events, but will likely fail in other + cases */ + +void +gdk_input_set_extension_events (GdkWindow *window, gint mask, + GdkExtensionMode mode) +{ + GdkWindowPrivate *window_private; + GList *tmp_list; + GdkInputWindow *iw; + + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + window_private = (GdkWindowPrivate*) window; + if (GDK_DRAWABLE_DESTROYED (window)) + return; + + if (mode == GDK_EXTENSION_EVENTS_NONE) + mask = 0; + + if (mask != 0) + { + iw = g_new(GdkInputWindow,1); + + iw->window = window; + iw->mode = mode; + + iw->obscuring = NULL; + iw->num_obscuring = 0; + iw->grabbed = FALSE; + + gdk_input_windows = g_list_append(gdk_input_windows,iw); + window_private->extension_events = mask; + + /* Add enter window events to the event mask */ + /* FIXME, this is not needed for XINPUT_NONE */ + gdk_window_set_events (window, + gdk_window_get_events (window) | + GDK_ENTER_NOTIFY_MASK); + } + else + { + iw = gdk_input_window_find (window); + if (iw) + { + gdk_input_windows = g_list_remove(gdk_input_windows,iw); + g_free(iw); + } + + window_private->extension_events = 0; + } + + for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data); + + if (gdkdev->info.deviceid != GDK_CORE_POINTER) + { + if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED + && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL)) + gdk_input_enable_window(window,gdkdev); + else + gdk_input_disable_window(window,gdkdev); + } + } +} + +void +gdk_input_window_destroy (GdkWindow *window) +{ + GdkInputWindow *input_window; + + input_window = gdk_input_window_find (window); + g_return_if_fail (input_window != NULL); + + gdk_input_windows = g_list_remove (gdk_input_windows,input_window); + g_free(input_window); +} + +void +gdk_input_exit (void) +{ + GList *tmp_list; + GdkDevicePrivate *gdkdev; + + for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (gdkdev->info.deviceid != GDK_CORE_POINTER) + { + gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED); + + g_free(gdkdev->info.name); +#ifndef XINPUT_NONE + g_free(gdkdev->axes); +#endif + g_free(gdkdev->info.axes); + g_free(gdkdev->info.keys); + g_free(gdkdev); + } + } + + g_list_free(gdk_input_devices); + + for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + { + g_free(tmp_list->data); + } + g_list_free(gdk_input_windows); +} + +GdkDevicePrivate * +gdk_input_find_device(guint32 id) +{ + GList *tmp_list = gdk_input_devices; + GdkDevicePrivate *gdkdev; + while (tmp_list) + { + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (gdkdev->info.deviceid == id) + return gdkdev; + tmp_list = tmp_list->next; + } + return NULL; +} + +void +gdk_input_window_get_pointer (GdkWindow *window, + guint32 deviceid, + gdouble *x, + gdouble *y, + gdouble *pressure, + gdouble *xtilt, + gdouble *ytilt, + GdkModifierType *mask) +{ + if (gdk_input_vtable.get_pointer) + gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure, + xtilt, ytilt, mask); +} diff --git a/gdk/nanox/gdkmain-nanox.c b/gdk/nanox/gdkmain-nanox.c new file mode 100644 index 0000000000..2892940354 --- /dev/null +++ b/gdk/nanox/gdkmain-nanox.c @@ -0,0 +1,250 @@ +#include "gdk.h" +#include "gdkinternals.h" +#include "gdkprivate-nanox.h" + +static GR_SCREEN_INFO screen_info; +static int gdk_use_xshm = 0; /* shm not supported */ +guint gdk_selection_property = 0; +gchar* gdk_progclass = NULL; +GdkWindowPrivate* gdk_xgrab_window = NULL; + +GdkArgDesc _gdk_windowing_args[] = { + {NULL} +}; + +gboolean +_gdk_windowing_init_check (int argc, char **argv) +{ + int result = GrOpen(); + if (result < 0) + return 0; + GrGetScreenInfo(&screen_info); + + return 1; +} + + +gchar* +gdk_set_locale (void) +{ + return ""; +} + +void +gdk_set_use_xshm (gboolean use_xshm) +{ + gdk_use_xshm = 0; /* shm not supported */ +} + +gboolean +gdk_get_use_xshm (void) +{ + return gdk_use_xshm; +} + +gint +gdk_pointer_grab (GdkWindow * window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow * confine_to, + GdkCursor * cursor, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +void +gdk_pointer_ungrab (guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +gboolean +gdk_pointer_is_grabbed (void) +{ + return gdk_xgrab_window != NULL; +} + +gint +gdk_keyboard_grab (GdkWindow * window, + gboolean owner_events, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +void +gdk_keyboard_ungrab (guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +gint +gdk_screen_width (void) +{ + return screen_info.cols; +} + +gint +gdk_screen_height (void) +{ + return screen_info.rows; +} + +gint +gdk_screen_width_mm (void) +{ + return screen_info.cols*10/screen_info.xdpcm; +} + +gint +gdk_screen_height_mm (void) +{ + return screen_info.rows*10/screen_info.ydpcm; +} + +void +gdk_set_sm_client_id (const gchar* sm_client_id) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_key_repeat_disable (void) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_key_repeat_restore (void) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_beep (void) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_windowing_exit (void) +{ + GrClose(); +} + +gchar * +gdk_get_display (void) +{ + return "nano-X"; +} + +gchar* +gdk_keyval_name (guint keyval) +{ + static gchar buf[64]; + g_snprintf(buf, 64, "%c", keyval); + return buf; +} + +guint +gdk_keyval_from_name (const gchar *keyval_name) +{ + return *keyval_name; +} + +/* +void +gdk_keyval_convert_case (guint symbol, + guint *lower, + guint *upper) +{ +} +*/ + +static guint gdk_xid_hash (guint *xid); +static gint gdk_xid_compare (guint *a, + guint *b); + + +static GHashTable *xid_ht = NULL; + + +void +gdk_xid_table_insert (guint *xid, + gpointer data) +{ + g_return_if_fail (xid != NULL); + + if (!xid_ht) + xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, + (GCompareFunc) gdk_xid_compare); + + g_hash_table_insert (xid_ht, xid, data); +} + +void +gdk_xid_table_remove (guint xid) +{ + if (!xid_ht) + xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, + (GCompareFunc) gdk_xid_compare); + + g_hash_table_remove (xid_ht, &xid); +} + +gpointer +gdk_xid_table_lookup (guint xid) +{ + gpointer data = NULL; + + if (xid_ht) + data = g_hash_table_lookup (xid_ht, &xid); + + return data; +} + + +static guint +gdk_xid_hash (guint *xid) +{ + return *xid; +} + +static gint +gdk_xid_compare (guint *a, + guint *b) +{ + return (*a == *b); +} + +gchar * +gdk_wcstombs (const GdkWChar *src) +{ + gchar *mbstr; + gint i, length = 0; + + while (src[length] != 0) + length++; + mbstr = g_new (gchar, length + 1); + for (i=0; i klass = &klass; + private->klass_data = g_new (GdkDrawableXData, 1); + private->window_type = GDK_DRAWABLE_PIXMAP; + + return drawable; +} + +GdkPixmap* +gdk_pixmap_new (GdkWindow *window, + gint width, + gint height, + gint depth) +{ + GdkPixmap *pixmap; + GdkDrawablePrivate *private; + + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); + g_return_val_if_fail ((window != NULL) || (depth != -1), NULL); + g_return_val_if_fail ((width != 0) && (height != 0), NULL); + + if (!window) + window = gdk_parent_root; + + if (GDK_DRAWABLE_DESTROYED (window)) + return NULL; + + if (depth == -1) + depth = gdk_drawable_get_visual (window)->depth; + + pixmap = gdk_nanox_pixmap_alloc (); + private = (GdkDrawablePrivate *)pixmap; + + GDK_DRAWABLE_XDATA (private)->xid = GrNewPixmap (width, height, NULL); + private->width = width; + private->height = height; + + gdk_xid_table_insert (&GDK_DRAWABLE_XID (pixmap), pixmap); + + return pixmap; +} + +GdkPixmap * +gdk_bitmap_create_from_data (GdkWindow *window, + const gchar *data, + gint width, + gint height) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkPixmap* +gdk_pixmap_create_from_data (GdkWindow *window, + const gchar *data, + gint width, + gint height, + gint depth, + GdkColor *fg, + GdkColor *bg) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + + +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm (GdkWindow *window, + GdkColormap *colormap, + GdkBitmap **mask, + GdkColor *transparent_color, + const gchar *filename) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + + +GdkPixmap* +gdk_pixmap_create_from_xpm (GdkWindow *window, + GdkBitmap **mask, + GdkColor *transparent_color, + const gchar *filename) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm_d (GdkWindow *window, + GdkColormap *colormap, + GdkBitmap **mask, + GdkColor *transparent_color, + gchar **data) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkPixmap* +gdk_pixmap_create_from_xpm_d (GdkWindow *window, + GdkBitmap **mask, + GdkColor *transparent_color, + gchar **data) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkPixmap* +gdk_pixmap_foreign_new (guint32 anid) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + diff --git a/gdk/nanox/gdkpolyreg-generic.c b/gdk/nanox/gdkpolyreg-generic.c new file mode 100644 index 0000000000..b98bd5641e --- /dev/null +++ b/gdk/nanox/gdkpolyreg-generic.c @@ -0,0 +1,616 @@ +/* $TOG: PolyReg.c /main/15 1998/02/06 17:47:08 kaleb $ */ +/************************************************************************ + +Copyright 1987, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* $XFree86: xc/lib/X11/PolyReg.c,v 1.4 1998/10/03 08:41:21 dawes Exp $ */ + +#define LARGE_COORDINATE 1000000 +#define SMALL_COORDINATE -LARGE_COORDINATE + +#include +#include "gdkregion-generic.h" +#include "gdkpoly-generic.h" + +/* + * InsertEdgeInET + * + * Insert the given edge into the edge table. + * First we must find the correct bucket in the + * Edge table, then find the right slot in the + * bucket. Finally, we can insert it. + * + */ +static void +InsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock) + EdgeTable *ET; + EdgeTableEntry *ETE; + int scanline; + ScanLineListBlock **SLLBlock; + int *iSLLBlock; +{ + EdgeTableEntry *start, *prev; + ScanLineList *pSLL, *pPrevSLL; + ScanLineListBlock *tmpSLLBlock; + + /* + * find the right bucket to put the edge into + */ + pPrevSLL = &ET->scanlines; + pSLL = pPrevSLL->next; + while (pSLL && (pSLL->scanline < scanline)) + { + pPrevSLL = pSLL; + pSLL = pSLL->next; + } + + /* + * reassign pSLL (pointer to ScanLineList) if necessary + */ + if ((!pSLL) || (pSLL->scanline > scanline)) + { + if (*iSLLBlock > SLLSPERBLOCK-1) + { + tmpSLLBlock = + (ScanLineListBlock *)g_malloc(sizeof(ScanLineListBlock)); + (*SLLBlock)->next = tmpSLLBlock; + tmpSLLBlock->next = (ScanLineListBlock *)NULL; + *SLLBlock = tmpSLLBlock; + *iSLLBlock = 0; + } + pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); + + pSLL->next = pPrevSLL->next; + pSLL->edgelist = (EdgeTableEntry *)NULL; + pPrevSLL->next = pSLL; + } + pSLL->scanline = scanline; + + /* + * now insert the edge in the right bucket + */ + prev = (EdgeTableEntry *)NULL; + start = pSLL->edgelist; + while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) + { + prev = start; + start = start->next; + } + ETE->next = start; + + if (prev) + prev->next = ETE; + else + pSLL->edgelist = ETE; +} + +/* + * CreateEdgeTable + * + * This routine creates the edge table for + * scan converting polygons. + * The Edge Table (ET) looks like: + * + * EdgeTable + * -------- + * | ymax | ScanLineLists + * |scanline|-->------------>-------------->... + * -------- |scanline| |scanline| + * |edgelist| |edgelist| + * --------- --------- + * | | + * | | + * V V + * list of ETEs list of ETEs + * + * where ETE is an EdgeTableEntry data structure, + * and there is one ScanLineList per scanline at + * which an edge is initially entered. + * + */ + +static void +CreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock) + int count; + GdkPoint *pts; + EdgeTable *ET; + EdgeTableEntry *AET; + EdgeTableEntry *pETEs; + ScanLineListBlock *pSLLBlock; +{ + GdkPoint *top, *bottom; + GdkPoint *PrevPt, *CurrPt; + int iSLLBlock = 0; + int dy; + + if (count < 2) return; + + /* + * initialize the Active Edge Table + */ + AET->next = (EdgeTableEntry *)NULL; + AET->back = (EdgeTableEntry *)NULL; + AET->nextWETE = (EdgeTableEntry *)NULL; + AET->bres.minor_axis = SMALL_COORDINATE; + + /* + * initialize the Edge Table. + */ + ET->scanlines.next = (ScanLineList *)NULL; + ET->ymax = SMALL_COORDINATE; + ET->ymin = LARGE_COORDINATE; + pSLLBlock->next = (ScanLineListBlock *)NULL; + + PrevPt = &pts[count-1]; + + /* + * for each vertex in the array of points. + * In this loop we are dealing with two vertices at + * a time -- these make up one edge of the polygon. + */ + while (count--) + { + CurrPt = pts++; + + /* + * find out which point is above and which is below. + */ + if (PrevPt->y > CurrPt->y) + { + bottom = PrevPt, top = CurrPt; + pETEs->ClockWise = 0; + } + else + { + bottom = CurrPt, top = PrevPt; + pETEs->ClockWise = 1; + } + + /* + * don't add horizontal edges to the Edge table. + */ + if (bottom->y != top->y) + { + pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */ + + /* + * initialize integer edge algorithm + */ + dy = bottom->y - top->y; + BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres); + + InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock); + + if (PrevPt->y > ET->ymax) + ET->ymax = PrevPt->y; + if (PrevPt->y < ET->ymin) + ET->ymin = PrevPt->y; + pETEs++; + } + + PrevPt = CurrPt; + } +} + +/* + * loadAET + * + * This routine moves EdgeTableEntries from the + * EdgeTable into the Active Edge Table, + * leaving them sorted by smaller x coordinate. + * + */ + +static void +loadAET(AET, ETEs) + EdgeTableEntry *AET, *ETEs; +{ + EdgeTableEntry *pPrevAET; + EdgeTableEntry *tmp; + + pPrevAET = AET; + AET = AET->next; + while (ETEs) + { + while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) + { + pPrevAET = AET; + AET = AET->next; + } + tmp = ETEs->next; + ETEs->next = AET; + if (AET) + AET->back = ETEs; + ETEs->back = pPrevAET; + pPrevAET->next = ETEs; + pPrevAET = ETEs; + + ETEs = tmp; + } +} + +/* + * computeWAET + * + * This routine links the AET by the + * nextWETE (winding EdgeTableEntry) link for + * use by the winding number rule. The final + * Active Edge Table (AET) might look something + * like: + * + * AET + * ---------- --------- --------- + * |ymax | |ymax | |ymax | + * | ... | |... | |... | + * |next |->|next |->|next |->... + * |nextWETE| |nextWETE| |nextWETE| + * --------- --------- ^-------- + * | | | + * V-------------------> V---> ... + * + */ +static void +computeWAET(AET) + EdgeTableEntry *AET; +{ + EdgeTableEntry *pWETE; + int inside = 1; + int isInside = 0; + + AET->nextWETE = (EdgeTableEntry *)NULL; + pWETE = AET; + AET = AET->next; + while (AET) + { + if (AET->ClockWise) + isInside++; + else + isInside--; + + if ((!inside && !isInside) || + ( inside && isInside)) + { + pWETE->nextWETE = AET; + pWETE = AET; + inside = !inside; + } + AET = AET->next; + } + pWETE->nextWETE = (EdgeTableEntry *)NULL; +} + +/* + * InsertionSort + * + * Just a simple insertion sort using + * pointers and back pointers to sort the Active + * Edge Table. + * + */ + +static int +InsertionSort(AET) + EdgeTableEntry *AET; +{ + EdgeTableEntry *pETEchase; + EdgeTableEntry *pETEinsert; + EdgeTableEntry *pETEchaseBackTMP; + int changed = 0; + + AET = AET->next; + while (AET) + { + pETEinsert = AET; + pETEchase = AET; + while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) + pETEchase = pETEchase->back; + + AET = AET->next; + if (pETEchase != pETEinsert) + { + pETEchaseBackTMP = pETEchase->back; + pETEinsert->back->next = AET; + if (AET) + AET->back = pETEinsert->back; + pETEinsert->next = pETEchase; + pETEchase->back->next = pETEinsert; + pETEchase->back = pETEinsert; + pETEinsert->back = pETEchaseBackTMP; + changed = 1; + } + } + return(changed); +} + +/* + * Clean up our act. + */ +static void +FreeStorage(pSLLBlock) + ScanLineListBlock *pSLLBlock; +{ + ScanLineListBlock *tmpSLLBlock; + + while (pSLLBlock) + { + tmpSLLBlock = pSLLBlock->next; + g_free (pSLLBlock); + pSLLBlock = tmpSLLBlock; + } +} + +/* + * Create an array of rectangles from a list of points. + * If indeed these things (POINTS, RECTS) are the same, + * then this proc is still needed, because it allocates + * storage for the array, which was allocated on the + * stack by the calling procedure. + * + */ +static int PtsToRegion(numFullPtBlocks, iCurPtBlock, FirstPtBlock, reg) + int numFullPtBlocks, iCurPtBlock; + POINTBLOCK *FirstPtBlock; + GdkRegion *reg; +{ + GdkRegionBox *rects; + GdkPoint *pts; + POINTBLOCK *CurPtBlock; + int i; + GdkRegionBox *extents; + int numRects; + + extents = ®->extents; + + numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; + + reg->rects = g_renew (GdkRegionBox, reg->rects, numRects); + + reg->size = numRects; + CurPtBlock = FirstPtBlock; + rects = reg->rects - 1; + numRects = 0; + extents->x1 = G_MAXSHORT, extents->x2 = G_MINSHORT; + + for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { + /* the loop uses 2 points per iteration */ + i = NUMPTSTOBUFFER >> 1; + if (!numFullPtBlocks) + i = iCurPtBlock >> 1; + for (pts = CurPtBlock->pts; i--; pts += 2) { + if (pts->x == pts[1].x) + continue; + if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && + pts[1].x == rects->x2 && + (numRects == 1 || rects[-1].y1 != rects->y1) && + (i && pts[2].y > pts[1].y)) { + rects->y2 = pts[1].y + 1; + continue; + } + numRects++; + rects++; + rects->x1 = pts->x; rects->y1 = pts->y; + rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1; + if (rects->x1 < extents->x1) + extents->x1 = rects->x1; + if (rects->x2 > extents->x2) + extents->x2 = rects->x2; + } + CurPtBlock = CurPtBlock->next; + } + + if (numRects) { + extents->y1 = reg->rects->y1; + extents->y2 = rects->y2; + } else { + extents->x1 = 0; + extents->y1 = 0; + extents->x2 = 0; + extents->y2 = 0; + } + reg->numRects = numRects; + + return(TRUE); +} + +/* + * polytoregion + * + * Scan converts a polygon by returning a run-length + * encoding of the resultant bitmap -- the run-length + * encoding is in the form of an array of rectangles. + */ +GdkRegion * +gdk_region_polygon(GdkPoint *Pts, gint Count, GdkFillRule rule) +{ + GdkRegion *region; + EdgeTableEntry *pAET; /* Active Edge Table */ + int y; /* current scanline */ + int iPts = 0; /* number of pts in buffer */ + EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ + ScanLineList *pSLL; /* current scanLineList */ + GdkPoint *pts; /* output buffer */ + EdgeTableEntry *pPrevAET; /* ptr to previous AET */ + EdgeTable ET; /* header node for ET */ + EdgeTableEntry AET; /* header node for AET */ + EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ + ScanLineListBlock SLLBlock; /* header for scanlinelist */ + int fixWAET = FALSE; + POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ + POINTBLOCK *tmpPtBlock; + int numFullPtBlocks = 0; + + region = gdk_region_new (); + + /* special case a rectangle */ + pts = Pts; + if (((Count == 4) || + ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) && + (((pts[0].y == pts[1].y) && + (pts[1].x == pts[2].x) && + (pts[2].y == pts[3].y) && + (pts[3].x == pts[0].x)) || + ((pts[0].x == pts[1].x) && + (pts[1].y == pts[2].y) && + (pts[2].x == pts[3].x) && + (pts[3].y == pts[0].y)))) { + region->extents.x1 = MIN(pts[0].x, pts[2].x); + region->extents.y1 = MIN(pts[0].y, pts[2].y); + region->extents.x2 = MAX(pts[0].x, pts[2].x); + region->extents.y2 = MAX(pts[0].y, pts[2].y); + if ((region->extents.x1 != region->extents.x2) && + (region->extents.y1 != region->extents.y2)) { + region->numRects = 1; + *(region->rects) = region->extents; + } + return(region); + } + + pETEs = g_new (EdgeTableEntry, Count); + + pts = FirstPtBlock.pts; + CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); + pSLL = ET.scanlines.next; + curPtBlock = &FirstPtBlock; + + if (rule == GDK_EVEN_ODD_RULE) { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + + /* + * for each active edge + */ + while (pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; + iPts = 0; + } + EVALUATEEDGEEVENODD(pAET, pPrevAET, y); + } + (void) InsertionSort(&AET); + } + } + else { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + computeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * add to the buffer only those edges that + * are in the Winding active edge table. + */ + if (pWETE == pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; iPts = 0; + } + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); + } + + /* + * recompute the winding active edge table if + * we just resorted or have exited an edge. + */ + if (InsertionSort(&AET) || fixWAET) { + computeWAET(&AET); + fixWAET = FALSE; + } + } + } + FreeStorage(SLLBlock.next); + (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); + for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { + tmpPtBlock = curPtBlock->next; + g_free (curPtBlock); + curPtBlock = tmpPtBlock; + } + g_free (pETEs); + return(region); +} diff --git a/gdk/nanox/gdkproperty-nanox.c b/gdk/nanox/gdkproperty-nanox.c new file mode 100644 index 0000000000..2c88c70485 --- /dev/null +++ b/gdk/nanox/gdkproperty-nanox.c @@ -0,0 +1,55 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +GdkAtom +gdk_atom_intern (const gchar *atom_name, + gboolean only_if_exists) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +gchar* +gdk_atom_name (GdkAtom atom) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +gboolean +gdk_property_get (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gulong offset, + gulong length, + gint pdelete, + GdkAtom *actual_property_type, + gint *actual_format_type, + gint *actual_length, + guchar **data) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void +gdk_property_change (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gint format, + GdkPropMode mode, + const guchar *data, + gint nelements) +{ + g_message("unimplemented %s", __FUNCTION__); + return; +} + +void +gdk_property_delete (GdkWindow *window, + GdkAtom property) +{ + g_message("unimplemented %s", __FUNCTION__); + return; +} + diff --git a/gdk/nanox/gdkregion-generic.c b/gdk/nanox/gdkregion-generic.c new file mode 100644 index 0000000000..0319f939f4 --- /dev/null +++ b/gdk/nanox/gdkregion-generic.c @@ -0,0 +1,1505 @@ +/* $TOG: Region.c /main/31 1998/02/06 17:50:22 kaleb $ */ +/************************************************************************ + +Copyright 1987, 1988, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* $XFree86: xc/lib/X11/Region.c,v 1.5 1999/05/09 10:50:01 dawes Exp $ */ +/* + * The functions in this file implement the Region abstraction, similar to one + * used in the X11 sample server. A Region is simply an area, as the name + * implies, and is implemented as a "y-x-banded" array of rectangles. To + * explain: Each Region is made up of a certain number of rectangles sorted + * by y coordinate first, and then by x coordinate. + * + * Furthermore, the rectangles are banded such that every rectangle with a + * given upper-left y coordinate (y1) will have the same lower-right y + * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it + * will span the entire vertical distance of the band. This means that some + * areas that could be merged into a taller rectangle will be represented as + * several shorter rectangles to account for shorter rectangles to its left + * or right but within its "vertical scope". + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible. E.g. no two rectangles in a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). This maintains + * the y-x-banding that's so nice to have... + */ + +#include +#include "gdkregion-generic.h" + +#ifdef DEBUG +#include +#define assert(expr) {if (!(expr)) fprintf(stderr,\ +"Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); } +#else +#define assert(expr) +#endif + +typedef void (*overlapFunc) (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2); +typedef void (*nonOverlapFunc) (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2); + +static void miRegionCopy (GdkRegion *dstrgn, + GdkRegion *rgn); +static void miRegionOp (GdkRegion *newReg, + GdkRegion *reg1, + GdkRegion *reg2, + overlapFunc overlapFn, + nonOverlapFunc nonOverlap1Fn, + nonOverlapFunc nonOverlap2Fn); + +/* Create a new empty region */ + +GdkRegion * +gdk_region_new () +{ + GdkRegion *temp; + + temp = g_new (GdkRegion, 1); + temp->rects = g_new (GdkRegionBox, 1); + + temp->numRects = 0; + temp->extents.x1 = 0; + temp->extents.y1 = 0; + temp->extents.x2 = 0; + temp->extents.y2 = 0; + temp->size = 1; + + return temp; +} + +GdkRegion * +gdk_region_rectangle (GdkRectangle *rectangle) +{ + GdkRegion *temp; + + if (rectangle->width <= 0 || rectangle->height <= 0) + return gdk_region_new(); + + temp = g_new (GdkRegion, 1); + temp->rects = g_new (GdkRegionBox, 1); + + temp->numRects = 1; + temp->extents.x1 = temp->rects[0].x1 = rectangle->x; + temp->extents.y1 = temp->rects[0].y1 = rectangle->y; + temp->extents.x2 = temp->rects[0].x2 = rectangle->x + rectangle->width; + temp->extents.y2 = temp->rects[0].y2 = rectangle->y + rectangle->height; + temp->size = 1; + + return temp; +} + +GdkRegion * +gdk_region_copy (GdkRegion *region) +{ + GdkRegion *temp; + + temp = g_new (GdkRegion, 1); + temp->rects = g_new (GdkRegionBox, region->numRects); + + temp->numRects = region->numRects; + temp->extents = region->extents; + temp->size = region->numRects; + + memcpy (temp->rects, region->rects, region->numRects * sizeof (GdkRegionBox)); + + return temp; +} + +void +gdk_region_get_clipbox (GdkRegion *r, GdkRectangle *rect) +{ + rect->x = r->extents.x1; + rect->y = r->extents.y1; + rect->width = r->extents.x2 - r->extents.x1; + rect->height = r->extents.y2 - r->extents.y1; +} + +void +gdk_region_union_with_rect (GdkRegion *region, + GdkRectangle *rect) +{ + GdkRegion tmp_region; + + if (!rect->width || !rect->height) + return; + + tmp_region.rects = &tmp_region.extents; + tmp_region.numRects = 1; + tmp_region.extents.x1 = rect->x; + tmp_region.extents.y1 = rect->y; + tmp_region.extents.x2 = rect->x + rect->width; + tmp_region.extents.y2 = rect->y + rect->height; + tmp_region.size = 1; + + gdk_region_union (region, &tmp_region); +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +static void +miSetExtents (GdkRegion *pReg) +{ + GdkRegionBox *pBox, *pBoxEnd, *pExtents; + + if (pReg->numRects == 0) + { + pReg->extents.x1 = 0; + pReg->extents.y1 = 0; + pReg->extents.x2 = 0; + pReg->extents.y2 = 0; + return; + } + + pExtents = &pReg->extents; + pBox = pReg->rects; + pBoxEnd = &pBox[pReg->numRects - 1]; + + /* + * Since pBox is the first rectangle in the region, it must have the + * smallest y1 and since pBoxEnd is the last rectangle in the region, + * it must have the largest y2, because of banding. Initialize x1 and + * x2 from pBox and pBoxEnd, resp., as good things to initialize them + * to... + */ + pExtents->x1 = pBox->x1; + pExtents->y1 = pBox->y1; + pExtents->x2 = pBoxEnd->x2; + pExtents->y2 = pBoxEnd->y2; + + assert(pExtents->y1 < pExtents->y2); + while (pBox <= pBoxEnd) + { + if (pBox->x1 < pExtents->x1) + { + pExtents->x1 = pBox->x1; + } + if (pBox->x2 > pExtents->x2) + { + pExtents->x2 = pBox->x2; + } + pBox++; + } + assert(pExtents->x1 < pExtents->x2); +} + +void +gdk_region_destroy (GdkRegion *r) +{ + g_free (r->rects); + g_free (r); +} + + +/* TranslateRegion(pRegion, x, y) + translates in place + added by raymond +*/ + +void +gdk_region_offset (GdkRegion *region, + gint x, + gint y) +{ + int nbox; + GdkRegionBox *pbox; + + pbox = region->rects; + nbox = region->numRects; + + while(nbox--) + { + pbox->x1 += x; + pbox->x2 += x; + pbox->y1 += y; + pbox->y2 += y; + pbox++; + } + region->extents.x1 += x; + region->extents.x2 += x; + region->extents.y1 += y; + region->extents.y2 += y; +} + +/* + Utility procedure Compress: + Replace r by the region r', where + p in r' iff (Quantifer m <= dx) (p + m in r), and + Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and + (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE. + + Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region + of all points p such that p and the next dx points on the same + horizontal scan line are all in r. We do this using by noting + that p is the head of a run of length 2^i + k iff p is the head + of a run of length 2^i and p+2^i is the head of a run of length + k. Thus, the loop invariant: s contains the region corresponding + to the runs of length shift. r contains the region corresponding + to the runs of length 1 + dxo & (shift-1), where dxo is the original + value of dx. dx = dxo & ~(shift-1). As parameters, s and t are + scratch regions, so that we don't have to allocate them on every + call. +*/ + +#define ZOpRegion(a,b) if (grow) gdk_region_union (a, b); \ + else gdk_region_intersect (a,b) +#define ZShiftRegion(a,b) if (xdir) gdk_region_offset (a,b,0); \ + else gdk_region_offset (a,0,b) + +static void +Compress(GdkRegion *r, + GdkRegion *s, + GdkRegion *t, + guint dx, + int xdir, + int grow) +{ + guint shift = 1; + + miRegionCopy (s, r); + while (dx) + { + if (dx & shift) + { + ZShiftRegion(r, -(int)shift); + ZOpRegion(r, s); + dx -= shift; + if (!dx) break; + } + miRegionCopy (t, s); + ZShiftRegion(s, -(int)shift); + ZOpRegion(s, t); + shift <<= 1; + } +} + +#undef ZOpRegion +#undef ZShiftRegion +#undef ZCopyRegion + +void +gdk_region_shrink (GdkRegion *r, + int dx, + int dy) +{ + GdkRegion *s, *t; + int grow; + + if (!dx && !dy) + return; + + s = gdk_region_new (); + t = gdk_region_new (); + + grow = (dx < 0); + if (grow) + dx = -dx; + if (dx) + Compress(r, s, t, (unsigned) 2*dx, TRUE, grow); + + grow = (dy < 0); + if (grow) + dy = -dy; + if (dy) + Compress(r, s, t, (unsigned) 2*dy, FALSE, grow); + + gdk_region_offset (r, dx, dy); + gdk_region_destroy (s); + gdk_region_destroy (t); +} + + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * None. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miIntersectO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + int x1; + int x2; + GdkRegionBox *pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + x1 = MAX (r1->x1,r2->x1); + x2 = MIN (r1->x2,r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 < x2) + { + assert (y1rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert (pReg->numRects <= pReg->size); + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->x2 < r2->x2) + { + r1++; + } + else if (r2->x2 < r1->x2) + { + r2++; + } + else + { + r1++; + r2++; + } + } +} + +void +gdk_region_intersect (GdkRegion *region, + GdkRegion *other) +{ + /* check for trivial reject */ + if ((!(region->numRects)) || (!(other->numRects)) || + (!EXTENTCHECK(®ion->extents, &other->extents))) + region->numRects = 0; + else + miRegionOp (region, region, other, + miIntersectO, (nonOverlapFunc) NULL, (nonOverlapFunc) NULL); + + /* + * Can't alter region's extents before miRegionOp depends on the + * extents of the regions being unchanged. Besides, this way there's + * no checking against rectangles that will be nuked due to + * coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(region); +} + +static void +miRegionCopy(GdkRegion *dstrgn, GdkRegion *rgn) +{ + if (dstrgn != rgn) /* don't want to copy to itself */ + { + if (dstrgn->size < rgn->numRects) + { + dstrgn->rects = g_renew (GdkRegionBox, dstrgn->rects, rgn->numRects); + dstrgn->size = rgn->numRects; + } + dstrgn->numRects = rgn->numRects; + dstrgn->extents.x1 = rgn->extents.x1; + dstrgn->extents.y1 = rgn->extents.y1; + dstrgn->extents.x2 = rgn->extents.x2; + dstrgn->extents.y2 = rgn->extents.y2; + + memcpy (dstrgn->rects, rgn->rects, rgn->numRects * sizeof (GdkRegionBox)); + } +} + + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. + * + * Results: + * The new index for the previous band. + * + * Side Effects: + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. + * + *----------------------------------------------------------------------- + */ +/* static int*/ +static int +miCoalesce (GdkRegion *pReg, /* Region to coalesce */ + gint prevStart, /* Index of start of previous band */ + gint curStart) /* Index of start of current band */ +{ + GdkRegionBox *pPrevBox; /* Current box in previous band */ + GdkRegionBox *pCurBox; /* Current box in current band */ + GdkRegionBox *pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ + + pRegEnd = &pReg->rects[pReg->numRects]; + + pPrevBox = &pReg->rects[prevStart]; + prevNumRects = curStart - prevStart; + + /* + * Figure out how many rectangles are in the current band. Have to do + * this because multiple bands could have been added in miRegionOp + * at the end when one region has been exhausted. + */ + pCurBox = &pReg->rects[curStart]; + bandY1 = pCurBox->y1; + for (curNumRects = 0; + (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); + curNumRects++) + { + pCurBox++; + } + + if (pCurBox != pRegEnd) + { + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while (pRegEnd[-1].y1 == pRegEnd->y1) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects; + pRegEnd = pReg->rects + pReg->numRects; + } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->y2 == pCurBox->y1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->x1 != pCurBox->x1) || + (pPrevBox->x2 != pCurBox->x2)) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->y2 = pCurBox->y2; + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } + while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } + while (pCurBox != pRegEnd); + } + + } + } + return curStart; +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... + * + * Results: + * None. + * + * Side Effects: + * The new region is overwritten. + * + * Notes: + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * second, the overlapFunc is called to process the entire band. It + * is responsible for clipping the rectangles in the band, though + * this function provides the boundaries. + * At the end of each band, the new region is coalesced, if possible, + * to reduce the number of rectangles in the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miRegionOp(GdkRegion *newReg, + GdkRegion *reg1, + GdkRegion *reg2, + overlapFunc overlapFn, /* Function to call for over- + * lapping bands */ + nonOverlapFunc nonOverlap1Fn, /* Function to call for non- + * overlapping bands in region + * 1 */ + nonOverlapFunc nonOverlap2Fn) /* Function to call for non- + * overlapping bands in region + * 2 */ +{ + GdkRegionBox *r1; /* Pointer into first region */ + GdkRegionBox *r2; /* Pointer into 2d region */ + GdkRegionBox *r1End; /* End of 1st region */ + GdkRegionBox *r2End; /* End of 2d region */ + int ybot; /* Bottom of intersection */ + int ytop; /* Top of intersection */ + GdkRegionBox *oldRects; /* Old rects for newReg */ + int prevBand; /* Index of start of + * previous band in newReg */ + int curBand; /* Index of start of current + * band in newReg */ + GdkRegionBox *r1BandEnd; /* End of current band in r1 */ + GdkRegionBox *r2BandEnd; /* End of current band in r2 */ + int top; /* Top of non-overlapping + * band */ + int bot; /* Bottom of non-overlapping + * band */ + + /* + * Initialization: + * set r1, r2, r1End and r2End appropriately, preserve the important + * parts of the destination region until the end in case it's one of + * the two source regions, then mark the "new" region empty, allocating + * another array of rectangles for it to use. + */ + r1 = reg1->rects; + r2 = reg2->rects; + r1End = r1 + reg1->numRects; + r2End = r2 + reg2->numRects; + + oldRects = newReg->rects; + + EMPTY_REGION(newReg); + + /* + * Allocate a reasonable number of rectangles for the new region. The idea + * is to allocate enough so the individual functions don't need to + * reallocate and copy the array, which is time consuming, yet we don't + * have to worry about using too much memory. I hope to be able to + * nuke the Xrealloc() at the end of this function eventually. + */ + newReg->size = MAX (reg1->numRects, reg2->numRects) * 2; + newReg->rects = g_new (GdkRegionBox, newReg->size); + + /* + * Initialize ybot and ytop. + * In the upcoming loop, ybot and ytop serve different functions depending + * on whether the band being handled is an overlapping or non-overlapping + * band. + * In the case of a non-overlapping band (only one of the regions + * has points in the band), ybot is the bottom of the most recent + * intersection and thus clips the top of the rectangles in that band. + * ytop is the top of the next intersection between the two regions and + * serves to clip the bottom of the rectangles in the current band. + * For an overlapping band (where the two regions intersect), ytop clips + * the top of the rectangles of both regions and ybot clips the bottoms. + */ + if (reg1->extents.y1 < reg2->extents.y1) + ybot = reg1->extents.y1; + else + ybot = reg2->extents.y1; + + /* + * prevBand serves to mark the start of the previous band so rectangles + * can be coalesced into larger rectangles. qv. miCoalesce, above. + * In the beginning, there is no previous band, so prevBand == curBand + * (curBand is set later on, of course, but the first band will always + * start at index 0). prevBand and curBand must be indices because of + * the possible expansion, and resultant moving, of the new region's + * array of rectangles. + */ + prevBand = 0; + + do + { + curBand = newReg->numRects; + + /* + * This algorithm proceeds one source-band (as opposed to a + * destination band, which is determined by where the two regions + * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the + * rectangle after the last one in the current band for their + * respective regions. + */ + r1BandEnd = r1; + while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + + r2BandEnd = r2; + while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + + /* + * First handle the band that doesn't intersect, if any. + * + * Note that attention is restricted to one band in the + * non-intersecting region at once, so if a region has n + * bands between the current position and the next place it overlaps + * the other, this entire loop will be passed through n times. + */ + if (r1->y1 < r2->y1) + { + top = MAX (r1->y1,ybot); + bot = MIN (r1->y2,r2->y1); + + if ((top != bot) && (nonOverlap1Fn != (void (*)())NULL)) + { + (* nonOverlap1Fn) (newReg, r1, r1BandEnd, top, bot); + } + + ytop = r2->y1; + } + else if (r2->y1 < r1->y1) + { + top = MAX (r2->y1,ybot); + bot = MIN (r2->y2,r1->y1); + + if ((top != bot) && (nonOverlap2Fn != (void (*)())NULL)) + { + (* nonOverlap2Fn) (newReg, r2, r2BandEnd, top, bot); + } + + ytop = r1->y1; + } + else + { + ytop = r1->y1; + } + + /* + * If any rectangles got added to the region, try and coalesce them + * with rectangles from the previous band. Note we could just do + * this test in miCoalesce, but some machines incur a not + * inconsiderable cost for function calls, so... + */ + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * Now see if we've hit an intersecting band. The two bands only + * intersect if ybot > ytop + */ + ybot = MIN (r1->y2, r2->y2); + curBand = newReg->numRects; + if (ybot > ytop) + { + (* overlapFn) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); + + } + + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * If we've finished with a band (y2 == ybot) we skip forward + * in the region to the next band. + */ + if (r1->y2 == ybot) + { + r1 = r1BandEnd; + } + if (r2->y2 == ybot) + { + r2 = r2BandEnd; + } + } while ((r1 != r1End) && (r2 != r2End)); + + /* + * Deal with whichever region still has rectangles left. + */ + curBand = newReg->numRects; + if (r1 != r1End) + { + if (nonOverlap1Fn != (nonOverlapFunc )NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + (* nonOverlap1Fn) (newReg, r1, r1BandEnd, + MAX (r1->y1,ybot), r1->y2); + r1 = r1BandEnd; + } while (r1 != r1End); + } + } + else if ((r2 != r2End) && (nonOverlap2Fn != (nonOverlapFunc) NULL)) + { + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + (* nonOverlap2Fn) (newReg, r2, r2BandEnd, + MAX (r2->y1,ybot), r2->y2); + r2 = r2BandEnd; + } while (r2 != r2End); + } + + if (newReg->numRects != curBand) + { + (void) miCoalesce (newReg, prevBand, curBand); + } + + /* + * A bit of cleanup. To keep regions from growing without bound, + * we shrink the array of rectangles to match the new number of + * rectangles in the region. This never goes to 0, however... + * + * Only do this stuff if the number of rectangles allocated is more than + * twice the number of rectangles in the region (a simple optimization...). + */ + if (newReg->numRects < (newReg->size >> 1)) + { + if (REGION_NOT_EMPTY (newReg)) + { + newReg->size = newReg->numRects; + newReg->rects = g_renew (GdkRegionBox, newReg->rects, newReg->size); + } + else + { + /* + * No point in doing the extra work involved in an Xrealloc if + * the region is empty + */ + newReg->size = 1; + g_free (newReg->rects); + newReg->rects = g_new (GdkRegionBox, 1); + } + } + g_free (oldRects); +} + + +/*====================================================================== + * Region Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionNonO -- + * Handle a non-overlapping band for the union operation. Just + * Adds the rectangles into the region. Doesn't have to check for + * subsumption or anything. + * + * Results: + * None. + * + * Side Effects: + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. + * + *----------------------------------------------------------------------- + */ +static void +miUnionNonO (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2) +{ + GdkRegionBox *pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1 < y2); + + while (r != rEnd) + { + assert(r->x1 < r->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + r++; + } +} + + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. + * + * Results: + * None. + * + * Side Effects: + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. + * + *----------------------------------------------------------------------- + */ + +/* static void*/ +static void +miUnionO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + +#define MERGERECT(r) \ + if ((pReg->numRects != 0) && \ + (pNextRect[-1].y1 == y1) && \ + (pNextRect[-1].y2 == y2) && \ + (pNextRect[-1].x2 >= r->x1)) \ + { \ + if (pNextRect[-1].x2 < r->x2) \ + { \ + pNextRect[-1].x2 = r->x2; \ + assert(pNextRect[-1].x1rects); \ + pNextRect->y1 = y1; \ + pNextRect->y2 = y2; \ + pNextRect->x1 = r->x1; \ + pNextRect->x2 = r->x2; \ + pReg->numRects += 1; \ + pNextRect += 1; \ + } \ + assert(pReg->numRects<=pReg->size); \ + r++; + + assert (y1x1 < r2->x1) + { + MERGERECT(r1); + } + else + { + MERGERECT(r2); + } + } + + if (r1 != r1End) + { + do + { + MERGERECT(r1); + } while (r1 != r1End); + } + else while (r2 != r2End) + { + MERGERECT(r2); + } +} + +void +gdk_region_union (GdkRegion *region, + GdkRegion *other) +{ + /* checks all the simple cases */ + + /* + * region and other are the same or other is empty + */ + if ((region == other) || (!(other->numRects))) + return; + + /* + * region is empty + */ + if (!(region->numRects)) + { + miRegionCopy (region, other); + return; + } + + /* + * region completely subsumes otehr + */ + if ((region->numRects == 1) && + (region->extents.x1 <= other->extents.x1) && + (region->extents.y1 <= other->extents.y1) && + (region->extents.x2 >= other->extents.x2) && + (region->extents.y2 >= other->extents.y2)) + return; + + /* + * other completely subsumes region + */ + if ((other->numRects == 1) && + (other->extents.x1 <= region->extents.x1) && + (other->extents.y1 <= region->extents.y1) && + (other->extents.x2 >= region->extents.x2) && + (other->extents.y2 >= region->extents.y2)) + { + miRegionCopy(region, other); + return; + } + + miRegionOp (region, region, other, miUnionO, + miUnionNonO, miUnionNonO); + + region->extents.x1 = MIN (region->extents.x1, other->extents.x1); + region->extents.y1 = MIN (region->extents.y1, other->extents.y1); + region->extents.x2 = MAX (region->extents.x2, other->extents.x2); + region->extents.y2 = MAX (region->extents.y2, other->extents.y2); +} + + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miSubtractNonO -- + * Deal with non-overlapping band for subtraction. Any parts from + * region 2 we discard. Anything from region 1 we add to the region. + * + * Results: + * None. + * + * Side Effects: + * pReg may be affected. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miSubtractNonO1 (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1x1x2); + MEMCHECK (pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert (pReg->numRects <= pReg->size); + + r++; + } +} + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * None. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miSubtractO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + int x1; + + x1 = r1->x1; + + assert(y1rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + if (r2->x2 <= x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + assert(x1x1); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r2->x1; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects<=pReg->size); + } + r1++; + x1 = r1->x1; + } + } + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + assert(x1x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + r1++; + if (r1 != r1End) + { + x1 = r1->x1; + } + } +} + +/*- + *----------------------------------------------------------------------- + * gdk_region_subtract -- + * Subtract other from region and leave the result in region. + * + * Results: + * TRUE. + * + * Side Effects: + * region is overwritten. + * + *----------------------------------------------------------------------- + */ + +void +gdk_region_subtract (GdkRegion *region, + GdkRegion *other) +{ + /* check for trivial reject */ + if ((!(region->numRects)) || (!(other->numRects)) || + (!EXTENTCHECK(®ion->extents, &other->extents))) + return; + + miRegionOp (region, region, other, miSubtractO, + miSubtractNonO1, (nonOverlapFunc) NULL); + + /* + * Can't alter region's extents before we call miRegionOp because miRegionOp + * depends on the extents of those regions being the unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents (region); +} + +void +gdk_region_xor (GdkRegion *sra, + GdkRegion *srb) +{ + GdkRegion *trb; + + trb = gdk_region_copy (srb); + + gdk_region_subtract (trb, sra); + gdk_region_subtract (sra, srb); + + gdk_region_union (sra,trb); + + gdk_region_destroy (trb); +} + +/* + * Check to see if the region is empty. Assumes a region is passed + * as a parameter + */ +gboolean +gdk_region_empty (GdkRegion *r) +{ + if (r->numRects == 0) + return TRUE; + else + return FALSE; +} + +/* + * Check to see if two regions are equal + */ +gboolean +gdk_region_equal (GdkRegion *r1, + GdkRegion *r2) +{ + int i; + + if (r1->numRects != r2->numRects) return FALSE; + else if (r1->numRects == 0) return TRUE; + else if (r1->extents.x1 != r2->extents.x1) return FALSE; + else if (r1->extents.x2 != r2->extents.x2) return FALSE; + else if (r1->extents.y1 != r2->extents.y1) return FALSE; + else if (r1->extents.y2 != r2->extents.y2) return FALSE; + else + for(i=0; i < r1->numRects; i++ ) + { + if (r1->rects[i].x1 != r2->rects[i].x1) return FALSE; + else if (r1->rects[i].x2 != r2->rects[i].x2) return FALSE; + else if (r1->rects[i].y1 != r2->rects[i].y1) return FALSE; + else if (r1->rects[i].y2 != r2->rects[i].y2) return FALSE; + } + return TRUE; +} + +gboolean +gdk_region_point_in (GdkRegion *region, + int x, + int y) +{ + int i; + + if (region->numRects == 0) + return FALSE; + if (!INBOX(region->extents, x, y)) + return FALSE; + for (i=0; inumRects; i++) + { + if (INBOX (region->rects[i], x, y)) + return TRUE; + } + return FALSE; +} + +GdkOverlapType +gdk_region_rect_in (GdkRegion *region, + GdkRectangle *rectangle) +{ + GdkRegionBox *pbox; + GdkRegionBox *pboxEnd; + GdkRegionBox rect; + GdkRegionBox *prect = ▭ + gboolean partIn, partOut; + + gint rx = rectangle->x; + gint ry = rectangle->y; + + prect->x1 = rx; + prect->y1 = ry; + prect->x2 = rx + rectangle->width; + prect->y2 = ry + rectangle->height; + + /* this is (just) a useful optimization */ + if ((region->numRects == 0) || !EXTENTCHECK (®ion->extents, prect)) + return GDK_OVERLAP_RECTANGLE_IN; + + partOut = FALSE; + partIn = FALSE; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = region->rects, pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + + if (pbox->y2 <= ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > ry) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + ry = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= rx) + continue; /* not far enough over yet */ + + if (pbox->x1 > rx) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + ry = pbox->y2; /* finished with this band */ + if (ry >= prect->y2) + break; + rx = prect->x1; /* reset x out to left again */ + } + else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } + + } + + return (partIn ? + ((ry < prect->y2) ? + GDK_OVERLAP_RECTANGLE_PART : GDK_OVERLAP_RECTANGLE_IN) : + GDK_OVERLAP_RECTANGLE_OUT); +} diff --git a/gdk/nanox/gdkregion-nanox.c b/gdk/nanox/gdkregion-nanox.c new file mode 100644 index 0000000000..b0bcc33d81 --- /dev/null +++ b/gdk/nanox/gdkregion-nanox.c @@ -0,0 +1,107 @@ +#include "gdkprivate-nanox.h" + +GdkRegion* +gdk_region_new (void) +{ + return NULL; +} + + +void +gdk_region_destroy (GdkRegion *region) +{ +} + + +gboolean +gdk_region_empty (GdkRegion *region) +{ + return 1; +} + +gboolean +gdk_region_equal (GdkRegion *region1, + GdkRegion *region2) +{ + return 1; +} + + +void +gdk_region_get_clipbox(GdkRegion *region, + GdkRectangle *rectangle) +{ +} + +gboolean +gdk_region_point_in (GdkRegion *region, + gint x, + gint y) +{ + return 0; +} + +GdkOverlapType +gdk_region_rect_in (GdkRegion *region, + GdkRectangle *rect) +{ + return 0; +} + +GdkRegion * +gdk_region_polygon (GdkPoint *points, + gint npoints, + GdkFillRule fill_rule) +{ + return NULL; +} + +void +gdk_region_offset (GdkRegion *region, + gint dx, + gint dy) +{ +} + +void +gdk_region_shrink (GdkRegion *region, + gint dx, + gint dy) +{ +} + +GdkRegion* +gdk_region_union_with_rect (GdkRegion *region, + GdkRectangle *rect) +{ + return NULL; +} + +GdkRegion* +gdk_regions_intersect (GdkRegion *source1, + GdkRegion *source2) +{ + return NULL; +} + +GdkRegion* +gdk_regions_union (GdkRegion *source1, + GdkRegion *source2) +{ + return NULL; +} + +GdkRegion* +gdk_regions_subtract (GdkRegion *source1, + GdkRegion *source2) +{ + return NULL; +} + +GdkRegion* +gdk_regions_xor (GdkRegion *source1, + GdkRegion *source2) +{ + return NULL; +} + diff --git a/gdk/nanox/gdkselection-nanox.c b/gdk/nanox/gdkselection-nanox.c new file mode 100644 index 0000000000..60d7fcaa2c --- /dev/null +++ b/gdk/nanox/gdkselection-nanox.c @@ -0,0 +1,89 @@ +#include "gdk.h" +#include "gdkprivate-nanox.h" + +gboolean +gdk_selection_owner_set (GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +GdkWindow* +gdk_selection_owner_get (GdkAtom selection) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + + +void +gdk_selection_convert (GdkWindow *requestor, + GdkAtom selection, + GdkAtom target, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +gint +gdk_selection_property_get (GdkWindow *requestor, + guchar **data, + GdkAtom *ret_type, + gint *ret_format) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +void +gdk_selection_send_notify (guint32 requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +gint +gdk_text_property_to_text_list (GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +void +gdk_free_text_list (gchar **list) +{ + g_return_if_fail (list != NULL); + +} + +gint +gdk_string_to_compound_text (const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void gdk_free_compound_text (guchar *ctext) +{ +/* if (ctext) + g_free (ctext);*/ +} + diff --git a/gdk/nanox/gdkvisual-nanox.c b/gdk/nanox/gdkvisual-nanox.c new file mode 100644 index 0000000000..616410d03b --- /dev/null +++ b/gdk/nanox/gdkvisual-nanox.c @@ -0,0 +1,95 @@ + +#include "gdkvisual.h" +#include "gdkprivate-nanox.h" +#include + +static GdkVisual system_visual; + +void +gdk_visual_init (void) +{ + system_visual.type = GDK_VISUAL_TRUE_COLOR; + system_visual.depth = 24; + system_visual.bits_per_rgb = 8; +} + +GdkVisual* +gdk_visual_ref (GdkVisual *visual) +{ + return visual; +} + +void +gdk_visual_unref (GdkVisual *visual) +{ + return; +} + +gint +gdk_visual_get_best_depth (void) +{ + return 24; +} + +GdkVisualType +gdk_visual_get_best_type (void) +{ + return GDK_VISUAL_TRUE_COLOR; +} + +GdkVisual* +gdk_visual_get_system (void) +{ + return ((GdkVisual*) &system_visual); +} + +GdkVisual* +gdk_visual_get_best (void) +{ + return ((GdkVisual*) &system_visual); +} + +GdkVisual* +gdk_visual_get_best_with_type (GdkVisualType visual_type) +{ + if (visual_type == GDK_VISUAL_TRUE_COLOR) + return &system_visual; + return NULL; +} + +GdkVisual* +gdk_visual_get_best_with_both (gint depth, + GdkVisualType visual_type) +{ + if (visual_type == GDK_VISUAL_TRUE_COLOR && depth == 24) + return &system_visual; + return NULL; +} + +void +gdk_query_depths (gint **depths, + gint *count) +{ + if (count) + *count = 1; + if (depths) + *depths[0] = 24; +} + +void +gdk_query_visual_types (GdkVisualType **visual_types, + gint *count) +{ + if (count) + *count = 1; + if (visual_types) + *visual_types[0] = GDK_VISUAL_TRUE_COLOR; +} + +GList* +gdk_list_visuals (void) +{ + return g_list_append(NULL, &system_visual); +} + + diff --git a/gdk/nanox/gdkwindow-nanox.c b/gdk/nanox/gdkwindow-nanox.c new file mode 100644 index 0000000000..c537c8fe95 --- /dev/null +++ b/gdk/nanox/gdkwindow-nanox.c @@ -0,0 +1,600 @@ + +#include "gdk.h" +#include "config.h" + +#include "gdkwindow.h" +#include "gdkprivate-nanox.h" +#include "gdkprivate.h" + +static void create_toplevel (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height); +static int manage_event (GR_EVENT *event); +static void set_title (GR_WINDOW_ID win, char* title); + +typedef struct { + char * name; + void (*create_toplevel) (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height); + int (*manage_event) (GR_EVENT *event); + void (*set_title) (GR_WINDOW_ID win, char* title); +} GdkWindowManager; + +typedef struct { + GR_WINDOW_ID pwin; + GR_WINDOW_ID win; + char *title; + GdkWMFunction functions; + GdkWMDecoration decors; +} WMInfo; + +static GdkWindowManager test_wm = { + "test", + create_toplevel, + manage_event, + set_title +}; + +static GdkWindowManager *default_wm = &test_wm; +static GHashTable * wm_hash = NULL; +GdkDrawableClass _gdk_windowing_window_class; + +static void create_toplevel (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height) +{ + WMInfo *winfo; + + winfo = g_new0(WMInfo, 1); + winfo->pwin = GrNewWindow(parent, x, y-20, width, height+20, 0, RGB(150, 50,150), WHITE); + winfo->win = win; + GrReparentWindow(winfo->pwin, win, 20, 0); + if (!wm_hash) + wm_hash = g_hash_table_new(g_int_hash, g_int_equal); + g_hash_table_insert(wm_hash, winfo->pwin, winfo); +} + +static int manage_event (GR_EVENT *event) { + return 0; +} + +static void set_title (GR_WINDOW_ID win, char* title) { +} + + +static void +gdk_nanox_window_destroy (GdkDrawable *drawable) +{ + if (!GDK_DRAWABLE_DESTROYED (drawable)) + { + if (GDK_DRAWABLE_TYPE (drawable) == GDK_WINDOW_FOREIGN) + gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable)); + else + g_warning ("losing last reference to undestroyed window\n"); + } + + g_free (GDK_DRAWABLE_XDATA (drawable)); +} + +static GdkWindowPrivate* +gdk_window_nanox_alloc() { + GdkWindow *window; + GdkWindowPrivate *private; + + static GdkDrawableClass klass; + static gboolean initialized = FALSE; + + if (!initialized) + { + initialized = TRUE; + + klass = _gdk_nanox_drawable_class; + klass.destroy = gdk_nanox_window_destroy; + } + + window = _gdk_window_alloc (); + private = (GdkWindowPrivate *)window; + + private->drawable.klass = &klass; + private->drawable.klass_data = g_new (GdkDrawableXData, 1); + + return window; +} + +static void +gdk_window_internal_destroy (GdkWindow *window, + gboolean xdestroy, + gboolean our_destroy) +{ +} + +GR_WINDOW_ID gdk_root_window = GR_ROOT_WINDOW_ID; + +void +gdk_window_init (void) +{ + GdkWindowPrivate *private; + + gdk_parent_root = gdk_window_nanox_alloc (); + private = (GdkWindowPrivate *)gdk_parent_root; + + GDK_DRAWABLE_XDATA (gdk_parent_root)->xid = gdk_root_window; + + private->drawable.window_type = GDK_WINDOW_ROOT; + private->drawable.width = gdk_screen_width(); + private->drawable.height = gdk_screen_height(); + + gdk_window_set_events(private, -1); + gdk_xid_table_insert (&gdk_root_window, gdk_parent_root); +} + + +GdkWindow* +gdk_window_new (GdkWindow *parent, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GR_WINDOW_ID new_win; + GdkWindowPrivate *private, *parent_private; + int x, y, width, height; + int border = 1; + + if (!parent) + parent = gdk_parent_root; + + if (GDK_DRAWABLE_DESTROYED (parent)) + return NULL; + + private->parent = parent; + + parent_private = (GdkWindowPrivate*)parent; + + if (attributes_mask & GDK_WA_X) + x = attributes->x; + else + x = 0; + + if (attributes_mask & GDK_WA_Y) + y = attributes->y; + else + y = 0; + + width = attributes->width; + height = attributes->height; + + private = gdk_window_nanox_alloc(); + private->x = x; + private->y = y; + private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1); + private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1); + private->drawable.window_type = attributes->window_type; + + if (attributes->window_type == GDK_WINDOW_TOPLEVEL || attributes->window_type == GDK_WINDOW_DIALOG) + border = 2; + /* if toplevel reparent to our own window managed window... (check override_redirect) */ + if (attributes->wclass == GDK_INPUT_OUTPUT) + new_win = GrNewWindow(GDK_WINDOW_XWINDOW(parent), x, y, width, height, border, RGB(150,150,150), WHITE); + else + new_win = GrNewInputWindow(GDK_WINDOW_XWINDOW(parent), x, y, width, height); + + GDK_DRAWABLE_XDATA(private)->xid = new_win; + gdk_drawable_ref(private); + + private->drawable.colormap = gdk_colormap_get_system (); + + gdk_xid_table_insert (&GDK_DRAWABLE_XID(private), private); + g_message("created window %d %d %d %d %d", new_win, x, y, width, height); + GrSelectEvents(GDK_DRAWABLE_XID(private), -1); + return (GdkWindow*)private;; +} + + +GdkWindow * +gdk_window_foreign_new (guint32 anid) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +void +gdk_window_destroy (GdkWindow *window) +{ + gdk_window_internal_destroy (window, TRUE, TRUE); + gdk_drawable_unref (window); +} + +void +gdk_window_destroy_notify (GdkWindow *window) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_show (GdkWindow *window) +{ + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + + private = (GdkWindowPrivate*) window; + if (!private->drawable.destroyed) + { + private->mapped = TRUE; + GrRaiseWindow (GDK_DRAWABLE_XID (window)); + GrMapWindow (GDK_DRAWABLE_XID (window)); + } +} + +void +gdk_window_hide (GdkWindow *window) +{ + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + + private = (GdkWindowPrivate*) window; + if (!private->drawable.destroyed) + { + private->mapped = FALSE; + GrUnmapWindow (GDK_DRAWABLE_XID (window)); + } +} + +void +gdk_window_raise (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_DRAWABLE_DESTROYED (window)) + GrRaiseWindow (GDK_DRAWABLE_XID (window)); +} + +void +gdk_window_lower (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_DRAWABLE_DESTROYED (window)) + GrLowerWindow (GDK_DRAWABLE_XID (window)); +} + +void +gdk_window_withdraw (GdkWindow *window) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_move (GdkWindow *window, + gint x, + gint y) +{ + GrMoveWindow(GDK_DRAWABLE_XID(window), x, y); +} + +void +gdk_window_resize (GdkWindow *window, + gint width, + gint height) +{ + GrResizeWindow(GDK_DRAWABLE_XID(window), width, height); +} + +void +gdk_window_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + GrMoveWindow(GDK_DRAWABLE_XID(window), x, y); + GrResizeWindow(GDK_DRAWABLE_XID(window), width, height); +} + +void +gdk_window_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + GrReparentWindow(GDK_DRAWABLE_XID(window), GDK_DRAWABLE_XID(new_parent), x, y); +} + +void +gdk_window_clear (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_DRAWABLE_DESTROYED (window)) + GrClearWindow (GDK_DRAWABLE_XID (window), 0); +} + +void +_gdk_windowing_window_clear_area (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_DRAWABLE_DESTROYED (window)) + GrClearWindow (GDK_DRAWABLE_XID (window), 0); +} + +void +_gdk_windowing_window_clear_area_e (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_DRAWABLE_DESTROYED (window)) + GrClearWindow (GDK_DRAWABLE_XID (window), 1); +} + +void +gdk_window_set_hints (GdkWindow *window, + gint x, + gint y, + gint min_width, + gint min_height, + gint max_width, + gint max_height, + gint flags) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_geometry_hints (GdkWindow *window, + GdkGeometry *geometry, + GdkWindowHints geom_mask) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_title (GdkWindow *window, + const gchar *title) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_role (GdkWindow *window, + const gchar *role) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_transient_for (GdkWindow *window, + GdkWindow *parent) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_background (GdkWindow *window, + GdkColor *color) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + g_message("unimplemented %s", __FUNCTION__); + if (GDK_DRAWABLE_DESTROYED (window)) + return; +} + + +void +gdk_window_set_back_pixmap (GdkWindow *window, + GdkPixmap *pixmap, + gboolean parent_relative) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_cursor (GdkWindow *window, + GdkCursor *cursor) +{ +} + +void +gdk_window_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height, + gint *depth) +{ + GR_WINDOW_INFO winfo; + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + if (!window) + window = gdk_parent_root; + + if (!GDK_DRAWABLE_DESTROYED (window)) + { + GrGetWindowInfo(GDK_DRAWABLE_XID(window), &winfo); + if (x) + *x = winfo.x; + if (y) + *y = winfo.y; + if (width) + *width = winfo.width; + if (height) + *height = winfo.height; + if (depth) + *depth = 24; + } +} + + +gint +gdk_window_get_origin (GdkWindow *window, + gint *x, + gint *y) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +gboolean +gdk_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + + +void +gdk_window_get_root_origin (GdkWindow *window, + gint *x, + gint *y) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +GdkWindow* +gdk_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkWindow* +gdk_window_at_pointer (gint *win_x, + gint *win_y) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + + +GList* +gdk_window_get_children (GdkWindow *window) +{ + g_message("unimplemented %s", __FUNCTION__); + return NULL; +} + +GdkEventMask +gdk_window_get_events (GdkWindow *window) +{ + return -1; +} + + +void +gdk_window_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ + GrSelectEvents(GDK_DRAWABLE_XID(window), -1); +} + + +void +gdk_window_shape_combine_mask (GdkWindow *window, + GdkBitmap *mask, + gint x, gint y) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_override_redirect (GdkWindow *window, + gboolean override_redirect) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_icon (GdkWindow *window, + GdkWindow *icon_window, + GdkPixmap *pixmap, + GdkBitmap *mask) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_icon_name (GdkWindow *window, + const gchar *name) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_set_functions (GdkWindow *window, + GdkWMFunction functions) +{ + g_message("unimplemented %s", __FUNCTION__); +} + +void +gdk_window_set_child_shapes (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_message("unimplemented %s", __FUNCTION__); +} + + +void +gdk_window_merge_child_shapes (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_message("unimplemented %s", __FUNCTION__); +} + + +gboolean +gdk_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + g_message("unimplemented %s", __FUNCTION__); + return 0; +} + +void +_gdk_windowing_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset) { + *x_offset = *y_offset = 0; +} + +gboolean +_gdk_windowing_window_queue_antiexpose (GdkWindow *window, GdkRegion *area) { + return FALSE; +} diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 43b19e47fa..781a3aad90 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -30,6 +30,8 @@ #include "x11/gdkx.h" #elif defined (GDK_WINDOWING_WIN32) #include "win32/gdkwin32.h" +#elif defined (GDK_WINDOWING_NANOX) +#include "nanox/gdkprivate-nanox.h" #endif #include "gdk/gdkkeysyms.h" diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c index ea68dd97aa..116e8e35fa 100644 --- a/gtk/gtkplug.c +++ b/gtk/gtkplug.c @@ -31,6 +31,8 @@ #include "x11/gdkx.h" #elif defined (GDK_WINDOWING_WIN32) #include "win32/gdkwin32.h" +#elif defined (GDK_WINDOWING_NANOX) +#include "nanox/gdkprivate-nanox.h" #endif #include "gdk/gdkkeysyms.h" diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c index 6f6ce8d04b..2bfbf95ed0 100644 --- a/gtk/gtkselection.c +++ b/gtk/gtkselection.c @@ -59,6 +59,8 @@ #include "x11/gdkx.h" /* For gdk_window_lookup() */ #elif defined (GDK_WINDOWING_WIN32) #include "win32/gdkwin32.h" /* For gdk_window_lookup() */ +#elif defined (GDK_WINDOWING_NANOX) +#include "nanox/gdkprivate-nanox.h" /* For gdk_window_lookup() */ #endif #include "gtkmain.h" diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 3c649d08e6..b738142296 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -33,6 +33,8 @@ #include "x11/gdkx.h" #elif defined (GDK_WINDOWING_WIN32) #include "win32/gdkwin32.h" +#elif defined (GDK_WINDOWING_NANOX) +#include "nanox/gdkprivate-nanox.h" #endif #include "gtkprivate.h"