summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFabien Costantini <fabien@onepost.net>2008-09-25 18:26:33 +0000
committerFabien Costantini <fabien@onepost.net>2008-09-25 18:26:33 +0000
commitffad932289d17877a506a51c5f2f32c743d747d8 (patch)
treef45d4fa0e5b42f4faad7c5aba99a3da01d243a9c /src
parentf9dc24a096d98abf3d3176eee74a759f886c4134 (diff)
+ Cairo branch merged after successful testing on Mac OS X 10.5.4, Linux Ubuntu 8.04,Windows XPSP2.
This integration is minimum as discussed, in particular it does not feature any fltk cairo drawing substitution as in fltk2. Still it provides all the fundations to go further even in next 1.4 ... By default *no* cairo features are implemented nor linked, it can only be activated by --enable-cairo whose default is false. Please visit the README.cairo for complete description. + fixed UTF8 compilation pb on linux ubuntu + minor comments fixes on the fly git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6350 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx5
-rw-r--r--src/Fl_Cairo.cxx151
-rw-r--r--src/Fl_Double_Window.cxx3
-rw-r--r--src/Fl_Menu_Window.cxx7
-rw-r--r--src/Fl_Overlay_Window.cxx7
-rw-r--r--src/Fl_Text_Buffer.cxx19
-rw-r--r--src/Fl_Window.cxx6
-rw-r--r--src/Fl_mac.cxx13
-rw-r--r--src/Fl_win32.cxx3
-rw-r--r--src/Fl_x.cxx6
-rw-r--r--src/Makefile1
-rw-r--r--src/xutf8/utf8Input.c2
12 files changed, 207 insertions, 16 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 667380c2a..a77a653c0 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -30,7 +30,7 @@
// mostly to get around the single active context in QD and
// to implement clipping. This should be changed into pure
// Quartz calls in the near future.
-
+#include "config.h"
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
@@ -1184,6 +1184,9 @@ void Fl_Window::hide() {
fl_release_dc(fl_window, fl_gc);
fl_window = (HWND)-1;
fl_gc = 0;
+# ifdef HAVE_CAIRO
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0);
+# endif
}
#elif defined(__APPLE_QD__)
if ( ip->xid == fl_window && !parent() )
diff --git a/src/Fl_Cairo.cxx b/src/Fl_Cairo.cxx
new file mode 100644
index 000000000..6a87d3c8c
--- /dev/null
+++ b/src/Fl_Cairo.cxx
@@ -0,0 +1,151 @@
+//
+// "$Id$"
+//
+// Main header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2008 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <config.h>
+
+#ifdef HAVE_CAIRO
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+
+// static Fl module initialization :
+Fl_Cairo_State Fl::cairo_state_; ///< contains all necesary info for current cairo context mapping
+// Fl cairo features implementation
+
+/**
+ Provides a corresponding cairo context for Window \a w.
+ This is needed in a draw() override if Fl::cairo_autolink_context()
+ returns false, which is the default.
+ The cairo_context() does not need to be freed as it is freed every time
+ a new cairo context is created. When the program terminates,
+ a call to Fl::cairo_make_current(0) will destroy any residual context.
+ \note A new cairo context is not always re-created when this method
+ is used. In particular, if the current graphical context and the current
+ window didn't change between two calls, the previous gc is internally kept,
+ thus optimizing the drawing performances.
+ Also, after this call, Fl::cairo_gc() is adequately updated with this
+ cairo context.
+ \note Only available when configure has the --enable-cairo option
+ \return the valid cairo_t* cairo context associated to this window.
+*/
+cairo_t * Fl::cairo_make_current(Fl_Window* wi) {
+ if (!wi) return NULL; // Precondition
+
+ if (fl_gc==0) { // means remove current cc
+ Fl::cairo_cc(0); // destroy any previous cc
+ cairo_state_.window(0);
+ return 0;
+ }
+
+ // don't re-create a context if it's the same gc/window couple
+ if (fl_gc==Fl::cairo_state_.gc() && fl_xid(wi) == (Window) Fl::cairo_state_.window())
+ return Fl::cairo_cc();
+
+ cairo_state_.window(wi);
+
+#if defined(USE_X11)
+ return Fl::cairo_make_current(0, wi->w(), wi->h());
+#else
+ return Fl::cairo_make_current(fl_gc, wi->w(), wi->h());
+#endif
+}
+
+/*
+ Creates transparently a cairo_surface_t object.
+ gc is an HDC context in WIN32, a CGContext* in Quartz, a display on X11
+ */
+static cairo_surface_t * cairo_create_surface(void * gc, int W, int H) {
+# if defined(USE_X11) // X11
+ return cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H);
+# elif defined(WIN32)
+ return cairo_win32_surface_create((HDC) gc);
+# elif defined(__APPLE_QUARTZ__)
+ return cairo_quartz_surface_create_for_cg_context((CGContext*) gc, W, H);
+# elif defined(__APPLE_QD__)
+# error Cairo is not supported under Apple Quickdraw, please use Apple Quartz.
+# else
+# error Cairo is not supported under this platform.
+# endif
+}
+
+/**
+ Creates a cairo context from a \a gc only, get its window size or offscreen size if fl_window is null
+ \note Only available when configure has the --enable-cairo option
+*/
+cairo_t * Fl::cairo_make_current(void *gc) {
+ int W=0,H=0;
+#if defined(USE_X11)
+ //FIXME X11 get W,H
+ // gc will be the window handle here
+# warning FIXME get W,H for cairo_make_current(void*)
+#elif defined(__APPLE_QUARTZ__)
+ if (fl_window) {
+ Rect portRect;
+ GetPortBounds(GetWindowPort( fl_window ), &portRect);
+ W = portRect.right-portRect.left;
+ H = portRect.bottom-portRect.top;
+ }
+ else {
+ W = CGBitmapContextGetHeight(fl_gc);
+ H = CGBitmapContextGetHeight(fl_gc);
+ }
+#elif defined(WIN32)
+ // we don't need any W,H for WIN32
+#else
+# error Cairo is not supported under this platform.
+#endif
+ if (!gc) {
+ Fl::cairo_cc(0);
+ cairo_state_.gc(0); // keep track for next time
+ return 0;
+ }
+ if (gc==Fl::cairo_state_.gc() && fl_window== (Window) Fl::cairo_state_.window())
+ return Fl::cairo_cc();
+ cairo_state_.gc(fl_gc); // keep track for next time
+ cairo_surface_t * s = cairo_create_surface(gc, W, H);
+ cairo_t * c = cairo_create(s);
+ cairo_surface_destroy(s);
+ Fl::cairo_cc(c);
+ return c;
+}
+
+/**
+ Creates a cairo context from a \a gc and its size
+ \note Only available when configure has the --enable-cairo option
+*/
+cairo_t * Fl::cairo_make_current(void *gc, int W, int H) {
+ cairo_surface_t * s = cairo_create_surface(gc, W, H);
+ cairo_t * c = cairo_create(s);
+ cairo_surface_destroy(s);
+ Fl::cairo_cc(c);
+ return c;
+}
+#endif // HAVE_CAIRO
+
+//
+// End of "$Id$" .
+//
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
index 6c86284e7..37bdd9e96 100644
--- a/src/Fl_Double_Window.cxx
+++ b/src/Fl_Double_Window.cxx
@@ -403,6 +403,9 @@ void Fl_Double_Window::flush(int eraseoverlay) {
RestoreDC(fl_gc, save);
DeleteDC(fl_gc);
fl_gc = _sgc;
+ //# if defined(HAVE_CAIRO)
+ //if Fl::cairo_autolink_context() Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
+ //# endif
#elif defined(__APPLE__)
if ( myi->other_xid ) {
fl_begin_offscreen( myi->other_xid );
diff --git a/src/Fl_Menu_Window.cxx b/src/Fl_Menu_Window.cxx
index 12422cfab..a7f17c7d0 100644
--- a/src/Fl_Menu_Window.cxx
+++ b/src/Fl_Menu_Window.cxx
@@ -67,7 +67,12 @@ void Fl_Menu_Window::flush() {
if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
Fl_X *myi = Fl_X::i(this);
fl_window = myi->xid;
- if (!gc) gc = XCreateGC(fl_display, myi->xid, 0, 0);
+ if (!gc) {
+ gc = XCreateGC(fl_display, myi->xid, 0, 0);
+# if defined(HAVE_CAIRO)
+ Fl::cairo_make_current(gc); // capture gc changes automatically to update the cairo context adequately
+# endif
+ }
fl_gc = gc;
fl_overlay = 1;
fl_clip_region(myi->region); myi->region = 0; current_ = this;
diff --git a/src/Fl_Overlay_Window.cxx b/src/Fl_Overlay_Window.cxx
index fd4fdfdcc..4e76566c9 100644
--- a/src/Fl_Overlay_Window.cxx
+++ b/src/Fl_Overlay_Window.cxx
@@ -131,8 +131,13 @@ void _Fl_Overlay::show() {
void _Fl_Overlay::flush() {
fl_window = fl_xid(this);
- if (!gc) gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
+ if (!gc) {
+ gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
+ }
fl_gc = gc;
+#if defined(HAVE_CAIRO)
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
+#endif
fl_overlay = 1;
Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
Fl_X *myi = Fl_X::i(this);
diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx
index 817217c8e..e3d07ea67 100644
--- a/src/Fl_Text_Buffer.cxx
+++ b/src/Fl_Text_Buffer.cxx
@@ -64,8 +64,15 @@ static char *expandTabs(const char *text, int startIndent, int tabDist,
char nullSubsChar, int *newLen);
static char *unexpandTabs(char *text, int startIndent, int tabDist,
char nullSubsChar, int *newLen);
-static int max(int i1, int i2);
-static int min(int i1, int i2);
+#ifndef min
+static int max(int i1, int i2) {
+ return i1 >= i2 ? i1 : i2;
+}
+
+static int min(int i1, int i2) {
+ return i1 <= i2 ? i1 : i2;
+}
+#endif
static const char *ControlCodeTable[ 32 ] = {
"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
@@ -2569,14 +2576,6 @@ static char *unexpandTabs(char *text, int startIndent, int tabDist,
return outStr;
}
-static int max(int i1, int i2) {
- return i1 >= i2 ? i1 : i2;
-}
-
-static int min(int i1, int i2) {
- return i1 <= i2 ? i1 : i2;
-}
-
int
/**
Inserts a file at the specified position. Returns 0 on success,
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
index 21eec3caa..32459d367 100644
--- a/src/Fl_Window.cxx
+++ b/src/Fl_Window.cxx
@@ -29,7 +29,7 @@
// This is the system-independent portions. The huge amount of
// crap you need to do to communicate with X is in Fl_x.cxx, the
// equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx
-
+#include "config.h"
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <stdlib.h>
@@ -132,6 +132,10 @@ void Fl_Window::draw() {
set_flag(saveflags);
y(savey);
x(savex);
+
+# if defined(HAVE_CAIRO)
+ Fl::cairo_make_current(this); // checkout if an update is necessary
+# endif
}
void Fl_Window::label(const char *name) {
diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx
index eb3b82393..94473b512 100644
--- a/src/Fl_mac.cxx
+++ b/src/Fl_mac.cxx
@@ -2312,10 +2312,18 @@ void Fl_Window::make_current()
fl_gc = i->gc;
CGContextSaveGState(fl_gc);
Fl_X::q_fill_context();
+#if defined(HAVE_CAIRO) && defined (__APPLE_QUARTZ__)
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
+#endif
+
#endif
fl_clip_region( 0 );
SetPortClipRegion( GetWindowPort(i->xid), fl_window_region );
- return;
+
+#if defined(__APPLE_QUARTZ__) && defined(HAVE_CAIRO)
+ // update the cairo_t context
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this);
+#endif
}
// helper function to manage the current CGContext fl_gc
@@ -2363,6 +2371,9 @@ void Fl_X::q_release_context(Fl_X *x) {
fprintf(stderr, "Error %d in QDEndCGContext\n", (int)err);
}
fl_gc = 0;
+#if defined(HAVE_CAIRO) && defined (__APPLE_QUARTZ__)
+ Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately
+#endif
}
void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) {
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index b67bf80dd..e3cf9e83b 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -1737,6 +1737,7 @@ HDC fl_GetDC(HWND w) {
// calling GetDC seems to always reset these: (?)
SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
SetBkMode(fl_gc, TRANSPARENT);
+
return fl_gc;
}
@@ -1755,6 +1756,8 @@ void Fl_Window::make_current() {
current_ = this;
fl_clip_region(0);
+
+
}
/* Make sure that all allocated fonts are released. This works only if
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 3fffb0ab5..3300f3741 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -1726,6 +1726,12 @@ void Fl_Window::make_current() {
fl_gc = gc;
current_ = this;
fl_clip_region(0);
+
+#ifdef HAVE_CAIRO
+ // update the cairo_t context
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this);
+#endif
+
}
#endif
diff --git a/src/Makefile b/src/Makefile
index f4ff7f9d4..f7d15b793 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,6 +34,7 @@ CPPFILES = \
Fl_Browser_load.cxx \
Fl_Box.cxx \
Fl_Button.cxx \
+ Fl_Cairo.cxx \
Fl_Chart.cxx \
Fl_Check_Browser.cxx \
Fl_Check_Button.cxx \
diff --git a/src/xutf8/utf8Input.c b/src/xutf8/utf8Input.c
index 205e7d0fc..6e956224d 100644
--- a/src/xutf8/utf8Input.c
+++ b/src/xutf8/utf8Input.c
@@ -40,7 +40,7 @@
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Intrinsic.h>
+#include <string.h>
#include <stdlib.h>
#if HAVE_LIBC_ICONV