Commit 2622c79d by Rolf W. Rasmussen Committed by Rolf Rasmussen

Makefile.am: Added rules for libgcjx library.

	* Makefile.am: Added rules for libgcjx library.
	* Makefile.in: Rebuilt.
	* configure.in: Added check for X.
	* configure: Rebuilt.
	* gnu/awt/LightweightRedirector.java: New file.
	* gnu/awt/j2d/AbstractGraphicsState.java: New file.
	* gnu/awt/j2d/DirectRasterGraphics.java: New file.
	* gnu/awt/j2d/Graphics2DImpl.java: New file.
	* gnu/awt/j2d/IntegerGraphicsState.java: New file.
	* gnu/awt/j2d/MappedRaster.java: New file.
	* gnu/awt/xlib/XCanvasPeer.java: New file.
	* gnu/awt/xlib/XEventLoop.java: New file.
	* gnu/awt/xlib/XEventQueue.java: New file.
	* gnu/awt/xlib/XFontMetrics.java: New file.
	* gnu/awt/xlib/XFramePeer.java: New file.
	* gnu/awt/xlib/XGraphics.java: New file.
	* gnu/awt/xlib/XGraphicsConfiguration.java: New file.
	* gnu/awt/xlib/XPanelPeer.java: New file.
	* gnu/awt/xlib/XToolkit.java: New file.
	* gnu/gcj/xlib/Clip.java: New file.
	* gnu/gcj/xlib/Colormap.java: New file.
	* gnu/gcj/xlib/Display.java: New file.
	* gnu/gcj/xlib/Drawable.java: New file.
	* gnu/gcj/xlib/Font.java: New file.
	* gnu/gcj/xlib/GC.java: New file.
	* gnu/gcj/xlib/Pixmap.java: New file.
	* gnu/gcj/xlib/Screen.java: New file.
	* gnu/gcj/xlib/Visual.java: New file.
	* gnu/gcj/xlib/WMSizeHints.java: New file.
	* gnu/gcj/xlib/Window.java: New file.
	* gnu/gcj/xlib/WindowAttributes.java: New file.
	* gnu/gcj/xlib/XAnyEvent.java: New file.
	* gnu/gcj/xlib/XButtonEvent.java: New file.
	* gnu/gcj/xlib/XColor.java: New file.
	* gnu/gcj/xlib/XConfigureEvent.java: New file.
	* gnu/gcj/xlib/XConnectException.java: New file.
	* gnu/gcj/xlib/XEvent.java: New file.
	* gnu/gcj/xlib/XException.java: New file.
	* gnu/gcj/xlib/XExposeEvent.java: New file.
	* gnu/gcj/xlib/XID.java: New file.
	* gnu/gcj/xlib/XImage.java: New file.
	* gnu/gcj/xlib/XUnmapEvent.java: New file.
	* gnu/gcj/xlib/natClip.cc: New file.
	* gnu/gcj/xlib/natColormap.cc: New file.
	* gnu/gcj/xlib/natDisplay.cc: New file.
	* gnu/gcj/xlib/natDrawable.cc: New file.
	* gnu/gcj/xlib/natFont.cc: New file.
	* gnu/gcj/xlib/natGC.cc: New file.
	* gnu/gcj/xlib/natPixmap.cc: New file.
	* gnu/gcj/xlib/natScreen.cc: New file.
	* gnu/gcj/xlib/natVisual.cc: New file.
	* gnu/gcj/xlib/natWMSizeHints.cc: New file.
	* gnu/gcj/xlib/natWindow.cc: New file.
	* gnu/gcj/xlib/natWindowAttributes.cc: New file.
	* gnu/gcj/xlib/natXAnyEvent.cc: New file.
	* gnu/gcj/xlib/natXButtonEvent.cc: New file.
	* gnu/gcj/xlib/natXColor.cc: New file.
	* gnu/gcj/xlib/natXConfigureEvent.cc: New file.
	* gnu/gcj/xlib/natXException.cc: New file.
	* gnu/gcj/xlib/natXExposeEvent.cc: New file.
	* gnu/gcj/xlib/natXImage.cc: New file.
	* gnu/gcj/xlib/natXUnmapEvent.cc: New file.
	* java/awt/EventDispatchThread.java: Start thead on creation.

From-SVN: r37005
parent 9b95cc4a
2000-10-22 Rolf W. Rasmussen <rolfwr@ii.uib.no>
* Makefile.am: Added rules for libgcjx library.
* Makefile.in: Rebuilt.
* configure.in: Added check for X.
* configure: Rebuilt.
* gnu/awt/LightweightRedirector.java: New file.
* gnu/awt/j2d/AbstractGraphicsState.java: New file.
* gnu/awt/j2d/DirectRasterGraphics.java: New file.
* gnu/awt/j2d/Graphics2DImpl.java: New file.
* gnu/awt/j2d/IntegerGraphicsState.java: New file.
* gnu/awt/j2d/MappedRaster.java: New file.
* gnu/awt/xlib/XCanvasPeer.java: New file.
* gnu/awt/xlib/XEventLoop.java: New file.
* gnu/awt/xlib/XEventQueue.java: New file.
* gnu/awt/xlib/XFontMetrics.java: New file.
* gnu/awt/xlib/XFramePeer.java: New file.
* gnu/awt/xlib/XGraphics.java: New file.
* gnu/awt/xlib/XGraphicsConfiguration.java: New file.
* gnu/awt/xlib/XPanelPeer.java: New file.
* gnu/awt/xlib/XToolkit.java: New file.
* gnu/gcj/xlib/Clip.java: New file.
* gnu/gcj/xlib/Colormap.java: New file.
* gnu/gcj/xlib/Display.java: New file.
* gnu/gcj/xlib/Drawable.java: New file.
* gnu/gcj/xlib/Font.java: New file.
* gnu/gcj/xlib/GC.java: New file.
* gnu/gcj/xlib/Pixmap.java: New file.
* gnu/gcj/xlib/Screen.java: New file.
* gnu/gcj/xlib/Visual.java: New file.
* gnu/gcj/xlib/WMSizeHints.java: New file.
* gnu/gcj/xlib/Window.java: New file.
* gnu/gcj/xlib/WindowAttributes.java: New file.
* gnu/gcj/xlib/XAnyEvent.java: New file.
* gnu/gcj/xlib/XButtonEvent.java: New file.
* gnu/gcj/xlib/XColor.java: New file.
* gnu/gcj/xlib/XConfigureEvent.java: New file.
* gnu/gcj/xlib/XConnectException.java: New file.
* gnu/gcj/xlib/XEvent.java: New file.
* gnu/gcj/xlib/XException.java: New file.
* gnu/gcj/xlib/XExposeEvent.java: New file.
* gnu/gcj/xlib/XID.java: New file.
* gnu/gcj/xlib/XImage.java: New file.
* gnu/gcj/xlib/XUnmapEvent.java: New file.
* gnu/gcj/xlib/natClip.cc: New file.
* gnu/gcj/xlib/natColormap.cc: New file.
* gnu/gcj/xlib/natDisplay.cc: New file.
* gnu/gcj/xlib/natDrawable.cc: New file.
* gnu/gcj/xlib/natFont.cc: New file.
* gnu/gcj/xlib/natGC.cc: New file.
* gnu/gcj/xlib/natPixmap.cc: New file.
* gnu/gcj/xlib/natScreen.cc: New file.
* gnu/gcj/xlib/natVisual.cc: New file.
* gnu/gcj/xlib/natWMSizeHints.cc: New file.
* gnu/gcj/xlib/natWindow.cc: New file.
* gnu/gcj/xlib/natWindowAttributes.cc: New file.
* gnu/gcj/xlib/natXAnyEvent.cc: New file.
* gnu/gcj/xlib/natXButtonEvent.cc: New file.
* gnu/gcj/xlib/natXColor.cc: New file.
* gnu/gcj/xlib/natXConfigureEvent.cc: New file.
* gnu/gcj/xlib/natXException.cc: New file.
* gnu/gcj/xlib/natXExposeEvent.cc: New file.
* gnu/gcj/xlib/natXImage.cc: New file.
* gnu/gcj/xlib/natXUnmapEvent.cc: New file.
* java/awt/EventDispatchThread.java: Start thead on creation.
2000-10-20 Tom Tromey <tromey@cygnus.com> 2000-10-20 Tom Tromey <tromey@cygnus.com>
From Arno J. Klaassen: From Arno J. Klaassen:
......
...@@ -23,7 +23,13 @@ toolexecdir = $(exec_prefix)/$(target_alias) ...@@ -23,7 +23,13 @@ toolexecdir = $(exec_prefix)/$(target_alias)
toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR) toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
endif endif
toolexeclib_LTLIBRARIES = libgcj.la if NO_X
cond_x_ltlibrary =
else
cond_x_ltlibrary = libgcjx.la
endif
toolexeclib_LTLIBRARIES = libgcj.la $(cond_x_ltlibrary)
toolexeclib_DATA = libgcj.spec toolexeclib_DATA = libgcj.spec
data_DATA = libgcj.zip data_DATA = libgcj.zip
...@@ -82,7 +88,7 @@ WARNINGS = -W -Wall ...@@ -82,7 +88,7 @@ WARNINGS = -W -Wall
AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \ AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \
## Some systems don't allow `$' in identifiers by default, so we force it. ## Some systems don't allow `$' in identifiers by default, so we force it.
-fdollars-in-identifiers \ -fdollars-in-identifiers \
@LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ $(WARNINGS) -D_GNU_SOURCE @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE
if USING_GCC if USING_GCC
AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS) AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
else else
...@@ -107,11 +113,13 @@ INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \ ...@@ -107,11 +113,13 @@ INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \
## Objects from C++ sources in subdirs. ## Objects from C++ sources in subdirs.
nat_files = $(nat_source_files:.cc=.lo) nat_files = $(nat_source_files:.cc=.lo)
x_nat_files = $(x_nat_source_files:.cc=.lo)
## Objects from C sources in subdirs. ## Objects from C sources in subdirs.
c_files = $(c_source_files:.c=.lo) c_files = $(c_source_files:.c=.lo)
## Objects from Java sources in subdirs. ## Objects from Java sources in subdirs.
javao_files = $(java_source_files:.java=.lo) \ javao_files = $(java_source_files:.java=.lo) \
$(built_java_source_files:.java=.lo) $(built_java_source_files:.java=.lo)
x_javao_files = $(x_java_source_files:.java=.lo)
## Extract the libffi object file names. ## Extract the libffi object file names.
libffi_files = `$(AR) t ../libffi/.libs/libffi.a 2>/dev/null | sed 's/\.o/\.lo/g' | sed 's/^/..\/libffi\//g'` libffi_files = `$(AR) t ../libffi/.libs/libffi.a 2>/dev/null | sed 's/\.o/\.lo/g' | sed 's/^/..\/libffi\//g'`
...@@ -130,6 +138,15 @@ libgcj_la_LDFLAGS = -lsupc++ -rpath $(toolexeclibdir) \ ...@@ -130,6 +138,15 @@ libgcj_la_LDFLAGS = -lsupc++ -rpath $(toolexeclibdir) \
-version-info `grep -v '^\#' $(srcdir)/libtool-version` -version-info `grep -v '^\#' $(srcdir)/libtool-version`
libgcj_la_LINK = $(LIBLINK) libgcj_la_LINK = $(LIBLINK)
libgcjx_la_SOURCES = $(x_nat_source_files)
EXTRA_libgcjx_la_SOURCES = $(x_java_source_files)
libgcjx_la_DEPENDENCIES = libgcj.zip $(x_javao_files)
libgcjx_la_LIBADD = $(x_javao_files)
libgcjx_la_LDFLAGS = @X_PRE_LIBS@ @X_LIBS@ -lX11 @X_EXTRA_LIBS@ \
-lsupc++ -rpath $(toolexeclibdir) \
## The mysterious backslash is consumed by make.
-version-info `grep -v '^\#' $(srcdir)/libtool-version`
libgcjx_la_LINK = $(LIBLINK)
## Make the .class files depend on the .zip file. This seems ## Make the .class files depend on the .zip file. This seems
## backwards, but is right. This doesn't catch all the .class files, ## backwards, but is right. This doesn't catch all the .class files,
...@@ -139,6 +156,11 @@ libgcj_la_LINK = $(LIBLINK) ...@@ -139,6 +156,11 @@ libgcj_la_LINK = $(LIBLINK)
## hand-maintained headers. ## hand-maintained headers.
$(java_source_files:.java=.class): libgcj.zip $(java_source_files:.java=.class): libgcj.zip
## The .class files for X will not be included in libgcj.zip, but the
## rule for libgcj.zip will cause all out-of-date .class files to be
## built. We need this to generate headers for the nat-files.
$(x_java_source_files:.java=.class): libgcj.zip
## FIXME: this isn't really correct. ## FIXME: this isn't really correct.
$(built_java_source_files:.java=.class): $(built_java_source_files) $(built_java_source_files:.java=.class): $(built_java_source_files)
## This little nastiness is here so that the backquoted stuff in the ## This little nastiness is here so that the backquoted stuff in the
...@@ -156,7 +178,7 @@ $(built_java_source_files:.java=.class): $(built_java_source_files) ...@@ -156,7 +178,7 @@ $(built_java_source_files:.java=.class): $(built_java_source_files)
## up-to-date, and foo.class is removed, and bar.java is touched, then ## up-to-date, and foo.class is removed, and bar.java is touched, then
## `make libgcj.zip' will not rebuilt foo.class. That's because ## `make libgcj.zip' will not rebuilt foo.class. That's because
## libgcj.zip is not out-of-date with respect to foo.java. ## libgcj.zip is not out-of-date with respect to foo.java.
libgcj.zip: $(java_source_files) libgcj.zip: $(java_source_files) $(x_java_source_files)
## Create a list of all Java sources, without exceeding any shell limits. ## Create a list of all Java sources, without exceeding any shell limits.
@: $(shell echo Creating list of files to compile...) $(shell rm -f tmp-list || :) $(shell touch tmp-list) $(foreach source,$(subst $(srcdir)/,,$?),$(shell echo $(source) >> tmp-list)) @: $(shell echo Creating list of files to compile...) $(shell rm -f tmp-list || :) $(shell touch tmp-list) $(foreach source,$(subst $(srcdir)/,,$?),$(shell echo $(source) >> tmp-list))
## FIXME: this ought to depend on built_java_source_files, but right ## FIXME: this ought to depend on built_java_source_files, but right
...@@ -171,9 +193,11 @@ libgcj.zip: $(java_source_files) ...@@ -171,9 +193,11 @@ libgcj.zip: $(java_source_files)
done done
-@rm -f tmp-list libgcj.zip -@rm -f tmp-list libgcj.zip
## Note that we explicitly want to include directory information. ## Note that we explicitly want to include directory information.
$(ZIP) -r libgcj java gnu -n .class -i '*.class' -i '*/' find java gnu -type d -o -type f -name '*.class' | \
sed -e '/\/\./d' -e '/\/xlib/d' | \
$(ZIP) libgcj -@ -n .class
MOSTLYCLEANFILES = $(javao_files) $(nat_files) $(nat_headers) $(c_files) MOSTLYCLEANFILES = $(javao_files) $(nat_files) $(nat_headers) $(c_files) $(x_javao_files) $(x_nat_files) $(x_nat_headers)
CLEANFILES = tmp-list libgcj.zip CLEANFILES = tmp-list libgcj.zip
clean-local: clean-local:
...@@ -192,7 +216,7 @@ SUFFIXES = .class .java .h ...@@ -192,7 +216,7 @@ SUFFIXES = .class .java .h
## special rule. The standard automake rule can't be overridden (this ## special rule. The standard automake rule can't be overridden (this
## is a bug in automake), and it also won't put the .o files into ## is a bug in automake), and it also won't put the .o files into
## subdirs. FIXME. ## subdirs. FIXME.
$(nat_files): %.lo: %.cc $(nat_files) $(x_nat_files): %.lo: %.cc
@echo '$(LTCXXCOMPILE) -c -o $@ $<'; \ @echo '$(LTCXXCOMPILE) -c -o $@ $<'; \
$(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c -o $@ $< $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
...@@ -209,7 +233,7 @@ $(c_files): %.lo: %.c ...@@ -209,7 +233,7 @@ $(c_files): %.lo: %.c
$(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h $(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
## FIXME: GNU make. ## FIXME: GNU make.
$(javao_files): %.lo: %.java $(javao_files) $(x_javao_files): %.lo: %.java
$(GCJCOMPILE) -o $@ $< $(GCJCOMPILE) -o $@ $<
## ################################################################ ## ################################################################
...@@ -228,6 +252,8 @@ nat_headers = $(ordinary_java_source_files:.java=.h) \ ...@@ -228,6 +252,8 @@ nat_headers = $(ordinary_java_source_files:.java=.h) \
java/io/ObjectOutputStream$$PutField.h \ java/io/ObjectOutputStream$$PutField.h \
java/io/ObjectInputStream$$GetField.h java/io/ObjectInputStream$$GetField.h
x_nat_headers = $(x_java_source_files:.java=.h)
java/lang/ClassLoader.h: java/lang/ClassLoader.class libgcj.zip java/lang/ClassLoader.h: java/lang/ClassLoader.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \ $(GCJH) -classpath $(top_builddir) \
-friend 'jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \ -friend 'jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \
...@@ -491,6 +517,16 @@ gnu/gcj/convert/UnicodeToBytes.java ...@@ -491,6 +517,16 @@ gnu/gcj/convert/UnicodeToBytes.java
special_java_source_files = java/lang/Class.java java/lang/Object.java special_java_source_files = java/lang/Class.java java/lang/Object.java
awt_java_source_files = \ awt_java_source_files = \
gnu/awt/LightweightRedirector.java \
gnu/awt/j2d/AbstractGraphicsState.java \
gnu/awt/j2d/DirectRasterGraphics.java \
gnu/awt/j2d/Graphics2DImpl.java \
gnu/awt/j2d/IntegerGraphicsState.java \
gnu/awt/j2d/MappedRaster.java \
gnu/gcj/awt/BitMaskExtent.java \
gnu/gcj/awt/Buffers.java \
gnu/gcj/awt/ComponentDataBlitOp.java \
gnu/gcj/awt/GLightweightPeer.java \
gnu/java/beans/editors/ColorEditor.java \ gnu/java/beans/editors/ColorEditor.java \
gnu/java/beans/editors/FontEditor.java \ gnu/java/beans/editors/FontEditor.java \
gnu/java/beans/editors/NativeBooleanEditor.java \ gnu/java/beans/editors/NativeBooleanEditor.java \
...@@ -506,10 +542,6 @@ gnu/java/beans/BeanInfoEmbryo.java \ ...@@ -506,10 +542,6 @@ gnu/java/beans/BeanInfoEmbryo.java \
gnu/java/beans/EmptyBeanInfo.java \ gnu/java/beans/EmptyBeanInfo.java \
gnu/java/beans/ExplicitBeanInfo.java \ gnu/java/beans/ExplicitBeanInfo.java \
gnu/java/beans/IntrospectionIncubator.java \ gnu/java/beans/IntrospectionIncubator.java \
gnu/gcj/awt/BitMaskExtent.java \
gnu/gcj/awt/Buffers.java \
gnu/gcj/awt/ComponentDataBlitOp.java \
gnu/gcj/awt/GLightweightPeer.java \
java/applet/Applet.java \ java/applet/Applet.java \
java/applet/AppletStub.java \ java/applet/AppletStub.java \
java/applet/AppletContext.java \ java/applet/AppletContext.java \
...@@ -1168,6 +1200,62 @@ java/util/natGregorianCalendar.cc \ ...@@ -1168,6 +1200,62 @@ java/util/natGregorianCalendar.cc \
java/util/zip/natDeflater.cc \ java/util/zip/natDeflater.cc \
java/util/zip/natInflater.cc java/util/zip/natInflater.cc
x_java_source_files = \
gnu/gcj/xlib/Clip.java \
gnu/gcj/xlib/Colormap.java \
gnu/gcj/xlib/Display.java \
gnu/gcj/xlib/Drawable.java \
gnu/gcj/xlib/Font.java \
gnu/gcj/xlib/GC.java \
gnu/gcj/xlib/Pixmap.java \
gnu/gcj/xlib/Screen.java \
gnu/gcj/xlib/Visual.java \
gnu/gcj/xlib/WMSizeHints.java \
gnu/gcj/xlib/Window.java \
gnu/gcj/xlib/WindowAttributes.java \
gnu/gcj/xlib/XAnyEvent.java \
gnu/gcj/xlib/XButtonEvent.java \
gnu/gcj/xlib/XColor.java \
gnu/gcj/xlib/XConfigureEvent.java \
gnu/gcj/xlib/XConnectException.java \
gnu/gcj/xlib/XEvent.java \
gnu/gcj/xlib/XException.java \
gnu/gcj/xlib/XExposeEvent.java \
gnu/gcj/xlib/XID.java \
gnu/gcj/xlib/XImage.java \
gnu/gcj/xlib/XUnmapEvent.java \
gnu/awt/xlib/XCanvasPeer.java \
gnu/awt/xlib/XEventLoop.java \
gnu/awt/xlib/XEventQueue.java \
gnu/awt/xlib/XFontMetrics.java \
gnu/awt/xlib/XFramePeer.java \
gnu/awt/xlib/XGraphics.java \
gnu/awt/xlib/XGraphicsConfiguration.java \
gnu/awt/xlib/XPanelPeer.java \
gnu/awt/xlib/XToolkit.java
x_nat_source_files = \
gnu/gcj/xlib/natClip.cc \
gnu/gcj/xlib/natColormap.cc \
gnu/gcj/xlib/natDisplay.cc \
gnu/gcj/xlib/natDrawable.cc \
gnu/gcj/xlib/natFont.cc \
gnu/gcj/xlib/natGC.cc \
gnu/gcj/xlib/natPixmap.cc \
gnu/gcj/xlib/natScreen.cc \
gnu/gcj/xlib/natVisual.cc \
gnu/gcj/xlib/natWMSizeHints.cc \
gnu/gcj/xlib/natWindow.cc \
gnu/gcj/xlib/natWindowAttributes.cc \
gnu/gcj/xlib/natXAnyEvent.cc \
gnu/gcj/xlib/natXButtonEvent.cc \
gnu/gcj/xlib/natXColor.cc \
gnu/gcj/xlib/natXConfigureEvent.cc \
gnu/gcj/xlib/natXException.cc \
gnu/gcj/xlib/natXExposeEvent.cc \
gnu/gcj/xlib/natXImage.cc \
gnu/gcj/xlib/natXUnmapEvent.cc
## ################################################################ ## ################################################################
## ##
...@@ -1182,7 +1270,7 @@ java/util/zip/natInflater.cc ...@@ -1182,7 +1270,7 @@ java/util/zip/natInflater.cc
## compile the C++ sources, but we can't make the .o files depend on ## compile the C++ sources, but we can't make the .o files depend on
## the headers, because in that case we'll force a complete rebuild of ## the headers, because in that case we'll force a complete rebuild of
## the C++ code whenever any .java file is touched. ## the C++ code whenever any .java file is touched.
all-recursive: $(nat_headers) all-recursive: $(nat_headers) $(x_nat_headers)
## ################################################################ ## ################################################################
......
...@@ -762,6 +762,10 @@ else ...@@ -762,6 +762,10 @@ else
multilib_arg= multilib_arg=
fi fi
AC_PATH_XTRA
AM_CONDITIONAL(NO_X, test "$no_x" = yes)
here=`pwd` here=`pwd`
AC_SUBST(here) AC_SUBST(here)
......
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt;
import java.awt.AWTEvent;
import java.awt.AWTError;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
/**
* Encapsulates the logic required to dispatch events to the correct
* component in a component tree that may contain lightweight
* components. Toolkits typically only identify heavyweight components
* as the source of events. This class redirects the events to the
* appropriate lightweight children of the heavyweight component.
*/
public class LightweightRedirector
{
final static int LAST_BUTTON_NUMBER = 3;
/* We sacrifice one array element to allow the button number to
match the index of this array. */
Component[] releaseTargets = new Component[LAST_BUTTON_NUMBER+1];
/**
*
* Modifies or replaces the given event with an event that has been
* properly redirected. State of button presses are kept so that
* button releases can be redirected to the same component as the
* button press. It is required that all events are sent through
* this method in chronological order.
*/
public AWTEvent redirect(AWTEvent event)
{
if (event instanceof MouseEvent)
return redirectMouse((MouseEvent) event);
/* In case we don't know how to redirect the event, simply return
the event unchanged. */
return event;
}
MouseEvent redirectMouse(MouseEvent event)
{
int button = getButtonNumber(event);
int id = event.getID();
Component heavySource = (Component) event.getSource();
Component source = heavySource;
int x = event.getX();
int y = event.getY();
if (id == MouseEvent.MOUSE_RELEASED)
{
Component target = releaseTargets[button];
if (target != null)
{
releaseTargets[button] = null;
source = target;
Component child = source;
while (child != heavySource)
{
x -= child.getX();
y -= child.getY();
child = child.getParent();
if (child == null)
System.err.println("warning, orphaned release target");
}
}
}
else
{
/* Find real component, and adjust source, x and y
accordingly. */
while (true)
{
Component parent = source;
Component child = parent.getComponentAt(x, y);
if (parent == child)
break;
// maybe ignoring would be better?
if (child == null)
{
String msg = "delivered event not within component. " +
"Heavyweight source was " + heavySource + ". " +
"Component was " + parent;
throw new AWTError(msg);
}
if (child.isLightweight())
{
// descend down to child
source = child;
x -= child.getX();
y -= child.getY();
}
else
{
System.err.println("warning: event delivered to wrong " +
"heavyweight component. Was " +
"delivered to " + source + ". " +
"Should have been delivered to " +
child + ". Maybe the native window " +
"system is bubbling events up the " +
"containment hierarchy.");
break;
}
}
/* ensure that the release event is delivered to the same
component as the press event. For most toolkits this is
only necessary for lightweight components, since the
underlying windowing system takes care of its heavyweight
components. */
if (id == MouseEvent.MOUSE_PRESSED)
releaseTargets[button] = source;
}
if (source == heavySource)
return event; // no change in event
// print warning for heavyweights
/* this warning can safely be removed if a toolkit that
needs heavyweight redirection support is ever created. */
if (!source.isLightweight())
System.err.println("warning: redirecting to heavyweight");
MouseEvent redirected = new MouseEvent(source, event.getID(),
event.getWhen(),
event.getModifiers(),
x, y,
event.getClickCount(),
event.isPopupTrigger());
return redirected;
}
/**
* Identifies the button number for an input event.
*
* @returns the button number, or 0 if no button modifier was set
* for the event.
*/
int getButtonNumber(InputEvent event)
{
int modifiers = event.getModifiers();
modifiers &=
InputEvent.BUTTON1_MASK |
InputEvent.BUTTON2_MASK |
InputEvent.BUTTON3_MASK;
switch (modifiers)
{
case InputEvent.BUTTON1_MASK:
return 1;
case InputEvent.BUTTON2_MASK:
return 2;
case InputEvent.BUTTON3_MASK:
return 3;
case 0:
return 0;
default:
System.err.println("FIXME: multibutton event");
return 0;
}
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.j2d;
import java.awt.Color;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.image.ImageObserver;
/**
* Base class for graphics state objects (State pattern, GOF book)
* that represents the current pipeline configuration. The Graphics2D
* object forwards most of the requests to the state object. The
* Graphics2D object itself only administers properties that are not
* specific for a certain state.
*/
public abstract class AbstractGraphicsState implements Cloneable
{
Graphics2DImpl frontend;
public void setFrontend(Graphics2DImpl frontend)
{
this.frontend = frontend;
}
public void dispose()
{
frontend = null;
}
// -------- Graphics methods:
public abstract void setColor(Color color);
public abstract void setPaintMode();
public abstract void setXORMode(Color altColor);
public abstract void setFont(Font font);
public abstract FontMetrics getFontMetrics(Font font);
public abstract void setClip(Shape clip);
public abstract Shape getClip();
public abstract Rectangle getClipBounds();
public abstract void copyArea(int x, int y,
int width, int height,
int dx, int dy);
public abstract void drawLine(int x1, int y1,
int x2, int y2);
public abstract void fillRect(int x, int y,
int width, int height);
public abstract void clearRect(int x, int y,
int width, int height);
public abstract void drawRoundRect(int x, int y,
int width, int height,
int arcWidth, int arcHeight);
public abstract void fillRoundRect(int x, int y,
int width, int height,
int arcWidth, int arcHeight);
public abstract void drawOval(int x, int y,
int width, int height);
public abstract void fillOval(int x, int y,
int width, int height);
public abstract void drawArc(int x, int y,
int width, int height,
int startAngle, int arcAngle);
public abstract void fillArc(int x, int y,
int width, int height,
int startAngle, int arcAngle);
public abstract void drawPolyline(int[] xPoints, int[] yPoints,int nPoints);
public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
public abstract boolean drawImage(Image image, int x, int y,
ImageObserver observer);
// -------- Graphics2D methods:
public abstract void draw(Shape shape);
public abstract void fill(Shape shape);
public abstract boolean hit(Rectangle rect, Shape text, boolean onStroke);
public abstract void drawString(String text, int x, int y);
public abstract void drawString(String text, float x, float y);
public abstract void translate(int x, int y);
public abstract void translate(double tx, double ty);
public abstract void rotate(double theta);
public abstract void rotate(double theta, double x, double y);
public abstract void scale(double scaleX, double scaleY);
public abstract void shear(double shearX, double shearY);
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.j2d;
import java.awt.Color;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.image.Raster;
import java.awt.image.ImageObserver;
/**
* Interface for a simple pixel based backend graphics object that
* does not handle translation/transforms, curves, nor advanced
* compositing.
*/
public interface DirectRasterGraphics extends Cloneable
{
public void dispose();
public void setColor(Color color);
public void setPaintMode();
public void setXORMode(Color altColor);
public void setFont(Font font);
public FontMetrics getFontMetrics(Font font);
// supports rects, multi-rects and polygons
public void setClip(Shape clip);
public void copyArea(int x, int y, int width, int height,
int dx, int dy);
public void drawLine(int x1, int y1, int x2, int y2);
public void drawRect(int x, int y, int width, int height);
public void fillRect(int x, int y, int width, int height);
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle);
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle);
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
public void drawString(String str, int x, int y);
public boolean drawImage(Image image, int x, int y,
ImageObserver observer);
/**
* Map the data for screen pixels in the requested bounds to a
* raster object. This gives read/write access to the screen
* pixels, allowing neat alpha and composite tricks.
*/
public MappedRaster mapRaster(Rectangle bounds);
/**
* Detach previously mapped pixel data from a raster object.
*/
public void unmapRaster(MappedRaster mappedRaster);
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.j2d;
import java.awt.Color;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.ColorModel;
/**
* IntegerGraphicsState is one of several graphics state
* implementations. This graphics state is used when the graphics
* object has simple properties, (coordinate translation only, no
* transform) and the backend supports integer coordinates (pixel
* based). For primitive paint operations, this object translates the
* coordinates and forwards the request to the backend. For requests
* to draw arbitrary shapes and paths, this object translates the
* requests to primitive drawing operations supported by the
* backend. IntegerGraphicsState is meant to support the most common
* state of an graphics object. The degree of functionality is roughly
* equivalent with the old java.awt.Graphics API.
*/
public class IntegerGraphicsState extends AbstractGraphicsState
{
int tx;
int ty;
DirectRasterGraphics directGfx;
Shape clip;
public IntegerGraphicsState(DirectRasterGraphics directGfx)
{
this.directGfx = directGfx;
}
public Object clone()
{
IntegerGraphicsState clone = (IntegerGraphicsState) super.clone();
clone.directGfx = (DirectRasterGraphics) directGfx.clone();
return clone;
}
public void dispose()
{
DirectRasterGraphics lDeviceGfx = directGfx;
directGfx = null;
if (lDeviceGfx != null)
lDeviceGfx.dispose();
super.dispose();
}
// -------- Graphics methods:
public void setColor(Color color)
{
directGfx.setColor(color);
}
public void setPaintMode()
{
directGfx.setPaintMode();
}
public void setXORMode(Color altColor)
{
directGfx.setXORMode(altColor);
}
public void setFont(Font font)
{
directGfx.setFont(font);
}
public FontMetrics getFontMetrics(Font font)
{
return directGfx.getFontMetrics(font);
}
public void setClip(Shape clip)
{
if (clip instanceof Rectangle)
{
Rectangle clipRect = (Rectangle) clip.clone();
clipRect.x += tx;
clipRect.y += ty;
this.clip = clipRect;
directGfx.setClip(clipRect);
return;
}
String msg =
"translating clip shape " + clip + " into device " +
"coordinate space has not been implemented yet";
throw new UnsupportedOperationException(msg);
}
public Shape getClip()
{
if (clip instanceof Rectangle)
{
Rectangle clipRect = (Rectangle) clip;
clipRect.x -= tx;
clipRect.y -= ty;
return clipRect;
}
String msg =
"translating clip shape " + clip + " into user " +
"coordinate space has not been implemented yet";
throw new UnsupportedOperationException(msg);
}
public Rectangle getClipBounds()
{
Rectangle clipRect = clip.getBounds();
clipRect.x -= tx;
clipRect.y -= ty;
return clipRect;
}
public void copyArea(int x, int y,
int width, int height,
int dx, int dy)
{
directGfx.copyArea(x+tx, y+ty, width, height, dx, dy);
}
public void drawLine(int x1, int y1,
int x2, int y2)
{
directGfx.drawLine(x1+tx, y1+ty, x2+tx, y2+ty);
}
public void fillRect(int x, int y,
int width, int height)
{
directGfx.fillRect(x+tx, y+ty, width, height);
}
public void clearRect(int x, int y,
int width, int height)
{
directGfx.setColor(frontend.getBackground());
directGfx.fillRect(x+tx, y+ty, width, height);
directGfx.setColor(frontend.getColor());
}
public void drawRoundRect(int x, int y,
int width, int height,
int arcWidth, int arcHeight)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void fillRoundRect(int x, int y,
int width, int height,
int arcWidth, int arcHeight)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void drawOval(int x, int y,
int width, int height)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void fillOval(int x, int y,
int width, int height)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void drawArc(int x, int y,
int width, int height,
int startAngle, int arcAngle)
{
directGfx.drawArc(x+tx, y+ty, width, height, startAngle, arcAngle);
}
public void fillArc(int x, int y,
int width, int height,
int startAngle, int arcAngle)
{
directGfx.fillArc(x+tx, y+ty, width, height, startAngle, arcAngle);
}
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
{
if ((tx == 0) || (ty == 0))
{
directGfx.drawPolyline(xPoints, yPoints, nPoints);
return;
}
throw new UnsupportedOperationException("translate not implemented");
}
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
if ((tx == 0) || (ty == 0))
{
directGfx.drawPolygon(xPoints, yPoints, nPoints);
return;
}
throw new UnsupportedOperationException("translate not implemented");
}
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
if ((tx == 0) || (ty == 0))
{
directGfx.fillPolygon(xPoints, yPoints, nPoints);
return;
}
throw new UnsupportedOperationException("translate not implemented");
}
public boolean drawImage(Image image, int x, int y,
ImageObserver observer)
{
x += tx;
y += ty;
if (image instanceof BufferedImage)
{
BufferedImage bImage = (BufferedImage) image;
Object config =
bImage.getProperty("java.awt.GraphicsConfiguration");
if (config == frontend.config)
return directGfx.drawImage(image, x, y, observer);
int width = image.getWidth(null);
int height = image.getHeight(null);
Rectangle bounds = new Rectangle(x, y, width, height);
MappedRaster mr = directGfx.mapRaster(bounds);
// manipulate raster here...
ColorModel colorModel = mr.getColorModel();
WritableRaster raster = mr.getRaster();
int xEnd = x + width;
int yEnd = y + height;
// FIXME: Use the following code only as a fallback. It's SLOW!
Object rgbElem = null;
for (int yy=0; yy<height; yy++)
{
for (int xx=0; xx<width; xx++)
{
int srgb = bImage.getRGB(xx, yy);
int sa = ((srgb >>> 24) & 0xff) + 1;
int sr = ((srgb >>> 16) & 0xff) + 1;
int sg = ((srgb >>> 8) & 0xff) + 1;
int sb = (srgb & 0xff) + 1;
rgbElem = raster.getDataElements(xx+x, yy+y, rgbElem);
int drgb = colorModel.getRGB(rgbElem);
int dr = ((drgb >>> 16) & 0xff) + 1;
int dg = ((drgb >>> 8) & 0xff) + 1;
int db = (drgb & 0xff) + 1;
int da = 256 - sa;
dr = ((sr*sa + dr*da) >>> 8) - 1;
dg = ((sg*sa + dg*da) >>> 8) - 1;
db = ((sb*sa + db*da) >>> 8) - 1;
drgb = (dr<<16) | (dg<<8) | db;
rgbElem = colorModel.getDataElements(drgb, rgbElem);
raster.setDataElements(xx+x, yy+y, rgbElem);
}
}
directGfx.unmapRaster(mr);
return true;
}
throw new UnsupportedOperationException("drawing image " + image +
"not implemented");
}
// -------- Graphics2D methods:
public void draw(Shape shape)
{
if (shape instanceof Rectangle)
{
Rectangle rect = (Rectangle) shape;
directGfx.drawRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
return;
}
throw new UnsupportedOperationException("shape not implemented");
}
public void fill(Shape shape)
{
if (shape instanceof Rectangle)
{
Rectangle rect = (Rectangle) shape;
directGfx.fillRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
return;
}
throw new UnsupportedOperationException("not implemented");
}
public boolean hit(Rectangle rect, Shape text,
boolean onStroke)
{
throw new UnsupportedOperationException("not implemented");
}
public void drawString(String text, int x, int y)
{
directGfx.drawString(text, x+tx, y+ty);
}
public void drawString(String text, float x, float y)
{
drawString(text, (int) x, (int) y);
}
public void translate(int x, int y)
{
tx += x;
ty += y;
}
public void translate(double tx, double ty)
{
if ((tx == 0) && (ty == 0))
return;
needAffineTransform();
}
public void rotate(double theta)
{
if (theta == 0)
return;
needAffineTransform();
}
public void rotate(double theta, double x, double y)
{
if (theta == 0)
return;
needAffineTransform();
}
public void scale(double scaleX, double scaleY)
{
if ((scaleX == 1) && (scaleY == 1))
return;
needAffineTransform();
}
public void shear(double shearX, double shearY)
{
if ((shearX == 0) && (shearY == 0))
return;
needAffineTransform();
}
private void needAffineTransform()
{
throw new UnsupportedOperationException("state with affine " +
"transform not implemented");
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.j2d;
import java.awt.image.WritableRaster;
import java.awt.image.ColorModel;
/* The raster and associated properties of a mapped screen region.
* The compositing capabilities of backends are often insufficient.
* The backend may not support alpha blending, or may not support some
* other special compositing rule. This means that compositing must
* sometimes be done within the rendering pipeline. The general
* compositing operation consists of combining new color and alpha
* values with existing color values on the drawing surface, to find
* the new color values for the drawing surface. The way the values
* are combined, determines what kind of compositing operation that is
* performed. The default compositing operation is alpha compositing.
*
* <p>In order to perform alpha compositing and other compositing
* operations, we need access to the color values of the imagery that
* has already been drawn on the drawing surface. The
* DirectRasterGraphics interface must therefore contain methods that
* makes it possible to gain access to the pixel values of the drawing
* surface. The methods are modeled after the POSIX mmap() and
* munmap() functions. But, instead of mapping and unmapping portions
* of data from a file descriptor to memory, the methods in
* DirectRasterGraphics maps and unmaps portions of the drawing
* surface to data arrays within writable raster objects. A call to
* mapRaster() will return a writable raster object, encapsulating the
* image data of the drawing surface in the requested domain. The data
* encapsulated by this raster object can be modified using the
* WritableRaster API, or the data buffers can be retrieved from the
* raster, so that the data arrays can be manipulated directly. When
* the raster image has been modified as desired, the data can be
* resynchronized with the drawing surface by calling mapRaster().
*
* <p>As with mmap() and munmap() the methods may work by direct
* manipulation of shared memory, (i.e. the raster object directly
* wraps the actual image data of the drawing surface), or may make a
* private copy that is resynched when the raster is unmapped. The
* backend may choose to implement either mechanism, and the pipeline
* code should not care what mechanism is actually used. This design
* allows us to make full use of speedups such as X shared memory
* extentions when available.
*/
public class MappedRaster
{
WritableRaster raster;
ColorModel cm;
public MappedRaster(WritableRaster raster, ColorModel cm)
{
this.raster = raster;
this.cm = cm;
}
public final WritableRaster getRaster()
{
return raster;
}
public final ColorModel getColorModel()
{
return cm;
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.Dimension;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Container;
import java.awt.Image;
import java.awt.GraphicsConfiguration;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.AWTEvent;
import java.awt.Cursor;
import java.awt.Shape;
import java.awt.peer.*;
import java.awt.image.*;
import java.awt.event.MouseListener;
import java.awt.event.PaintEvent;
import java.util.EventListener;
import gnu.gcj.xlib.WMSizeHints;
import gnu.gcj.xlib.Window;
import gnu.gcj.xlib.WindowAttributes;
import gnu.gcj.xlib.Display;
import gnu.gcj.xlib.Visual;
import gnu.gcj.xlib.Screen;
import gnu.gcj.xlib.XImage;
import gnu.awt.j2d.*;
public class XCanvasPeer implements CanvasPeer
{
static final Dimension MIN_SIZE = new Dimension(1, 1);
public // temporary
Window window;
Window parent;
Component component;
XGraphicsConfiguration config;
public XCanvasPeer(Component component)
{
this.component = component;
// Set up graphics configuration (ie. screen + visual):
config = (XGraphicsConfiguration)
component.getGraphicsConfiguration();
if (config == null)
{
// This will usually only happen for toplevel windows
config = getXToolkit().getDefaultXGraphicsConfiguration();
}
Rectangle bounds = component.getBounds();
parent = locateParentWindow(bounds);
// Windows in X must atleast be of size 1x1
boolean boundsChanged = false;
if (bounds.width < 1)
{
boundsChanged = true;
bounds.width = 1;
}
if (bounds.height < 1)
{
boundsChanged = true;
bounds.height = 1;
}
/* don't worry about this calling back to us, since the real
component object has not yet received a reference to this peer
object. */
component.setBounds(bounds);
WindowAttributes attributes = new WindowAttributes();
/* Set background color */
Color bg = component.getBackground();
if (bg != null)
{
int[] components =
{
bg.getRed(),
bg.getGreen(),
bg.getBlue(),
0xff
};
ColorModel cm = config.getColorModel();
long pixel = cm.getDataElement(components, 0);
attributes.setBackground(pixel);
}
/* Set exposure mask so that we get exposure events
that can be translated into paint() calls. */
long eventMask = WindowAttributes.MASK_EXPOSURE;
/* It would be nice to set up all other required events here, but
it is not possible to do so before after all the children of
this component has been realized. The reason is that it is not
determined whether a component is lightweight before after the
addNotify() method has been called. Thus, it is not possible
for parent component to determine what events it needs to
furnish for lightweight children. Instead, we currently rely
on the component calling our setEventMask() method after the
correct event mask has been determined. */
attributes.setEventMask(eventMask);
// TODO: set more window attributes?
/* don't allow event queue to process events from the newly
created window before this peer has been registered as client
data. */
synchronized (getXToolkit().eventLoop)
{
window = new gnu.gcj.xlib.Window(parent, bounds, attributes);
window.setClientData(this); /* make it possible to find back
to this peer object. Used by
XEventQueue. */
}
initWindowProperties();
if (component.isVisible())
EventQueue.invokeLater(new DoMap(window));
}
/**
* Override this in subclasses to implement other ways of obtaining
* parent windows. Toplevel windows will typically have a different
* implementation.
*/
gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
{
Container parent = component.getParent();
while (parent.isLightweight())
{
bounds.x += parent.getX();
bounds.y += parent.getY();
parent = parent.getParent();
// a null pointer here is a genuine error
}
XCanvasPeer parentPeer = (XCanvasPeer) parent.getPeer();
if (parentPeer == null)
throw new NullPointerException("Parent has no peer. This should " +
"not be possible, since the " +
"calls leading here should come " +
"from parent, after it has " +
"set the parent peer.");
return parentPeer.window;
}
/**
* Template method to allow subclasses to apply properties to X11
* window right after creation.
*/
void initWindowProperties()
{
}
XToolkit getXToolkit()
{
return XToolkit.INSTANCE;
}
protected void ensureFlush()
{
getXToolkit().flushIfIdle();
}
public Component getComponent()
{
return component;
}
long getBasicEventMask()
{
return WindowAttributes.MASK_EXPOSURE;
}
// -------- java.awt.peer.ComponentPeer implementation
public int checkImage(Image img, int width, int height, ImageObserver o)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public Image createImage(ImageProducer prod)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public Image createImage(int width, int height)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void dispose()
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public GraphicsConfiguration getGraphicsConfiguration()
{
return config;
}
public FontMetrics getFontMetrics(Font f)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public Graphics getGraphics()
{
DirectRasterGraphics gfxDevice = new XGraphics(window, config);
IntegerGraphicsState igState = new IntegerGraphicsState(gfxDevice);
Graphics2DImpl gfx2d = new Graphics2DImpl(config);
gfx2d.setState(igState);
gfx2d.setColor(component.getBackground());
return gfx2d;
}
public Point getLocationOnScreen()
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public Dimension getMinimumSize ()
{
return MIN_SIZE;
}
public Dimension getPreferredSize ()
{
return component.getSize();
}
public Toolkit getToolkit()
{
return getXToolkit();
}
public void handleEvent(AWTEvent event)
{
}
public boolean isFocusTraversable()
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void paint(Graphics gfx)
{
// do nothing by default
}
public boolean prepareImage(Image img, int width, int height,
ImageObserver o)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void print(Graphics graphics)
{
paint(graphics);
}
public void repaint(long tm, int x, int y, int w, int h)
{
/* TODO?
X allows intelligent X servers to do smart
refreshing. Perhaps involve X in repainting of components,
rather that keeping it all within the local event queue. */
PaintEvent updateEvent = new PaintEvent(component,
PaintEvent.UPDATE,
new Rectangle(x, y, w, h));
getXToolkit().queue.postEvent(updateEvent);
}
public void requestFocus()
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void setBackground(Color color)
{
throw new UnsupportedOperationException("not implemented");
}
public void setBounds(int x, int y, int width, int height)
{
width = Math.max(width, 1);
height = Math.max(height, 1);
window.setBounds(x, y, width, height);
ensureFlush();
}
public void setCursor(Cursor cursor)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void setEnabled(boolean enabled)
{
throw new UnsupportedOperationException("FIXME, not implemented");
}
public void setEventMask(long eventMask)
{
WindowAttributes attributes = new WindowAttributes();
long xEventMask = getBasicEventMask();
if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
{
xEventMask |=
WindowAttributes.MASK_BUTTON_PRESS |
WindowAttributes.MASK_BUTTON_RELEASE;
}
attributes.setEventMask(xEventMask);
window.setAttributes(attributes);
ensureFlush();
}
public void setFont(Font font)
{
/* default canvas peer does keep track of font, since it won't
write anything. */
}
public void setForeground(Color color)
{
/* default canvas peer does keep track of foreground, since it won't
paint anything. */
}
public void setVisible(boolean visible)
{
if (visible)
{
window.map();
ensureFlush();
}
else
{
throw new UnsupportedOperationException("unmap not implemented");
}
}
static class DoMap implements Runnable
{
Window window;
public DoMap(Window w)
{
this.window = w;
}
public void run()
{
window.map();
}
}
}
package gnu.awt.xlib;
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
import java.awt.*;
import gnu.awt.LightweightRedirector;
import gnu.gcj.xlib.Display;
import gnu.gcj.xlib.XAnyEvent;
import gnu.gcj.xlib.XExposeEvent;
import gnu.gcj.xlib.XButtonEvent;
import gnu.gcj.xlib.XConfigureEvent;
import java.awt.event.PaintEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.Vector;
public class XEventLoop implements Runnable
{
Display display;
EventQueue queue;
XAnyEvent anyEvent;
Thread eventLoopThread;
LightweightRedirector lightweightRedirector = new LightweightRedirector();
public XEventLoop(Display display, EventQueue queue)
{
this.display = display;
this.queue = queue;
anyEvent = new XAnyEvent(display);
eventLoopThread = new Thread(this, "AWT thread for XEventLoop");
eventLoopThread.start();
}
public void run()
{
while (true)
postNextEvent();
}
void postNextEvent()
{
try
{
AWTEvent evt = getNextEvent();
queue.postEvent(evt);
}
catch (InterruptedException ie)
{
// FIXME: what now?
System.err.println(ie);
}
}
/** get next event. Will block until events become available. */
public AWTEvent getNextEvent()
{
// ASSERT:
if (isIdle())
throw new Error("should not be idle");
AWTEvent event = null;
while (event == null)
{
loadNextEvent();
event = createEvent();
}
event = lightweightRedirector.redirect(event);
return event;
}
void loadNextEvent()
{
try
{
setIdle(true);
/* The code below will result in an XFlush(). However,
while we are waiting for events after calling XFlush(),
new X requests issued on other threads will not
automatically be flushed. This can lead to a deadlock
since XFlush() will not be called before after the
processing of the next event, and new events arriving
might be dependent on the delivery of the X
requests.
Code that issues X requests should therefore call
flushIfIdle() after they're done, to ensure that the
requests are delivered in a timely manner. XFlush is not
run if event processing is underway, since we are assured
that the event loop execution will return to this point,
where requests are flushed again, before waiting for new
events.
Alternatively, do the work on the AWT thread, since the
XEventQueue knows how to flush the display when it runs out
of events. */
//display.flush(); // implicit?
anyEvent.loadNext();
}
catch (RuntimeException re)
{
System.err.println("Exception thrown on event thread:" + re);
}
finally
{
setIdle(false);
}
}
/**
* @returns an AWT event created based on the current XEvent.
* Returns null if the current XEvent does not map to any perticular
* AWT event.
*/
AWTEvent createEvent()
{
/* avoid attempting to get client data before client data has
been set. */
Object peer;
synchronized (this)
{
peer = anyEvent.getWindow().getClientData();
}
Component source = null;
// Try to identify source component
if (peer instanceof XCanvasPeer)
{
source = ((XCanvasPeer) peer).getComponent();
}
if (source == null)
{
String msg = "unable to locate source for event (" +
anyEvent + ")";
throw new RuntimeException(msg);
}
/* if a mapping from anyEvent to AWTEvent is possible, construct a
new AWTEvent and return it. */
int type = anyEvent.getType();
switch (type)
{
case XAnyEvent.TYPE_EXPOSE:
return createPaintEvent(source);
case XAnyEvent.TYPE_BUTTON_PRESS:
case XAnyEvent.TYPE_BUTTON_RELEASE:
return createMouseEvent(type, source);
case XAnyEvent.TYPE_UNMAP_NOTIFY:
case XAnyEvent.TYPE_MAP_NOTIFY:
case XAnyEvent.TYPE_REPARENT_NOTIFY:
return null; // ignore for now
case XAnyEvent.TYPE_CONFIGURE_NOTIFY:
configureNotify(peer);
return null;
default:
String msg = "Do no know how to handle event (" + anyEvent + ")";
throw new RuntimeException(msg);
}
}
AWTEvent createPaintEvent(Component src)
{
XExposeEvent expose = new XExposeEvent(anyEvent);
PaintEvent pe = new PaintEvent(src, PaintEvent.PAINT,
expose.getBounds());
return pe;
}
AWTEvent createMouseEvent(int type, Component src)
{
XButtonEvent buttonEvt = new XButtonEvent(anyEvent);
int modifiers = 0; //buttonToModifierMap[buttonEvt.button];
/* Warning: this makes assumptions on the contents of
X.h... Button1 = 1, Button2 = 2, etc... */
switch (buttonEvt.button)
{
case 1:
modifiers = InputEvent.BUTTON1_MASK;
break;
case 2:
modifiers = InputEvent.BUTTON2_MASK;
break;
case 3:
modifiers = InputEvent.BUTTON2_MASK;
break;
}
int state = buttonEvt.state;
// remap bits from state to modifiers:
if ((state & XButtonEvent.MASK_SHIFT) != 0)
modifiers |= InputEvent.SHIFT_MASK;
if ((state & XButtonEvent.MASK_CONTROL) != 0)
modifiers |= InputEvent.CTRL_MASK;
/* FIXME: we need additional X code to properly map MODn states to
input modifiers */
int clickCount = 1; // FIXME... Can't get this from X.
boolean popupTrigger = false; // FIXME: look up policy somewhere
int x = buttonEvt.x;
int y = buttonEvt.y;
int id = (type == XAnyEvent.TYPE_BUTTON_PRESS) ?
MouseEvent.MOUSE_PRESSED :
MouseEvent.MOUSE_RELEASED;
MouseEvent me = new MouseEvent(src,
id,
buttonEvt.time, modifiers,
buttonEvt.x, buttonEvt.y,
clickCount, popupTrigger);
return me;
}
void configureNotify(Object peerObj)
{
XConfigureEvent configEvent = new XConfigureEvent(anyEvent);
XFramePeer peer = (XFramePeer) peerObj;
peer.configureNotify(configEvent);
}
public void flushIfIdle()
{
if (isIdle())
display.flush();
}
volatile boolean idle = false;
final synchronized void setIdle(boolean idle)
{
this.idle = idle;
}
final synchronized boolean isIdle()
{
return idle;
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.*;
import gnu.gcj.xlib.Display;
/**
* The only difference here from a standard EventQueue is that the X
* display connection is flushed before waiting for more events.
*/
public class XEventQueue extends EventQueue
{
Display display;
public XEventQueue(Display display)
{
this.display = display;
}
public AWTEvent getNextEvent() throws InterruptedException
{
if ((peekEvent() == null) && (display != null))
display.flush();
return super.getNextEvent();
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.FontMetrics;
public class XFontMetrics extends FontMetrics
{
gnu.gcj.xlib.Font xfont;
public XFontMetrics(gnu.gcj.xlib.Font xfont, java.awt.Font awtFont)
{
super(awtFont);
this.xfont = xfont;
}
public int getAscent()
{
return xfont.getAscent();
}
public int getDescent()
{
return xfont.getDescent();
}
public int getMaxAscent()
{
return xfont.getMaxAscent();
}
public int getMaxDescent()
{
return xfont.getMaxDescent();
}
public int stringWidth(String str)
{
return xfont.getStringWidth(str);
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.*;
import java.awt.peer.*;
import java.awt.image.*;
import gnu.gcj.xlib.WMSizeHints;
import gnu.gcj.xlib.WindowAttributes;
import gnu.gcj.xlib.Display;
import gnu.gcj.xlib.Visual;
import gnu.gcj.xlib.Screen;
import gnu.gcj.xlib.XConfigureEvent;
/** FIXME: a lot of the code here should be moved down to XWindowPeer. */
public class XFramePeer extends XCanvasPeer implements FramePeer
{
public XFramePeer(Frame frame)
{
super(frame);
// Set some defaults for a toplevel component:
if (frame.getFont() == null)
frame.setFont(new Font("helvetica", Font.PLAIN, 12));
if (frame.getBackground() == null)
frame.setBackground(Color.lightGray);
if (frame.getForeground() == null)
frame.setForeground(Color.black);
}
/** Find parent window for toplevel window, ie. root window of
selected screen. Bounds are not changed. */
gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
{
Screen screen = config.getVisual().getScreen();
return screen.getRootWindow();
}
void initWindowProperties()
{
Frame frame = (Frame) component;
setResizable(frame.isResizable());
String title = frame.getTitle();
if (!title.equals("")) setTitle(title);
}
long getBasicEventMask()
{
return super.getBasicEventMask() |
WindowAttributes.MASK_STRUCTURE_NOTIFY;
}
void configureNotify(XConfigureEvent configEvent)
{
component.setBounds(configEvent.getBounds());
/* FIXME: Validation should probably not be done here. The best
strategy is probably to validate on the AWT thread in response
to an ComponentEvent. This will make it possible to coalesce
resize validations. */
component.validate();
}
/* Overridden to ignore request to set bounds if the request occurs
on the X event loop thread. It is assumed that all requests that
occur on the X event loop thread are results of XConfigureNotify
events, in which case the X window already has the desired
bounds. */
public void setBounds(int x, int y, int width, int height)
{
if (Thread.currentThread() == getXToolkit().eventLoop.eventLoopThread)
return;
super.setBounds(x, y, width, height);
}
// Implementing ContainerPeer:
static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
public Insets getInsets()
{
return (Insets) INSETS_0_PROTOTYPE.clone();
}
public void beginValidate()
{
}
public void endValidate()
{
// reassert sizing hints
Frame frame = (Frame) component;
setResizable(frame.isResizable());
}
// Implementing WindowPeer:
public void toBack()
{
throw new UnsupportedOperationException("not implemented yet");
}
public void toFront()
{
throw new UnsupportedOperationException("not implemented yet");
}
// Implementing FramePeer:
public void setIconImage(Image image)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void setMenuBar(MenuBar mb)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void setTitle(String title)
{
synchronized (window.getDisplay())
{
// Oh, what a nice implementation :-)
window.setProperty("WM_NAME", "STRING", title);
ensureFlush();
}
}
public void setResizable(boolean resizable)
{
Frame frame = (Frame) component;
WMSizeHints sizeHints = new WMSizeHints();
if (resizable)
{
Dimension minSize = frame.getMinimumSize();
sizeHints.setMinSize(minSize.width, minSize.height);
Dimension maxSize = frame.getMaximumSize();
if ((maxSize.width < Short.MAX_VALUE) ||
(maxSize.height < Short.MAX_VALUE))
{
maxSize.width = Math.min(maxSize.width, Short.MAX_VALUE);
maxSize.height = Math.min(maxSize.height, Short.MAX_VALUE);
sizeHints.setMaxSize(maxSize.width, maxSize.height);
}
}
else
{
// lock resizing to current bounds
Dimension size = frame.getSize();
sizeHints.setMinSize(size.width, size.height);
sizeHints.setMaxSize(size.width, size.height);
}
sizeHints.applyNormalHints(window);
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.*;
import java.awt.image.WritableRaster;
import java.awt.image.Raster;
import java.awt.image.DataBuffer;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import gnu.gcj.xlib.GC;
import gnu.gcj.xlib.XImage;
import gnu.gcj.xlib.Drawable;
import gnu.gcj.xlib.Window;
import gnu.gcj.xlib.Drawable;
import gnu.gcj.xlib.Visual;
import gnu.awt.j2d.DirectRasterGraphics;
import gnu.awt.j2d.MappedRaster;
public class XGraphics implements Cloneable, DirectRasterGraphics
{
static class XRaster extends MappedRaster
{
XImage ximage;
public XRaster(WritableRaster raster, XImage ximage, ColorModel cm)
{
super(raster, cm);
this.ximage = ximage;
}
}
GC context;
XGraphicsConfiguration config;
Rectangle clipBounds;
XFontMetrics metrics;
public Object clone()
{
XGraphics gfxCopy = (XGraphics) super.clone();
gfxCopy.context = context.create();
return gfxCopy;
}
public void dispose()
{
GC lContext = context;
context = null;
config = null;
clipBounds = null;
if (lContext != null)
{
lContext.dispose();
}
}
public XGraphics(Drawable drawable, XGraphicsConfiguration config)
{
context = new GC(drawable);
this.config = config;
}
public void setColor(Color color)
{
context.setForeground(config.getPixel(color));
}
public void setPaintMode()
{
throw new UnsupportedOperationException("not implemented");
}
public void setXORMode(Color c1)
{
throw new UnsupportedOperationException("not implemented");
}
public void setFont(Font font)
{
if ((metrics != null) && font.equals(metrics.getFont())) return;
metrics = config.getXFontMetrics(font);
context.setFont(metrics.xfont);
}
public FontMetrics getFontMetrics(Font font)
{
if ((metrics != null) && font.equals(metrics.getFont()))
return metrics;
return config.getXFontMetrics(font);
}
public void setClip(int x, int y, int width, int height)
{
Rectangle[] rects = { new Rectangle(x, y, width, height) };
context.setClipRectangles(rects);
}
public void setClip(Shape clip)
{
/* TODO: create a special RectangleUnion shape that can be
used to draw advantage of the GCs ability to set multiple
rectangles.
*/
/* FIXME: creating all these objects is wasteful and can be
costly in the long run, since this code is run at every
expose. */
Rectangle newClipBounds = clip.getBounds();
if ((clipBounds != null) && !clipBounds.contains(newClipBounds))
{
System.err.println("warning: old clip ("+ clipBounds +") does " +
"not fully contain new clip (" +
newClipBounds + ")");
}
clipBounds = newClipBounds;
Rectangle[] rects = { clipBounds };
context.setClipRectangles(rects);
}
public void copyArea(int x, int y, int width, int height, int
dx, int dy)
{
throw new UnsupportedOperationException("not implemented");
}
public void drawLine(int x1, int y1, int x2, int y2)
{
context.drawLine(x1, y1, x2, y2);
}
public void drawRect(int x, int y, int width, int height)
{
throw new UnsupportedOperationException("not implemented yet");
}
public void fillRect(int x, int y, int width, int height)
{
context.fillRectangle(x, y, width, height);
}
public void drawArc(int x, int y, int width, int height, int
startAngle, int arcAngle)
{
throw new UnsupportedOperationException("not implemented");
}
public void fillArc(int x, int y, int width, int height, int
startAngle, int arcAngle)
{
throw new UnsupportedOperationException("not implemented");
}
public void drawPolyline(int[] xPoints, int[] yPoints, int
nPoints)
{
throw new UnsupportedOperationException("not implemented");
}
public void drawPolygon(int[] xPoints, int[] yPoints, int
nPoints)
{
throw new UnsupportedOperationException("not implemented");
}
public void fillPolygon(int[] xPoints, int[] yPoints, int
nPoints)
{
throw new UnsupportedOperationException("not implemented");
}
public void drawString(String str, int x, int y)
{
context.drawString(str, x, y);
}
public boolean drawImage(Image img, int x, int y,
ImageObserver observer)
{
if (clipBounds == null)
return false; // ***FIXME***
if (!(img instanceof BufferedImage))
{
throw new AWTError("unknown image class");
}
BufferedImage bimg = (BufferedImage) img;
XImage ximg = (XImage) bimg.getProperty("gnu.gcj.xlib.XImage");
if (ximg == null)
{
System.err.println("FIXME: skipping null XImage, should " +
"really do on the spot conversion");
return false;
}
/*
+------------------
| clip
| +---------+
| img | |
| +--+-------+ |
| | | | |
| | | | |
| | +-------+-+
| | |
| +----------+
*/
int iLeft = Math.max(x, clipBounds.x);
int iTop = Math.max(y, clipBounds.y);
int iRight = Math.min(x + bimg.getWidth(),
clipBounds.x + clipBounds.width);
int iBottom = Math.min(y + bimg.getHeight(),
clipBounds.y + clipBounds.height);
int srcX = iLeft - x;
int srcY = iTop - y;
int width = iRight - iLeft;
int height = iBottom - iTop;
if ((width > 0) && (height > 0))
context.putImage(ximg, srcX, srcY, iLeft, iTop, width, height);
return true;
}
public MappedRaster mapRaster(Rectangle bounds)
{
Visual visual = config.getVisual();
XImage ximage = new XImage(visual, bounds.width, bounds.height,
false // do not auto allocate memory
);
WritableRaster raster =
config.createRasterForXImage(ximage,
new Point(bounds.x, bounds.y));
DataBuffer dataB = raster.getDataBuffer();
XGraphicsConfiguration.attachData(ximage, dataB, 0);
Drawable drawable = context.getDrawable();
// TODO: restrict to clipping
Rectangle mBounds = drawable.copyIntoXImage(ximage, bounds, 0, 0);
return new XRaster(raster, ximage, config.imageCM);
}
public void unmapRaster(MappedRaster mappedRaster)
{
XRaster xraster = (XRaster) mappedRaster;
XImage ximage = xraster.ximage;
Raster raster = xraster.getRaster();
int x = raster.getMinX();
int y = raster.getMinY();
int width = raster.getWidth();
int height = raster.getHeight();
context.putImage(ximage, 0, 0, x, y, width, height);
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.*;
import java.awt.peer.*;
import java.awt.image.*;
import gnu.gcj.xlib.WMSizeHints;
import gnu.gcj.xlib.WindowAttributes;
import gnu.gcj.xlib.Display;
import gnu.gcj.xlib.Visual;
import gnu.gcj.xlib.Screen;
public class XPanelPeer extends XCanvasPeer implements PanelPeer
{
public XPanelPeer(Panel panel)
{
super(panel);
}
// no reason to override yet
//void initWindowProperties();
//gnu.gcj.xlib.Window getParentWindow();
// Implementing ContainerPeer:
// Default is no insets...
static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
public Insets getInsets()
{
return (Insets) INSETS_0_PROTOTYPE.clone();
}
public void beginValidate()
{
// NOP
}
public void endValidate()
{
// NOP
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.awt.xlib;
import java.awt.*;
import java.awt.peer.*;
import java.awt.image.ImageProducer;
import java.awt.image.ImageObserver;
import java.net.*;
import java.awt.datatransfer.Clipboard;
import gnu.gcj.xlib.Display;
import gnu.gcj.xlib.Screen;
import gnu.gcj.xlib.Visual;
public class XToolkit extends Toolkit
{
static XToolkit INSTANCE;
Display display;
EventQueue queue;
XEventLoop eventLoop;
XGraphicsConfiguration defaultConfig;
public XToolkit()
{
INSTANCE = this;
display = new Display();
synchronized (display)
{
queue = new XEventQueue(display);
eventLoop = new XEventLoop(display, queue);
}
}
public void flushIfIdle()
{
eventLoop.flushIfIdle();
}
protected ButtonPeer createButton(Button frontend)
{
// FIXME: Stubbed out, needs Swing:
/*
XCanvasPeer realPeer = new XCanvasPeer(frontend);
SButtonPeer sbPeer = new SButtonPeer(frontend, realPeer);
return sbPeer;
*/
return null;
}
protected TextFieldPeer createTextField(TextField frontend)
{
return null; // FIXME
}
protected LabelPeer createLabel(Label frontend)
{
return null; // FIXME
}
protected ListPeer createList(List frontend)
{
return null; // FIXME
}
protected CheckboxPeer createCheckbox(Checkbox frontend)
{
return null; // FIXME
}
protected ScrollbarPeer createScrollbar(Scrollbar frontend)
{
return null; // FIXME
}
protected ScrollPanePeer createScrollPane(ScrollPane frontend)
{
return null; // FIXME
}
protected TextAreaPeer createTextArea(TextArea frontend)
{
return null; // FIXME
}
protected ChoicePeer createChoice(Choice frontend)
{
return null; // FIXME
}
protected FramePeer createFrame(Frame frontend) {
return new XFramePeer(frontend);
}
protected CanvasPeer createCanvas(Canvas frontend) {
XCanvasPeer peer = new XCanvasPeer(frontend);
return peer;
}
protected PanelPeer createPanel(Panel frontend) {
return new XPanelPeer(frontend);
}
protected WindowPeer createWindow(Window frontend)
{
return null; // FIXME
}
protected DialogPeer createDialog(Dialog frontend)
{
return null; // FIXME
}
protected MenuBarPeer createMenuBar(MenuBar frontend)
{
return null; // FIXME
}
protected MenuPeer createMenu(Menu frontend)
{
return null; // FIXME
}
protected PopupMenuPeer createPopupMenu(PopupMenu frontend)
{
return null; // FIXME
}
protected MenuItemPeer createMenuItem(MenuItem frontend)
{
return null; // FIXME
}
protected FileDialogPeer createFileDialog(FileDialog frontend)
{
return null; // FIXME
}
protected CheckboxMenuItemPeer
createCheckboxMenuItem(CheckboxMenuItem frontend)
{
return null; // FIXME
}
protected java.awt.peer.FontPeer getFontPeer(String name, int style)
{
return null;
}
public Dimension getScreenSize()
{
throw new UnsupportedOperationException("not implemented yet");
}
public int getScreenResolution()
{
throw new UnsupportedOperationException("not implemented yet");
}
public java.awt.image.ColorModel getColorModel()
{
throw new UnsupportedOperationException("not implemented yet");
}
public String[] getFontList()
{
throw new UnsupportedOperationException("not implemented yet");
}
public FontMetrics getFontMetrics(Font font)
{
return defaultConfig.getXFontMetrics(font);
}
public void sync()
{
throw new UnsupportedOperationException("not implemented yet");
}
public Image getImage(String filename)
{
return createImage(filename);
}
public Image getImage(URL url)
{
throw new UnsupportedOperationException("not implemented yet");
}
public Image createImage(String filename)
{
// FIXME: Stubbed out. We need a proper image I/O API.
/*
BufferedImage jpeg;
FileInputStream fis = openFile(filename);
if (fis == null)
return null;
BasicRasterImageConsumer consumer = new BasicRasterImageConsumer();
JPEGImageDecoder jid = new JPEGImageDecoder(fis);
jid.startProduction(consumer);
jpeg = consumer.getImage();
int w = jpeg.getWidth();
int h = jpeg.getHeight();
BufferedImage img =
getDefaultXGraphicsConfiguration().createCompatibleImage(w, h);
Renderers renderers = Renderers.getInstance();
RasterOp renderer = renderers.createRenderer(jpeg.getColorModel(),
jpeg.getSampleModel(),
img.getColorModel(),
img.getSampleModel());
if (renderer == null)
{
throw new UnsupportedOperationException("couldn't find renderer");
}
renderer.filter(jpeg.getRaster(), img.getRaster());
return img;
*/
return null;
}
public Image createImage(URL url)
{
throw new UnsupportedOperationException("not implemented yet");
}
public boolean prepareImage(Image image,
int width,
int height,
ImageObserver observer)
{
throw new UnsupportedOperationException("not implemented yet");
}
public int checkImage(Image image,
int width,
int height,
ImageObserver observer)
{
throw new UnsupportedOperationException("not implemented yet");
}
public Image createImage(ImageProducer producer)
{
throw new UnsupportedOperationException("not implemented yet");
}
public Image createImage(byte[] imagedata,
int imageoffset,
int imagelength)
{
throw new UnsupportedOperationException("not implemented yet");
}
/*
public PrintJob getPrintJob(Frame frame,
String jobtitle,
Properties props);
*/
public void beep()
{
throw new UnsupportedOperationException("not implemented yet");
}
public Clipboard getSystemClipboard()
{
return null; // FIXME
}
protected EventQueue getSystemEventQueueImpl()
{
return queue;
}
XGraphicsConfiguration getDefaultXGraphicsConfiguration()
{
if (defaultConfig == null)
{
Screen screen = display.getDefaultScreen();
Visual visual = screen.getRootVisual();
defaultConfig = new XGraphicsConfiguration(visual);
// ASSERT:
if (!defaultConfig.getVisual().getScreen().equals(screen))
{
String msg = "screen of graphics configuration is not " +
"default screen";
throw new Error(msg);
}
}
return defaultConfig;
}
/*
public DragSourceContextPeer
createDragSourceContextPeer(DragGestureEvent dge)
throws InvalidDnDOperationException;
public DragGestureRecognizer
createDragGestureRecognizer(Class abstractRecognizerClass,
DragSource ds, Component c,
int srcActions, DragGestureListener dgl) {
throw new UnsupportedOperationException("not implemented");
}
*/
/*
public Map mapInputMethodHighlight(InputMethodHighlight highlight);
*/
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
import java.awt.Rectangle;
/**
* Describes a clip that is used to constrain drawing using a GC
* within a specific region. Currently it supports clip regions
* consisting of the union of multiple rectangles. Other clip forms
* may be implented later. This class is used internally by the GC
* class, and wraps a native XRectVector[].
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
final class Clip
{
public Clip(Rectangle[] rects)
{
init(rects);
}
private native void init(Rectangle[] rects);
public native void finalize();
RawData xrects;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* An X11 color map resource.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class Colormap extends XID
{
Screen screen;
public static final byte FLAG_SHARED = 1;
public static final byte FLAG_NOT_SHARED = 2;
public Colormap(Screen screen, int xid)
{
super(screen.getDisplay(), xid);
this.screen = screen;
}
/**
* Allocate color pixel.
*
* @param color The color to be allocated. If allocation is
* successful, this object will be modified to reflect the actual
* color that was allocated.
*
* @return the pixel value of the allocated color.
*/
public native long allocateColorPixel(XColor color);
/**
* Allocate a color consisting of the given RGB-triplet.
*
* @return a color object describing the allocated color.
*/
public XColor allocateColor(int r, int g, int b)
{
XColor color = new XColor(r, g, b);
allocateColorPixel(color);
return color;
}
/**
* Get an array of all colors that currently resides in shared (read
* only) color-cells in this color map.
*/
public native XColor[] getSharedColors();
/**
* Get all colors currently residing in this color map. Colors that
* are shared (read only) are marked as such by the color flags.
* The indexes of the returned array will correspond to the
* colorcells of the color map. Given a color <code>XColor
* color</code> from a given color-cell, the expression
* <code>color.getFlags() == Colormap.FLAG_SHARED</code> will check
* whether the color-cell is shared.
*/
public native XColor[] getXColors();
/**
* Convenience method used by native code to create fully
* initialized arrays of XColor objects.
*/
private XColor[] newXColorArray(int n)
{
XColor[] array = new XColor[n];
for (int i=0; i<n; i++)
array[i] = new XColor();
return array;
}
}
/* Copyright (C) 1999, 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import gnu.gcj.RawData;
/**
* A connection to an X11 display.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class Display
{
static
{
staticInit();
}
public Display()
{
init();
}
private static native void staticInit();
private native void init();
protected native void finalize();
RawData display = null;
/* TODO?: Rather than storing such data here, we might consider
using the context manager facilities provided by Xlib... */
private Dictionary xids = new Hashtable();
protected final void addXID(int xid, XID window)
{
xids.put(new Integer(xid), window);
}
protected final void removeXID(int xid)
{
xids.remove(new Integer(xid));
}
public final Window getDefaultRootWindow()
{
int rootXID = getDefaultRootWindowXID();
return getWindow(rootXID);
}
public final XID getXID(int xid)
{
return (XID) xids.get(new Integer(xid));
}
public final Window getWindow(int xid)
{
Window window = (Window) getXID(xid);
if (window == null)
{
window = new Window(this, xid);
addXID(xid, window);
}
return window;
}
public final Screen getDefaultScreen()
{
/* Screens objects are not cached since they are lightweight.
We just create a new object when requested. */
return new Screen(this, getDefaultScreenNumber());
}
public final native int getDefaultScreenNumber();
private final native int getDefaultRootWindowXID();
private Dictionary atoms = new Hashtable();
public final int getAtom(String name)
{
Integer atomInt = (Integer) atoms.get(name);
if (atomInt == null)
return internAtom(name);
return atomInt.intValue();
}
// TODO?: cache reverse lookup too?
public final native String getAtomName(int atom);
private final native int internAtom(String name);
public native void flush();
}
/* Copyright (C) 1999, 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import java.awt.Rectangle;
/** An X11 drawable.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class Drawable extends XID
{
public Drawable(Display display, int xid)
{
super(display, xid);
}
/**
* Gets as much as possible of the image data within the requested
* region. Data from obscured parts of windows may not be
* retrievable.
*
* @param dest where to place the image data.
*
* @return the actual region of image data that was retrieved.
*/
public Rectangle copyIntoXImage(XImage dest, Rectangle bounds,
int destX, int destY)
{
Rectangle newBounds = null;
int tries = 5;
while (!bounds.isEmpty())
{
if (copyIntoXImageImpl(dest, bounds.x, bounds.y,
bounds.width, bounds.height,
destX, destY))
return bounds;
// failed, likely due to wrong bounds...
newBounds = getBounds(newBounds);
bounds = newBounds.intersection(bounds);
tries--;
if (tries < 0)
throw new RuntimeException("copyIntoXImage is buggy");
}
return bounds; // always empty
}
/**
* Performs an XGetSubImage. This method will fail if the X server
* does not possess the requested image data. This might occur when
* requesting the image date of a window that is partially obscured.
*
* @param desitantionImage where to place the image data
*
* @return false if method was unable to read the requested region.
*/
private native boolean copyIntoXImageImpl(XImage destinationImage,
int x, int y,
int width, int height,
int destX, int destY);
public native Rectangle getBounds(Rectangle rv);
private static final String MSG_XGETSUBIMAGE_FAILED =
"XGetSubImage() failed.";
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* An X11 Font, implemented as a wrapper around an X11 Font XID and
* the associated Xlib XFontStruct structure.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class Font extends XID
{
/**
* @param lfdNamePattern a font name pattern following the
* <em>X Logical Font Description Conventions</em>.
*/
public Font(Display display, String lfdNamePattern)
{
this(display, loadFont(display, lfdNamePattern));
}
Font(Display display, RawData struct)
{
super(display, getXIDFromStruct(struct));
structure = struct;
}
static native RawData loadFont(Display display, String lfdNamePattern);
static native int getXIDFromStruct(RawData structure);
public native int getAscent();
public native int getDescent();
public native int getMaxAscent();
public native int getMaxDescent();
public native int getStringWidth(String str);
protected native void finalize();
RawData structure;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
import java.awt.Rectangle;
/**
* An X11 graphics context. Unlike a traditional X11 graphics
* context, the target drawable is part of the GC state.
*
* Implementation notes: There is no need to do coalescing of changes
* since Xlib will do this for us. The implementation relies on the
* Xlib GC cache and will not try to be clever.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class GC implements Cloneable
{
public GC(Drawable target)
{
this.target = target;
initStructure(null);
}
public Object clone()
{
GC gcClone = (GC) super.clone();
gcClone.structure = null;
gcClone.initStructure(this);
gcClone.updateClip();
return gcClone;
}
private native void initStructure(GC copyFrom);
public GC create()
{
return (GC) clone();
}
public void finalize()
{
disposeImpl();
}
public void dispose()
{
disposeImpl();
}
public synchronized native void disposeImpl();
public native void setForeground(long pixel);
public native void setFont(gnu.gcj.xlib.Font font);
/**
* Set the clip region for the graphics operations performed by the
* GC.
*
* This is one of the few costly operations of this class. It is
* suggested that the clip is only set or changed if really
* necessary. Higher level APIs can make such optimizations
* transparent.
*
* @param rectangles the union of these rectangles describe the clip
* region.
*/
public void setClipRectangles(Rectangle[] rectangles)
{
clip = new Clip(rectangles);
updateClip();
}
public native void drawString(String text, int x, int y);
public native void drawLine(int x1, int y1, int x2, int y2);
public native void drawRectangle(int x, int y, int w, int h);
public native void fillRectangle(int x, int y, int w, int h);
/**
*
* Clear area using the background pixel or pixmap of the drawable.
* Note that this operation does not adhere to the current clip.
*/
public native void clearArea(int x, int y, int w, int h,
boolean exposures);
public native void putImage(XImage image,
int srcX, int srcY,
int destX, int destY,
int width, int height);
public Drawable getDrawable()
{
return target;
}
private native void updateClip();
private Drawable target;
private RawData structure;
private Clip clip;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
/**
* An X11 Pixmap. A pixmap is an offscreen drawable that resides on
* the X server. A pixmap is bound to the screen it was created for.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class Pixmap extends Drawable
{
public Pixmap(XImage image, Screen screen)
{
this(screen.getRootWindow(),
image.getWidth(), image.getHeight(),
image.getDepth());
/* FIXME: don't create a new GC all the time. This might actually
not be as bad as initially believed. The GC cache of Xlib makes
this opertation less costly. */
GC gc = new GC(this);
gc.putImage(image, 0, 0, 0, 0, image.getWidth(), image.getHeight());
}
public Pixmap(Drawable sameScreenAs, int width, int height, int depth)
{
super(sameScreenAs.getDisplay(),
createXID(sameScreenAs, width, height, depth));
}
protected static native int createXID(Drawable sameScreenAs,
int width, int height, int depth);
protected native void finalize();
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* A flyweight class that denotes an X11 screen. Display and screen
* number is the only data kept by this class. The real screen
* structure is stored in the display. There may exist several
* objects denoting the same screen.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class Screen
{
static final int UNKNOWN = -1;
Display display;
int screenNumber = UNKNOWN;
RawData structure;
Screen(Display display, RawData screenStructure)
{
structure = screenStructure;
this.display = display;
}
public Screen(Display display)
{
this(display, display.getDefaultScreenNumber());
}
public Screen(Display display, int screenNumber)
{
this.display = display;
this.screenNumber = screenNumber;
initStructure();
}
public final Display getDisplay()
{
return display;
}
public Window getRootWindow()
{
int rootXID = getRootWindowXID();
return display.getWindow(rootXID);
}
public Visual getRootVisual()
{
RawData visualStructure = getRootVisualStructure();
int depth = getRootDepth();
return new Visual(visualStructure, this, depth);
}
private native RawData getRootVisualStructure();
public native int getRootDepth();
public native int getRootWindowXID();
public native int getDefaultColormapXID();
native void initStructure();
public Colormap getDefaultColormap()
{
return new Colormap(this, getDefaultColormapXID());
}
public final int getScreenNumber()
{
if (screenNumber == UNKNOWN)
screenNumber = findScreenNumber();
return screenNumber;
}
public native int findScreenNumber();
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* A visual determines how a color is encoded into a pixel/bitfield
* value. It does not determine how the pixel/bitfield value is
* encoded into the image data.
*
* <p>This class encapsulates all three Xlib representations of a
* visual.
*
* <ul>
*
* <li>int: visual id.
*
* <li>Visual: opaque data structure used by a lot of Xlib functions.
*
* <li>VisualInfo: transparent data structure that binds the visual to
* a certain screen and depth.
*
* </ul>
*
* <p>Implementation note: This class does not examine nor manipulate
* the Visual structure, since the X manual says the structure is
* opaque, and that XVisualInfo should be used instead.</p>
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class Visual
{
public static final int VC_STATIC_GRAY = 0,
VC_GRAY_SCALE = 1,
VC_STATIC_COLOR = 2,
VC_PSEUDO_COLOR = 3,
VC_TRUE_COLOR = 4,
VC_DIRECT_COLOR = 5;
protected static final int MASK_ID = 1 << 0,
MASK_SCREEN = 1 << 1,
MASK_DEPTH = 1 << 2,
MASK_CLASS = 1 << 3,
MASK_RED = 1 << 4,
MASK_GREEN = 1 << 5,
MASK_BLUE = 1 << 6,
MASK_COLORMAP_SIZE = 1 << 7,
MASK_BITS_PER_RGB = 1 << 8;
protected static final int MASK_ALL = MASK_ID
| MASK_SCREEN
| MASK_DEPTH
| MASK_CLASS
| MASK_RED
| MASK_GREEN
| MASK_BLUE
| MASK_COLORMAP_SIZE
| MASK_BITS_PER_RGB;
private static final int MASK_VISUAL_STRUCTURE = 1 << 31;
Display display;
RawData xVisualInfo;
int infoMask;
Screen screen;
Visual(RawData structure, Screen screen, int depth )
{
this.display = screen.getDisplay();
this.screen = screen;
init(structure, depth);
}
Visual(Display display, RawData structure, int depth )
{
this.display = display;
init(structure, depth);
}
protected native void init(RawData structure, int depth);
protected native void finalize();
/**
*
* Returns the a reference to the visual structure. This method has
* package accessibility since the data visual structure is only
* useful for direct Xlib calls.
*
* @return a pointer to the visual structure.
*/
native RawData getVisualStructure();
// These methods only make sense if the visual is decomposed:
public native int getRedMask();
public native int getGreenMask();
public native int getBlueMask();
public native int getScreenNumber();
public native int getDepth();
public Screen getScreen()
{
if (screen == null)
screen = new Screen(display, getScreenNumber());
return screen;
}
public native int getVisualClass();
public boolean hasRGBSubfields()
{
switch (getVisualClass())
{
case VC_TRUE_COLOR:
case VC_DIRECT_COLOR:
return true;
default:
return false;
}
}
protected native void ensureXVisualInfo(int requiredMask);
public String toString()
{
int missingInfo = ~infoMask;
boolean hasSubfieldInfo =
(missingInfo & (MASK_CLASS|MASK_RED|MASK_GREEN|MASK_BLUE)) == 0;
boolean hasDepth = (missingInfo & MASK_DEPTH) == 0;
return getClass().getName() + "[" +
(hasDepth ? "depth=" + getDepth() : "") +
(hasRGBSubfields() ?
(", redMask=" + Integer.toHexString(getRedMask()) +
", greenMask=" + Integer.toHexString(getGreenMask()) +
", blueMask=" + Integer.toHexString(getBlueMask())) :
", no-subfields") + ", class=" + getVisualClass() +
"]";
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* Size hints for an X11 window in its normal state. This class wraps
* the Xlib XSizeHints stucture.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class WMSizeHints implements Cloneable
{
public WMSizeHints()
{
init(null);
}
private native void init(WMSizeHints copyFrom);
protected native void finalize();
public Object clone() {
WMSizeHints hints = (WMSizeHints) super.clone();
// In case of an exception before the stucture is copied.
hints.structure = null;
hints.init(this);
return hints;
}
public native void applyNormalHints(Window window);
public native void setMinSize(int width, int height);
public native void setMaxSize(int width, int height);
RawData structure;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
import java.awt.Rectangle;
/**
* An X11 window.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class Window extends Drawable
{
// Must correspond with X.h definitions:
public static final int COPY_FROM_PARENT = 0;
public static final int INPUT_OUTPUT = 1;
public static final int INPUT_ONLY = 2;
public Window(Window parent, Rectangle bounds,
WindowAttributes attributes)
{
this(parent, bounds, attributes, null);
}
public Window(Window parent, Rectangle bounds,
WindowAttributes attributes, Visual visual)
{
this(parent, bounds, 0, attributes, COPY_FROM_PARENT, visual);
}
public Window(Window parent, Rectangle bounds, int borderWidth,
WindowAttributes attributes, int windowIOClass,
Visual visual)
{
this(parent.display,
parent.createChildXID(bounds, borderWidth, attributes,
windowIOClass, visual));
this.owned = true;
}
protected Window(Display display, int xid)
{
super(display, xid);
display.addXID(xid, this);
}
protected void finalize()
{
display.removeXID(xid);
if (owned)
{
destroy();
owned = false;
}
}
protected native void destroy();
protected native int createChildXID(Rectangle bounds,
int borderWidth,
WindowAttributes attributes,
int windowIOClass,
Visual visual);
public native void setAttributes(WindowAttributes attributes);
public native void map();
public native void unmap();
protected boolean owned = false;
public native void setProperty(int nameAtom, int typeAtom, byte[] data);
public void setProperty(int nameAtom, int typeAtom, String data)
{
int length = data.length();
byte[] byteData = new byte[length];
for (int i=0; i<length; i++)
byteData[i] = (byte) data.charAt(i);
setProperty(nameAtom, typeAtom, byteData);
}
public native void setWMProtocols(int[] atoms);
public native int[] getWMProtocols();
public void setProperty(String nameAtom, String typeAtom, String data)
{
int xaName = display.getAtom(nameAtom);
int xaType = display.getAtom(typeAtom);
setProperty(xaName, xaType, data);
}
public native void setBounds(int x, int y, int width, int height);
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
*
* Collection of attributes that can be applied to or read from an
* X11 window.
*
* <p>TODO: Split this class into two classes. One for the structure
* XSetWindowAttributes and one for the XWindowAttributes. However
* they should still share this common base class.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no> */
public class WindowAttributes
{
// Must match definitions in X.h:
public final static long MASK_BUTTON_PRESS = 1L<< 2,
MASK_BUTTON_RELEASE = 1L<< 3,
MASK_EXPOSURE = 1L<<15,
MASK_STRUCTURE_NOTIFY = 1L<<17;
public WindowAttributes()
{
init(null);
}
public WindowAttributes(Window from)
{
initFromWindow(from);
}
private native void initFromWindow(Window from);
private native void init(WindowAttributes copyFrom);
protected native void finalize();
public Object clone()
{
WindowAttributes attributes = (WindowAttributes) super.clone();
// In case of an exception before the stucture is copied.
attributes.in = 0;
attributes.out = 0;
// FIXME: do anything else?
attributes.init(this);
return attributes;
}
public native void setBackground(long pixel);
public native void setBackground(Pixmap pixmap);
public native void setEventMask(long eventMask);
public void setVisual(Visual visual)
{
this.visual = visual;
}
/**
* Retrieve the visual.
*
* @return the visual that is or should be used by a window. null
* means CopyFormParent.
*/
public native Visual getVisual();
Display display;
/**
* Reference to XWindowAttribute structure containing attributes
* read from a window.
*/
RawData in = 0;
/**
* Reference to XSetWindowAttribute structure containing attributes
* to be applied to a window.
*/
RawData out = 0;
long mask;
/** null means CopyFromParent during window creation. */
Visual visual = null;
public native void apply(Window window);
final RawData getXSetWindowAttributesStructure()
{
if (out == null)
initOut();
return out;
}
void initOut()
{
throw new UnsupportedOperationException("not implemented yet");
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* Mutable event structure that can contain any data from any event
* type. Events can be constructed or loaded from the event queue.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class XAnyEvent
{
// Must match the definitions in X.h:
public static final int TYPE_BUTTON_PRESS = 4,
TYPE_BUTTON_RELEASE = 5,
TYPE_EXPOSE = 12,
TYPE_UNMAP_NOTIFY = 18,
TYPE_MAP_NOTIFY = 19,
TYPE_REPARENT_NOTIFY = 21,
TYPE_CONFIGURE_NOTIFY = 22,
TYPE_CLIENT_MESSAGE = 33;
// Must match the definitions in X.h:
public final static long MASK_SUBSTRUCTURE_NOTIFY = 1L<<19,
MASK_SUBSTRUCTURE_REDIRECT = 1L<<20;
XAnyEvent(Display display)
{
this.display = display;
init();
}
private native void init();
protected native void finalize();
/**
* Load next event into the event structure.
*/
public native void loadNext();
public native int getType();
public native void setType(int type);
public native Window getWindow();
public native void setWindow(Window window);
/**
* @returns the number of the last request processed by the server.
*/
public native long getSerial();
public native void send(Window destination, boolean propagate,
long mask);
RawData structure;
Display display;
public String toString()
{
if (structure == null)
return getClass().getName() + "[no-structure]";
return getClass().getName() +
"[type=" + getType() +
",window=" + getWindow() + "]";
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
/**
* Interprets data from an Xlib XButtonEvent into members of java
* primitive types.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XButtonEvent extends XEvent
{
// Must match the definition in X.h:
public static final int MASK_SHIFT = 1<<0,
MASK_LOCK = 1<<1,
MASK_CONTROL = 1<<2,
MASK_MOD1 = 1<<3,
MASK_MOD2 = 1<<4,
MASK_MOD3 = 1<<5,
MASK_MOD4 = 1<<6,
MASK_MOD5 = 1<<7;
public XButtonEvent(XAnyEvent event)
{
super(event);
// FIXME: Avoid double checking?
if ((event.getType() != XAnyEvent.TYPE_BUTTON_PRESS) &&
(event.getType() != XAnyEvent.TYPE_BUTTON_RELEASE))
{
throw new IllegalArgumentException("Wrong event type");
}
init();
}
native void init();
public long time;
public int x;
public int y;
public int state;
public int button;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* A color or color-cell on the X server.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public final class XColor
{
public XColor(int r, int g, int b)
{
this();
setRGB(r, g, b);
}
public XColor()
{
init();
}
private native void init();
protected native void finalize();
public final native void setRGB(int r, int g, int b);
public final native int getRed();
public final native int getGreen();
public final native int getBlue();
public final native byte getFlags();
public final native long getPixelValue();
RawData structure = 0;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import java.awt.Rectangle;
/**
* Interprets and retrieves data from an Xlib XConfigureEvent.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XConfigureEvent extends XEvent
{
public XConfigureEvent(XAnyEvent event)
{
super(event);
// FIXME: Avoid double checking?
if (event.getType() != XAnyEvent.TYPE_CONFIGURE_NOTIFY)
throw new IllegalArgumentException("Wrong event type");
}
public native Rectangle getBounds();
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import java.io.IOException;
/**
* Indicates that something went wrong with the connection to an X11
* display.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XConnectException extends IOException
{
public XConnectException()
{
super();
}
public XConnectException(String message)
{
super(message);
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* Base class for interpreters of specific X event types. For methods
* concerning all X events, see XAnyEvent.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XEvent
{
public XEvent(XAnyEvent event)
{
this.event = event;
}
public XEvent(int type, Display display)
{
this(new XAnyEvent(display));
event.setType(type);
}
XAnyEvent event;
public XAnyEvent getXAnyEvent()
{
return event;
}
public String toString()
{
if (event == null)
return super.toString();
return event.toString();
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
/**
* Runtime exception that occured during an Xlib opertation.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XException extends RuntimeException
{
public XException() {}
public XException(String msg) { super(msg); }
public XException(Display display, int status)
{
super(toString(display, status));
}
static native String toString(Display display, int status);
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import java.awt.Rectangle;
/**
* Interprets data from an Xlib XExposeEvent.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XExposeEvent extends XEvent
{
public XExposeEvent(XAnyEvent event)
{
super(event);
// FIXME: Avoid double checking?
if (event.getType() != XAnyEvent.TYPE_EXPOSE)
throw new IllegalArgumentException("Wrong event type");
}
public native Rectangle getBounds();
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
/**
* Common base class for all resources that are stored on the server
* and refered to on the client side using XIDs.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XID
{
public XID(Display display, int xid)
{
this.display = display;
this.xid = xid;
}
public final int getXID()
{
return xid;
}
public final Display getDisplay()
{
return display;
}
protected Display display;
protected int xid;
private Object clientData;
public final Object getClientData()
{
return clientData;
}
public final void setClientData(Object clientData)
{
this.clientData = clientData;
}
protected String params()
{
return "display=" + display + ",xid=" + Integer.toHexString(xid);
}
public String toString()
{
return getClass().getName() +
"[" + params() + "]";
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
import gnu.gcj.RawData;
/**
* Structure containing image data that resides on the client side.
* The format, depth and offset attributes of an XImage determines how
* bitfields are encoded in a raster image. However, it does not
* determine how a color is encoded into a bitfield. I.e. the XImage
* pixel values in a specific structure, but does not determine what
* colors that will be used to represent these pixel values on the
* screen.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XImage
{
/** This object reference points to the data, hindering garbage
collection of the data. */
Object dataRef;
// Must match definitions in X.h:
public static final int XYBITMAP_FORMAT = 0,
XYPIXMAP_FORMAT = 1,
ZPIXMAP_FORMAT = 2;
// Must match definitions in X.h:
public static final int LEAST_SIGNIFICANT_B_FIRST_ORDER = 0,
MOST_SIGNIFICANT_B_FIRST_ORDER = 1;
public XImage(Visual visual, int depth, int format, int xoffset,
int width, int height, int bitmapPad,
int bytesPerLine)
{
this(visual, depth, format, xoffset, width, height, bitmapPad,
bytesPerLine,
0 // bitsPerPixel
);
}
public XImage(Visual visual, int depth, int format, int xoffset,
int width, int height, int bitmapPad,
int bytesPerLine, int bitsPerPixel)
{
if (visual == null) throw new
NullPointerException("a visual must be specified");
init(visual, depth, format, xoffset, width, height,
bitmapPad, bytesPerLine, bitsPerPixel);
}
public native void init(Visual visual, int depth, int format, int xoffset,
int width, int height, int bitmapPad,
int bytesPerLine, int bitsPerPixel);
private native void init(Visual visual, int width, int height);
public XImage(Visual visual, int width, int height)
{
this(visual, width, height,
true // Automatically allocate memory
);
}
/**
* Create a new XImage.
*
* @param allocate specifies whether to automatically allocate
* memory for the image. It is possible to create the data array
* elsewhere, so that we can for instance use a DataBufferUShort as
* data. Ie. not limit ourself to byte arrays. This is done by
* passing false and calling a setData() method manually after
* creation.
*/
public XImage(Visual visual, int width, int height, boolean allocate)
{
if (visual == null)
throw new NullPointerException("a visual must be specified");
init(visual, width, height);
if (allocate)
{
/* Now that Xlib has figured out the appropriate bytes per
line, we can allocate memory for the image. */
// FIXME: What about formats with several layers/bands?
byte[] data = new byte[getBytesPerLine()*height];
setData(data, 0);
}
}
/**
* Attach image data to this XImage.
*
* @param offset the index of the first actual data element in the array.
*/
public void setData(byte[] data, int offset)
{
dataRef = data;
internalSetData(data, offset);
}
/**
* Attach image data to this XImage.
*
* @param offset the index of the first actual data element in the
* array. Note: this is short offset, not a byte offset.
*/
public void setData(short[] data, int offset)
{
dataRef = data;
internalSetData(data, offset);
}
/**
* Attach image data to this XImage
*
* @param offset the index of the first actual data element in the array.
* Note: this is not a byte offset.
*/
public void setData(int[] data, int offset)
{
dataRef = data;
internalSetData(data, offset);
}
private native void internalSetData(byte[] data, int offset);
private native void internalSetData(short[] data, int offset);
private native void internalSetData(int[] data, int offset);
protected native void finalize();
boolean ownsData = false;
RawData structure = 0;
public final native int getWidth();
public final native int getHeight();
public final native int getDepth();
public final native int getFormat();
public final boolean isZPixmapFormat()
{
return getFormat() == ZPIXMAP_FORMAT;
}
/**
* Get the xoffset. The xoffset avoids the need of shifting the
* scanlines into place.
*/
public final native int getXOffset();
public native final int getBytesPerLine();
public native final int getBitsPerPixel();
public native final int getImageByteOrder();
public native final int getBitmapBitOrder();
public native final int getBitmapUnit();
public native final int getBitmapPad();
// True/Direct Color specific:
public native int getRedMask();
public native int getGreenMask();
public native int getBlueMask();
/**
* Set a pixel value at a given position in the image. This method
* is slow. Don't use it, except as a fall-back.
*/
public native final void setPixel(int x, int y, int pixel);
public String toString()
{
String format;
switch(getFormat())
{
case ZPIXMAP_FORMAT:
format = "ZPixmapFormat";
}
String imageByteOrder;
switch(getImageByteOrder())
{
case LEAST_SIGNIFICANT_B_FIRST_ORDER:
imageByteOrder = "leastSignificantByteFirst";
break;
case MOST_SIGNIFICANT_B_FIRST_ORDER:
imageByteOrder = "mostSignificantByteFirst";
}
String bitmapBitOrder;
switch(getBitmapBitOrder())
{
case LEAST_SIGNIFICANT_B_FIRST_ORDER:
bitmapBitOrder = "leastSignificantBitFirst";
break;
case MOST_SIGNIFICANT_B_FIRST_ORDER:
bitmapBitOrder = "mostSignificantBitFirst";
}
return getClass().getName() + "[" + format +
", width=" + getWidth() +
", height=" + getHeight() +
", bytesPerLine=" + getBytesPerLine() +
", xoffset=" + getXOffset() +
", depth=" + getDepth() +
", bitsPerPixel=" + getBitsPerPixel() +
", bitmapUnit=" + getBitmapUnit() +
", bitmapPad=" + getBitmapPad() +
", byteOrder=" + imageByteOrder +
", bitOrder=" + bitmapBitOrder +
"]";
}
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.xlib;
/**
* Interprets data from an Xlib XUnmapEvent.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class XUnmapEvent extends XEvent
{
public XUnmapEvent(Display display, Window eventWindow,
Window unmappedWindow,
boolean fromConfigure)
{
super(XAnyEvent.TYPE_UNMAP_NOTIFY, display);
getXAnyEvent().setWindow(eventWindow);
setUnmappedWindow(unmappedWindow);
setFromConfigure(fromConfigure);
}
public native void setUnmappedWindow(Window unmappedWindow);
public native void setFromConfigure(boolean fromConfigure);
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
// Needed to avoid linking in libstdc++
#ifndef __STL_USE_EXCEPTIONS
# include <java/lang/OutOfMemoryError.h>
# define __THROW_BAD_ALLOC throw new java::lang::OutOfMemoryError()
#endif
#include <vector>
#include <X11/Xlib.h>
#include <gcj/cni.h>
#include <gnu/gcj/RawData.h>
#include <java/awt/Rectangle.h>
#include "gnu/gcj/xlib/Clip.h"
typedef java::awt::Rectangle AWTRect;
typedef JArray<AWTRect*> AWTRectArray;
typedef std::vector<XRectangle> XRectVector;
void gnu::gcj::xlib::Clip::init(AWTRectArray* rectangles)
{
// Prepare rectangles:
int numRect = JvGetArrayLength(rectangles);
XRectVector* xrectvector = new XRectVector(numRect);
for (int i=0; i<numRect; i++)
{
AWTRect* awtrect = elements(rectangles)[i];
XRectangle& xrect = (*xrectvector)[i];
xrect.x = awtrect->x;
xrect.y = awtrect->y;
xrect.width = awtrect->width;
xrect.height = awtrect->height;
}
xrects = reinterpret_cast<gnu::gcj::RawData*>(xrectvector);
}
void gnu::gcj::xlib::Clip::finalize()
{
delete xrects; xrects = 0;
}
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
// Needed to avoid linking in libstdc++
#ifndef __STL_USE_EXCEPTIONS
# include <java/lang/OutOfMemoryError.h>
# define __THROW_BAD_ALLOC throw new java::lang::OutOfMemoryError()
#endif
#include <vector>
#include <X11/Xlib.h>
#include <gcj/cni.h>
#include <java/lang/RuntimeException.h>
#include <gnu/gcj/xlib/Display.h>
#include <gnu/gcj/xlib/Screen.h>
#include <gnu/gcj/xlib/Colormap.h>
#include <gnu/gcj/xlib/XColor.h>
#include <gnu/gcj/RawData.h>
jlong gnu::gcj::xlib::Colormap::allocateColorPixel(XColor* color)
{
::Display* dpy = (::Display*) (screen->getDisplay()->display);
::XColor* col = (::XColor*) (color->structure);
Status result = XAllocColor(dpy, xid, col);
if (result == 0)
throw new java::lang::RuntimeException(
JvNewStringLatin1("Unable to allocate color pixel."));
return col->pixel;
}
typedef JArray<gnu::gcj::xlib::XColor*>* xcolorarray;
xcolorarray gnu::gcj::xlib::Colormap::getSharedColors()
{
::Display* dpy = (::Display*) (screen->getDisplay()->display);
unsigned int nCells = CellsOfScreen(ScreenOfDisplay(dpy, screen->screenNumber));
typedef ::XColor xcolor;
std::vector<xcolor> colors(nCells);
for (unsigned int i=0; i<nCells; i++)
colors[i].pixel = i;
::XColor* cols = colors.get_allocator().address(colors.front());
XQueryColors(dpy, xid, cols,
nCells);
int nShared = 0;
for (unsigned int i=0; i<nCells; i++)
{
::XColor color = colors[i];
if (!XAllocColor(dpy, xid, &color))
continue;
/* FIXME: In some cases this algorithm may identify a free
color cell as a shared one. */
if (color.pixel != i)
{
// Oops, the color wasn't shared. Free it.
XFreeColors(dpy, xid, &(color.pixel), 1, 0);
colors[i].flags = FLAG_NOT_SHARED;
continue;
}
// FIXME: Shared or free?
nShared++;
colors[i].flags = FLAG_SHARED;
}
JArray<XColor*>* shared = newXColorArray(nShared);
int si=0;
for (unsigned int i=0; i<nCells; i++)
{
if (colors[i].flags != FLAG_SHARED)
continue;
XColor* col = elements(shared)[si++];
gnu::gcj::RawData* colorData = col->structure;
::XColor* colStruct = reinterpret_cast<xcolor*>(colorData);
*colStruct = colors[i];
}
return shared;
}
xcolorarray gnu::gcj::xlib::Colormap::getXColors()
{
::Display* dpy = (::Display*) (screen->getDisplay()->display);
unsigned int nCells =
CellsOfScreen(ScreenOfDisplay(dpy, screen->screenNumber));
typedef ::XColor xcolor;
std::vector<xcolor> colors(nCells);
JArray<XColor*>* colArray = newXColorArray(nCells);
for (unsigned int i=0; i<nCells; i++)
colors[i].pixel = i;
XQueryColors(dpy, xid, &(colors.front()), nCells);
/* TODO: The current problem with this code is that it relies on
(color.pixel == i) as an indicator that the color is
shared. However, (color.pixel == i), may also occur simply
because color cell i simply was the next free in the list of
unallocated color cells. IDEA: run through the list both
backwards and forwards, and only pick out the colorcells that
have been identified as shared during both passes. Reversing the
traversal direction might prevent i from corresponding to the
next free colorcell, atleast in one of the passes. */
for (unsigned int i=0; i<nCells; i++)
{
::XColor color = colors[i];
char flag = FLAG_NOT_SHARED;
if (XAllocColor(dpy, xid, &color))
{
if (color.pixel == i)
{
flag = FLAG_SHARED;
}
else
{
// Oops, the color wasn't shared. Free it.
XFreeColors(dpy, xid, &(color.pixel), 1, 0);
}
}
// Copy color data into object in array
XColor* col = elements(colArray)[i];
gnu::gcj::RawData* colorData = col->structure;
::XColor* colStruct = reinterpret_cast<xcolor*>(colorData);
*colStruct = colors[i];
colStruct->flags = flag;
}
return colArray;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment