2002-07-23 07:22:23 +00:00
|
|
|
|
/*
|
|
|
|
|
|
* $XFree86: $
|
|
|
|
|
|
*
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* Copyright <EFBFBD> 2002 Carl D. Worth
|
2002-07-23 07:22:23 +00:00
|
|
|
|
*
|
|
|
|
|
|
* 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
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* appear in supporting documentation, and that the name of Carl
|
|
|
|
|
|
* D. Worth not be used in advertising or publicity pertaining to
|
|
|
|
|
|
* distribution of the software without specific, written prior
|
|
|
|
|
|
* permission. Carl D. Worth makes no representations about the
|
|
|
|
|
|
* suitability of this software for any purpose. It is provided "as
|
|
|
|
|
|
* is" without express or implied warranty.
|
2002-07-23 07:22:23 +00:00
|
|
|
|
*
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* CARL D. WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
|
|
* FITNESS, IN NO EVENT SHALL CARL D. WORTH 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.
|
|
|
|
|
|
*/
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
2002-11-04 00:24:44 +00:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
#include "xrint.h"
|
|
|
|
|
|
|
2002-11-04 00:24:44 +00:00
|
|
|
|
XrSurface *
|
|
|
|
|
|
_XrSurfaceCreate(Display *dpy)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrSurface *surface;
|
|
|
|
|
|
|
|
|
|
|
|
surface = malloc(sizeof(XrSurface));
|
|
|
|
|
|
|
|
|
|
|
|
if (surface)
|
|
|
|
|
|
_XrSurfaceInit(surface, dpy);
|
|
|
|
|
|
|
|
|
|
|
|
return surface;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
void
|
2002-10-16 12:57:00 +00:00
|
|
|
|
_XrSurfaceInit(XrSurface *surface, Display *dpy)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
surface->dpy = dpy;
|
|
|
|
|
|
|
|
|
|
|
|
surface->drawable = 0;
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->gc = 0;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
2002-11-04 00:24:44 +00:00
|
|
|
|
surface->width = 0;
|
|
|
|
|
|
surface->height = 0;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
surface->depth = 0;
|
|
|
|
|
|
|
2002-10-30 21:54:50 +00:00
|
|
|
|
surface->xc_sa_mask = 0;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
2002-11-04 00:24:44 +00:00
|
|
|
|
_XrSurfaceSetFormat(surface, XrFormatARGB32);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
|
2002-10-30 21:54:50 +00:00
|
|
|
|
surface->xc_surface = 0;
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->needs_new_xc_surface = 1;
|
2002-10-28 09:00:10 +00:00
|
|
|
|
|
|
|
|
|
|
surface->ref_count = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-04 00:24:44 +00:00
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceDeinit(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (surface->xc_surface)
|
|
|
|
|
|
XcFreeSurface(surface->dpy, surface->xc_surface);
|
|
|
|
|
|
if (surface->gc)
|
|
|
|
|
|
XFreeGC(surface->dpy, surface->gc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceDestroy(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
_XrSurfaceDeinit(surface);
|
|
|
|
|
|
free(surface);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-10-28 09:00:10 +00:00
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceReference(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
surface->ref_count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceDereference(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (surface->ref_count == 0)
|
|
|
|
|
|
_XrSurfaceDeinit(surface);
|
|
|
|
|
|
else
|
|
|
|
|
|
surface->ref_count--;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceDereferenceDestroy(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (surface->ref_count == 0)
|
2002-11-04 00:24:44 +00:00
|
|
|
|
_XrSurfaceDestroy(surface);
|
|
|
|
|
|
else
|
|
|
|
|
|
_XrSurfaceDereference(surface);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-11-01 19:45:30 +00:00
|
|
|
|
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
/* XXX: QUESTION: Special handling for depth==1 ala xftdraw.c? */
|
2002-10-30 21:54:50 +00:00
|
|
|
|
if (surface->xc_surface == 0) {
|
2002-11-01 19:45:30 +00:00
|
|
|
|
Pixmap pix = XCreatePixmap(surface->dpy,
|
|
|
|
|
|
DefaultRootWindow(surface->dpy),
|
|
|
|
|
|
1, 1,
|
|
|
|
|
|
surface->xc_format->depth);
|
2002-11-04 00:24:44 +00:00
|
|
|
|
_XrSurfaceSetDrawableWH(surface, pix, 1, 1);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->xc_sa_mask |= CPRepeat;
|
|
|
|
|
|
surface->xc_sa.repeat = True;
|
|
|
|
|
|
_XrSurfaceGetXcSurface(surface);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XFreePixmap(surface->dpy, pix);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XcFillRectangle(surface->dpy, PictOpSrc,
|
2002-10-30 21:54:50 +00:00
|
|
|
|
surface->xc_surface, &color->xc_color,
|
2002-07-23 07:22:23 +00:00
|
|
|
|
0, 0, 1, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
XrStatus
|
|
|
|
|
|
_XrSurfaceSetImage(XrSurface *surface,
|
|
|
|
|
|
char *data,
|
|
|
|
|
|
unsigned int width,
|
|
|
|
|
|
unsigned int height,
|
|
|
|
|
|
unsigned int stride)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
2002-11-01 19:45:30 +00:00
|
|
|
|
XImage *image;
|
|
|
|
|
|
unsigned int depth, bitmap_pad;
|
|
|
|
|
|
Pixmap pix;
|
|
|
|
|
|
|
|
|
|
|
|
depth = surface->xc_format->depth;
|
|
|
|
|
|
|
|
|
|
|
|
if (depth > 16)
|
|
|
|
|
|
bitmap_pad = 32;
|
|
|
|
|
|
else if (depth > 8)
|
|
|
|
|
|
bitmap_pad = 16;
|
|
|
|
|
|
else
|
|
|
|
|
|
bitmap_pad = 8;
|
|
|
|
|
|
|
|
|
|
|
|
pix = XCreatePixmap(surface->dpy,
|
|
|
|
|
|
DefaultRootWindow(surface->dpy),
|
|
|
|
|
|
width, height,
|
|
|
|
|
|
depth);
|
2002-11-04 00:24:44 +00:00
|
|
|
|
_XrSurfaceSetDrawableWH(surface, pix, width, height);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
|
|
|
|
|
|
image = XCreateImage(surface->dpy,
|
|
|
|
|
|
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
|
|
|
|
|
|
depth, ZPixmap, 0,
|
|
|
|
|
|
data, width, height,
|
|
|
|
|
|
bitmap_pad,
|
|
|
|
|
|
stride);
|
|
|
|
|
|
if (image == NULL)
|
|
|
|
|
|
return XrStatusNoMemory;
|
|
|
|
|
|
|
|
|
|
|
|
XPutImage(surface->dpy, surface->drawable, surface->gc,
|
|
|
|
|
|
image, 0, 0, 0, 0, width, height);
|
|
|
|
|
|
|
2002-11-02 10:24:12 +00:00
|
|
|
|
|
|
|
|
|
|
/* I want to free the pixmap, so I have to commit to an xc_surface
|
|
|
|
|
|
to reference the pixmap in the Picture. */
|
|
|
|
|
|
_XrSurfaceGetXcSurface(surface);
|
|
|
|
|
|
XFreePixmap(surface->dpy, pix);
|
|
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
/* Foolish XDestroyImage thinks it can free my data, but I won't
|
|
|
|
|
|
stand for it. */
|
|
|
|
|
|
image->data = NULL;
|
|
|
|
|
|
XDestroyImage(image);
|
|
|
|
|
|
|
|
|
|
|
|
return XrStatusSuccess;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
/* XXX: We may want to move to projective matrices at some point. If
|
|
|
|
|
|
nothing else, that would eliminate the two different transform data
|
|
|
|
|
|
structures we have here. */
|
|
|
|
|
|
XrStatus
|
|
|
|
|
|
_XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
2002-11-01 19:45:30 +00:00
|
|
|
|
XTransform xtransform;
|
|
|
|
|
|
|
|
|
|
|
|
xtransform.matrix[0][0] = XDoubleToFixed(transform->m[0][0]);
|
2002-11-11 12:46:17 +00:00
|
|
|
|
xtransform.matrix[0][1] = XDoubleToFixed(transform->m[1][0]);
|
|
|
|
|
|
xtransform.matrix[0][2] = XDoubleToFixed(transform->m[2][0]);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
|
2002-11-11 12:46:17 +00:00
|
|
|
|
xtransform.matrix[1][0] = XDoubleToFixed(transform->m[0][1]);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
xtransform.matrix[1][1] = XDoubleToFixed(transform->m[1][1]);
|
2002-11-11 12:46:17 +00:00
|
|
|
|
xtransform.matrix[1][2] = XDoubleToFixed(transform->m[2][1]);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
|
|
|
|
|
|
xtransform.matrix[2][0] = 0;
|
|
|
|
|
|
xtransform.matrix[2][1] = 0;
|
|
|
|
|
|
xtransform.matrix[2][2] = XDoubleToFixed(1);
|
2002-11-11 12:46:17 +00:00
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
XcSetSurfaceTransform(surface->dpy,
|
|
|
|
|
|
_XrSurfaceGetXcSurface(surface),
|
|
|
|
|
|
&xtransform);
|
|
|
|
|
|
|
|
|
|
|
|
return XrStatusSuccess;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-10-16 12:57:00 +00:00
|
|
|
|
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable)
|
2002-11-04 00:24:44 +00:00
|
|
|
|
{
|
|
|
|
|
|
Window root;
|
|
|
|
|
|
int x, y;
|
|
|
|
|
|
unsigned int border, depth;
|
|
|
|
|
|
unsigned int width, height;
|
|
|
|
|
|
|
|
|
|
|
|
XGetGeometry (surface->dpy, drawable,
|
|
|
|
|
|
&root, &x, &y,
|
|
|
|
|
|
&width, &height,
|
|
|
|
|
|
&border, &depth);
|
|
|
|
|
|
|
|
|
|
|
|
_XrSurfaceSetDrawableWH(surface, drawable, width, height);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
_XrSurfaceSetDrawableWH(XrSurface *surface,
|
|
|
|
|
|
Drawable drawable,
|
|
|
|
|
|
unsigned int width,
|
|
|
|
|
|
unsigned int height)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
2002-11-01 19:45:30 +00:00
|
|
|
|
if (surface->gc)
|
|
|
|
|
|
XFreeGC(surface->dpy, surface->gc);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
|
|
|
|
|
surface->drawable = drawable;
|
2002-11-04 00:24:44 +00:00
|
|
|
|
surface->width = width;
|
|
|
|
|
|
surface->height = height;
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->gc = XCreateGC(surface->dpy, surface->drawable, 0, 0);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->needs_new_xc_surface = 1;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-10-16 12:57:00 +00:00
|
|
|
|
_XrSurfaceSetVisual(XrSurface *surface, Visual *visual)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
2002-10-30 21:54:50 +00:00
|
|
|
|
surface->xc_format = XcFindVisualFormat(surface->dpy, visual);
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->needs_new_xc_surface = 1;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-10-16 12:57:00 +00:00
|
|
|
|
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format)
|
2002-07-23 07:22:23 +00:00
|
|
|
|
{
|
2002-11-04 00:24:44 +00:00
|
|
|
|
surface->format = format;
|
2002-10-30 21:54:50 +00:00
|
|
|
|
surface->xc_format = XcFindStandardFormat(surface->dpy, format);
|
2002-11-04 00:24:44 +00:00
|
|
|
|
|
|
|
|
|
|
switch (surface->format) {
|
|
|
|
|
|
case XrFormatARGB32:
|
|
|
|
|
|
surface->depth = 32;
|
|
|
|
|
|
case XrFormatRGB32:
|
|
|
|
|
|
/* XXX: Is this correct? */
|
|
|
|
|
|
surface->depth = 24;
|
|
|
|
|
|
case XrFormatA8:
|
|
|
|
|
|
surface->depth = 8;
|
|
|
|
|
|
case XrFormatA1:
|
|
|
|
|
|
surface->depth = 1;
|
|
|
|
|
|
default:
|
|
|
|
|
|
surface->depth = 32;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
surface->needs_new_xc_surface = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XcSurface *
|
|
|
|
|
|
_XrSurfaceGetXcSurface(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (surface == NULL)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (! surface->needs_new_xc_surface)
|
|
|
|
|
|
return surface->xc_surface;
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->xc_surface)
|
|
|
|
|
|
XcFreeSurface(surface->dpy, surface->xc_surface);
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->drawable)
|
|
|
|
|
|
surface->xc_surface = XcCreateDrawableSurface(surface->dpy,
|
|
|
|
|
|
surface->drawable,
|
|
|
|
|
|
surface->xc_format,
|
|
|
|
|
|
surface->xc_sa_mask,
|
|
|
|
|
|
&surface->xc_sa);
|
|
|
|
|
|
else
|
|
|
|
|
|
/* XXX: Is this what we wnat to do here? */
|
|
|
|
|
|
surface->xc_surface = 0;
|
|
|
|
|
|
|
|
|
|
|
|
surface->needs_new_xc_surface = 0;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
2002-11-01 19:45:30 +00:00
|
|
|
|
return surface->xc_surface;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
2002-10-30 21:54:50 +00:00
|
|
|
|
|
|
|
|
|
|
Picture
|
|
|
|
|
|
_XrSurfaceGetPicture(XrSurface *surface)
|
|
|
|
|
|
{
|
2002-11-01 19:45:30 +00:00
|
|
|
|
return XcSurfaceGetPicture(_XrSurfaceGetXcSurface(surface));
|
2002-10-30 21:54:50 +00:00
|
|
|
|
}
|
2002-11-04 00:24:44 +00:00
|
|
|
|
|
|
|
|
|
|
Drawable
|
|
|
|
|
|
_XrSurfaceGetDrawable(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
return surface->drawable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
|
|
_XrSurfaceGetWidth(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
return surface->width;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
|
|
_XrSurfaceGetHeight(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
return surface->height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
|
|
_XrSurfaceGetDepth(XrSurface *surface)
|
|
|
|
|
|
{
|
|
|
|
|
|
return surface->depth;
|
|
|
|
|
|
}
|