diff options
author | Keith Packard <keithp@keithp.com> | 2004-09-15 20:43:17 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2004-09-15 20:43:17 +0000 |
commit | 266f94cdcc59dee4a6b15dc7ca75a591096651f6 (patch) | |
tree | 6b56278bc464e5309d487dbd99191f83d3a52c7a |
Initial revision
-rw-r--r-- | AUTHORS | 0 | ||||
-rw-r--r-- | COPYING | 19 | ||||
-rw-r--r-- | ChangeLog | 0 | ||||
-rw-r--r-- | INSTALL | 229 | ||||
-rw-r--r-- | Makefile.am | 27 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rw-r--r-- | README | 0 | ||||
-rw-r--r-- | architecture | 54 | ||||
-rwxr-xr-x | autogen.sh | 3 | ||||
-rw-r--r-- | configure.ac | 56 | ||||
-rw-r--r-- | twin.h | 244 | ||||
-rw-r--r-- | twin.pc.in | 10 | ||||
-rw-r--r-- | twin_draw.c | 408 | ||||
-rw-r--r-- | twin_pixmap.c | 118 | ||||
-rw-r--r-- | twin_primitive.c | 230 | ||||
-rw-r--r-- | twin_screen.c | 148 | ||||
-rw-r--r-- | twin_x11.c | 116 | ||||
-rw-r--r-- | twinint.h | 213 | ||||
-rw-r--r-- | xtwin.c | 79 |
19 files changed, 1954 insertions, 0 deletions
@@ -0,0 +1,19 @@ +Copyright © 2004 Keith Packard + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of Keith Packard not be used in +advertising or publicity pertaining to distribution of the software without +specific, written prior permission. Keith Packard makes no +representations about the suitability of this software for any purpose. It +is provided "as is" without express or implied warranty. + +KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,229 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a673b9e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,27 @@ +CFLAGS=-g +INCLUDES= @X_CFLAGS@ @WARN_CFLAGS@ + +#libtwin_la_SOURCES = \ +# twin.h \ +# twin_draw.c \ +# twin_pixmap.c \ +# twin_primitive.c \ +# twin_screen.c \ +# twin_x11.c \ +# twinint.h +# +#lib_LTLIBRARIES = libtwin.la + +bin_PROGRAMS = xtwin + +xtwin_SOURCES = \ + twin.h \ + twin_draw.c \ + twin_pixmap.c \ + twin_primitive.c \ + twin_screen.c \ + twin_x11.c \ + twinint.h \ + xtwin.c + +xtwin_LDADD = @X_LIBS@ diff --git a/architecture b/architecture new file mode 100644 index 0000000..dd095fd --- /dev/null +++ b/architecture @@ -0,0 +1,54 @@ + TWIN: a tiny window system + 2004/8/23 + Keith Packard + HP Cambridge Research Laboratory + +1. Introduction + +twin is a window system designed for devices with constrained memory, CPU +and display space. + +2. Pixel formats + +twin supports a limited set of pixel formats; additional formats introduce +significant cost into the system. + + Name Bits Content + A8 8 8-bit A + RGB16 16 5-6-5 RGB + ARGB32 32 8-8-8-8 ARGB + +3. Objects + +twin unifies onscreen and offscreen data in a single 'pixmap' object. The +screen is constructed from a list of pixmaps composited together to form the +final image. Pixmaps contain position, width height and stride +information and stacking information. A pixmap is "on screen" if it is +included in the list of on-screen pixmaps. + +4. Operators + +twin is architected with an abstract single operator that performs all of +the basic pixel manipulation. That operator is: + + dest = source IN mask OP dest + +IN is the Porter/Duff operator of the same name, OP is either OVER or +SOURCE. If necessary, OP may be extended in the future to cover additional +Porter/Duff operators. + +In the above operator, Source and mask may be replaced with constant values, +mask may be elided (in which case it is implicitly replaced with a constant +opaque pixel). + +5. Screen Generation + +The screen image is generated by compositing the list of displayed pixmaps. +Displayed pixmaps may be in any format which contains RGB data. Underneath +all of the windows the screen is white. + +6. Geometric figures + +Geometry can be displayed by computing an appropriate A8 pixmap and +compositing the result to a pixmap. + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..b1376df --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install || exit 1 +./configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..21268c7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,56 @@ +dnl +dnl $Id$ +dnl +dnl Copyright © 2003 Keith Packard, Noah Levitt +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation, and that the name of Keith Packard not be used in +dnl advertising or publicity pertaining to distribution of the software without +dnl specific, written prior permission. Keith Packard makes no +dnl representations about the suitability of this software for any purpose. It +dnl is provided "as is" without express or implied warranty. +dnl +dnl KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +dnl EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR +dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +dnl PERFORMANCE OF THIS SOFTWARE. +dnl +dnl Process this file with autoconf to create configure. + +AC_PREREQ([2.57]) + +AC_INIT(libtwin, 0.0.0, [keithp@keithp.com], libtwin) +AM_INIT_AUTOMAKE() +AM_MAINTAINER_MODE + +AM_CONFIG_HEADER(config.h) +AC_CONFIG_AUX_DIR(.) + +# Check for progs +AC_PROG_CC +AC_PROG_LIBTOOL + +WARN_CFLAGS="" + +if test "x$GCC" = "xyes"; then + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs -fno-strict-aliasing" +fi +AC_SUBST(WARN_CFLAGS) + +# Check for X +PKG_CHECK_MODULES(X, x11, + [x_found_with_pkgconfig=yes], + [x_found_with_pkgconfig=no]) +AC_SUBST(X_CFLAGS) +AC_SUBST(X_LIBS) + +AC_OUTPUT([Makefile + twin.pc]) @@ -0,0 +1,244 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _TWIN_H_ +#define _TWIN_H_ + +#include <stdlib.h> +#include <stdint.h> + +typedef uint8_t twin_a8_t; +typedef uint16_t twin_rgb16_t; +typedef uint32_t twin_argb32_t; +typedef int twin_bool; + +#define TWIN_FALSE 0 +#define TWIN_TRUE 1 + +typedef enum { TWIN_A8, TWIN_RGB16, TWIN_ARGB32 } twin_format_t; + +#define twin_bytes_per_pixel(format) (1 << (int) (format)) + +/* + * A rectangle + */ +typedef struct _twin_rect { + int left, right, top, bottom; +} twin_rect_t; + +typedef union _twin_pointer { + void *v; + uint8_t *b; + twin_a8_t *a8; + twin_rgb16_t *rgb16; + twin_argb32_t *argb32; +} twin_pointer_t; + +/* + * A rectangular array of pixels + */ +typedef struct _twin_pixmap { + /* + * Screen showing these pixels + */ + struct _twin_screen *screen; + /* + * List of displayed pixmaps + */ + struct _twin_pixmap *higher; + /* + * Screen position + */ + int x, y; + /* + * Pixmap layout + */ + twin_format_t format; + int width; /* pixels */ + int height; /* pixels */ + int stride; /* bytes */ + /* + * Pixels + */ + twin_pointer_t p; +} twin_pixmap_t; + +/* + * A function that paints pixels to the screen + */ +typedef void (*twin_put_span_t) (int x, + int y, + int width, + twin_argb32_t *pixels, + void *closure); + +/* + * A screen + */ +typedef struct _twin_screen { + /* + * List of displayed pixmaps + */ + twin_pixmap_t *bottom; + /* + * Output size + */ + int width, height; + /* + * Damage + */ + twin_rect_t damage; + /* + * Repaint function + */ + twin_put_span_t put_span; + void *closure; +} twin_screen_t; + +/* + * A source operand + */ + +typedef enum { TWIN_SOLID, TWIN_PIXMAP } twin_source_t; + +typedef struct _twin_operand { + twin_source_t source_kind; + union { + twin_pixmap_t *pixmap; + twin_argb32_t argb; + } u; +} twin_operand_t; + +typedef enum { TWIN_OVER, TWIN_SOURCE } twin_operator_t; + +/* + * twin_draw.c + */ + +void +twin_composite (twin_pixmap_t *dst, + int dst_x, + int dst_y, + twin_operand_t *src, + int src_x, + int src_y, + twin_operand_t *msk, + int msk_x, + int msk_y, + twin_operator_t operator, + int width, + int height); + +void +twin_fill (twin_pixmap_t *dst, + twin_argb32_t pixel, + twin_operator_t operator, + int x, + int y, + int width, + int height); + +/* + * twin_pixmap.c + */ + +twin_pixmap_t * +twin_pixmap_create (twin_format_t format, int width, int height); + +void +twin_pixmap_destroy (twin_pixmap_t *pixmap); + +void +twin_pixmap_show (twin_pixmap_t *pixmap, + twin_screen_t *screen, + twin_pixmap_t *higher); + +void +twin_pixmap_hide (twin_pixmap_t *pixmap); + +void +twin_pixmap_damage (twin_pixmap_t *pixmap, + int x1, int y1, int x2, int y2); + +void +twin_pixmap_move (twin_pixmap_t *pixmap, int x, int y); + +twin_pointer_t +twin_pixmap_pointer (twin_pixmap_t *pixmap, int x, int y); + +/* + * twin_screen.c + */ + +twin_screen_t * +twin_screen_create (int width, + int height, + twin_put_span_t put_span, + void *closure); + +void +twin_screen_destroy (twin_screen_t *screen); + +void +twin_screen_damage (twin_screen_t *screen, + int x1, int y1, int x2, int y2); + +void +twin_screen_resize (twin_screen_t *screen, int width, int height); + +twin_bool +twin_screen_damaged (twin_screen_t *screen); + +void +twin_screen_update (twin_screen_t *screen); + +/* twin_x11.c */ + +#include <X11/Xlib.h> + +typedef struct _twin_x11 { + twin_screen_t *screen; + Display *dpy; + Window win; + GC gc; + Visual *visual; + int depth; +} twin_x11_t; + +twin_x11_t * +twin_x11_create (Display *dpy, int width, int height); + +void +twin_x11_destroy (twin_x11_t *tx); + +void +twin_x11_damage (twin_x11_t *tx, XExposeEvent *ev); + +void +twin_x11_configure (twin_x11_t *tx, XConfigureEvent *ev); + +void +twin_x11_update (twin_x11_t *tx); + +#endif /* _TWIN_H_ */ diff --git a/twin.pc.in b/twin.pc.in new file mode 100644 index 0000000..93678ff --- /dev/null +++ b/twin.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: twin +Description: Twin window system library +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} @X_CFLAGS@ +Libs: -L${libdir} -ltwin @X_LIBS@ diff --git a/twin_draw.c b/twin_draw.c new file mode 100644 index 0000000..b7c7a1f --- /dev/null +++ b/twin_draw.c @@ -0,0 +1,408 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twinint.h" + +/* op, src, dst */ +static twin_src_op comp2[2][4][3] = { + { /* OVER */ + { /* A8 */ + _twin_a8_over_a8, + _twin_a8_over_rgb16, + _twin_a8_over_argb32, + }, + { /* RGB16 */ + _twin_rgb16_over_a8, + _twin_rgb16_over_rgb16, + _twin_rgb16_over_argb32, + }, + { /* ARGB32 */ + _twin_argb32_over_a8, + _twin_argb32_over_rgb16, + _twin_argb32_over_argb32, + }, + { /* C */ + _twin_c_over_a8, + _twin_c_over_rgb16, + _twin_c_over_argb32, + } + }, + { /* SOURCE */ + { /* A8 */ + _twin_a8_source_a8, + _twin_a8_source_rgb16, + _twin_a8_source_argb32, + }, + { /* RGB16 */ + _twin_rgb16_source_a8, + _twin_rgb16_source_rgb16, + _twin_rgb16_source_argb32, + }, + { /* ARGB32 */ + _twin_argb32_source_a8, + _twin_argb32_source_rgb16, + _twin_argb32_source_argb32, + }, + { /* C */ + _twin_c_source_a8, + _twin_c_source_rgb16, + _twin_c_source_argb32, + } + } +}; + +/* op, src, msk, dst */ +static twin_src_msk_op comp3[2][4][4][3] = { + { /* OVER */ + { /* A8 */ + { /* A8 */ + _twin_a8_in_a8_over_a8, + _twin_a8_in_a8_over_rgb16, + _twin_a8_in_a8_over_argb32, + }, + { /* RGB16 */ + _twin_a8_in_rgb16_over_a8, + _twin_a8_in_rgb16_over_rgb16, + _twin_a8_in_rgb16_over_argb32, + }, + { /* ARGB32 */ + _twin_a8_in_argb32_over_a8, + _twin_a8_in_argb32_over_rgb16, + _twin_a8_in_argb32_over_argb32, + }, + { /* C */ + _twin_a8_in_c_over_a8, + _twin_a8_in_c_over_rgb16, + _twin_a8_in_c_over_argb32, + }, + }, + { /* RGB16 */ + { /* A8 */ + _twin_rgb16_in_a8_over_a8, + _twin_rgb16_in_a8_over_rgb16, + _twin_rgb16_in_a8_over_argb32, + }, + { /* RGB16 */ + _twin_rgb16_in_rgb16_over_a8, + _twin_rgb16_in_rgb16_over_rgb16, + _twin_rgb16_in_rgb16_over_argb32, + }, + { /* ARGB32 */ + _twin_rgb16_in_argb32_over_a8, + _twin_rgb16_in_argb32_over_rgb16, + _twin_rgb16_in_argb32_over_argb32, + }, + { /* C */ + _twin_rgb16_in_c_over_a8, + _twin_rgb16_in_c_over_rgb16, + _twin_rgb16_in_c_over_argb32, + }, + }, + { /* ARGB32 */ + { /* A8 */ + _twin_argb32_in_a8_over_a8, + _twin_argb32_in_a8_over_rgb16, + _twin_argb32_in_a8_over_argb32, + }, + { /* RGB16 */ + _twin_argb32_in_rgb16_over_a8, + _twin_argb32_in_rgb16_over_rgb16, + _twin_argb32_in_rgb16_over_argb32, + }, + { /* ARGB32 */ + _twin_argb32_in_argb32_over_a8, + _twin_argb32_in_argb32_over_rgb16, + _twin_argb32_in_argb32_over_argb32, + }, + { /* C */ + _twin_argb32_in_c_over_a8, + _twin_argb32_in_c_over_rgb16, + _twin_argb32_in_c_over_argb32, + }, + }, + { /* C */ + { /* A8 */ + _twin_c_in_a8_over_a8, + _twin_c_in_a8_over_rgb16, + _twin_c_in_a8_over_argb32, + }, + { /* RGB16 */ + _twin_c_in_rgb16_over_a8, + _twin_c_in_rgb16_over_rgb16, + _twin_c_in_rgb16_over_argb32, + }, + { /* ARGB32 */ + _twin_c_in_argb32_over_a8, + _twin_c_in_argb32_over_rgb16, + _twin_c_in_argb32_over_argb32, + }, + { /* C */ + _twin_c_in_c_over_a8, + _twin_c_in_c_over_rgb16, + _twin_c_in_c_over_argb32, + }, + }, + }, + { /* SOURCE */ + { /* A8 */ + { /* A8 */ + _twin_a8_in_a8_source_a8, + _twin_a8_in_a8_source_rgb16, + _twin_a8_in_a8_source_argb32, + }, + { /* RGB16 */ + _twin_a8_in_rgb16_source_a8, + _twin_a8_in_rgb16_source_rgb16, + _twin_a8_in_rgb16_source_argb32, + }, + { /* ARGB32 */ + _twin_a8_in_argb32_source_a8, + _twin_a8_in_argb32_source_rgb16, + _twin_a8_in_argb32_source_argb32, + }, + { /* C */ + _twin_a8_in_c_source_a8, + _twin_a8_in_c_source_rgb16, + _twin_a8_in_c_source_argb32, + }, + }, + { /* RGB16 */ + { /* A8 */ + _twin_rgb16_in_a8_source_a8, + _twin_rgb16_in_a8_source_rgb16, + _twin_rgb16_in_a8_source_argb32, + }, + { /* RGB16 */ + _twin_rgb16_in_rgb16_source_a8, + _twin_rgb16_in_rgb16_source_rgb16, + _twin_rgb16_in_rgb16_source_argb32, + }, + { /* ARGB32 */ + _twin_rgb16_in_argb32_source_a8, + _twin_rgb16_in_argb32_source_rgb16, + _twin_rgb16_in_argb32_source_argb32, + }, + { /* C */ + _twin_rgb16_in_c_source_a8, + _twin_rgb16_in_c_source_rgb16, + _twin_rgb16_in_c_source_argb32, + }, + }, + { /* ARGB32 */ + { /* A8 */ + _twin_argb32_in_a8_source_a8, + _twin_argb32_in_a8_source_rgb16, + _twin_argb32_in_a8_source_argb32, + }, + { /* RGB16 */ + _twin_argb32_in_rgb16_source_a8, + _twin_argb32_in_rgb16_source_rgb16, + _twin_argb32_in_rgb16_source_argb32, + }, + { /* ARGB32 */ + _twin_argb32_in_argb32_source_a8, + _twin_argb32_in_argb32_source_rgb16, + _twin_argb32_in_argb32_source_argb32, + }, + { /* C */ + _twin_argb32_in_c_source_a8, + _twin_argb32_in_c_source_rgb16, + _twin_argb32_in_c_source_argb32, + }, + }, + { /* C */ + { /* A8 */ + _twin_c_in_a8_source_a8, + _twin_c_in_a8_source_rgb16, + _twin_c_in_a8_source_argb32, + }, + { /* RGB16 */ + _twin_c_in_rgb16_source_a8, + _twin_c_in_rgb16_source_rgb16, + _twin_c_in_rgb16_source_argb32, + }, + { /* ARGB32 */ + _twin_c_in_argb32_source_a8, + _twin_c_in_argb32_source_rgb16, + _twin_c_in_argb32_source_argb32, + }, + { /* C */ + _twin_c_in_c_source_a8, + _twin_c_in_c_source_rgb16, + _twin_c_in_c_source_argb32, + }, + }, + } +}; + +#define operand_index(o) ((o)->source_kind == TWIN_SOLID ? 3 : o->u.pixmap->format) + +void +twin_composite (twin_pixmap_t *dst, + int dst_x, + int dst_y, + twin_operand_t *src, + int src_x, + int src_y, + twin_operand_t *msk, + int msk_x, + int msk_y, + twin_operator_t operator, + int width, + int height) +{ + int iy; + int left, right, top, bottom; + + if (msk) + { + twin_src_msk_op op; + twin_source_u s, m; + int sdx, sdy, mdx, mdy; + twin_argb32_t *src_tmp; + twin_argb32_t *msk_tmp; + twin_argb32_t *dst_tmp; + + sdx = src_x - dst_x; + sdy = src_y - dst_y; + mdx = msk_x - dst_x; + mdy = msk_y - dst_y; + + left = dst_x; + right = dst_x + width; + top = dst_y; + bottom = dst_y + height; + if (left < 0) + left = 0; + if (right > dst->width) + right = dst->width; + if (top < 0) + top = 0; + if (top > dst->height) + top = dst->height; + + op = comp3[operator][operand_index(src)][operand_index(msk)][dst->format]; + if (op) + { + if (src->source_kind == TWIN_SOLID) + s.c = src->u.argb; + if (msk->source_kind == TWIN_SOLID) + s.c = msk->u.argb; + for (iy = top; iy < bottom; iy++) + { + if (src->source_kind == TWIN_PIXMAP) + s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy); + if (msk->source_kind == TWIN_PIXMAP) + m.p = twin_pixmap_pointer (msk->u.pixmap, left+mdx, iy+mdy); + (*op) (twin_pixmap_pointer (dst, left, iy), + s, m, right - left); + } + } + else + { + } + } + else + { + twin_src_op op; + twin_source_u s; + int sdx, sdy; + + sdx = src_x - dst_x; + sdy = src_y - dst_y; + + left = dst_x; + right = dst_x + width; + top = dst_y; + bottom = dst_y + height; + if (left < 0) + left = 0; + if (right > dst->width) + right = dst->width; + if (top < 0) + top = 0; + if (top > dst->height) + top = dst->height; + + op = comp2[operator][operand_index(src)][dst->format]; + if (src->source_kind == TWIN_SOLID) + s.c = src->u.argb; + for (iy = top; iy < bottom; iy++) + { + if (src->source_kind == TWIN_PIXMAP) + s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy); + (*op) (twin_pixmap_pointer (dst, left, iy), + s, right - left); + } + } +} + +/* + * array primary index is OVER SOURCE + * array secondary index is ARGB32 RGB16 A8 + */ +static twin_src_op fill[2][3] = { + { /* OVER */ + _twin_c_over_a8, + _twin_c_over_rgb16, + _twin_c_over_argb32, + }, + { /* SOURCE */ + _twin_c_source_a8, + _twin_c_source_rgb16, + _twin_c_source_argb32, + } +}; + +void +twin_fill (twin_pixmap_t *dst, + twin_argb32_t pixel, + twin_operator_t operator, + int x, + int y, + int width, + int height) +{ + twin_src_op op; + twin_source_u src; + int iy; + int left, right, top, bottom; + + src.c = pixel; + left = x; + right = x + width; + top = y; + bottom = y + height; + if (left < 0) + left = 0; + if (right > dst->width) + right = dst->width; + if (top < 0) + top = 0; + if (top > dst->height) + top = dst->height; + op = fill[operator][dst->format]; + for (iy = top; iy < bottom; iy++) + (*op) (twin_pixmap_pointer (dst, left, iy), src, right - left); +} diff --git a/twin_pixmap.c b/twin_pixmap.c new file mode 100644 index 0000000..3610e01 --- /dev/null +++ b/twin_pixmap.c @@ -0,0 +1,118 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twinint.h" + +twin_pixmap_t * +twin_pixmap_create (twin_format_t format, int width, int height) +{ + int stride = twin_bytes_per_pixel (format) * width; + int size = sizeof (twin_pixmap_t) + stride * height; + twin_pixmap_t *pixmap = malloc (size); + if (!pixmap) + return 0; + pixmap->screen = 0; + pixmap->higher = 0; + pixmap->x = pixmap->y = 0; + pixmap->format = format; + pixmap->width = width; + pixmap->height = height; + pixmap->stride = stride; + pixmap->p.v = pixmap + 1; + return pixmap; +} + +void +twin_pixmap_destroy (twin_pixmap_t *pixmap) +{ + if (pixmap->screen) + twin_pixmap_hide (pixmap); + free (pixmap); +} + +void +twin_pixmap_show (twin_pixmap_t *pixmap, + twin_screen_t *screen, + twin_pixmap_t *lower) +{ + twin_pixmap_t **higherp; + if (pixmap->screen) + twin_pixmap_hide (pixmap); + pixmap->screen = screen; + if (lower) + higherp = &lower->higher; + else + higherp = &screen->bottom; + pixmap->higher = *higherp; + *higherp = pixmap; + twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height); +} + +void +twin_pixmap_hide (twin_pixmap_t *pixmap) +{ + twin_screen_t *screen = pixmap->screen; + twin_pixmap_t **higherp; + + if (!screen) + return; + twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height); + for (higherp = &screen->bottom; *higherp != pixmap; higherp = &(*higherp)->higher) + ; + *higherp = pixmap->higher; + pixmap->screen = 0; + pixmap->higher = 0; +} + +twin_pointer_t +twin_pixmap_pointer (twin_pixmap_t *pixmap, int x, int y) +{ + twin_pointer_t p; + + p.b = (pixmap->p.b + + y * pixmap->stride + + x * twin_bytes_per_pixel(pixmap->format)); + return p; +} + +void +twin_pixmap_damage (twin_pixmap_t *pixmap, + int x1, int y1, int x2, int y2) +{ + if (pixmap->screen) + twin_screen_damage (pixmap->screen, + x1 + pixmap->x, + y1 + pixmap->y, + x2 + pixmap->x, + y2 + pixmap->y); +} + +void +twin_pixmap_move (twin_pixmap_t *pixmap, int x, int y) +{ + twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height); + pixmap->x = x; + pixmap->y = y; + twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height); +} diff --git a/twin_primitive.c b/twin_primitive.c new file mode 100644 index 0000000..2f69938 --- /dev/null +++ b/twin_primitive.c @@ -0,0 +1,230 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twinint.h" + +static twin_argb32_t __inline +in_over (twin_argb32_t dst, + twin_argb32_t src, + twin_a8_t msk) +{ + uint16_t t1, t2, t3, t4; + twin_a8_t a; + + src = (twin_in(src,0,msk,t1) | + twin_in(src,8,msk,t2) | + twin_in(src,16,msk,t3) | + twin_in(src,24,msk,t4)); + a = ~(src >> 24); + return (twin_over (src, dst, 0, a, t1) | + twin_over (src, dst, 8, a, t2) | + twin_over (src, dst, 16, a, t3) | + twin_over (src, dst, 24, a, t4)); +} + +static twin_argb32_t __inline +in (twin_argb32_t src, + twin_a8_t msk) +{ + uint16_t t1, t2, t3, t4; + + return (twin_in(src,0,msk,t1) | + twin_in(src,8,msk,t2) | + twin_in(src,16,msk,t3) | + twin_in(src,24,msk,t4)); +} + +static twin_argb32_t __inline +over (twin_argb32_t dst, + twin_argb32_t src) +{ + uint16_t t1, t2, t3, t4; + twin_a8_t a; + + a = ~(src >> 24); + return (twin_over (src, dst, 0, a, t1) | + twin_over (src, dst, 8, a, t2) | + twin_over (src, dst, 16, a, t3) | + twin_over (src, dst, 24, a, t4)); +} + +static twin_argb32_t __inline +rgb16_to_argb32 (twin_rgb16_t v) +{ + return twin_rgb16_to_argb32(v); +} + +static twin_argb32_t __inline +a8_to_argb32 (twin_a8_t v) +{ + return v << 24; +} + +static twin_rgb16_t __inline +argb32_to_rgb16 (twin_argb32_t v) +{ + return twin_argb32_to_rgb16 (v); +} + +static twin_a8_t __inline +argb32_to_a8 (twin_argb32_t v) +{ + return v >> 24; +} + +/* + * Naming convention + * + * _twin_<src>_in_<msk>_op_<dst> + * + * Use 'c' for constant + */ + +#define dst_argb32_get (*dst.argb32) +#define dst_argb32_set (*dst.argb32++) = +#define dst_rgb16_get (rgb16_to_argb32(*dst.rgb16)) +#define dst_rgb16_set (*dst.rgb16++) = argb32_to_rgb16 +#define dst_a8_get (a8_to_argb32(*dst.a8)) +#define dst_a8_set (*dst.a8++) = argb32_to_a8 + +#define src_c (src.c) +#define src_argb32 (*src.p.argb32++) +#define src_rgb16 (rgb16_to_argb32(*src.p.rgb16++)) +#define src_a8 (a8_to_argb32(*src.p.a8++)) + +#define msk_c (argb32_to_a8 (msk.c)) +#define msk_argb32 (argb32_to_a8 (*msk.p.argb32++)) +#define msk_rgb16 (0xff) +#define msk_a8 (*msk.p.a8++) + +#define cat2(a,b) a##b +#define cat3(a,b,c) a##b##c +#define cat4(a,b,c,d) a##b##c##d +#define cat6(a,b,c,d,e,f) a##b##c##d##e##f + +#define _twin_in_op_name(src,op,msk,dst) cat6(_twin_,src,_in_,msk,op,dst) + +#define _twin_op_name(src,op,dst) cat4(_twin_,src,op,dst) + +#define make_twin_in_over(__dst,__src,__msk) \ +void \ +_twin_in_op_name(__src,_over_,__msk,__dst)(twin_pointer_t dst, \ + twin_source_u src, \ + twin_source_u msk, \ + int width) \ +{ \ + twin_argb32_t dst32; \ + twin_argb32_t src32; \ + twin_a8_t msk8; \ + while (width--) { \ + dst32 = cat3(dst_,__dst,_get); \ + src32 = cat2(src_,__src); \ + msk8 = cat2(msk_,__msk); \ + dst32 = in_over (dst32, src32, msk8); \ + cat3(dst_,__dst,_set) (dst32); \ + } \ +} + +#define make_twin_in_source(__dst,__src,__msk) \ +void \ +_twin_in_op_name(__src,_source_,__msk,__dst)(twin_pointer_t dst, \ + twin_source_u src, \ + twin_source_u msk, \ + int width) \ +{ \ + twin_argb32_t dst32; \ + twin_argb32_t src32; \ + twin_a8_t msk8; \ + while (width--) { \ + src32 = cat2(src_,__src); \ + msk8 = cat2(msk_,__msk); \ + dst32 = in (src32, msk8); \ + cat3(dst_,__dst,_set) (dst32); \ + } \ +} + +#define make_twin_in_op_msks(op,dst,src) \ +cat2(make_twin_in_,op)(dst,src,argb32) \ +cat2(make_twin_in_,op)(dst,src,rgb16) \ +cat2(make_twin_in_,op)(dst,src,a8) \ +cat2(make_twin_in_,op)(dst,src,c) + +#define make_twin_in_op_srcs_msks(op,dst) \ +make_twin_in_op_msks(op,dst,argb32) \ +make_twin_in_op_msks(op,dst,rgb16) \ +make_twin_in_op_msks(op,dst,a8) \ +make_twin_in_op_msks(op,dst,c) + +#define make_twin_in_op_dsts_srcs_msks(op) \ +make_twin_in_op_srcs_msks(op,argb32) \ +make_twin_in_op_srcs_msks(op,rgb16) \ +make_twin_in_op_srcs_msks(op,a8) + +make_twin_in_op_dsts_srcs_msks(over) +make_twin_in_op_dsts_srcs_msks(source) + +#define make_twin_over(__dst,__src) \ +void \ +_twin_op_name(__src,_over_,__dst) (twin_pointer_t dst, \ + twin_source_u src, \ + int width) \ +{ \ + twin_argb32_t dst32; \ + twin_argb32_t src32; \ + while (width--) { \ + dst32 = cat3(dst_,__dst,_get); \ + src32 = cat2(src_,__src); \ + dst32 = over (dst32, src32); \ + cat3(dst_,__dst,_set) (dst32); \ + } \ +} + +#define make_twin_source(__dst,__src) \ +void \ +_twin_op_name(__src,_source_,__dst) (twin_pointer_t dst, \ + twin_source_u src, \ + int width) \ +{ \ + twin_argb32_t dst32; \ + twin_argb32_t src32; \ + while (width--) { \ + src32 = cat2(src_,__src); \ + dst32 = src32; \ + cat3(dst_,__dst,_set) (dst32); \ + } \ +} + +#define make_twin_op_srcs(op,dst) \ +cat2(make_twin_,op)(dst,argb32) \ +cat2(make_twin_,op)(dst,rgb16) \ +cat2(make_twin_,op)(dst,a8) \ +cat2(make_twin_,op)(dst,c) + +#define make_twin_op_dsts_srcs(op) \ +make_twin_op_srcs(op,argb32) \ +make_twin_op_srcs(op,rgb16) \ +make_twin_op_srcs(op,a8) + +make_twin_op_dsts_srcs(over) +make_twin_op_dsts_srcs(source) diff --git a/twin_screen.c b/twin_screen.c new file mode 100644 index 0000000..c8936f7 --- /dev/null +++ b/twin_screen.c @@ -0,0 +1,148 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twinint.h" + +twin_screen_t * +twin_screen_create (int width, + int height, + twin_put_span_t put_span, + void *closure) +{ + twin_screen_t *screen = malloc (sizeof (twin_screen_t)); + if (!screen) + return 0; + screen->bottom = 0; + screen->width = width; + screen->height = height; + screen->damage.left = screen->damage.right = 0; + screen->damage.top = screen->damage.bottom = 0; + screen->put_span = put_span; + screen->closure = closure; + return screen; +} + +void +twin_screen_destroy (twin_screen_t *screen) +{ + while (screen->bottom) + twin_pixmap_hide (screen->bottom); + free (screen); +} + +void +twin_screen_damage (twin_screen_t *screen, + int left, int top, int right, int bottom) +{ + if (screen->damage.left == screen->damage.right) + { + screen->damage.left = left; + screen->damage.right = right; + screen->damage.top = top; + screen->damage.bottom = bottom; + } + else + { + if (left < screen->damage.left) + screen->damage.left = left; + if (top < screen->damage.top) + screen->damage.top = top; + if (screen->damage.right < right) + screen->damage.right = right; + if (screen->damage.bottom < bottom) + screen->damage.bottom = bottom; + } +} + +void +twin_screen_resize (twin_screen_t *screen, int width, int height) +{ + screen->width = width; + screen->height = height; + twin_screen_damage (screen, 0, 0, screen->width, screen->height); +} + +twin_bool +twin_screen_damaged (twin_screen_t *screen) +{ + return (screen->damage.left < screen->damage.right && + screen->damage.top < screen->damage.bottom); +} + +void +twin_screen_update (twin_screen_t *screen) +{ + if (screen->damage.left < screen->damage.right && + screen->damage.top < screen->damage.bottom) + { + int x = screen->damage.left; + int y = screen->damage.top; + int width = screen->damage.right - screen->damage.left; + int height = screen->damage.bottom - screen->damage.top; + twin_argb32_t *span; + twin_pixmap_t *p; + + /* XXX what is the maximum number of lines? */ + span = malloc (width * sizeof (twin_argb32_t)); + if (!span) + return; + + while (height--) + { + memset (span, 0xff, width * sizeof (twin_argb32_t)); + for (p = screen->bottom; p; p = p->higher) + { + twin_pointer_t dst; + twin_source_u src; + + int left, right; + /* bounds check in y */ + if (y < p->y) + continue; + if (p->y + p->height <= y) + continue; + /* bounds check in x*/ + left = x; + if (left < p->x) + left = p->x; + right = x + width; + if (right > p->x + p->width) + right = p->x + p->width; + if (left >= right) + continue; + dst.argb32 = span + (left - x); + src.p = twin_pixmap_pointer (p, left - p->x, y - p->y); + if (p->format == TWIN_RGB16) + _twin_rgb16_source_argb32 (dst, src, right - left); + else + _twin_argb32_over_argb32 (dst, src, right - left); + } + (*screen->put_span) (x, y, width, span, screen->closure); + y++; + } + free (span); + screen->damage.left = screen->damage.right = 0; + screen->damage.top = screen->damage.bottom = 0; + } +} diff --git a/twin_x11.c b/twin_x11.c new file mode 100644 index 0000000..31797bc --- /dev/null +++ b/twin_x11.c @@ -0,0 +1,116 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twinint.h" +#include <X11/Xutil.h> + +static void +_twin_x11_put_span (int x, + int y, + int width, + twin_argb32_t *pixels, + void *closure) +{ + twin_x11_t *tx = closure; + XImage *image; + int ix = 0; + int iw = width; + + image = XCreateImage (tx->dpy, tx->visual, tx->depth, ZPixmap, + 0, 0, width, 1, 32, 0); + + image->data = malloc (4 * width); + + while (iw--) + { + twin_argb32_t pixel = *pixels++; + + if (tx->depth == 16) + pixel = twin_argb32_to_rgb16 (pixel); + XPutPixel (image, ix, 0, pixel); + ix++; + } + XPutImage (tx->dpy, tx->win, tx->gc, image, 0, 0, x, y, width, 1); + XDestroyImage (image); +} + +twin_x11_t * +twin_x11_create (Display *dpy, int width, int height) +{ + twin_x11_t *tx; + int scr = DefaultScreen (dpy); + XSetWindowAttributes wa; + + tx = malloc (sizeof (twin_x11_t)); + if (!tx) + return 0; + tx->dpy = dpy; + tx->visual = DefaultVisual (dpy, scr); + tx->depth = DefaultDepth (dpy, scr); + + wa.background_pixmap = None; + wa.event_mask = (KeyPressMask| + KeyReleaseMask| + ButtonPressMask| + ButtonReleaseMask| + PointerMotionMask| + ExposureMask| + StructureNotifyMask); + + tx->win = XCreateWindow (dpy, RootWindow (dpy, scr), + 0, 0, width, height, 0, + tx->depth, InputOutput, + tx->visual, CWBackPixmap|CWEventMask, &wa); + tx->gc = XCreateGC (dpy, tx->win, 0, 0); + tx->screen = twin_screen_create (width, height, + _twin_x11_put_span, tx); + XMapWindow (dpy, tx->win); + return tx; +} + +void +twin_x11_destroy (twin_x11_t *tx) +{ + twin_screen_destroy (tx->screen); + XDestroyWindow (tx->dpy, tx->win); +} + +void +twin_x11_damage (twin_x11_t *tx, XExposeEvent *ev) +{ + twin_screen_damage (tx->screen, + ev->x, ev->y, ev->x + ev->width, ev->y + ev->height); +} + +void +twin_x11_configure (twin_x11_t *tx, XConfigureEvent *ev) +{ + twin_screen_resize (tx->screen, ev->width, ev->height); +} + +void +twin_x11_update (twin_x11_t *tx) +{ + twin_screen_update (tx->screen); +} diff --git a/twinint.h b/twinint.h new file mode 100644 index 0000000..3c2dc6d --- /dev/null +++ b/twinint.h @@ -0,0 +1,213 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _TWININT_H_ +#define _TWININT_H_ + +#include "twin.h" +#include <string.h> + +#define twin_int_mult(a,b,t) ((t) = (a) * (b) + 0x80, \ + ((((t)>>8 ) + (t))>>8 )) +#define twin_int_div(a,b) (((uint16_t) (a) * 255) / (b)) +#define twin_get_8(v,i) ((uint16_t) (uint8_t) ((v) >> (i))) +#define twin_sat(t) ((uint8_t) ((t) | (0 - ((t) >> 8)))) + +#define twin_in(s,i,m,t) \ + ((twin_argb32_t) twin_int_mult (twin_get_8(s,i),(m),(t)) << (i)) + +#define twin_over(s,d,i,m,t) \ + ((t) = twin_int_mult(twin_get_8(d,i),(m),(t)) + twin_get_8(s,i),\ + (twin_argb32_t) twin_sat (t) << (i)) + +#define twin_over(s,d,i,m,t) \ + ((t) = twin_int_mult(twin_get_8(d,i),(m),(t)) + twin_get_8(s,i),\ + (twin_argb32_t) twin_sat (t) << (i)) + +#define twin_argb32_to_rgb16(s) ((((s) >> 3) & 0x001f) | \ + (((s) >> 5) & 0x07e0) | \ + (((s) >> 8) & 0xf800)) +#define twin_rgb16_to_argb32(s) \ + (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ + ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ + ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)) | \ + 0xff000000) + +typedef union { + twin_pointer_t p; + twin_argb32_t c; +} twin_source_u; + +typedef void (*twin_src_msk_op) (twin_pointer_t dst, + twin_source_u src, + twin_source_u msk, + int width); + +typedef void (*twin_src_op) (twin_pointer_t dst, + twin_source_u src, + int width); + +/* twin_primitive.c */ + +typedef void twin_in_op_func (twin_pointer_t dst, + twin_source_u src, + twin_source_u msk, + int width); + +typedef void twin_op_func (twin_pointer_t dst, + twin_source_u src, + int width); + +twin_in_op_func _twin_argb32_in_argb32_over_argb32; +twin_in_op_func _twin_argb32_in_rgb16_over_argb32; +twin_in_op_func _twin_argb32_in_a8_over_argb32; +twin_in_op_func _twin_argb32_in_c_over_argb32; +twin_in_op_func _twin_rgb16_in_argb32_over_argb32; +twin_in_op_func _twin_rgb16_in_rgb16_over_argb32; +twin_in_op_func _twin_rgb16_in_a8_over_argb32; +twin_in_op_func _twin_rgb16_in_c_over_argb32; +twin_in_op_func _twin_a8_in_argb32_over_argb32; +twin_in_op_func _twin_a8_in_rgb16_over_argb32; +twin_in_op_func _twin_a8_in_a8_over_argb32; +twin_in_op_func _twin_a8_in_c_over_argb32; +twin_in_op_func _twin_c_in_argb32_over_argb32; +twin_in_op_func _twin_c_in_rgb16_over_argb32; +twin_in_op_func _twin_c_in_a8_over_argb32; +twin_in_op_func _twin_c_in_c_over_argb32; +twin_in_op_func _twin_argb32_in_argb32_over_rgb16; +twin_in_op_func _twin_argb32_in_rgb16_over_rgb16; +twin_in_op_func _twin_argb32_in_a8_over_rgb16; +twin_in_op_func _twin_argb32_in_c_over_rgb16; +twin_in_op_func _twin_rgb16_in_argb32_over_rgb16; +twin_in_op_func _twin_rgb16_in_rgb16_over_rgb16; +twin_in_op_func _twin_rgb16_in_a8_over_rgb16; +twin_in_op_func _twin_rgb16_in_c_over_rgb16; +twin_in_op_func _twin_a8_in_argb32_over_rgb16; +twin_in_op_func _twin_a8_in_rgb16_over_rgb16; +twin_in_op_func _twin_a8_in_a8_over_rgb16; +twin_in_op_func _twin_a8_in_c_over_rgb16; +twin_in_op_func _twin_c_in_argb32_over_rgb16; +twin_in_op_func _twin_c_in_rgb16_over_rgb16; +twin_in_op_func _twin_c_in_a8_over_rgb16; +twin_in_op_func _twin_c_in_c_over_rgb16; +twin_in_op_func _twin_argb32_in_argb32_over_a8; +twin_in_op_func _twin_argb32_in_rgb16_over_a8; +twin_in_op_func _twin_argb32_in_a8_over_a8; +twin_in_op_func _twin_argb32_in_c_over_a8; +twin_in_op_func _twin_rgb16_in_argb32_over_a8; +twin_in_op_func _twin_rgb16_in_rgb16_over_a8; +twin_in_op_func _twin_rgb16_in_a8_over_a8; +twin_in_op_func _twin_rgb16_in_c_over_a8; +twin_in_op_func _twin_a8_in_argb32_over_a8; +twin_in_op_func _twin_a8_in_rgb16_over_a8; +twin_in_op_func _twin_a8_in_a8_over_a8; +twin_in_op_func _twin_a8_in_c_over_a8; +twin_in_op_func _twin_c_in_argb32_over_a8; +twin_in_op_func _twin_c_in_rgb16_over_a8; +twin_in_op_func _twin_c_in_a8_over_a8; +twin_in_op_func _twin_c_in_c_over_a8; +twin_in_op_func _twin_argb32_in_argb32_over_c; + +twin_in_op_func _twin_argb32_in_argb32_source_argb32; +twin_in_op_func _twin_argb32_in_rgb16_source_argb32; +twin_in_op_func _twin_argb32_in_a8_source_argb32; +twin_in_op_func _twin_argb32_in_c_source_argb32; +twin_in_op_func _twin_rgb16_in_argb32_source_argb32; +twin_in_op_func _twin_rgb16_in_rgb16_source_argb32; +twin_in_op_func _twin_rgb16_in_a8_source_argb32; +twin_in_op_func _twin_rgb16_in_c_source_argb32; +twin_in_op_func _twin_a8_in_argb32_source_argb32; +twin_in_op_func _twin_a8_in_rgb16_source_argb32; +twin_in_op_func _twin_a8_in_a8_source_argb32; +twin_in_op_func _twin_a8_in_c_source_argb32; +twin_in_op_func _twin_c_in_argb32_source_argb32; +twin_in_op_func _twin_c_in_rgb16_source_argb32; +twin_in_op_func _twin_c_in_a8_source_argb32; +twin_in_op_func _twin_c_in_c_source_argb32; +twin_in_op_func _twin_argb32_in_argb32_source_rgb16; +twin_in_op_func _twin_argb32_in_rgb16_source_rgb16; +twin_in_op_func _twin_argb32_in_a8_source_rgb16; +twin_in_op_func _twin_argb32_in_c_source_rgb16; +twin_in_op_func _twin_rgb16_in_argb32_source_rgb16; +twin_in_op_func _twin_rgb16_in_rgb16_source_rgb16; +twin_in_op_func _twin_rgb16_in_a8_source_rgb16; +twin_in_op_func _twin_rgb16_in_c_source_rgb16; +twin_in_op_func _twin_a8_in_argb32_source_rgb16; +twin_in_op_func _twin_a8_in_rgb16_source_rgb16; +twin_in_op_func _twin_a8_in_a8_source_rgb16; +twin_in_op_func _twin_a8_in_c_source_rgb16; +twin_in_op_func _twin_c_in_argb32_source_rgb16; +twin_in_op_func _twin_c_in_rgb16_source_rgb16; +twin_in_op_func _twin_c_in_a8_source_rgb16; +twin_in_op_func _twin_c_in_c_source_rgb16; +twin_in_op_func _twin_argb32_in_argb32_source_a8; +twin_in_op_func _twin_argb32_in_rgb16_source_a8; +twin_in_op_func _twin_argb32_in_a8_source_a8; +twin_in_op_func _twin_argb32_in_c_source_a8; +twin_in_op_func _twin_rgb16_in_argb32_source_a8; +twin_in_op_func _twin_rgb16_in_rgb16_source_a8; +twin_in_op_func _twin_rgb16_in_a8_source_a8; +twin_in_op_func _twin_rgb16_in_c_source_a8; +twin_in_op_func _twin_a8_in_argb32_source_a8; +twin_in_op_func _twin_a8_in_rgb16_source_a8; +twin_in_op_func _twin_a8_in_a8_source_a8; +twin_in_op_func _twin_a8_in_c_source_a8; +twin_in_op_func _twin_c_in_argb32_source_a8; +twin_in_op_func _twin_c_in_rgb16_source_a8; +twin_in_op_func _twin_c_in_a8_source_a8; +twin_in_op_func _twin_c_in_c_source_a8; +twin_in_op_func _twin_argb32_in_argb32_source_c; + +twin_op_func _twin_argb32_over_argb32; +twin_op_func _twin_rgb16_over_argb32; +twin_op_func _twin_a8_over_argb32; +twin_op_func _twin_c_over_argb32; +twin_op_func _twin_argb32_over_rgb16; +twin_op_func _twin_rgb16_over_rgb16; +twin_op_func _twin_a8_over_rgb16; +twin_op_func _twin_c_over_rgb16; +twin_op_func _twin_argb32_over_a8; +twin_op_func _twin_rgb16_over_a8; +twin_op_func _twin_a8_over_a8; +twin_op_func _twin_c_over_a8; +twin_op_func _twin_argb32_source_argb32; +twin_op_func _twin_rgb16_source_argb32; +twin_op_func _twin_a8_source_argb32; +twin_op_func _twin_c_source_argb32; +twin_op_func _twin_argb32_source_rgb16; +twin_op_func _twin_rgb16_source_rgb16; +twin_op_func _twin_a8_source_rgb16; +twin_op_func _twin_c_source_rgb16; +twin_op_func _twin_argb32_source_a8; +twin_op_func _twin_rgb16_source_a8; +twin_op_func _twin_a8_source_a8; +twin_op_func _twin_c_source_a8; + +twin_argb32_t * +_twin_fetch_rgb16 (twin_pixmap_t *pixmap, int x, int y, int w, twin_argb32_t *span); + +twin_argb32_t * +_twin_fetch_argb32 (twin_pixmap_t *pixmap, int x, int y, int w, twin_argb32_t *span); + +#endif /* _TWININT_H_ */ @@ -0,0 +1,79 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include <X11/Xlib.h> +#include "twin.h" +#include <string.h> +#include <stdio.h> + +int +main (int argc, char **argv) +{ + Display *dpy = XOpenDisplay (0); + twin_x11_t *x11 = twin_x11_create (dpy, 256, 256); + twin_pixmap_t *red = twin_pixmap_create (TWIN_ARGB32, 100, 100); + twin_pixmap_t *blue = twin_pixmap_create (TWIN_ARGB32, 100, 100); + XEvent ev; + int x, y; + + twin_fill (red, 0x80800000, TWIN_SOURCE, 0, 0, 100, 100); + twin_fill (red, 0xffffff00, TWIN_SOURCE, 25, 25, 50, 50); + twin_fill (blue, 0x80000080, TWIN_SOURCE, 0, 0, 100, 100); + twin_fill (blue, 0xff00c000, TWIN_SOURCE, 25, 25, 50, 50); + twin_pixmap_move (red, 20, 20); + twin_pixmap_move (blue, 80, 80); + twin_pixmap_show (red, x11->screen, 0); + twin_pixmap_show (blue, x11->screen, 0); + for (;;) + { + if (twin_screen_damaged (x11->screen)) + twin_x11_update (x11); + do { + XNextEvent (dpy, &ev); + switch (ev.type) { + case Expose: + twin_x11_damage (x11, &ev.xexpose); + break; + case ButtonPress: + if (ev.xbutton.button == 2) + { + if (red->higher == 0) + twin_pixmap_show (red, x11->screen, 0); + else + twin_pixmap_show (blue, x11->screen, 0); + } + break; + case MotionNotify: + x = ev.xmotion.x - 50; + y = ev.xmotion.y - 50; + if (ev.xmotion.state & Button1Mask) + twin_pixmap_move (red, x, y); + if (ev.xmotion.state & Button3Mask) + twin_pixmap_move (blue, x, y); + break; + } + } while (QLength (dpy)); + } +} + |