diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2021-04-17 23:48:15 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2022-02-25 01:44:57 +0000 |
commit | 64db153c43d67d4ff08350a64cbb169c50bdb85e (patch) | |
tree | 40b338279d7afe50e5cc418b7bb0314dff151ec4 | |
parent | 1fa3b10ccea26ae9259674bbf10ac86a8abcb908 (diff) | |
download | cairo-64db153c43d67d4ff08350a64cbb169c50bdb85e.tar.gz |
Drop OS/2 support
OS/2 support was last built in Cairo 1.12, which was released 10 years
ago.
Additionally, OS/2 is not supported by Meson.
-rw-r--r-- | README | 11 | ||||
-rw-r--r-- | boilerplate/Makefile.win32.features | 10 | ||||
-rw-r--r-- | build/Makefile.win32.features | 1 | ||||
-rw-r--r-- | build/Makefile.win32.features-h | 3 | ||||
-rw-r--r-- | build/configure.ac.features | 1 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | perf/cairo-perf.c | 9 | ||||
-rw-r--r-- | src/Makefile.sources | 4 | ||||
-rw-r--r-- | src/Makefile.win32.features | 14 | ||||
-rw-r--r-- | src/cairo-mutex-impl-private.h | 15 | ||||
-rw-r--r-- | src/cairo-os2-private.h | 67 | ||||
-rw-r--r-- | src/cairo-os2-surface.c | 1416 | ||||
-rw-r--r-- | src/cairo-os2.h | 110 | ||||
-rw-r--r-- | src/cairo-time.c | 28 | ||||
-rw-r--r-- | test/api-special-cases.c | 3 | ||||
-rw-r--r-- | test/error-setters.c | 9 |
17 files changed, 3 insertions, 1712 deletions
@@ -7,7 +7,7 @@ Cairo is a 2D graphics library with support for multiple output devices. Currently supported output targets include the X Window System (via both Xlib and XCB), quartz, win32, and image buffers, as well as PDF, PostScript, and SVG file output. Experimental backends -include OpenGL, OS/2, and DirectFB. +include OpenGL and DirectFB. Cairo is designed to produce consistent output on all output media while taking advantage of display hardware acceleration when available @@ -167,15 +167,6 @@ Font backends (required to have at least one) 7.1 or later, including the free Microsoft Visual Studio Express editions, produce correct code. -Experimental surface backends ------------------------------ - os2 backend - ----------- - Cairo should run on any recent version of OS/2 or eComStation, but it - requires a font backend. See the freetype dependency list. Ready to use - packages and developer dependencies are available at Netlabs: - ftp://ftp.netlabs.org/pub/cairo - Compiling ========= diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features index 4dff05f21..5cef41220 100644 --- a/boilerplate/Makefile.win32.features +++ b/boilerplate/Makefile.win32.features @@ -117,16 +117,6 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_win32_font_private) enabled_cairo_boilerplate_sources += $(cairo_boilerplate_win32_font_sources) endif -unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers) -all_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers) -all_cairo_boilerplate_private += $(cairo_boilerplate_os2_private) -all_cairo_boilerplate_sources += $(cairo_boilerplate_os2_sources) -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) -enabled_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers) -enabled_cairo_boilerplate_private += $(cairo_boilerplate_os2_private) -enabled_cairo_boilerplate_sources += $(cairo_boilerplate_os2_sources) -endif - unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_drm_headers) all_cairo_boilerplate_headers += $(cairo_boilerplate_drm_headers) all_cairo_boilerplate_private += $(cairo_boilerplate_drm_private) diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features index 39efb7e6e..bd03d5ce9 100644 --- a/build/Makefile.win32.features +++ b/build/Makefile.win32.features @@ -10,7 +10,6 @@ CAIRO_HAS_QUARTZ_FONT=0 CAIRO_HAS_QUARTZ_IMAGE_SURFACE=0 CAIRO_HAS_WIN32_SURFACE=1 CAIRO_HAS_WIN32_FONT=1 -CAIRO_HAS_OS2_SURFACE=0 CAIRO_HAS_DRM_SURFACE=0 CAIRO_HAS_GALLIUM_SURFACE=0 CAIRO_HAS_PNG_FUNCTIONS=1 diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h index 5fa7f0f16..3c3d97733 100644 --- a/build/Makefile.win32.features-h +++ b/build/Makefile.win32.features-h @@ -35,9 +35,6 @@ endif ifeq ($(CAIRO_HAS_WIN32_FONT),1) @echo "#define CAIRO_HAS_WIN32_FONT 1" >> $(top_srcdir)/src/cairo-features.h endif -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) - @echo "#define CAIRO_HAS_OS2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif ifeq ($(CAIRO_HAS_DRM_SURFACE),1) @echo "#define CAIRO_HAS_DRM_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h endif diff --git a/build/configure.ac.features b/build/configure.ac.features index 8cd8d4329..a1a3ff830 100644 --- a/build/configure.ac.features +++ b/build/configure.ac.features @@ -371,7 +371,6 @@ AC_DEFUN([CAIRO_REPORT], echo " Quartz-image: $use_quartz_image" echo " XCB: $use_xcb" echo " Win32: $use_win32" - echo " OS2: $use_os2" echo " CairoScript: $use_script" echo " PostScript: $use_ps" echo " PDF: $use_pdf" diff --git a/configure.ac b/configure.ac index 8d5fb9637..dcbb3bdf5 100644 --- a/configure.ac +++ b/configure.ac @@ -239,19 +239,6 @@ AM_CONDITIONAL(CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE, test "x$test_win32_printin dnl =========================================================================== -CAIRO_ENABLE_SURFACE_BACKEND(os2, OS/2, no, [ - case "$host" in - *-*-os2*) - : - ;; - *) - use_os2="no (requires an OS/2 platform)" - ;; - esac -]) - -dnl =========================================================================== - CAIRO_ENABLE_SURFACE_BACKEND(drm, DRM, no, [ dnl Keep in sync with meson.build! drm_REQUIRES="libudev >= 136, libdrm >= 2.4" diff --git a/meson.build b/meson.build index 9d5b82b37..d73e636a6 100644 --- a/meson.build +++ b/meson.build @@ -990,7 +990,6 @@ summary({ 'Quartz-image': feature_conf.get('CAIRO_HAS_QUARTZ_IMAGE_SURFACE', 0) == 1, 'XCB': feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1, 'Win32': feature_conf.get('CAIRO_HAS_WIN32_SURFACE', 0) == 1, - 'OS2': false, 'CairoScript': feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1, 'PostScript': feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1, 'PDF': feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1, diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index 18db0c544..ebef8eb59 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -36,10 +36,7 @@ #include <unistd.h> #endif -#if defined(__OS2__) -#define INCL_BASE -#include <os2.h> -#elif defined(_WIN32) +#if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include <windows.h> #elif defined(_POSIX_PRIORITY_SCHEDULING) @@ -86,9 +83,7 @@ cairo_perf_yield (void) { /* try to deactivate this thread until the scheduler calls it again */ -#if defined(__OS2__) - DosSleep (0); -#elif defined(_WIN32) +#if defined(_WIN32) SleepEx(0, TRUE); #elif defined(_POSIX_PRIORITY_SCHEDULING) sched_yield (); diff --git a/src/Makefile.sources b/src/Makefile.sources index bf3bb87df..329b8bdd8 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -361,10 +361,6 @@ cairo_win32_font_sources = \ win32/cairo-win32-font.c \ $(NULL) -cairo_os2_headers = cairo-os2.h -cairo_os2_private = cairo-os2-private.h -cairo_os2_sources = cairo-os2-surface.c - cairo_gl_headers = cairo-gl.h cairo_gl_private = cairo-gl-private.h \ cairo-gl-dispatch-private.h \ diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features index 83d60ef0f..7ddc6a8b7 100644 --- a/src/Makefile.win32.features +++ b/src/Makefile.win32.features @@ -159,20 +159,6 @@ ifeq ($(CAIRO_HAS_WIN32_FONT),1) enabled_cairo_pkgconf += cairo-win32-font.pc endif -unsupported_cairo_headers += $(cairo_os2_headers) -all_cairo_headers += $(cairo_os2_headers) -all_cairo_private += $(cairo_os2_private) -all_cairo_sources += $(cairo_os2_sources) -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) -enabled_cairo_headers += $(cairo_os2_headers) -enabled_cairo_private += $(cairo_os2_private) -enabled_cairo_sources += $(cairo_os2_sources) -endif -all_cairo_pkgconf += cairo-os2.pc -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) -enabled_cairo_pkgconf += cairo-os2.pc -endif - unsupported_cairo_headers += $(cairo_drm_headers) all_cairo_headers += $(cairo_drm_headers) all_cairo_private += $(cairo_drm_private) diff --git a/src/cairo-mutex-impl-private.h b/src/cairo-mutex-impl-private.h index f4049d236..9f208aaa9 100644 --- a/src/cairo-mutex-impl-private.h +++ b/src/cairo-mutex-impl-private.h @@ -195,21 +195,6 @@ # define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex)) # define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 } -#elif defined __OS2__ /******************************************************/ - -# define INCL_BASE -# define INCL_PM -# include <os2.h> - - typedef HMTX cairo_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_OS2 1 -# define CAIRO_MUTEX_IMPL_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) DosReleaseMutexSem(mutex) -# define CAIRO_MUTEX_IMPL_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE) -# define CAIRO_MUTEX_IMPL_FINI(mutex) DosCloseMutexSem (mutex) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0 - #elif CAIRO_HAS_PTHREAD /* and finally if there are no native mutexes ********/ # include <pthread.h> diff --git a/src/cairo-os2-private.h b/src/cairo-os2-private.h deleted file mode 100644 index 829dd3c8d..000000000 --- a/src/cairo-os2-private.h +++ /dev/null @@ -1,67 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - */ - -#ifndef CAIRO_OS2_PRIVATE_H -#define CAIRO_OS2_PRIVATE_H - -#include "cairo-os2.h" -#include "cairoint.h" - -typedef struct _cairo_os2_surface -{ - cairo_surface_t base; - - /* Mutex semaphore to protect private fields from concurrent access */ - HMTX hmtx_use_private_fields; - /* Private fields: */ - HPS hps_client_window; - HWND hwnd_client_window; - BITMAPINFO2 bitmap_info; - unsigned char *pixels; - cairo_image_surface_t *image_surface; - int pixel_array_lend_count; - HEV hev_pixel_array_came_back; - - RECTL rcl_dirty_area; - cairo_bool_t dirty_area_present; - - /* General flags: */ - cairo_bool_t blit_as_changes; - cairo_bool_t use_24bpp; -} cairo_os2_surface_t; - -#endif /* CAIRO_OS2_PRIVATE_H */ diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c deleted file mode 100644 index 84f08c807..000000000 --- a/src/cairo-os2-surface.c +++ /dev/null @@ -1,1416 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - * Rich Walsh <dragtext@e-vertise.com> - */ - -#include "cairoint.h" - -#include "cairo-os2-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-surface-fallback-private.h" -#include "cairo-image-surface-private.h" - -#if CAIRO_HAS_FC_FONT -#include <fontconfig/fontconfig.h> -#endif - -#include <float.h> -#ifdef BUILD_CAIRO_DLL -# include "cairo-os2.h" -# ifndef __WATCOMC__ -# include <emx/startup.h> -# endif -#endif - -/* - * Here comes the extra API for the OS/2 platform. Currently it consists - * of two extra functions, the cairo_os2_init() and the - * cairo_os2_fini(). Both of them are called automatically if - * Cairo is compiled to be a DLL file, but you have to call them before - * using the Cairo API if you link to Cairo statically! - * - * You'll also find the code in here which deals with DLL initialization - * and termination, if the code is built to be a DLL. - * (if BUILD_CAIRO_DLL is defined) - */ - -/* Initialization counter: */ -static int cairo_os2_initialization_count = 0; - -static inline void -DisableFPUException (void) -{ - unsigned short usCW; - - /* Some OS/2 PM API calls modify the FPU Control Word, - * but forget to restore it. - * - * This can result in XCPT_FLOAT_INVALID_OPCODE exceptions, - * so to be sure, we disable Invalid Opcode FPU exception - * before using FPU stuffs. - */ - usCW = _control87 (0, 0); - usCW = usCW | EM_INVALID | 0x80; - _control87 (usCW, MCW_EM | 0x80); -} - -/** - * cairo_os2_init: - * - * Initializes the Cairo library. This function is automatically called if - * Cairo was compiled to be a DLL (however it's not a problem if it's called - * multiple times). But if you link to Cairo statically, you have to call it - * once to set up Cairo's internal structures and mutexes. - * - * Since: 1.4 - **/ -cairo_public void -cairo_os2_init (void) -{ - /* This may initialize some stuffs, like create mutex semaphores etc.. */ - - cairo_os2_initialization_count++; - if (cairo_os2_initialization_count > 1) return; - - DisableFPUException (); - -#if CAIRO_HAS_FC_FONT - /* Initialize FontConfig */ - FcInit (); -#endif - - CAIRO_MUTEX_INITIALIZE (); -} - -/** - * cairo_os2_fini: - * - * Uninitializes the Cairo library. This function is automatically called if - * Cairo was compiled to be a DLL (however it's not a problem if it's called - * multiple times). But if you link to Cairo statically, you have to call it - * once to shut down Cairo, to let it free all the resources it has allocated. - * - * Since: 1.4 - **/ -cairo_public void -cairo_os2_fini (void) -{ - /* This has to uninitialize some stuffs, like destroy mutex semaphores etc.. */ - - if (cairo_os2_initialization_count <= 0) return; - cairo_os2_initialization_count--; - if (cairo_os2_initialization_count > 0) return; - - DisableFPUException (); - - cairo_debug_reset_static_data (); - -#if CAIRO_HAS_FC_FONT -# if HAVE_FCFINI - /* Uninitialize FontConfig */ - FcFini (); -# endif -#endif - -#ifdef __WATCOMC__ - /* It can happen that the libraries we use have memory leaks, - * so there are still memory chunks allocated at this point. - * In these cases, Watcom might still have a bigger memory chunk, - * called "the heap" allocated from the OS. - * As we want to minimize the memory we lose from the point of - * view of the OS, we call this function to shrink that heap - * as much as possible. - */ - _heapshrink (); -#else - /* GCC has a heapmin function that approximately corresponds to - * what the Watcom function does - */ - _heapmin (); -#endif -} - -/* - * This function calls the allocation function depending on which - * method was compiled into the library: it can be native allocation - * (DosAllocMem/DosFreeMem) or C-Library based allocation (malloc/free). - * Actually, for pixel buffers that we use this function for, cairo - * uses _cairo_malloc_abc, so we use that here, too. And use the - * change to check the size argument - */ -void *_buffer_alloc (size_t a, size_t b, const unsigned int size) -{ - size_t nbytes; - void *buffer = NULL; - - if (!a || !b || !size || - a >= INT32_MAX / b || a*b >= INT32_MAX / size) { - return NULL; - } - nbytes = a * b * size; - -#ifdef OS2_USE_PLATFORM_ALLOC - /* Using OBJ_ANY on a machine that isn't configured for hi-mem - * will cause ERROR_INVALID_PARAMETER. If this occurs, or this - * build doesn't have hi-mem enabled, fall back to using lo-mem. - */ -#ifdef OS2_HIGH_MEMORY - if (!DosAllocMem (&buffer, nbytes, - OBJ_ANY | PAG_READ | PAG_WRITE | PAG_COMMIT)) - return buffer; -#endif - if (DosAllocMem (&buffer, nbytes, - PAG_READ | PAG_WRITE | PAG_COMMIT)) - return NULL; -#else - /* Clear the malloc'd buffer the way DosAllocMem() does. */ - buffer = _cairo_malloc (nbytes); - if (buffer) { - memset (buffer, 0, nbytes); - } -#endif - return buffer; -} - -/* - * This function selects the free function depending on which - * allocation method was compiled into the library - */ -void _buffer_free (void *buffer) -{ -#ifdef OS2_USE_PLATFORM_ALLOC - DosFreeMem (buffer); -#else - free (buffer); -#endif -} - -/* XXX - * The cairo_os2_ini() and cairo_os2_fini() functions should be removed and - * the LibMain code moved to cairo-system.c. It should also call - * cairo_debug_reset_static_data() instead of duplicating its logic... - */ - -#ifdef BUILD_CAIRO_DLL -/* The main DLL entry for DLL initialization and uninitialization */ -/* Only include this code if we're about to build a DLL. */ - -#ifdef __WATCOMC__ -unsigned _System -LibMain (unsigned hmod, - unsigned termination) -#else -unsigned long _System -_DLL_InitTerm (unsigned long hModule, - unsigned long termination) -#endif -{ - if (termination) { - /* Unloading the DLL */ - cairo_os2_fini (); - -#ifndef __WATCOMC__ - /* Uninitialize RTL of GCC */ - __ctordtorTerm (); - _CRT_term (); -#endif - return 1; - } else { - /* Loading the DLL */ -#ifndef __WATCOMC__ - /* Initialize RTL of GCC */ - if (_CRT_init () != 0) - return 0; - __ctordtorInit (); -#endif - - cairo_os2_init (); - return 1; - } -} - -#endif /* BUILD_CAIRO_DLL */ - -/* - * The following part of the source file contains the code which might - * be called the "core" of the OS/2 backend support. This contains the - * OS/2 surface support functions and structures. - */ - -/* Forward declaration */ -static const cairo_surface_backend_t cairo_os2_surface_backend; - -/* Unpublished API: - * GpiEnableYInversion = PMGPI.723 - * GpiQueryYInversion = PMGPI.726 - * BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight); - * LONG APIENTRY GpiQueryYInversion (HPS hps); - */ -BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight); -LONG APIENTRY GpiQueryYInversion (HPS hps); - -#ifdef __WATCOMC__ -/* Function declaration for GpiDrawBits () (missing from OpenWatcom headers) */ -LONG APIENTRY GpiDrawBits (HPS hps, - PVOID pBits, - PBITMAPINFO2 pbmiInfoTable, - LONG lCount, - PPOINTL aptlPoints, - LONG lRop, - ULONG flOptions); -#endif - -static void -_cairo_os2_surface_blit_pixels (cairo_os2_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - POINTL aptlPoints[4]; - LONG lOldYInversion; - LONG rc = GPI_OK; - - /* Check the limits (may not be necessary) */ - if (prcl_begin_paint_rect->xLeft < 0) - prcl_begin_paint_rect->xLeft = 0; - if (prcl_begin_paint_rect->yBottom < 0) - prcl_begin_paint_rect->yBottom = 0; - if (prcl_begin_paint_rect->xRight > (LONG) surface->bitmap_info.cx) - prcl_begin_paint_rect->xRight = (LONG) surface->bitmap_info.cx; - if (prcl_begin_paint_rect->yTop > (LONG) surface->bitmap_info.cy) - prcl_begin_paint_rect->yTop = (LONG) surface->bitmap_info.cy; - - /* Exit if the rectangle is empty */ - if (prcl_begin_paint_rect->xLeft >= prcl_begin_paint_rect->xRight || - prcl_begin_paint_rect->yBottom >= prcl_begin_paint_rect->yTop) - return; - - /* Set the Target & Source coordinates */ - *((PRECTL)&aptlPoints[0]) = *prcl_begin_paint_rect; - *((PRECTL)&aptlPoints[2]) = *prcl_begin_paint_rect; - - /* Make the Target coordinates non-inclusive */ - aptlPoints[1].x -= 1; - aptlPoints[1].y -= 1; - - /* Enable Y Inversion for the HPS, so GpiDrawBits will - * work with upside-top image, not with upside-down image! - */ - lOldYInversion = GpiQueryYInversion (hps_begin_paint); - GpiEnableYInversion (hps_begin_paint, surface->bitmap_info.cy-1); - - /* Debug code to draw rectangle limits */ -#if 0 - { - int x, y; - unsigned char *pixels; - - pixels = surface->pixels; - for (x = 0; x < surface->bitmap_info.cx; x++) { - for (y = 0; y < surface->bitmap_info.cy; y++) { - if ((x == 0) || - (y == 0) || - (x == y) || - (x >= surface->bitmap_info.cx-1) || - (y >= surface->bitmap_info.cy-1)) - { - pixels[y*surface->bitmap_info.cx*4+x*4] = 255; - } - } - } - } -#endif - if (!surface->use_24bpp) { - rc = GpiDrawBits (hps_begin_paint, - surface->pixels, - &(surface->bitmap_info), - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - if (rc != GPI_OK) - surface->use_24bpp = TRUE; - } - - if (surface->use_24bpp) { - /* If GpiDrawBits () failed then this is most likely because the - * display driver could not handle a 32bit bitmap. So we need to - * - create a buffer that only contains 3 bytes per pixel - * - change the bitmap info header to contain 24bit - * - pass the new buffer to GpiDrawBits () again - * - clean up the new buffer - */ - BITMAPINFO2 bmpinfo; - unsigned char *pchPixBuf; - unsigned char *pchTarget; - ULONG *pulSource; - ULONG ulX; - ULONG ulY; - ULONG ulPad; - - /* Set up the bitmap header, but this time for 24bit depth. */ - bmpinfo = surface->bitmap_info; - bmpinfo.cBitCount = 24; - - /* The start of each row has to be DWORD aligned. Calculate the - * of number aligned bytes per row, the total size of the bitmap, - * and the number of padding bytes at the end of each row. - */ - ulX = (((bmpinfo.cx * bmpinfo.cBitCount) + 31) / 32) * 4; - bmpinfo.cbImage = ulX * bmpinfo.cy; - ulPad = ulX - bmpinfo.cx * 3; - - /* Allocate temporary pixel buffer. If the rows don't need - * padding, it has to be 1 byte larger than the size of the - * bitmap or else the high-order byte from the last source - * row will end up in unallocated memory. - */ - pchPixBuf = (unsigned char *)_buffer_alloc (1, 1, - bmpinfo.cbImage + (ulPad ? 0 : 1)); - - if (pchPixBuf) { - /* Copy 4 bytes from the source but advance the target ptr only - * 3 bytes, so the high-order alpha byte will be overwritten by - * the next copy. At the end of each row, skip over the padding. - */ - pchTarget = pchPixBuf; - pulSource = (ULONG*)surface->pixels; - for (ulY = bmpinfo.cy; ulY; ulY--) { - for (ulX = bmpinfo.cx; ulX; ulX--) { - *((ULONG*)pchTarget) = *pulSource++; - pchTarget += 3; - } - pchTarget += ulPad; - } - - rc = GpiDrawBits (hps_begin_paint, - pchPixBuf, - &bmpinfo, - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - if (rc != GPI_OK) - surface->use_24bpp = FALSE; - - _buffer_free (pchPixBuf); - } - } - - /* Restore Y inversion */ - GpiEnableYInversion (hps_begin_paint, lOldYInversion); -} - -static void -_cairo_os2_surface_get_pixels_from_screen (cairo_os2_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - HPS hps; - HDC hdc; - SIZEL sizlTemp; - HBITMAP hbmpTemp; - BITMAPINFO2 bmi2Temp; - POINTL aptlPoints[4]; - int y; - unsigned char *pchTemp; - - /* To copy pixels from screen to our buffer, we do the following steps: - * - * - Blit pixels from screen to a HBITMAP: - * -- Create Memory Device Context - * -- Create a PS into it - * -- Create a HBITMAP - * -- Select HBITMAP into memory PS - * -- Blit dirty pixels from screen to HBITMAP - * - Copy HBITMAP lines (pixels) into our buffer - * - Free resources - */ - - /* Create a memory device context */ - hdc = DevOpenDC (0, OD_MEMORY,"*",0L, NULL, NULLHANDLE); - if (!hdc) { - return; - } - - /* Create a memory PS */ - sizlTemp.cx = prcl_begin_paint_rect->xRight - prcl_begin_paint_rect->xLeft; - sizlTemp.cy = prcl_begin_paint_rect->yTop - prcl_begin_paint_rect->yBottom; - hps = GpiCreatePS (0, - hdc, - &sizlTemp, - PU_PELS | GPIT_NORMAL | GPIA_ASSOC); - if (!hps) { - DevCloseDC (hdc); - return; - } - - /* Create an uninitialized bitmap. */ - /* Prepare BITMAPINFO2 structure for our buffer */ - memset (&bmi2Temp, 0, sizeof (bmi2Temp)); - bmi2Temp.cbFix = sizeof (BITMAPINFOHEADER2); - bmi2Temp.cx = sizlTemp.cx; - bmi2Temp.cy = sizlTemp.cy; - bmi2Temp.cPlanes = 1; - bmi2Temp.cBitCount = 32; - - hbmpTemp = GpiCreateBitmap (hps, - (PBITMAPINFOHEADER2) &bmi2Temp, - 0, - NULL, - NULL); - - if (!hbmpTemp) { - GpiDestroyPS (hps); - DevCloseDC (hdc); - return; - } - - /* Select the bitmap into the memory device context. */ - GpiSetBitmap (hps, hbmpTemp); - - /* Target coordinates (Noninclusive) */ - aptlPoints[0].x = 0; - aptlPoints[0].y = 0; - - aptlPoints[1].x = sizlTemp.cx; - aptlPoints[1].y = sizlTemp.cy; - - /* Source coordinates (Inclusive) */ - aptlPoints[2].x = prcl_begin_paint_rect->xLeft; - aptlPoints[2].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; - - aptlPoints[3].x = prcl_begin_paint_rect->xRight; - aptlPoints[3].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yTop; - - /* Blit pixels from screen to bitmap */ - GpiBitBlt (hps, - hps_begin_paint, - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - - /* Now we have to extract the pixels from the bitmap. */ - pchTemp = - surface->pixels + - (prcl_begin_paint_rect->yBottom)*surface->bitmap_info.cx*4 + - prcl_begin_paint_rect->xLeft*4; - for (y = 0; y < sizlTemp.cy; y++) { - /* Get one line of pixels */ - GpiQueryBitmapBits (hps, - sizlTemp.cy - y - 1, /* lScanStart */ - 1, /* lScans */ - (PBYTE)pchTemp, - &bmi2Temp); - - /* Go for next line */ - pchTemp += surface->bitmap_info.cx*4; - } - - /* Clean up resources */ - GpiSetBitmap (hps, (HBITMAP) NULL); - GpiDeleteBitmap (hbmpTemp); - GpiDestroyPS (hps); - DevCloseDC (hdc); -} - -static cairo_status_t -_cairo_os2_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - /* Increase lend counter */ - surface->pixel_array_lend_count++; - - *image_out = surface->image_surface; - *image_extra = NULL; - - DosReleaseMutexSem (surface->hmtx_use_private_fields); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_os2_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - /* Decrease Lend counter! */ - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - if (surface->pixel_array_lend_count > 0) - surface->pixel_array_lend_count--; - DosPostEventSem (surface->hev_pixel_array_came_back); - - DosReleaseMutexSem (surface->hmtx_use_private_fields); -} - -static cairo_image_surface_t * -_cairo_os2_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - /* Increase lend counter */ - surface->pixel_array_lend_count++; - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - /* XXX: BROKEN! */ - *image_out = _cairo_surface_create_for_rectangle_int (surface->image_surface, - extents); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_os2_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - /* So, we got back the image, and if all goes well, then - * something has been changed inside the interest_rect. - * So, we blit it to the screen! - */ - if (surface->blit_as_changes) { - RECTL rclToBlit; - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (surface->hmtx_use_private_fields, - SEM_INDEFINITE_WAIT) != NO_ERROR) - { - /* Could not get mutex! */ - return; - } - - rclToBlit.xLeft = image->base.device_transform_inverse.x0; - rclToBlit.xRight = rclToBlit.xLeft + image->width; /* Noninclusive */ - rclToBlit.yTop = image->base.device_transform_inverse.y0; - rclToBlit.yBottom = rclToBlit.yTop + image->height; /* Noninclusive */ - - if (surface->hwnd_client_window) { - /* We know the HWND, so let's invalidate the window region, - * so the application will redraw itself, using the - * cairo_os2_surface_refresh_window () API from its own PM thread. - * - * This is the safe method, which should be preferred every time. - */ - rclToBlit.yTop = surface->bitmap_info.cy - rclToBlit.yTop; - rclToBlit.yBottom = surface->bitmap_info.cy - rclToBlit.yTop; - WinInvalidateRect (surface->hwnd_client_window, - &rclToBlit, - FALSE); - } else { - /* We don't know the HWND, so try to blit the pixels from here! - * Please note that it can be problematic if this is not the PM thread! - * - * It can cause internal PM stuffs to be screwed up, for some reason. - * Please always tell the HWND to the surface using the - * cairo_os2_surface_set_hwnd () API, and call cairo_os2_surface_refresh_window () - * from your WM_PAINT, if it's possible! - */ - _cairo_os2_surface_blit_pixels (surface, - surface->hps_client_window, - &rclToBlit); - } - - DosReleaseMutexSem (surface->hmtx_use_private_fields); - } - /* Also decrease Lend counter! */ - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - if (surface->pixel_array_lend_count > 0) - surface->pixel_array_lend_count--; - DosPostEventSem (surface->hev_pixel_array_came_back); - - DosReleaseMutexSem (surface->hmtx_use_private_fields); -} - -static cairo_bool_t -_cairo_os2_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->bitmap_info.cx; - rectangle->height = surface->bitmap_info.cy; - - return TRUE; -} - -/** - * cairo_os2_surface_create: - * @hps_client_window: the presentation handle to bind the surface to - * @width: the width of the surface - * @height: the height of the surface - * - * Create a Cairo surface which is bound to a given presentation space (HPS). - * The caller retains ownership of the HPS and must dispose of it after the - * the surface has been destroyed. The surface will be created to have the - * given size. By default every change to the surface will be made visible - * immediately by blitting it into the window. This can be changed with - * cairo_os2_surface_set_manual_window_refresh(). - * Note that the surface will contain garbage when created, so the pixels - * have to be initialized by hand first. You can use the Cairo functions to - * fill it with black, or use cairo_surface_mark_dirty() to fill the surface - * with pixels from the window/HPS. - * - * Return value: the newly created surface - * - * Since: 1.4 - **/ -cairo_surface_t * -cairo_os2_surface_create (HPS hps_client_window, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface = 0; - cairo_status_t status; - int rc; - - /* Check the size of the window */ - if ((width <= 0) || (height <= 0)) { - status = _cairo_error (CAIRO_STATUS_INVALID_SIZE); - goto error_exit; - } - - /* Allocate an OS/2 surface structure. */ - local_os2_surface = (cairo_os2_surface_t *) _cairo_malloc (sizeof (cairo_os2_surface_t)); - if (!local_os2_surface) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error_exit; - } - - memset(local_os2_surface, 0, sizeof(cairo_os2_surface_t)); - - /* Allocate resources: mutex & event semaphores and the pixel buffer */ - if (DosCreateMutexSem (NULL, - &(local_os2_surface->hmtx_use_private_fields), - 0, - FALSE)) - { - status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - goto error_exit; - } - - if (DosCreateEventSem (NULL, - &(local_os2_surface->hev_pixel_array_came_back), - 0, - FALSE)) - { - status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - goto error_exit; - } - - local_os2_surface->pixels = (unsigned char *) _buffer_alloc (height, width, 4); - if (!local_os2_surface->pixels) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error_exit; - } - - /* Create image surface from pixel array */ - local_os2_surface->image_surface = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (local_os2_surface->pixels, - CAIRO_FORMAT_ARGB32, - width, /* Width */ - height, /* Height */ - width * 4); /* Rowstride */ - status = local_os2_surface->image_surface->base.status; - if (status) - goto error_exit; - - /* Set values for OS/2-specific data that aren't zero/NULL/FALSE. - * Note: hps_client_window may be null if this was called by - * cairo_os2_surface_create_for_window(). - */ - local_os2_surface->hps_client_window = hps_client_window; - local_os2_surface->blit_as_changes = TRUE; - - /* Prepare BITMAPINFO2 structure for our buffer */ - local_os2_surface->bitmap_info.cbFix = sizeof (BITMAPINFOHEADER2); - local_os2_surface->bitmap_info.cx = width; - local_os2_surface->bitmap_info.cy = height; - local_os2_surface->bitmap_info.cPlanes = 1; - local_os2_surface->bitmap_info.cBitCount = 32; - - /* Initialize base surface */ - _cairo_surface_init (&local_os2_surface->base, - &cairo_os2_surface_backend, - NULL, /* device */ - _cairo_content_from_format (CAIRO_FORMAT_ARGB32), - FALSE); /* is_vector */ - - /* Successful exit */ - return (cairo_surface_t *)local_os2_surface; - - error_exit: - - /* This point will only be reached if an error occurred */ - - if (local_os2_surface) { - if (local_os2_surface->pixels) - _buffer_free (local_os2_surface->pixels); - if (local_os2_surface->hev_pixel_array_came_back) - DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); - if (local_os2_surface->hmtx_use_private_fields) - DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); - free (local_os2_surface); - } - - return _cairo_surface_create_in_error (status); -} - -/** - * cairo_os2_surface_create_for_window: - * @hwnd_client_window: the window handle to bind the surface to - * @width: the width of the surface - * @height: the height of the surface - * - * Create a Cairo surface which is bound to a given window; the caller retains - * ownership of the window. This is a convenience function for use with - * windows that will only be updated when cairo_os2_surface_refresh_window() - * is called (usually in response to a WM_PAINT message). It avoids the need - * to create a persistent HPS for every window and assumes that one will be - * supplied by the caller when a cairo function needs one. If it isn't, an - * HPS will be created on-the-fly and released before the function which needs - * it returns. - * - * Return value: the newly created surface - * - * Since: 1.10 - **/ -cairo_surface_t * -cairo_os2_surface_create_for_window (HWND hwnd_client_window, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface; - - /* A window handle must be provided. */ - if (!hwnd_client_window) { - return _cairo_surface_create_in_error ( - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - /* Create the surface. */ - local_os2_surface = (cairo_os2_surface_t *) - cairo_os2_surface_create (0, width, height); - - /* If successful, save the hwnd & turn off automatic repainting. */ - if (!local_os2_surface->image_surface->base.status) { - local_os2_surface->hwnd_client_window = hwnd_client_window; - local_os2_surface->blit_as_changes = FALSE; - } - - return (cairo_surface_t *)local_os2_surface; -} - -/** - * cairo_os2_surface_set_size: - * @surface: the cairo surface to resize - * @new_width: the new width of the surface - * @new_height: the new height of the surface - * @timeout: timeout value in milliseconds - * - * When the client window is resized, call this API to set the new size in the - * underlying surface accordingly. This function will reallocate everything, - * so you'll have to redraw everything in the surface after this call. - * The surface will contain garbage after the resizing. So the notes of - * cairo_os2_surface_create() apply here, too. - * - * The timeout value specifies how long the function should wait on other parts - * of the program to release the buffers. It is necessary, because it can happen - * that Cairo is just drawing something into the surface while we want to - * destroy and recreate it. - * - * Return value: %CAIRO_STATUS_SUCCESS if the surface could be resized, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * %CAIRO_STATUS_INVALID_SIZE for invalid sizes - * %CAIRO_STATUS_NO_MEMORY if the new size could not be allocated, or if the - * timeout happened before all the buffers were released - * - * Since: 1.4 - **/ -int -cairo_os2_surface_set_size (cairo_surface_t *surface, - int new_width, - int new_height, - int timeout) -{ - cairo_os2_surface_t *local_os2_surface; - unsigned char *pchNewPixels; - int rc; - cairo_image_surface_t *pNewImageSurface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - if ((new_width <= 0) || - (new_height <= 0)) - { - /* Invalid size! */ - return _cairo_error (CAIRO_STATUS_INVALID_SIZE); - } - - /* Allocate memory for new stuffs */ - pchNewPixels = (unsigned char *) _buffer_alloc (new_height, new_width, 4); - if (!pchNewPixels) { - /* Not enough memory for the pixels! - * Everything remains the same! - */ - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Create image surface from new pixel array */ - pNewImageSurface = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (pchNewPixels, - CAIRO_FORMAT_ARGB32, - new_width, /* Width */ - new_height, /* Height */ - new_width * 4); /* Rowstride */ - - if (pNewImageSurface->base.status) { - /* Could not create image surface! - * Everything remains the same! - */ - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Okay, new memory allocated, so it's time to swap old buffers - * to new ones! - */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT)!=NO_ERROR) { - /* Could not get mutex! - * Everything remains the same! - */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* We have to make sure that we won't destroy a surface which - * is lent to some other code (Cairo is drawing into it)! - */ - while (local_os2_surface->pixel_array_lend_count > 0) { - ULONG ulPostCount; - DosResetEventSem (local_os2_surface->hev_pixel_array_came_back, &ulPostCount); - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - /* Wait for somebody to return the pixels! */ - rc = DosWaitEventSem (local_os2_surface->hev_pixel_array_came_back, timeout); - if (rc != NO_ERROR) { - /* Either timeout or something wrong... Exit. */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - /* Okay, grab mutex and check counter again! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! - * Everything remains the same! - */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - /* Destroy old image surface */ - cairo_surface_destroy ((cairo_surface_t *) (local_os2_surface->image_surface)); - /* Destroy old pixel buffer */ - _buffer_free (local_os2_surface->pixels); - /* Set new image surface */ - local_os2_surface->image_surface = pNewImageSurface; - /* Set new pixel buffer */ - local_os2_surface->pixels = pchNewPixels; - /* Change bitmap2 structure */ - local_os2_surface->bitmap_info.cx = new_width; - local_os2_surface->bitmap_info.cy = new_height; - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_refresh_window: - * @surface: the cairo surface to refresh - * @hps_begin_paint: the presentation handle of the window to refresh - * @prcl_begin_paint_rect: the rectangle to redraw - * - * This function can be used to force a repaint of a given area of the client - * window. It should usually be called from the WM_PAINT processing of the - * window procedure. However, it can be called any time a given part of the - * window has to be updated. - * - * The HPS and RECTL to be passed can be taken from the usual WinBeginPaint call - * of the window procedure, but you can also get the HPS using WinGetPS, and you - * can assemble your own update rectangle by hand. - * If hps_begin_paint is %NULL, the function will use the HPS passed into - * cairo_os2_surface_create(). If @prcl_begin_paint_rect is %NULL, the function - * will query the current window size and repaint the whole window. - * - * Cairo assumes that if you set the HWND to the surface using - * cairo_os2_surface_set_hwnd(), this function will be called by the application - * every time it gets a WM_PAINT for that HWND. If the HWND is set in the - * surface, Cairo uses this function to handle dirty areas too. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_refresh_window (cairo_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - cairo_os2_surface_t *local_os2_surface; - RECTL rclTemp; - HPS hpsTemp = 0; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - /* If an HPS wasn't provided, see if we can get one. */ - if (!hps_begin_paint) { - hps_begin_paint = local_os2_surface->hps_client_window; - if (!hps_begin_paint) { - if (local_os2_surface->hwnd_client_window) { - hpsTemp = WinGetPS(local_os2_surface->hwnd_client_window); - hps_begin_paint = hpsTemp; - } - /* No HPS & no way to get one, so exit */ - if (!hps_begin_paint) - return; - } - } - - if (prcl_begin_paint_rect == NULL) { - /* Update the whole window! */ - rclTemp.xLeft = 0; - rclTemp.xRight = local_os2_surface->bitmap_info.cx; - rclTemp.yTop = local_os2_surface->bitmap_info.cy; - rclTemp.yBottom = 0; - } else { - /* Use the rectangle we got passed as parameter! */ - rclTemp.xLeft = prcl_begin_paint_rect->xLeft; - rclTemp.xRight = prcl_begin_paint_rect->xRight; - rclTemp.yTop = local_os2_surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; - rclTemp.yBottom = local_os2_surface->bitmap_info.cy - prcl_begin_paint_rect->yTop ; - } - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - if (hpsTemp) - WinReleasePS(hpsTemp); - return; - } - - if ((local_os2_surface->dirty_area_present) && - (local_os2_surface->rcl_dirty_area.xLeft == rclTemp.xLeft) && - (local_os2_surface->rcl_dirty_area.xRight == rclTemp.xRight) && - (local_os2_surface->rcl_dirty_area.yTop == rclTemp.yTop) && - (local_os2_surface->rcl_dirty_area.yBottom == rclTemp.yBottom)) - { - /* Aha, this call was because of a dirty area, so in this case we - * have to blit the pixels from the screen to the surface! - */ - local_os2_surface->dirty_area_present = FALSE; - _cairo_os2_surface_get_pixels_from_screen (local_os2_surface, - hps_begin_paint, - &rclTemp); - } else { - /* Okay, we have the surface, have the HPS - * (might be from WinBeginPaint () or from WinGetPS () ) - * Now blit there the stuffs! - */ - _cairo_os2_surface_blit_pixels (local_os2_surface, - hps_begin_paint, - &rclTemp); - } - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - if (hpsTemp) - WinReleasePS(hpsTemp); -} - -static cairo_status_t -_cairo_os2_surface_finish (void *abstract_surface) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) abstract_surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - /* Destroy old image surface */ - cairo_surface_destroy ((cairo_surface_t *) (local_os2_surface->image_surface)); - /* Destroy old pixel buffer */ - _buffer_free (local_os2_surface->pixels); - DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); - DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); - - /* The memory itself will be free'd by the cairo_surface_destroy () - * who called us. - */ - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_set_hwnd: - * @surface: the cairo surface to associate with the window handle - * @hwnd_client_window: the window handle of the client window - * - * Sets window handle for surface; the caller retains ownership of the window. - * If Cairo wants to blit into the window because it is set to blit as the - * surface changes (see cairo_os2_surface_set_manual_window_refresh()), then - * there are two ways it can choose: - * If it knows the HWND of the surface, then it invalidates that area, so the - * application will get a WM_PAINT message and it can call - * cairo_os2_surface_refresh_window() to redraw that area. Otherwise cairo itself - * will use the HPS it got at surface creation time, and blit the pixels itself. - * It's also a solution, but experience shows that if this happens from a non-PM - * thread, then it can screw up PM internals. - * - * So, best solution is to set the HWND for the surface after the surface - * creation, so every blit will be done from application's message processing - * loop, which is the safest way to do. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_set_hwnd (cairo_surface_t *surface, - HWND hwnd_client_window) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - return; - } - - local_os2_surface->hwnd_client_window = hwnd_client_window; - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); -} - -/** - * cairo_os2_surface_set_manual_window_refresh: - * @surface: the cairo surface to set the refresh mode for - * @manual_refresh: the switch for manual surface refresh - * - * This API can tell Cairo if it should show every change to this surface - * immediately in the window or if it should be cached and will only be visible - * once the user calls cairo_os2_surface_refresh_window() explicitly. If the - * HWND was not set in the cairo surface, then the HPS will be used to blit the - * graphics. Otherwise it will invalidate the given window region so the user - * will get the WM_PAINT message to redraw that area of the window. - * - * So, if you're only interested in displaying the final result after several - * drawing operations, you might get better performance if you put the surface - * into manual refresh mode by passing a true value to this function. Then call - * cairo_os2_surface_refresh() whenever desired. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface, - cairo_bool_t manual_refresh) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - local_os2_surface->blit_as_changes = !manual_refresh; -} - -/** - * cairo_os2_surface_get_manual_window_refresh: - * @surface: the cairo surface to query the refresh mode from - * - * This space left intentionally blank. - * - * Return value: current refresh mode of the surface (true by default) - * - * Since: 1.4 - **/ -cairo_bool_t -cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return FALSE; - } - - return !(local_os2_surface->blit_as_changes); -} - -/** - * cairo_os2_surface_get_hps: - * @surface: the cairo surface to be querued - * @hps: HPS currently associated with the surface (if any) - * - * This API retrieves the HPS associated with the surface. - * - * Return value: %CAIRO_STATUS_SUCCESS if the hps could be retrieved, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * %CAIRO_STATUS_NULL_POINTER if the hps argument is null - * - * Since: 1.10 - **/ -cairo_status_t -cairo_os2_surface_get_hps (cairo_surface_t *surface, - HPS *hps) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - if (!hps) - { - return _cairo_error (CAIRO_STATUS_NULL_POINTER); - } - *hps = local_os2_surface->hps_client_window; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_set_hps: - * @surface: the cairo surface to associate with the HPS - * @hps: new HPS to be associated with the surface (the HPS may be null) - * - * This API replaces the HPS associated with the surface with a new one. - * The caller retains ownership of the HPS and must dispose of it after - * the surface has been destroyed or it has been replaced by another - * call to this function. - * - * Return value: %CAIRO_STATUS_SUCCESS if the hps could be replaced, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * - * Since: 1.10 - **/ -cairo_status_t -cairo_os2_surface_set_hps (cairo_surface_t *surface, - HPS hps) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - local_os2_surface->hps_client_window = hps; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_os2_surface_mark_dirty_rectangle (void *surface, - int x, - int y, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface; - RECTL rclToBlit; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - return CAIRO_STATUS_NO_MEMORY; - } - - /* Check for defaults */ - if (width < 0) - width = local_os2_surface->bitmap_info.cx; - if (height < 0) - height = local_os2_surface->bitmap_info.cy; - - if (local_os2_surface->hwnd_client_window) { - /* We know the HWND, so let's invalidate the window region, - * so the application will redraw itself, using the - * cairo_os2_surface_refresh_window () API from its own PM thread. - * From that function we'll note that it's not a redraw but a - * dirty-rectangle deal stuff, so we'll handle the things from - * there. - * - * This is the safe method, which should be preferred every time. - */ - rclToBlit.xLeft = x; - rclToBlit.xRight = x + width; /* Noninclusive */ - rclToBlit.yTop = local_os2_surface->bitmap_info.cy - (y); - rclToBlit.yBottom = local_os2_surface->bitmap_info.cy - (y + height); /* Noninclusive */ - -#if 0 - if (local_os2_surface->dirty_area_present) { - /* Yikes, there is already a dirty area which should be - * cleaned up, but we'll overwrite it. Sorry. - * TODO: Something clever should be done here. - */ - } -#endif - - /* Set up dirty area reminder stuff */ - memcpy (&(local_os2_surface->rcl_dirty_area), &rclToBlit, sizeof (RECTL)); - local_os2_surface->dirty_area_present = TRUE; - - /* Invalidate window area */ - WinInvalidateRect (local_os2_surface->hwnd_client_window, - &rclToBlit, - FALSE); - } else { - /* We don't know the HWND, so try to blit the pixels from here! - * Please note that it can be problematic if this is not the PM thread! - * - * It can cause internal PM stuffs to be scewed up, for some reason. - * Please always tell the HWND to the surface using the - * cairo_os2_surface_set_hwnd () API, and call cairo_os2_surface_refresh_window () - * from your WM_PAINT, if it's possible! - */ - - rclToBlit.xLeft = x; - rclToBlit.xRight = x + width; /* Noninclusive */ - rclToBlit.yBottom = y; - rclToBlit.yTop = y + height; /* Noninclusive */ - /* Now get the pixels from the screen! */ - _cairo_os2_surface_get_pixels_from_screen (local_os2_surface, - local_os2_surface->hps_client_window, - &rclToBlit); - } - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_os2_surface_backend = { - CAIRO_SURFACE_TYPE_OS2, - _cairo_os2_surface_finish, - _cairo_default_context_create, - - NULL, /* create_similar */ - NULL, /* create_similar_image */ - _cairo_os2_surface_map_to_image, - _cairo_os2_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_os2_surface_acquire_source_image, - _cairo_os2_surface_release_source_image, - NULL, /* snapshot */ - - _cairo_os2_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - _cairo_os2_surface_mark_dirty_rectangle, - - _cairo_surface_fallback_paint, - _cairo_surface_fallback_mask, - _cairo_surface_fallback_fill, - _cairo_surface_fallback_stroke, - NULL, /* fill/stroke */ - _cairo_surface_fallback_glyphs, -}; diff --git a/src/cairo-os2.h b/src/cairo-os2.h deleted file mode 100644 index d23f2dec4..000000000 --- a/src/cairo-os2.h +++ /dev/null @@ -1,110 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - * Rich Walsh <dragtext@e-vertise.com> - */ - -#ifndef _CAIRO_OS2_H_ -#define _CAIRO_OS2_H_ - -#define INCL_DOS -#define INCL_DOSSEMAPHORES -#define INCL_DOSERRORS -#define INCL_WIN -#define INCL_GPI - -#include "cairo.h" - -#include <os2.h> - -CAIRO_BEGIN_DECLS - -/* The OS/2 Specific Cairo API */ - -cairo_public void -cairo_os2_init (void); - -cairo_public void -cairo_os2_fini (void); - -#if CAIRO_HAS_OS2_SURFACE - -cairo_public cairo_surface_t * -cairo_os2_surface_create (HPS hps_client_window, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_os2_surface_create_for_window (HWND hwnd_client_window, - int width, - int height); - -cairo_public void -cairo_os2_surface_set_hwnd (cairo_surface_t *surface, - HWND hwnd_client_window); - -cairo_public int -cairo_os2_surface_set_size (cairo_surface_t *surface, - int new_width, - int new_height, - int timeout); - -cairo_public void -cairo_os2_surface_refresh_window (cairo_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect); - -cairo_public void -cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface, - cairo_bool_t manual_refresh); - -cairo_public cairo_bool_t -cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface); - -cairo_public cairo_status_t -cairo_os2_surface_get_hps (cairo_surface_t *surface, - HPS *hps); - -cairo_public cairo_status_t -cairo_os2_surface_set_hps (cairo_surface_t *surface, - HPS hps); - -#else /* CAIRO_HAS_OS2_SURFACE */ -# error Cairo was not compiled with support for the OS/2 backend -#endif /* CAIRO_HAS_OS2_SURFACE */ - -CAIRO_END_DECLS - -#endif /* _CAIRO_OS2_H_ */ diff --git a/src/cairo-time.c b/src/cairo-time.c index a0003fbfc..c93205908 100644 --- a/src/cairo-time.c +++ b/src/cairo-time.c @@ -61,34 +61,6 @@ _cairo_time_get (void) return mach_absolute_time (); } -#elif defined(__OS2__) -#define INCL_BASE -#include <os2.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - ULONG freq; - - DosTmrQueryFreq (&freq); - - return freq; -} - -cairo_time_t -_cairo_time_get (void) -{ - QWORD t; - cairo_int64_t r; - - DosTmrQueryTime (&t); - - r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.ulHi), 32); - r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.ulLo)); - - return r; -} - #elif _WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/test/api-special-cases.c b/test/api-special-cases.c index ae87d0e5d..ce54200b7 100644 --- a/test/api-special-cases.c +++ b/test/api-special-cases.c @@ -66,9 +66,6 @@ #if CAIRO_HAS_GL_SURFACE #include <cairo-gl.h> #endif -#if CAIRO_HAS_OS2_SURFACE -#include <cairo-os2.h> -#endif #if CAIRO_HAS_PDF_SURFACE #include <cairo-pdf.h> #endif diff --git a/test/error-setters.c b/test/error-setters.c index 8ad823def..c69a6d89b 100644 --- a/test/error-setters.c +++ b/test/error-setters.c @@ -32,9 +32,6 @@ #if CAIRO_HAS_GL_SURFACE #include <cairo-gl.h> #endif -#if CAIRO_HAS_OS2_SURFACE -#include <cairo-os2.h> -#endif #if CAIRO_HAS_PDF_SURFACE #include <cairo-pdf.h> #endif @@ -61,12 +58,6 @@ preamble (cairo_test_context_t *ctx) cairo_gl_surface_swapbuffers (surface); #endif -#if CAIRO_HAS_OS2_SURFACE - cairo_os2_surface_set_hwnd (surface, 0); - cairo_os2_surface_set_size (surface, 0, 0, 0); - cairo_os2_surface_set_manual_window_refresh (surface, FALSE); -#endif - #if CAIRO_HAS_PDF_SURFACE cairo_pdf_surface_restrict_to_version (surface, CAIRO_PDF_VERSION_1_4); cairo_pdf_surface_set_size (surface, 0, 0); |