Porting efforts, minimal Android stuff, cleanup.

- Moving code around for Fl_Double_Window, but not yet happy
- Tested CMake for Android cross compilation. Very happy!

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11142 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2016-02-09 21:54:38 +00:00
parent 7a0fe79f99
commit 94f0278d47
11 changed files with 344 additions and 248 deletions

View File

@ -136,6 +136,7 @@ public:
Fl_Graphics_Driver();
virtual ~Fl_Graphics_Driver() { if (p) free(p); }
public:
virtual char can_do_alpha_blending() { return 0; }
// --- implementation is in src/fl_rect.cxx which includes src/drivers/xxx/Fl_xxx_Graphics_Driver_rect.cxx
virtual void point(int x, int y) = 0;
virtual void rect(int x, int y, int w, int h) = 0;

View File

@ -57,6 +57,9 @@
# include <wchar.h>
# include <sys/stat.h>
# define xchar wchar_t
#elif defined(ANDROID)
# include <wchar.h>
# define xchar wchar_t
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: include utf8 support files and define utf8 types"
# define xchar unsigned short

2
FL/x.H
View File

@ -30,6 +30,8 @@
# include "win32.H"
# elif defined(__APPLE__)
# include "mac.H"
# elif defined(ANDROID)
# error "A clean port requires a driver-style system for Fl_X"
# elif defined(FL_PORTING)
# pragma message "FL_PORTING: write a header file based on this file, win32.H, or mac.H to define the FLTK core internals"
# include "porting.H"

95
README.Android.txt Normal file
View File

@ -0,0 +1,95 @@
README.Android.txt - Building and using FLTK with CMake for the Android platform
--------------------------------------------------------------------------------
WARNING: BUILDING FLTK FOR ANDROID IS WORK IN PROGRESS IN A PRETTY EARLY STAGE.
WARNING: THIS FILE MERELY CONTAINS A ROUGH LAYOUT AND SOME SIMPLE IDEAS HOW
FLTK WILL BUILD FOR ANDROID EVENTUALLY.
CONTENTS
==========
1 INTRODUCTION TO CMAKE
2 USING CMAKE TO BUILD FLTK
2.1 Prerequisites
2.2 Options
2.3 Building under Linux with Unix Makefiles
2.4 Crosscompiling
3 USING CMAKE WITH FLTK
3.1 Library names
3.2 Using Fluid files
4 DOCUMENT HISTORY
INTRODUCTION TO CMAKE
=======================
Please read README.CMake.txt in the same directory to learn about CMake.
More information on CMake can be found on its web site http://www.cmake.org.
USING CMAKE TO BUILD FLTK FOR ANDROID ON OS X AND LINUX
=========================================================
PREREQUISITES
---------------
Get CMake 3.2.3 or newer.
Go to https://github.com/taka-no-me/android-cmake and download the content
as a zip file.
Go into the FLTK base directory, then:
> mkdir build
> cd build
> unzip ~/Downloads/android-cmake-master.zip
> mv android-cmake-master Android
> cd Android
> cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake -DANDROID_NDK=~/dev/android-ndk-r10e -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="armeabi-v7a" ../..
> make
At this time, compilation will fail relatively soon, but we are working hard to make porting easier,
and to prove our work, we poert FLTK to Android at the same time. Using CMake to cross-compile
is one of the many steps required to make life easier and maintenance more flexible.
OPTIONS
---------
Options can be specified to cmake with the -D flag:
cmake -D <OPTION_NAME>=<OPTION_VALUE>
WARNING: Old outdated information:
Building FLTK on Android (pre alpha, don't expect miracles)
1. cd to the root of its source code ('cd android/hello')
2. Run ndk-build. This builds the native code, and should result in some .so files being put into the libs directory.
3. android update project --path . --name hello
4. ant debug (or similar). This will build the Java code and create an .apk. Crucially, the build process will pick up the .so files left within the libs directory and include them into the .apk.
5. adb install bin/name-of-project.apk
6. Then launch as normal using the Android GUI or using an am start command such as you give.
6a. emulator -avd Intel_x86
7. adb shell am start -n com.example.native_activity
8. adb uninstall com.example.native_activity
DOCUMENT HISTORY
==================
Feb 9 2016 - matt: recreated document with more warnings and active support

View File

@ -105,256 +105,9 @@ void Fl_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen
delete[] img;
}
#if defined(USE_X11)
#include "drivers/Xlib/Fl_Xlib_Graphics_Driver.h"
#if HAVE_XRENDER
#include <X11/extensions/Xrender.h>
#endif
void Fl_Xlib_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) {
XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y);
}
void Fl_Xlib_Graphics_Driver::copy_offscreen_with_alpha(int x, int y, int w, int h,
Fl_Offscreen pixmap, int srcx, int srcy) {
#if HAVE_XRENDER
XRenderPictureAttributes srcattr;
memset(&srcattr, 0, sizeof(XRenderPictureAttributes));
static XRenderPictFormat *srcfmt = XRenderFindStandardFormat(fl_display, PictStandardARGB32);
static XRenderPictFormat *dstfmt = XRenderFindStandardFormat(fl_display, PictStandardRGB24);
Picture src = XRenderCreatePicture(fl_display, pixmap, srcfmt, 0, &srcattr);
Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, &srcattr);
if (!src || !dst) {
fprintf(stderr, "Failed to create Render pictures (%lu %lu)\n", src, dst);
return;
}
const Fl_Region clipr = fl_clip_region();
if (clipr)
XRenderSetPictureClipRegion(fl_display, dst, clipr);
XRenderComposite(fl_display, PictOpOver, src, None, dst, srcx, srcy, 0, 0,
x, y, w, h);
XRenderFreePicture(fl_display, src);
XRenderFreePicture(fl_display, dst);
#endif
}
char fl_can_do_alpha_blending() {
return Fl_X::xrender_supported();
return Fl_Display_Device::display_device()->driver()->can_do_alpha_blending();
}
#elif defined(WIN32)
#include "drivers/GDI/Fl_GDI_Graphics_Driver.h"
// Code used to switch output to an off-screen window. See macros in
// win32.H which save the old state in local variables.
typedef struct { BYTE a; BYTE b; BYTE c; BYTE d; } FL_BLENDFUNCTION;
typedef BOOL (WINAPI* fl_alpha_blend_func)
(HDC,int,int,int,int,HDC,int,int,int,int,FL_BLENDFUNCTION);
static fl_alpha_blend_func fl_alpha_blend = NULL;
static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1};
/*
* This function checks if the version of MSWindows that we
* curently run on supports alpha blending for bitmap transfers
* and finds the required function if so.
*/
char fl_can_do_alpha_blending() {
static char been_here = 0;
static char can_do = 0;
// do this test only once
if (been_here) return can_do;
been_here = 1;
// load the library that implements alpha blending
HMODULE hMod = LoadLibrary("MSIMG32.DLL");
// give up if that doesn't exist (Win95?)
if (!hMod) return 0;
// now find the blending function inside that dll
fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend");
// give up if we can't find it (Win95)
if (!fl_alpha_blend) return 0;
// we have the call, but does our display support alpha blending?
// get the desktop's device context
HDC dc = GetDC(0L);
if (!dc) return 0;
// check the device capabilities flags. However GetDeviceCaps
// does not return anything useful, so we have to do it manually:
HBITMAP bm = CreateCompatibleBitmap(dc, 1, 1);
HDC new_gc = CreateCompatibleDC(dc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bm);
/*COLORREF set = */ SetPixel(new_gc, 0, 0, 0x01010101);
BOOL alpha_ok = fl_alpha_blend(dc, 0, 0, 1, 1, new_gc, 0, 0, 1, 1, blendfunc);
RestoreDC(new_gc, save);
DeleteDC(new_gc);
DeleteObject(bm);
ReleaseDC(0L, dc);
if (alpha_ok) can_do = 1;
return can_do;
}
HDC fl_makeDC(HBITMAP bitmap) {
HDC new_gc = CreateCompatibleDC(fl_gc);
SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
SetBkMode(new_gc, TRANSPARENT);
#if USE_COLORMAP
if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
#endif
SelectObject(new_gc, bitmap);
return new_gc;
}
void Fl_GDI_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
RestoreDC(new_gc, save);
DeleteDC(new_gc);
}
void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
BOOL alpha_ok = 0;
// first try to alpha blend
if ( fl_can_do_alpha_blending() ) {
alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc);
}
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
if (!alpha_ok) {
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
}
RestoreDC(new_gc, save);
DeleteDC(new_gc);
}
#elif defined(__APPLE_QUARTZ__) || defined(FL_DOXYGEN)
#include "src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h"
char fl_can_do_alpha_blending() {
return 1;
}
/** \addtogroup fl_drawings
@{
*/
/**
Creation of an offscreen graphics buffer.
\param w,h width and height in pixels of the buffer.
\return the created graphics buffer.
*/
Fl_Offscreen fl_create_offscreen(int w, int h) {
void *data = calloc(w*h,4);
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(
data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast);
CGColorSpaceRelease(lut);
return (Fl_Offscreen)ctx;
}
static void bmProviderRelease (void *src, const void *data, size_t size) {
CFIndex count = CFGetRetainCount(src);
CFRelease(src);
if(count == 1) free((void*)data);
}
void Fl_Quartz_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) {
CGContextRef src = (CGContextRef)osrc;
void *data = CGBitmapContextGetData(src);
int sw = CGBitmapContextGetWidth(src);
int sh = CGBitmapContextGetHeight(src);
CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src);
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
// when output goes to a Quartz printercontext, release of the bitmap must be
// delayed after the end of the print page
CFRetain(src);
CGDataProviderRef src_bytes = CGDataProviderCreateWithData( src, data, sw*sh*4, bmProviderRelease);
CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha,
src_bytes, 0L, false, kCGRenderingIntentDefault);
// fl_push_clip();
CGRect rect = CGRectMake(x, y, w, h);
Fl_X::q_begin_image(rect, srcx, srcy, sw, sh);
CGContextDrawImage(fl_gc, rect, img);
Fl_X::q_end_image();
CGImageRelease(img);
CGColorSpaceRelease(lut);
CGDataProviderRelease(src_bytes);
}
/** Deletion of an offscreen graphics buffer.
\param ctx the buffer to be deleted.
*/
void fl_delete_offscreen(Fl_Offscreen ctx) {
if (!ctx) return;
void *data = CGBitmapContextGetData((CGContextRef)ctx);
CFIndex count = CFGetRetainCount(ctx);
CGContextRelease((CGContextRef)ctx);
if(count == 1) free(data);
}
const int stack_max = 16;
static int stack_ix = 0;
static CGContextRef stack_gc[stack_max];
static Window stack_window[stack_max];
static Fl_Surface_Device *_ss;
/** Send all subsequent drawing commands to this offscreen buffer.
\param ctx the offscreen buffer.
*/
void fl_begin_offscreen(Fl_Offscreen ctx) {
_ss = Fl_Surface_Device::surface();
Fl_Display_Device::display_device()->set_current();
if (stack_ix<stack_max) {
stack_gc[stack_ix] = fl_gc;
stack_window[stack_ix] = fl_window;
} else
fprintf(stderr, "FLTK CGContext Stack overflow error\n");
stack_ix++;
fl_gc = (CGContextRef)ctx;
fl_window = 0;
CGContextSaveGState(fl_gc);
fl_push_no_clip();
}
/** Quit sending drawing commands to the current offscreen buffer.
*/
void fl_end_offscreen() {
fl_pop_clip();
CGContextRestoreGState(fl_gc); // matches CGContextSaveGState in fl_begin_offscreen()
CGContextFlush(fl_gc);
if (stack_ix>0)
stack_ix--;
else
fprintf(stderr, "FLTK CGContext Stack underflow error\n");
if (stack_ix<stack_max) {
fl_gc = stack_gc[stack_ix];
fl_window = stack_window[stack_ix];
}
_ss->set_current();
}
/** @} */
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement offscreen render space generation and management"
#else
# error unsupported platform
#endif
/**
Forces the window to be redrawn.

View File

@ -36,6 +36,92 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
return new Fl_GDI_Graphics_Driver();
}
// Code used to switch output to an off-screen window. See macros in
// win32.H which save the old state in local variables.
typedef struct { BYTE a; BYTE b; BYTE c; BYTE d; } FL_BLENDFUNCTION;
typedef BOOL (WINAPI* fl_alpha_blend_func)
(HDC,int,int,int,int,HDC,int,int,int,int,FL_BLENDFUNCTION);
static fl_alpha_blend_func fl_alpha_blend = NULL;
static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1};
/*
* This function checks if the version of MSWindows that we
* curently run on supports alpha blending for bitmap transfers
* and finds the required function if so.
*/
char Fl_GDI_Graphics_Driver::can_do_alpha_blending() {
static char been_here = 0;
static char can_do = 0;
// do this test only once
if (been_here) return can_do;
been_here = 1;
// load the library that implements alpha blending
HMODULE hMod = LoadLibrary("MSIMG32.DLL");
// give up if that doesn't exist (Win95?)
if (!hMod) return 0;
// now find the blending function inside that dll
fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend");
// give up if we can't find it (Win95)
if (!fl_alpha_blend) return 0;
// we have the call, but does our display support alpha blending?
// get the desktop's device context
HDC dc = GetDC(0L);
if (!dc) return 0;
// check the device capabilities flags. However GetDeviceCaps
// does not return anything useful, so we have to do it manually:
HBITMAP bm = CreateCompatibleBitmap(dc, 1, 1);
HDC new_gc = CreateCompatibleDC(dc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bm);
/*COLORREF set = */ SetPixel(new_gc, 0, 0, 0x01010101);
BOOL alpha_ok = fl_alpha_blend(dc, 0, 0, 1, 1, new_gc, 0, 0, 1, 1, blendfunc);
RestoreDC(new_gc, save);
DeleteDC(new_gc);
DeleteObject(bm);
ReleaseDC(0L, dc);
if (alpha_ok) can_do = 1;
return can_do;
}
HDC fl_makeDC(HBITMAP bitmap) {
HDC new_gc = CreateCompatibleDC(fl_gc);
SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
SetBkMode(new_gc, TRANSPARENT);
#if USE_COLORMAP
if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
#endif
SelectObject(new_gc, bitmap);
return new_gc;
}
void Fl_GDI_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
RestoreDC(new_gc, save);
DeleteDC(new_gc);
}
void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
BOOL alpha_ok = 0;
// first try to alpha blend
if ( fl_can_do_alpha_blending() ) {
alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc);
}
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
if (!alpha_ok) {
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
}
RestoreDC(new_gc, save);
DeleteDC(new_gc);
}
//
// End of "$Id$".

View File

@ -41,6 +41,7 @@ public:
static const char *class_id;
const char *class_name() {return class_id;};
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
char can_do_alpha_blending();
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);

View File

@ -42,6 +42,118 @@ Fl_Offscreen Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(int w, int h
return (Fl_Offscreen)ctx;
}
char Fl_Quartz_Graphics_Driver::can_do_alpha_blending() {
return 1;
}
static void bmProviderRelease (void *src, const void *data, size_t size) {
CFIndex count = CFGetRetainCount(src);
CFRelease(src);
if(count == 1) free((void*)data);
}
void Fl_Quartz_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) {
CGContextRef src = (CGContextRef)osrc;
void *data = CGBitmapContextGetData(src);
int sw = CGBitmapContextGetWidth(src);
int sh = CGBitmapContextGetHeight(src);
CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src);
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
// when output goes to a Quartz printercontext, release of the bitmap must be
// delayed after the end of the print page
CFRetain(src);
CGDataProviderRef src_bytes = CGDataProviderCreateWithData( src, data, sw*sh*4, bmProviderRelease);
CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha,
src_bytes, 0L, false, kCGRenderingIntentDefault);
// fl_push_clip();
CGRect rect = CGRectMake(x, y, w, h);
Fl_X::q_begin_image(rect, srcx, srcy, sw, sh);
CGContextDrawImage(fl_gc, rect, img);
Fl_X::q_end_image();
CGImageRelease(img);
CGColorSpaceRelease(lut);
CGDataProviderRelease(src_bytes);
}
/** \addtogroup fl_drawings
@{
*/
// FIXME: driver system
/**
Creation of an offscreen graphics buffer.
\param w,h width and height in pixels of the buffer.
\return the created graphics buffer.
*/
Fl_Offscreen fl_create_offscreen(int w, int h) {
void *data = calloc(w*h,4);
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(
data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast);
CGColorSpaceRelease(lut);
return (Fl_Offscreen)ctx;
}
// FIXME: driver system
/** Deletion of an offscreen graphics buffer.
\param ctx the buffer to be deleted.
*/
void fl_delete_offscreen(Fl_Offscreen ctx) {
if (!ctx) return;
void *data = CGBitmapContextGetData((CGContextRef)ctx);
CFIndex count = CFGetRetainCount(ctx);
CGContextRelease((CGContextRef)ctx);
if(count == 1) free(data);
}
// FIXME: driver system
const int stack_max = 16;
static int stack_ix = 0;
static CGContextRef stack_gc[stack_max];
static Window stack_window[stack_max];
static Fl_Surface_Device *_ss;
// FIXME: driver system
/** Send all subsequent drawing commands to this offscreen buffer.
\param ctx the offscreen buffer.
*/
void fl_begin_offscreen(Fl_Offscreen ctx) {
_ss = Fl_Surface_Device::surface();
Fl_Display_Device::display_device()->set_current();
if (stack_ix<stack_max) {
stack_gc[stack_ix] = fl_gc;
stack_window[stack_ix] = fl_window;
} else
fprintf(stderr, "FLTK CGContext Stack overflow error\n");
stack_ix++;
fl_gc = (CGContextRef)ctx;
fl_window = 0;
CGContextSaveGState(fl_gc);
fl_graphics_driver->push_no_clip();
}
// FIXME: driver system
/** Quit sending drawing commands to the current offscreen buffer.
*/
void fl_end_offscreen() {
fl_graphics_driver->pop_clip();
CGContextRestoreGState(fl_gc); // matches CGContextSaveGState in fl_begin_offscreen()
CGContextFlush(fl_gc);
if (stack_ix>0)
stack_ix--;
else
fprintf(stderr, "FLTK CGContext Stack underflow error\n");
if (stack_ix<stack_max) {
fl_gc = stack_gc[stack_ix];
fl_window = stack_window[stack_ix];
}
_ss->set_current();
}
/** @} */
//
// End of "$Id$".

View File

@ -43,6 +43,7 @@ public:
static const char *class_id;
const char *class_name() {return class_id;};
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
char can_do_alpha_blending();
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);

View File

@ -21,6 +21,10 @@
#include "../../config_lib.h"
#include "Fl_Xlib_Graphics_Driver.h"
#if HAVE_XRENDER
#include <X11/extensions/Xrender.h>
#endif
const char *Fl_Xlib_Graphics_Driver::class_id = "Fl_Xlib_Graphics_Driver";
@ -34,6 +38,43 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
return new Fl_Xlib_Graphics_Driver();
}
char Fl_Xlib_Graphics_Driver::can_do_alpha_blending() {
return Fl_X::xrender_supported();
}
void Fl_Xlib_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) {
XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y);
}
void Fl_Xlib_Graphics_Driver::copy_offscreen_with_alpha(int x, int y, int w, int h,
Fl_Offscreen pixmap, int srcx, int srcy) {
#if HAVE_XRENDER
XRenderPictureAttributes srcattr;
memset(&srcattr, 0, sizeof(XRenderPictureAttributes));
static XRenderPictFormat *srcfmt = XRenderFindStandardFormat(fl_display, PictStandardARGB32);
static XRenderPictFormat *dstfmt = XRenderFindStandardFormat(fl_display, PictStandardRGB24);
Picture src = XRenderCreatePicture(fl_display, pixmap, srcfmt, 0, &srcattr);
Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, &srcattr);
if (!src || !dst) {
fprintf(stderr, "Failed to create Render pictures (%lu %lu)\n", src, dst);
return;
}
const Fl_Region clipr = fl_clip_region();
if (clipr)
XRenderSetPictureClipRegion(fl_display, dst, clipr);
XRenderComposite(fl_display, PictOpOver, src, None, dst, srcx, srcy, 0, 0,
x, y, w, h);
XRenderFreePicture(fl_display, src);
XRenderFreePicture(fl_display, dst);
#endif
}
//
// End of "$Id$".
//

View File

@ -37,6 +37,7 @@ public:
static const char *class_id;
const char *class_name() {return class_id;};
virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
char can_do_alpha_blending();
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);