back-ericwa-experimental: delete a pile of legacy code

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/branches/ericwa-experimental@34068 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Eric Wasylishen 2011-10-25 19:30:02 +00:00
parent 401132302e
commit addea6d663
27 changed files with 28 additions and 7283 deletions

View file

@ -1,43 +0,0 @@
/*
Win32CairoGlitzSurface.h
Copyright (C) 2008 Free Software Foundation, Inc.
March 2nd, 2008
Author: Xavier Glattard <xavier.glattard@free.fr>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef Win32CairoGlitzSurface_h
#define Win32CairoGlitzSurface_h
#include "win32/WIN32Server.h"
#include "cairo/CairoSurface.h"
@interface Win32CairoGlitzSurface : CairoSurface
{
}
@end
#endif

View file

@ -1,43 +0,0 @@
/*
Win32CairoSurface.h
Copyright (C) 2008 Free Software Foundation, Inc.
March 2nd, 2008
Author: Xavier Glattard <xavier.glattard@free.fr>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef Win32CairoSurface_h
#define Win32CairoSurface_h
#include "win32/WIN32Server.h"
#include "cairo/CairoSurface.h"
@interface Win32CairoSurface : CairoSurface
{
}
@end
#endif

View file

@ -1,40 +0,0 @@
/*
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef XGCairoGlitzSurface_h
#define XGCairoGlitzSurface_h
#include "x11/XGServer.h"
#include "x11/XGServerWindow.h"
#include "cairo/CairoSurface.h"
@interface XGCairoGlitzSurface : CairoSurface
{
}
@end
#endif

View file

@ -1,37 +0,0 @@
/*
Copyright (C) 2002 Free Software Foundation, Inc.
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef XGCairoSurface_h
#define XGCairoSurface_h
#include "cairo/CairoSurface.h"
@interface XGCairoSurface : CairoSurface
{
}
@end
#endif

View file

@ -1,41 +0,0 @@
/*
Copyright (C) 2002 Free Software Foundation, Inc.
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef XGCairoXImageSurface_h
#define XGCairoXImageSurface_h
#include "cairo/CairoSurface.h"
@class XWindowBuffer;
@interface XGCairoXImageSurface : CairoSurface
{
@private
XWindowBuffer *wi;
}
@end
#endif

View file

@ -1,112 +0,0 @@
/* $XConsortium: StdCmap.h,v 1.4 94/04/17 20:16:15 converse Exp $ */
/*
Copyright (c) 1988 X Consortium
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.
*/
/*
* The interfaces described by this header file are for miscellaneous utilities
* and are not part of the Xlib standard.
*/
#ifndef _XMU_STDCMAP_H_
#define _XMU_STDCMAP_H_
#include <X11/Xfuncproto.h>
_XFUNCPROTOBEGIN
Status XmuAllStandardColormaps(
#if NeedFunctionPrototypes
Display* /* dpy */
#endif
);
Status XmuCreateColormap(
#if NeedFunctionPrototypes
Display* /* dpy */,
XStandardColormap* /* colormap */
#endif
);
void XmuDeleteStandardColormap(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
Atom /* property */
#endif
);
Status XmuGetColormapAllocation(
#if NeedFunctionPrototypes
XVisualInfo* /* vinfo */,
Atom /* property */,
unsigned long* /* red_max_return */,
unsigned long* /* green_max_return */,
unsigned long* /* blue_max_return */
#endif
);
Status XmuLookupStandardColormap(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
VisualID /* visualid */,
unsigned int /* depth */,
Atom /* property */,
Bool /* replace */,
Bool /* retain */
#endif
);
XStandardColormap *XmuStandardColormap(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
VisualID /* visualid */,
unsigned int /* depth */,
Atom /* property */,
Colormap /* cmap */,
unsigned long /* red_max */,
unsigned long /* green_max */,
unsigned long /* blue_max */
#endif
);
Status XmuVisualStandardColormaps(
#if NeedFunctionPrototypes
Display* /* dpy */,
int /* screen */,
VisualID /* visualid */,
unsigned int /* depth */,
Bool /* replace */,
Bool /* retain */
#endif
);
_XFUNCPROTOEND
#endif /* _XMU_STDCMAP_H_ */

View file

@ -86,7 +86,6 @@ typedef struct _gswindow_device_t {
Window root; /* Handle of root window */
Window parent; /* Handle of parent window */
int screen; /* Screeen this window is on */
GC gc; /* GC for drawing */
long number; /* Globally unique identifier */
unsigned int depth; /* Window depth */
unsigned int border; /* Border size */
@ -98,12 +97,8 @@ typedef struct _gswindow_device_t {
unsigned int buffer_width; /* Size in pixels of the current buffers. */
unsigned int buffer_height;
Drawable buffer; /* Backing store pixmap */
Drawable alpha_buffer; /* Alpha buffer. Managed by gdriver
will be freed if HandlesBacking=0 */
BOOL is_exposed;
NSMutableArray *exposedRects; /* List of exposure event rects */
Region region; /* Used between several expose events */
XWMHints gen_hints;
XSizeHints siz_hints;
GNUstepWMAttributes win_attrs;
@ -124,8 +119,6 @@ typedef struct _gswindow_device_t {
#endif
} gswindow_device_t;
#define GET_XDRAWABLE(win) ((win)->buffer ? (win)->buffer: (win)->ident)
@interface XGServer (DPSWindow)
+ (gswindow_device_t *) _windowForXWindow: (Window)xWindow;
+ (gswindow_device_t *) _windowForXParent: (Window)xWindow;

View file

@ -1,152 +0,0 @@
/*
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
Author: Alexander Malmberg <alexander@malmberg.org>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef XWindowBuffer_h
#define XWindowBuffer_h
#include <config.h>
#ifdef XSHM
#include <X11/extensions/XShm.h>
#else
// FIXME
#define XShmSegmentInfo int
#endif
struct XWindowBuffer_depth_info_s
{
/* The drawing depth according to X. Usually the number of bits of color
data in each pixel. */
int drawing_depth;
/* The number of bytes used by a pixel. There is generally no
relationship between this and drawing_depth, except that
bytes_per_pixel*8>=drawing_depth. (Eg. 32-bit modes usually have a
drawing depth of 24.) */
int bytes_per_pixel;
/* If alpha is to be stored inside the normal data, this should be YES.
Otherwise, a separate buffer will be allocated for the alpha data (which
never does any harm, but it wastes memory if there's enough space in a
pixel, as in 32-bit modes. There needs to be 8 bits available for alpha
data at a byte boundary for this to work, though. (This could be fixed,
but in the mean time, just setting inline_alpha to NO is easier.)
inline_alpha_ofs should be the offset to the byte in each pixel that
holds the alpha value. */
BOOL inline_alpha;
int inline_alpha_ofs;
/* The byte order used for the buffer. This must be either MSBFirst or
LSBFirst. */
int byte_order;
};
/*
XWindowBuffer maintains an XImage for a window. Each ARTGState that
renders to that window uses the same XWindowBuffer (and thus the same
buffer, etc.).
Many states might render to the same window, so we need to make sure
that there's only one XWindowBuffer for each window. */
@interface XWindowBuffer : NSObject
{
@public
gswindow_device_t *window;
@private
GC gc;
Drawable drawable;
XImage *ximage;
Display *display;
Pixmap pixmap;
int use_shm;
XShmSegmentInfo shminfo;
struct XWindowBuffer_depth_info_s DI;
/* While a XShmPutImage is in progress we don't try to call it
again. The pending updates are stored here, and when we get the
ShmCompletion event, we handle them. */
int pending_put; /* There are pending updates */
struct
{
int x, y, w, h;
} pending_rect; /* in this rectangle. */
int pending_event; /* We're waiting for the ShmCompletion event. */
/* This is for the ugly shape-hack */
unsigned char *old_shape;
int old_shape_size;
@public
unsigned char *data;
int sx, sy;
int bytes_per_line, bits_per_pixel, bytes_per_pixel;
/* If has_alpha is 1 and alpha is NULL, the alpha is stored in data
somehow. The drawing mechanism code should know how to deal with
it. A separate alpha buffer will always be exactly the right size,
so each row is sx bytes long.
If has_alpha is 0, the window is assumed to be completely opaque.
*/
unsigned char *alpha;
int has_alpha;
}
/*
Returns a _retained_ XWindowBuffer for the specified gswindow_device_t.
The depth info is only used if a new XWindowBuffer needs to be allocated.
*/
+ windowBufferForWindow: (gswindow_device_t *)awindow
depthInfo: (struct XWindowBuffer_depth_info_s *)aDI;
/*
Note that alpha is _not_ guaranteed to exist after this has been called;
you still need to check has_alpha. If the call fails, a message will be
logged.
(In ARTGState, I handle failures by simply ignoring the operation that
required alpha.)
The alpha channel is initialized to being completely opaque when first
created.
*/
-(void) needsAlpha;
-(void) _gotShmCompletion;
-(void) _exposeRect: (NSRect)r;
+(void) _gotShmCompletion: (Drawable)d;
@end
#endif

View file

@ -1,477 +0,0 @@
/*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Environment variables:
*
* WRASTER_GAMMA <rgamma>/<ggamma>/<bgamma>
* gamma correction value. Must be greater than 0
* Only for PseudoColor visuals.
*
* Default:
* WRASTER_GAMMA 1/1/1
*
*
* If you want a specific value for a screen, append the screen number
* preceded by a hash to the variable name as in
* WRASTER_GAMMA#1
* for screen number 1
*/
#ifndef RLRASTER_H_
#define RLRASTER_H_
/* version of the header for the library: 0.21 */
#define WRASTER_HEADER_VERSION 21
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef XSHM
#include <X11/extensions/XShm.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* RBestMatchRendering or RDitheredRendering */
#define RC_RenderMode (1<<0)
/* number of colors per channel for colormap in PseudoColor mode */
#define RC_ColorsPerChannel (1<<1)
/* do gamma correction */
#define RC_GammaCorrection (1<<2)
/* visual id to use */
#define RC_VisualID (1<<3)
/* shared memory usage */
#define RC_UseSharedMemory (1<<4)
/* use default instead of best visual */
#define RC_DefaultVisual (1<<5)
/* filter type for smoothed scaling */
#define RC_ScalingFilter (1<<6)
/* standard colormap usage */
#define RC_StandardColormap (1<<7)
/* std colormap usage/creation modes */
enum {
RUseStdColormap, /* default. fallbacks to RIgnore.. if
there is none defined */
RCreateStdColormap,
RIgnoreStdColormap
};
typedef struct RContextAttributes {
int flags;
int render_mode;
int colors_per_channel; /* for PseudoColor */
float rgamma; /* gamma correction for red, */
float ggamma; /* green, */
float bgamma; /* and blue */
VisualID visualid; /* visual ID to use */
int use_shared_memory; /* True of False */
int scaling_filter;
int standard_colormap_mode; /* what to do with std cma */
} RContextAttributes;
/*
* describes a screen in terms of depth, visual, number of colors
* we can use, if we should do dithering, and what colors to use for
* dithering.
*/
typedef struct RContext {
Display *dpy;
int screen_number;
Colormap cmap;
RContextAttributes *attribs;
GC copy_gc;
Visual *visual;
int depth;
Window drawable; /* window to pass for XCreatePixmap().*/
/* generally = root */
int vclass;
unsigned long black;
unsigned long white;
int red_offset; /* only used in 24bpp */
int green_offset;
int blue_offset;
/* only used for pseudocolor and grayscale */
XStandardColormap *std_rgb_map; /* standard RGB colormap */
XStandardColormap *std_gray_map; /* standard grayscale colormap */
int ncolors; /* total number of colors we can use */
XColor *colors; /* internal colormap */
unsigned long *pixels; /* RContext->colors[].pixel */
struct {
unsigned int use_shared_pixmap:1;
unsigned int optimize_for_speed:1;
} flags;
struct RHermesData *hermes_data; /* handle for Hermes stuff */
} RContext;
typedef struct RColor {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
} RColor;
typedef struct RHSVColor {
unsigned short hue; /* 0-359 */
unsigned char saturation; /* 0-255 */
unsigned char value; /* 0-255 */
} RHSVColor;
typedef struct RPoint {
int x, y;
} RPoint;
typedef struct RSegment {
int x1, y1, x2, y2;
} RSegment;
/* image formats */
enum RImageFormat {
RRGBFormat,
RRGBAFormat
};
/*
* internal 24bit+alpha image representation
*/
typedef struct RImage {
unsigned char *data; /* image data RGBA or RGB */
int width, height; /* size of the image */
enum RImageFormat format;
RColor background; /* background color */
int refCount;
} RImage;
/*
* internal wrapper for XImage. Used for shm abstraction
*/
typedef struct RXImage {
XImage *image;
/* Private data. Do not access */
#ifdef XSHM
XShmSegmentInfo info;
char is_shared;
#endif
} RXImage;
/* image display modes */
enum {
RDitheredRendering = 0,
RBestMatchRendering = 1
};
/* smoothed scaling filter types */
enum {
RBoxFilter,
RTriangleFilter,
RBellFilter,
RBSplineFilter,
RLanczos3Filter,
RMitchellFilter
};
/* note that not all operations are supported in all functions */
enum {
RClearOperation, /* clear with 0 */
RCopyOperation,
RNormalOperation, /* same as combine */
RAddOperation,
RSubtractOperation
};
enum {
RAbsoluteCoordinates = 0,
RRelativeCoordinates = 1
};
enum {
RSunkenBevel = -1,
RNoBevel = 0,
RRaisedBevel = 1
};
/* bw compat */
#define RBEV_SUNKEN RSunkenBevel
/* 1 pixel wide */
#define RBEV_RAISED RRaisedBevel
/* 1 pixel wide on top/left 2 on bottom/right */
#define RBEV_RAISED2 2
/* 2 pixel width */
#define RBEV_RAISED3 3
enum {
RHorizontalGradient = 2,
RVerticalGradient = 3,
RDiagonalGradient = 4
};
/* for backwards compatibility */
#define RGRD_HORIZONTAL RHorizontalGradient
#define RGRD_VERTICAL RVerticalGradient
#define RGRD_DIAGONAL RDiagonalGradient
/* error codes */
#define RERR_NONE 0
#define RERR_OPEN 1 /* cant open file */
#define RERR_READ 2 /* error reading from file */
#define RERR_WRITE 3 /* error writing to file */
#define RERR_NOMEMORY 4 /* out of memory */
#define RERR_NOCOLOR 5 /* out of color cells */
#define RERR_BADIMAGEFILE 6 /* image file is corrupted or invalid */
#define RERR_BADFORMAT 7 /* image file format is unknown */
#define RERR_BADINDEX 8 /* no such image index in file */
#define RERR_BADVISUALID 16 /* invalid visual ID requested for context */
#define RERR_STDCMAPFAIL 17 /* failed to created std colormap */
#define RERR_XERROR 127 /* internal X error */
#define RERR_INTERNAL 128 /* should not happen */
/*
* Returns a NULL terminated array of strings containing the
* supported formats, such as: TIFF, XPM, PNG, JPEG, PPM, GIF
* Do not free the returned data.
*/
char **RSupportedFileFormats(void);
char *RGetImageFileFormat(char *file);
/*
* Xlib contexts
*/
RContext *RCreateContext(Display *dpy, int screen_number,
RContextAttributes *attribs);
void RDestroyContext(RContext *context);
Bool RGetClosestXColor(RContext *context, RColor *color, XColor *retColor);
/*
* RImage creation
*/
RImage *RCreateImage(unsigned width, unsigned height, int alpha);
RImage *RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask);
RImage *RCreateImageFromDrawable(RContext *context, Drawable drawable,
Pixmap mask);
RImage *RLoadImage(RContext *context, char *file, int index);
RImage* RRetainImage(RImage *image);
void RReleaseImage(RImage *image);
/* Obsoleted function. Use RReleaseImage() instead. This was kept only to
* allow a smoother transition and to avoid breaking existing programs, but
* it will be removed in a future release. Right now is just an alias to
* RReleaseImage(). Do _NOT_ use RDestroyImage() anymore in your programs.
* Being an alias to RReleaseImage() this function no longer actually
* destroys the image, unless the image is no longer retained in some other
* place.
*/
void RDestroyImage(RImage *image);
RImage *RGetImageFromXPMData(RContext *context, char **xpmData);
/*
* RImage storing
*/
Bool RSaveImage(RImage *image, char *filename, char *format);
/*
* Area manipulation
*/
RImage *RCloneImage(RImage *image);
RImage *RGetSubImage(RImage *image, int x, int y, unsigned width,
unsigned height);
void RCombineImageWithColor(RImage *image, RColor *color);
void RCombineImages(RImage *image, RImage *src);
void RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
unsigned height, int dx, int dy);
void RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness);
void RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
unsigned width, unsigned height, int dx, int dy,
int opaqueness);
RImage *RScaleImage(RImage *image, unsigned new_width, unsigned new_height);
RImage *RSmoothScaleImage(RImage *src, unsigned new_width,
unsigned new_height);
RImage *RRotateImage(RImage *image, float angle);
RImage *RMakeTiledImage(RImage *tile, unsigned width, unsigned height);
RImage* RMakeCenteredImage(RImage *image, unsigned width, unsigned height,
RColor *color);
/*
* Drawing
*/
Bool RGetPixel(RImage *image, int x, int y, RColor *color);
void RPutPixel(RImage *image, int x, int y, RColor *color);
void ROperatePixel(RImage *image, int operation, int x, int y, RColor *color);
void RPutPixels(RImage *image, RPoint *points, int npoints, int mode,
RColor *color);
void ROperatePixels(RImage *image, int operation, RPoint *points,
int npoints, int mode, RColor *color);
int RDrawLine(RImage *image, int x0, int y0, int x1, int y1, RColor *color);
int ROperateLine(RImage *image, int operation, int x0, int y0, int x1, int y1,
RColor *color);
void RDrawLines(RImage *image, RPoint *points, int npoints, int mode,
RColor *color);
void ROperateLines(RImage *image, int operation, RPoint *points, int npoints,
int mode, RColor *color);
void RDrawSegments(RImage *image, RSegment *segs, int nsegs, RColor *color);
void ROperateSegments(RImage *image, int operation, RSegment *segs, int nsegs,
RColor *color);
/*
* Color convertion
*/
void RRGBtoHSV(RColor *color, RHSVColor *hsv);
void RHSVtoRGB(RHSVColor *hsv, RColor *rgb);
/*
* Painting
*/
void RClearImage(RImage *image, RColor *color);
void RFillImage(RImage *image, RColor *color);
void RBevelImage(RImage *image, int bevel_type);
RImage *RRenderGradient(unsigned width, unsigned height, RColor *from,
RColor *to, int style);
RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor **colors,
int style);
RImage *RRenderInterwovenGradient(unsigned width, unsigned height,
RColor colors1[2], int thickness1,
RColor colors2[2], int thickness2);
/*
* Convertion into X Pixmaps
*/
int RConvertImage(RContext *context, RImage *image, Pixmap *pixmap);
int RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
Pixmap *mask, int threshold);
/*
* misc. utilities
*/
RXImage *RCreateXImage(RContext *context, int depth,
unsigned width, unsigned height);
RXImage *RGetXImage(RContext *context, Drawable d, int x, int y,
unsigned width, unsigned height);
void RDestroyXImage(RContext *context, RXImage *ximage);
void RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage,
int src_x, int src_y, int dest_x, int dest_y,
unsigned width, unsigned height);
/* do not free the returned string! */
const char *RMessageForError(int errorCode);
int RBlurImage(RImage *image);
/****** Global Variables *******/
extern int RErrorCode;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View file

@ -53,7 +53,7 @@
# include "cairo/XGCairoModernSurface.h"
# endif /* USE_GLITZ */
# include "x11/XGServerWindow.h"
# include "x11/XWindowBuffer.h"
//# include "x11/XWindowBuffer.h"
#elif BUILD_SERVER == SERVER_win32
# include <windows.h>
# ifdef USE_GLITZ
@ -116,12 +116,13 @@
/* Private backend methods */
+ (void) handleExposeRect: (NSRect)rect forDriver: (void *)driver
{
if ([(id)driver isKindOfClass: [XWindowBuffer class]])
{
// For XGCairoXImageSurface
[(XWindowBuffer *)driver _exposeRect: rect];
}
else if ([(id)driver isKindOfClass: [CairoSurface class]])
// if ([(id)driver isKindOfClass: [XWindowBuffer class]])
// {
// // For XGCairoXImageSurface
// [(XWindowBuffer *)driver _exposeRect: rect];
// }
// else
if ([(id)driver isKindOfClass: [CairoSurface class]])
{
// For XGCairoModernSurface
[(CairoSurface *)driver handleExposeRect: rect];
@ -132,12 +133,12 @@
+ (void) _gotShmCompletion: (Drawable)d
{
[XWindowBuffer _gotShmCompletion: d];
// [XWindowBuffer _gotShmCompletion: d];
}
- (void) gotShmCompletion: (Drawable)d
{
[XWindowBuffer _gotShmCompletion: d];
// [XWindowBuffer _gotShmCompletion: d];
}
#endif // XSHM

View file

@ -39,20 +39,7 @@ cairo_OBJC_FILES = CairoSurface.m \
CairoPDFSurface.m \
ifeq ($(BUILD_SERVER),x11)
ifeq ($(WITH_GLITZ),yes)
cairo_OBJC_FILES += XGCairoGlitzSurface.m
else
cairo_OBJC_FILES += XGCairoSurface.m XGCairoXImageSurface.m XGCairoModernSurface.m
endif
else
ifeq ($(BUILD_GRAPHICS),cairo)
ifeq ($(WITH_GLITZ),yes)
cairo_OBJC_FILES += Win32CairoGlitzSurface.m
else
cairo_OBJC_FILES += Win32CairoSurface.m
# Win32CairoXImageSurface.m
endif
endif
cairo_OBJC_FILES += XGCairoModernSurface.m
endif
cairo_OBJC_FILES +=

View file

@ -1,162 +0,0 @@
/*
Win32CairoGlitzSurface.m
Copyright (C) 2008 Free Software Foundation, Inc.
Author: Xavier Glattard <xavier.glattard@online.fr>
Based on the work of:
Alexander Malmberg <alexander@malmberg.org>
Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "cairo/Win32CairoGlitzSurface.h"
#include <cairo-glitz.h>
#include <glitz-wgl.h>
#define GSWINDEVICE ((HWND)gsDevice)
@implementation Win32CairoGlitzSurface
+ (void) initialize
{
NSLog(@"Win32CairoGlitzSurface : %d : glitz_wgl_init", __LINE__);
glitz_wgl_init(NULL);
}
- (id) initWithDevice: (void *)device
{
WIN_INTERN *win;
unsigned long mask = 0;
glitz_drawable_format_t dtempl;
//static
glitz_drawable_format_t *dformat = NULL;
glitz_drawable_t *drawable = NULL;
glitz_format_t *format = NULL;
glitz_surface_t *surface = NULL;
RECT sz;
gsDevice = device;
GetClientRect(GSWINDEVICE, &sz);
win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA);
if (win && win->useHDC)
{
HGDIOBJ old;
old = SelectObject(win->hdc, win->old);
DeleteObject(old);
DeleteDC(win->hdc);
win->hdc = NULL;
win->old = NULL;
win->useHDC = NO;
}
//NSLog(@"Win32CairoGlitzSurface : init window %d (%d,%d-%d,%d)",GSWINDEVICE,sz.left,sz.top,sz.right,sz.bottom);
//if(!dformat)
{
dtempl.samples = 1;
mask |= GLITZ_FORMAT_SAMPLES_MASK;
dtempl.color.red_size = 8;
dtempl.color.green_size = 8;
dtempl.color.blue_size = 8;
dtempl.color.alpha_size = 8;
dtempl.color.fourcc = GLITZ_FOURCC_RGB;
mask |= GLITZ_FORMAT_FOURCC_MASK
| GLITZ_FORMAT_RED_SIZE_MASK
| GLITZ_FORMAT_GREEN_SIZE_MASK
| GLITZ_FORMAT_BLUE_SIZE_MASK
| GLITZ_FORMAT_ALPHA_SIZE_MASK;
dtempl.doublebuffer = 0;
mask |= GLITZ_FORMAT_DOUBLEBUFFER_MASK;
dformat = glitz_wgl_find_window_format(mask, &dtempl, 0);
if (!dformat)
{
NSLog(@"Win32CairoGlitzSurface : %d : no format for drawable",__LINE__);
exit(1);
}
/* NSLog (@"ID:%d RGBA:%d/%d/%d/%d D:%d St:%d DB:%d S:%d",
(int) dformat->id,
dformat->color.red_size,
dformat->color.green_size,
dformat->color.blue_size,
dformat->color.alpha_size,
dformat->depth_size,
dformat->stencil_size,
dformat->doublebuffer,
dformat->samples
);
*/
}
drawable = glitz_wgl_create_drawable_for_window(
dformat,
GSWINDEVICE,
sz.right - sz.left,
sz.bottom - sz.top);
if (!drawable)
{
NSLog(@"Win32CairoGlitzSurface : %d : no glitz drawable",__LINE__);
exit(1);
}
format = glitz_find_standard_format(drawable, GLITZ_STANDARD_ARGB32);
if (!format)
{
NSLog(@"Win32CairoGlitzSurface : %d (%d) : couldn't find ARGB32 surface format",__LINE__,GSWINDEVICE);
exit(1);
}
surface = glitz_surface_create(
drawable, format,
sz.right - sz.left,
sz.bottom - sz.top,
0, NULL);
if (!surface)
{
NSLog(@"Win32CairoGlitzSurface : %d : couldn't create glitz surface",__LINE__);
exit(1);
}
glitz_surface_attach(surface, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
_surface = cairo_glitz_surface_create(surface);
if (cairo_surface_status(_surface))
{
DESTROY(self);
}
return self;
}
- (NSSize) size
{
RECT sz;
GetClientRect(GSWINDEVICE, &sz);
return NSMakeSize(sz.right - sz.left, sz.bottom - sz.top);
}
@end

View file

@ -1,73 +0,0 @@
/*
Win32CairoSurface.m
Copyright (C) 2008 Free Software Foundation, Inc.
Author: Xavier Glattard <xavier.glattard@online.fr>
Based on the work of:
Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "cairo/Win32CairoSurface.h"
#include <cairo-win32.h>
#define GSWINDEVICE ((HWND)gsDevice)
@implementation Win32CairoSurface
- (id) initWithDevice: (void *)device
{
HDC hDC;
WIN_INTERN *win;
gsDevice = device;
win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA);
if (win && win->useHDC)
hDC = win->hdc;
else
hDC = GetDC(GSWINDEVICE);
if (!hDC)
{
NSLog(@"Win32CairoSurface : %d : no device context",__LINE__);
exit(1);
}
_surface = cairo_win32_surface_create(hDC);
if (!(win && win->useHDC))
ReleaseDC(GSWINDEVICE, hDC);
if (cairo_surface_status(_surface))
{
DESTROY(self);
}
return self;
}
- (NSSize) size
{
RECT sz;
GetClientRect(GSWINDEVICE, &sz);
return NSMakeSize(sz.right - sz.left, sz.top - sz.bottom);
}
@end

View file

@ -1,105 +0,0 @@
/*
Copyright (C) 2002 Free Software Foundation, Inc.
Author: Alexander Malmberg <alexander@malmberg.org>
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "cairo/XGCairoGlitzSurface.h"
#include <cairo-glitz.h>
#include <glitz-glx.h>
#define GSWINDEVICE ((gswindow_device_t *)gsDevice)
@implementation XGCairoGlitzSurface
- (id) initWithDevice: (void *)device
{
glitz_drawable_format_t templ;
glitz_drawable_format_t *dformat = NULL;
glitz_drawable_t *drawable = NULL;
glitz_format_t *format = NULL;
glitz_surface_t *surface = NULL;
gsDevice = device;
/*
if (GSWINDEVICE->type != NSBackingStoreNonretained)
{
XSetWindowBackgroundPixmap(GSWINDEVICE->display,
GSWINDEVICE->ident,
GSWINDEVICE->buffer);
}
*/
templ.doublebuffer = 0;
dformat = glitz_glx_find_drawable_format_for_visual(GSWINDEVICE->display,
GSWINDEVICE->screen,
XVisualIDFromVisual(DefaultVisual(GSWINDEVICE->display, GSWINDEVICE->screen)));
if (!dformat)
{
NSLog(@"XGCairoGlitzSurface : %d : no format",__LINE__);
exit(1);
}
drawable = glitz_glx_create_drawable_for_window(GSWINDEVICE->display,
GSWINDEVICE->screen,
dformat,
GSWINDEVICE->ident,
GSWINDEVICE->xframe.size.width,
GSWINDEVICE->xframe.size.height);
if (!drawable)
{
NSLog(@"XGCairoGlitzSurface : %d : no glitz drawable", __LINE__);
exit(1);
}
format = glitz_find_standard_format(drawable, GLITZ_STANDARD_ARGB32);
if (!format)
{
NSLog(@"XGCairoGlitzSurface : %d : couldn't find ARGB32 surface format", __LINE__);
exit(1);
}
surface = glitz_surface_create(drawable, format,
GSWINDEVICE->xframe.size.width,
GSWINDEVICE->xframe.size.height,
0, NULL);
if (!surface)
{
NSLog(@"XGCairoGlitzSurface : %d : couldn't create glitz surface", __LINE__);
exit(1);
}
glitz_surface_attach(surface, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
_surface = cairo_glitz_surface_create(surface);
return self;
}
- (NSSize) size
{
return GSWINDEVICE->xframe.size;
}
@end

View file

@ -1,175 +0,0 @@
/*
Copyright (C) 2002 Free Software Foundation, Inc.
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <AppKit/NSImage.h>
#include <AppKit/NSGraphics.h>
#include "x11/XGServer.h"
#include "x11/XGServerWindow.h"
#include "cairo/XGCairoSurface.h"
#include <cairo-xlib.h>
#define GSWINDEVICE ((gswindow_device_t *)gsDevice)
@implementation XGCairoSurface
- (id) initWithDevice: (void *)device
{
Display *dpy;
Drawable drawable;
Visual* visual;
XWindowAttributes attributes;
gsDevice = device;
dpy = GSWINDEVICE->display;
if (GSWINDEVICE->type != NSBackingStoreNonretained)
{
drawable = GSWINDEVICE->buffer;
}
else
{
drawable = GSWINDEVICE->ident;
}
/*
if (GSWINDEVICE->type != NSBackingStoreNonretained)
{
GSWINDEVICE->gdriverProtocol |= GDriverHandlesExpose;
XSetWindowBackgroundPixmap(GSWINDEVICE->display,
GSWINDEVICE->ident,
GSWINDEVICE->buffer);
}
*/
if (!XGetWindowAttributes (dpy, GSWINDEVICE->ident, &attributes))
{
visual = DefaultVisual (dpy, DefaultScreen (dpy));
}
else
{
visual = attributes.visual;
}
_surface = cairo_xlib_surface_create(dpy,
drawable,
visual,
GSWINDEVICE->xframe.size.width,
GSWINDEVICE->xframe.size.height);
return self;
}
- (NSSize) size
{
return GSWINDEVICE->xframe.size;
}
@end
@implementation XGServer (ScreenCapture)
- (NSImage *) contentsOfScreen: (int)screen inRect: (NSRect)rect
{
Window win;
XWindowAttributes attrs;
win = [self xDisplayRootWindowForScreen: screen];
if (XGetWindowAttributes(dpy, win, &attrs))
{
NSInteger width = rect.size.width;
NSInteger height = rect.size.height;
NSImage *result;
NSBitmapImageRep *bmp;
cairo_surface_t *src, *dest;
// Convert rect to flipped coordinates
rect.origin.y = attrs.height - NSMaxY(rect);
bmp = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
pixelsWide: width
pixelsHigh: height
bitsPerSample: 8
samplesPerPixel: 4
hasAlpha: YES
isPlanar: NO
colorSpaceName: NSDeviceRGBColorSpace
bitmapFormat: 0
bytesPerRow: 0
bitsPerPixel: 32] autorelease];
src = cairo_xlib_surface_create(dpy, win, attrs.visual, attrs.width, attrs.height);
dest = cairo_image_surface_create_for_data([bmp bitmapData], CAIRO_FORMAT_ARGB32, width, height, [bmp bytesPerRow]);
{
cairo_t *cr = cairo_create(dest);
cairo_set_source_surface(cr, src, -1 * rect.origin.x, -1 * rect.origin.y);
cairo_paint(cr);
cairo_destroy(cr);
}
cairo_surface_destroy(src);
cairo_surface_destroy(dest);
// Convert BGRA to RGBA
{
NSInteger stride;
NSInteger x, y;
unsigned char *cdata;
stride = [bmp bytesPerRow];
cdata = [bmp bitmapData];
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
NSInteger i = (y * stride) + (x * 4);
unsigned char d = cdata[i];
#if GS_WORDS_BIGENDIAN
cdata[i] = cdata[i + 1];
cdata[i + 1] = cdata[i + 2];
cdata[i + 2] = cdata[i + 3];
cdata[i + 3] = d;
#else
cdata[i] = cdata[i + 2];
//cdata[i + 1] = cdata[i + 1];
cdata[i + 2] = d;
//cdata[i + 3] = cdata[i + 3];
#endif
}
}
}
result = [[[NSImage alloc] initWithSize: NSMakeSize(width, height)] autorelease];
[result addRepresentation: bmp];
return result;
}
return nil;
}
@end

View file

@ -1,85 +0,0 @@
/*
Copyright (C) 2002 Free Software Foundation, Inc.
Author: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "x11/XGServer.h"
#include "x11/XGServerWindow.h"
#include "x11/XWindowBuffer.h"
#include "cairo/XGCairoXImageSurface.h"
#include "cairo/XGCairoSurface.h"
#define GSWINDEVICE ((gswindow_device_t *)gsDevice)
@implementation XGCairoXImageSurface
- (id) initWithDevice: (void *)device
{
struct XWindowBuffer_depth_info_s di;
gsDevice = device;
if (GSWINDEVICE->type == NSBackingStoreNonretained)
{
// FIXME: This is a hack to get non-reatined backing store working.
// I see no reason, why it isn't working, as the code is identical
// to the one in the art backend.
RELEASE(self);
return [[XGCairoSurface alloc] initWithDevice: device];
}
di.drawing_depth = GSWINDEVICE->depth;
// FIXME: The next lines may be wrong for depth <> 32.
// But then art uses a depth of 24 for 32 bit modes. Strange!
di.bytes_per_pixel = 4;
di.inline_alpha = YES;
di.inline_alpha_ofs = 0;
/* The cairo image surface uses the client's byte order (cf. bug #28590). */
#if GS_WORDS_BIGENDIAN
di.byte_order = MSBFirst;
#else
di.byte_order = LSBFirst;
#endif
ASSIGN(wi, [XWindowBuffer windowBufferForWindow: GSWINDEVICE depthInfo: &di]);
_surface = cairo_image_surface_create_for_data((unsigned char*)wi->data,
CAIRO_FORMAT_ARGB32,
wi->sx, wi->sy,
wi->bytes_per_line);
return self;
}
- (void) dealloc
{
DESTROY(wi);
[super dealloc];
}
- (NSSize) size
{
return GSWINDEVICE->xframe.size;
}
@end

View file

@ -33,18 +33,8 @@ include ../../config.make
SUBPROJECT_NAME=x11
# The C source files to be compiled
ifeq ($(WITH_WRASTER),yes)
x11_C_FILES = \
xdnd.c
else
x11_C_FILES = \
context.c \
convert.c \
raster.c \
scale.c \
xdnd.c \
xutil.c
endif
# The Objective-C source files to be compiled
x11_OBJC_FILES = \
@ -53,7 +43,6 @@ XGServerEvent.m \
XGServerWindow.m \
XGDragView.m \
XIMInputServer.m \
XWindowBuffer.m\
XGGLFormat.m\
XGGLContext.m

View file

@ -56,12 +56,6 @@ terminate(int sig)
}
}
#ifdef HAVE_WRASTER_H
#include "wraster.h"
#else
#include "x11/wraster.h"
#endif
#include "x11/XGServer.h"
#include "x11/XGInputServer.h"
#ifdef HAVE_GLX
@ -130,218 +124,6 @@ _parse_display_name(NSString *name, int *dn, int *sn)
- (void) setupRunLoopInputSourcesForMode: (NSString*)mode;
@end
@interface XGScreenContext : NSObject
{
RContext *rcontext;
XGDrawMechanism drawMechanism;
}
- initForDisplay: (Display *)dpy screen: (int)screen_number;
- (XGDrawMechanism) drawMechanism;
- (RContext *) context;
@end
@implementation XGScreenContext
- (RContextAttributes *) _getXDefaults
{
int dummy;
RContextAttributes *attribs;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
attribs = (RContextAttributes *)malloc(sizeof(RContextAttributes));
attribs->flags = 0;
if ([defaults boolForKey: @"NSDefaultVisual"])
attribs->flags |= RC_DefaultVisual;
if ((dummy = [defaults integerForKey: @"NSDefaultVisual"]))
{
attribs->flags |= RC_VisualID;
attribs->visualid = dummy;
}
if ((dummy = [defaults integerForKey: @"NSColorsPerChannel"]))
{
attribs->flags |= RC_ColorsPerChannel;
attribs->colors_per_channel = dummy;
}
return attribs;
}
- initForDisplay: (Display *)dpy screen: (int)screen_number
{
RContextAttributes *attribs;
XColor testColor;
unsigned char r, g, b;
/* Get the visual information */
attribs = NULL;
//attribs = [self _getXDefaults];
rcontext = RCreateContext(dpy, screen_number, attribs);
/*
* If we have shared memory available, only use it when the XGPS-Shm
* default is set to YES
*/
if (rcontext->attribs->use_shared_memory == True
&& [[NSUserDefaults standardUserDefaults] boolForKey: @"XGPS-Shm"] != YES)
rcontext->attribs->use_shared_memory = False;
/*
* Crude tests to see if we can accelerate creation of pixels from
* 8-bit red, green and blue color values.
*/
if (rcontext->depth == 12 || rcontext->depth == 16)
{
drawMechanism = XGDM_FAST16;
r = 8;
g = 9;
b = 7;
testColor.pixel = (((r << 5) + g) << 6) + b;
XQueryColor(rcontext->dpy, rcontext->cmap, &testColor);
if (((testColor.red >> 11) != r)
|| ((testColor.green >> 11) != g)
|| ((testColor.blue >> 11) != b))
{
NSLog(@"WARNING - XGServer is unable to use the "
@"fast algorithm for writing to a 16-bit display on "
@"this host - perhaps you'd like to adjust the code "
@"to work ... and submit a patch.");
drawMechanism = XGDM_PORTABLE;
}
}
else if (rcontext->depth == 15)
{
drawMechanism = XGDM_FAST15;
r = 8;
g = 9;
b = 7;
testColor.pixel = (((r << 5) + g) << 5) + b;
XQueryColor(rcontext->dpy, rcontext->cmap, &testColor);
if (((testColor.red >> 11) != r)
|| ((testColor.green >> 11) != g)
|| ((testColor.blue >> 11) != b))
{
NSLog(@"WARNING - XGServer is unable to use the "
@"fast algorithm for writing to a 15-bit display on "
@"this host - perhaps you'd like to adjust the code "
@"to work ... and submit a patch.");
drawMechanism = XGDM_PORTABLE;
}
}
else if (rcontext->depth == 24 || rcontext->depth == 32)
{
drawMechanism = XGDM_FAST32;
r = 32;
g = 33;
b = 31;
testColor.pixel = (((r << 8) + g) << 8) + b;
XQueryColor(rcontext->dpy, rcontext->cmap, &testColor);
if (((testColor.red >> 8) == r)
&& ((testColor.green >> 8) == g)
&& ((testColor.blue >> 8) == b))
{
drawMechanism = XGDM_FAST32;
}
else if (((testColor.red >> 8) == b)
&& ((testColor.green >> 8) == g)
&& ((testColor.blue >> 8) == r))
{
drawMechanism = XGDM_FAST32_BGR;
}
else
{
NSLog(@"WARNING - XGServer is unable to use the "
@"fast algorithm for writing to a 32-bit display on "
@"this host - perhaps you'd like to adjust the code "
@"to work ... and submit a patch.");
drawMechanism = XGDM_PORTABLE;
}
}
else if (rcontext->depth == 8)
{
drawMechanism = XGDM_FAST8;
r = 2;
g = 3;
b = 1;
testColor.pixel = (((r << 3) + g) << 2) + b;
XQueryColor(rcontext->dpy, rcontext->cmap, &testColor);
if (((testColor.red >> 13) != r)
|| ((testColor.green >> 13) != g)
|| ((testColor.blue >> 14) != b))
{
NSLog(@"WARNING - XGServer is unable to use the "
@"fast algorithm for writing to an 8-bit display on "
@"this host - the most likely reason being "
@"the StandardColormap RGB_BEST_MAP has not been installed.");
drawMechanism = XGDM_PORTABLE;
}
}
else
{
NSLog(@"WARNING - XGServer is unable to use a "
@"fast algorithm for writing to the display on "
@"this host - perhaps you'd like to adjust the code "
@"to work ... and submit a patch.");
drawMechanism = XGDM_PORTABLE;
}
NSDebugLLog(@"XGTrace", @"Draw mech %d for screen %d", drawMechanism,
screen_number);
return self;
}
- (void) dealloc
{
#ifndef HAVE_WRASTER_H
// FIXME: context.c does not include a clean up function for Rcontext,
// so we try do it here.
/*
Note that this can be done only when we use our own version of wraster.
If we're using an external version of wraster, the rcontext structure
might be different (different fields, or differently used fields), which
breaks this code.
*/
if (rcontext)
{
XFreeGC(rcontext->dpy, rcontext->copy_gc);
if (rcontext->drawable)
{
XDestroyWindow(rcontext->dpy, rcontext->drawable);
}
if (rcontext->pixels)
{
free(rcontext->pixels);
}
if (rcontext->colors)
{
free(rcontext->colors);
}
if (rcontext->hermes_data)
{
free(rcontext->hermes_data);
}
free(rcontext->attribs);
free(rcontext);
}
#endif
[super dealloc];
}
- (XGDrawMechanism) drawMechanism
{
return drawMechanism;
}
- (RContext *) context
{
return rcontext;
}
@end
/**
<unit>
<heading>XGServer</heading>
@ -502,164 +284,6 @@ _parse_display_name(NSString *name, int *dn, int *sn)
return dpy;
}
- (XGScreenContext *) _screenContextForScreen: (int)screen_number
{
int count = ScreenCount(dpy);
XGScreenContext *screen;
if (screen_number >= count)
{
[NSException raise: NSInvalidArgumentException
format: @"Request for invalid screen"];
}
screen = NSMapGet(screenList, (void *)(uintptr_t)screen_number);
if (screen == NULL)
{
screen = [[XGScreenContext alloc]
initForDisplay: dpy screen: screen_number];
NSMapInsert(screenList, (void *)(uintptr_t)screen_number, (void *)screen);
RELEASE(screen);
}
return screen;
}
/**
Returns a pointer to a structure which describes aspects of the
X windows display
*/
- (void *) xrContextForScreen: (int)screen_number
{
return [[self _screenContextForScreen: screen_number] context];
}
- (Visual *) visualForScreen: (int)screen_number
{
return [[self _screenContextForScreen: screen_number] context]->visual;
}
- (int) depthForScreen: (int)screen_number
{
return [[self _screenContextForScreen: screen_number] context]->depth;
}
/**
Returns the XGDrawMechanism, which roughly describes the depth of
the screen and how pixels should be drawn to the screen for maximum
speed.
*/
- (XGDrawMechanism) drawMechanismForScreen: (int)screen_number
{
return [[self _screenContextForScreen: screen_number] drawMechanism];
}
// Could use NSSwapInt() instead
static unsigned int flip_bytes32(unsigned int i)
{
return ((i >> 24) & 0xff)
|((i >> 8) & 0xff00)
|((i << 8) & 0xff0000)
|((i << 24) & 0xff000000);
}
static unsigned int flip_bytes16(unsigned int i)
{
return ((i >> 8) & 0xff)
|((i << 8) & 0xff00);
}
static int byte_order(void)
{
union
{
unsigned int i;
char c;
} foo;
foo.i = 1;
return foo.c != 1;
}
/**
* Used by the art backend to determine the drawing mechanism.
*/
- (void) getForScreen: (int)screen_number pixelFormat: (int *)bpp_number
masks: (int *)red_mask : (int *)green_mask : (int *)blue_mask
{
Visual *visual;
XImage *i;
int bpp;
#if 0
XVisualInfo template;
XVisualInfo *visualInfo;
int numMatches;
/*
We need a visual that we can generate pixel values for by ourselves.
Thus, we try to find a DirectColor or TrueColor visual. If that fails,
we use the default visual and hope that it's usable.
*/
template.class = DirectColor;
visualInfo = XGetVisualInfo(dpy, VisualClassMask, &template, &numMatches);
if (!visualInfo)
{
template.class = TrueColor;
visualInfo = XGetVisualInfo(dpy, VisualClassMask, &template, &numMatches);
}
if (visualInfo)
{
visual = visualInfo->visual;
bpp = visualInfo->depth;
XFree(visualInfo);
}
else
{
visual = DefaultVisual(dpy, DefaultScreen(dpy));
bpp = DefaultDepth(dpy, DefaultScreen(dpy));
}
#else
RContext *context;
// Better to get the used visual from the context.
context = [self xrContextForScreen: screen_number];
visual = context->visual;
bpp = context->depth;
#endif
i = XCreateImage(dpy, visual, bpp, ZPixmap, 0, NULL, 8, 8, 8, 0);
bpp = i->bits_per_pixel;
XDestroyImage(i);
*red_mask = visual->red_mask;
*green_mask = visual->green_mask;
*blue_mask = visual->blue_mask;
*bpp_number = bpp;
/* If the server doesn't have the same endianness as we do, we need
to flip the masks around (well, at least sometimes; not sure
what'll really happen for 15/16bpp modes). */
{
int us = byte_order(); /* True iff we're big-endian. */
int them = ImageByteOrder(dpy); /* True iff the server is big-endian. */
if (us != them)
{
if ((bpp == 32) || (bpp == 24))
{
*red_mask = flip_bytes32(*red_mask);
*green_mask = flip_bytes32(*green_mask);
*blue_mask = flip_bytes32(*blue_mask);
}
else if (bpp == 16)
{
*red_mask = flip_bytes16(*red_mask);
*green_mask = flip_bytes16(*green_mask);
*blue_mask = flip_bytes16(*blue_mask);
}
}
}
}
/**
Returns the root window of the display
*/
@ -668,26 +292,6 @@ static int byte_order(void)
return RootWindow(dpy, screen_number);
}
/**
Returns the closest color in the current colormap to the indicated
X color
*/
- (XColor) xColorFromColor: (XColor)color forScreen: (int)screen_number
{
Status ret;
RColor rcolor;
RContext *context = [self xrContextForScreen: screen_number];
XAllocColor(dpy, context->cmap, &color);
rcolor.red = color.red / 256;
rcolor.green = color.green / 256;
rcolor.blue = color.blue / 256;
ret = RGetClosestXColor(context, &rcolor, &color);
if (ret == False)
NSLog(@"Failed to alloc color (%d,%d,%d)\n",
(int)rcolor.red, (int)rcolor.green, (int)rcolor.blue);
return color;
}
/**
Returns the application root window, which is used for many things
such as window hints

View file

@ -49,23 +49,10 @@
#include "x11/XGGeneric.h"
#include "x11/xdnd.h"
#ifdef HAVE_WRASTER_H
#include "wraster.h"
#else
#include "x11/wraster.h"
#endif
#include "math.h"
#include <X11/keysym.h>
#include <X11/Xproto.h>
#if LIB_FOUNDATION_LIBRARY
# include <Foundation/NSPosixFileDescriptor.h>
#elif defined(NeXT_PDO)
# include <Foundation/NSFileHandle.h>
# include <Foundation/NSNotification.h>
#endif
#define cWin ((gswindow_device_t*)generic.cachedWindow)
// NumLock's mask (it depends on the keyboard mapping)
@ -95,15 +82,6 @@ void __objc_xgcontextevent_linking (void)
{
}
static SEL procSel = 0;
static void (*procEvent)(id, SEL, XEvent*) = 0;
#ifdef XSHM
@interface NSGraphicsContext (SharedMemory)
-(void) gotShmCompletion: (Drawable)d;
@end
#endif
@interface XGServer (Private)
- (void) receivedEvent: (void*)data
type: (RunLoopEventType)type
@ -251,12 +229,6 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym)
watcher: (id<RunLoopEvents>)self
forMode: mode];
#endif
if (procSel == 0)
{
procSel = @selector(processEvent:);
procEvent = (void (*)(id, SEL, XEvent*))
[self methodForSelector: procSel];
}
}
#if LIB_FOUNDATION_LIBRARY
@ -307,7 +279,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
}
#endif
(*procEvent)(self, procSel, &xEvent);
[self processEvent: &xEvent];
}
}
@ -1735,15 +1707,6 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
// We shouldn't get here unless we forgot to trap an event above
default:
#ifdef XSHM
if (xEvent.type == XShmGetEventBase(dpy)+ShmCompletion
&& [gcontext respondsToSelector: @selector(gotShmCompletion:)])
{
[gcontext gotShmCompletion:
((XShmCompletionEvent *)&xEvent)->drawable];
break;
}
#endif
NSLog(@"Received an untrapped event\n");
break;
}

File diff suppressed because it is too large Load diff

View file

@ -1,748 +0,0 @@
/*
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Author: Alexander Malmberg <alexander@malmberg.org>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <config.h>
#include <Foundation/NSUserDefaults.h>
#include "x11/XGServer.h"
#include "x11/XGServerWindow.h"
#include "x11/XWindowBuffer.h"
#include <math.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#ifdef HAVE_XSHAPE
#include <X11/extensions/shape.h>
#endif
static XWindowBuffer **window_buffers;
static int num_window_buffers;
static int use_shape_hack = 0; /* this is an ugly hack : ) */
#ifdef XSHM
static int did_test_xshm = 0;
static int use_xshm = 1;
static Bool use_xshm_pixmaps = 0;
static int num_xshm_test_errors = 0;
static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
{
num_xshm_test_errors++;
return 0;
}
static void test_xshm(Display *display, Visual *visual, int drawing_depth)
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
did_test_xshm = 1;
if ([ud objectForKey: @"XWindowBufferUseXShm"])
use_xshm = [ud boolForKey: @"XWindowBufferUseXShm"];
/* If the user doesn't want XShm, there's no point in doing any further
testing. */
if (!use_xshm)
return;
/* This seems to return success if the X server understands the XShm
protocol, regardless of whether XShm can actually be used or not... */
{
int major, minor;
if (!XShmQueryExtension(display) ||
!XShmQueryVersion(display, &major, &minor, &use_xshm_pixmaps))
{
NSLog(@"XShm not supported by X server.");
NSLog(@"Falling back to normal XImage (will be slower).");
use_xshm = 0;
return;
}
}
/* ... so we check that it actually works here. To do this, we need to
set up our own error handler (because the xlib calls never fail, they
just cause error events to be sent to us), explicitly synchronize
(or we wouldn't get to handle, and thus detect, the errors until much
later), and try actually creating a XShm image. Yuck. */
{
XImage *ximage;
XShmSegmentInfo shminfo;
int (*old_error_handler)();
old_error_handler = XSetErrorHandler(test_xshm_error_handler);
ximage = XShmCreateImage(display, visual,
drawing_depth, ZPixmap, NULL, &shminfo,
1, 1);
XSync(display, False);
if (!ximage || num_xshm_test_errors)
{
NSLog(@"XShm not supported, XShmCreateImage failed.");
goto no_xshm;
}
shminfo.shmid = shmget(IPC_PRIVATE,
64, /* We don't have exact bytes per row values here, but this
should be safe, and we'll probably get a full page anyway.
(And if it turns out not to be enough, the X server will notice
and give us errors, causing us to think that XShm isn't
supported.) */
IPC_CREAT | 0700);
if (shminfo.shmid == -1 || num_xshm_test_errors)
{
NSLog(@"XShm not supported, shmget() failed: %m.");
XDestroyImage(ximage);
goto no_xshm;
}
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
if ((intptr_t)shminfo.shmaddr == -1 || num_xshm_test_errors)
{
NSLog(@"XShm not supported, shmat() failed: %m.");
XDestroyImage(ximage);
shmctl(shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
shminfo.readOnly = 0;
if (!XShmAttach(display, &shminfo))
num_xshm_test_errors++;
XSync(display, False);
if (num_xshm_test_errors)
{
NSLog(@"XShm not supported, XShmAttach() failed.");
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
XShmDetach(display, &shminfo);
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
/* Most of the time, all the above calls will return success despite
actually failing. To catch all errors generated by the calls before
returning, we synchronize here. */
XSync(display, False);
shmctl(shminfo.shmid, IPC_RMID, 0);
if (num_xshm_test_errors)
{
NSLog(@"XShm not supported.");
no_xshm:
NSLog(@"Falling back to normal XImage (will be slower).");
use_xshm = 0;
}
XSetErrorHandler(old_error_handler);
}
}
#endif
@implementation XWindowBuffer
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
}
+ windowBufferForWindow: (gswindow_device_t *)awindow
depthInfo: (struct XWindowBuffer_depth_info_s *)aDI
{
int i;
XWindowBuffer *wi;
int drawing_depth;
Visual *visual;
for (i = 0; i < num_window_buffers; i++)
{
if (window_buffers[i]->window == awindow)
break;
}
if (i == num_window_buffers)
{
wi = [[XWindowBuffer alloc] init];
wi->window = awindow;
window_buffers = realloc(window_buffers,
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
if (!window_buffers)
{
NSLog(@"Out of memory (failed to allocate %lu bytes)",
(unsigned long)sizeof(XWindowBuffer *) * (num_window_buffers + 1));
exit(1);
}
window_buffers[num_window_buffers++] = wi;
}
else
{
wi = window_buffers[i];
wi = RETAIN(wi);
}
wi->DI = *aDI;
wi->gc = awindow->gc;
wi->drawable = awindow->ident;
wi->display = awindow->display;
wi->window->gdriverProtocol = GDriverHandlesExpose | GDriverHandlesBacking;
wi->window->gdriver = wi;
#if 0
drawing_depth = aDI->drawing_depth;
visual = DefaultVisual(wi->display, DefaultScreen(wi->display));
#else
// Better to get the used visual from the XGServer.
visual = [(XGServer*)GSCurrentServer() visualForScreen: awindow->screen];
drawing_depth = [(XGServer*)GSCurrentServer() depthForScreen: awindow->screen];
#endif
/* TODO: resolve properly.
-x11 is creating buffers before I have a chance to tell it not to, so
I'm freeing them here to reduce memory consumption (and prevent
leaks, though that should be fixed now) */
if (awindow->buffer)
{
XFreePixmap (awindow->display, awindow->buffer);
awindow->buffer = 0;
}
if (awindow->alpha_buffer)
{
XFreePixmap (awindow->display, awindow->alpha_buffer);
awindow->alpha_buffer = 0;
}
/* create the image if necessary */
if (!wi->ximage ||
wi->sx != awindow->xframe.size.width ||
wi->sy != awindow->xframe.size.height)
{
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
wi->window->xframe.size.width, wi->window->xframe.size.height);*/
if (wi->ximage)
{
#ifdef XSHM
if (wi->use_shm)
{
XShmDetach(wi->display, &wi->shminfo);
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
}
else
#endif
XDestroyImage(wi->ximage);
}
if (wi->pixmap)
{
XFreePixmap(wi->display,wi->pixmap);
XSetWindowBackground(wi->display,wi->window->ident,None);
wi->pixmap=0;
}
wi->has_alpha = 0;
if (wi->alpha)
{
free(wi->alpha);
wi->alpha = NULL;
}
wi->pending_put = wi->pending_event = 0;
wi->ximage = NULL;
/* TODO: only use shared memory for 'real' on-screen windows. how can
we tell? don't create shared buffer until first expose? */
/* The primary problems seems to be the system limit on the _number_
of shared memory segments, not their total size, so we only create
shared buffers for reasonably large buffers and assume that the small
ones are just caches of images and will never be displayed, anyway
(and if they are displayed, it won't cost much, since they're small).
*/
if (wi->window->xframe.size.width * wi->window->xframe.size.height < 4096)
goto no_xshm;
#ifdef XSHM
if (!did_test_xshm)
test_xshm(wi->display, visual, drawing_depth);
if (!use_xshm)
goto no_xshm;
/* Use XShm if possible, else fall back to normal XImage: s */
wi->use_shm = 1;
wi->ximage = XShmCreateImage(wi->display, visual,
drawing_depth, ZPixmap, NULL, &wi->shminfo,
wi->window->xframe.size.width,
wi->window->xframe.size.height);
if (!wi->ximage)
{
NSLog(@"Warning: XShmCreateImage failed!");
NSLog(@"Falling back to normal XImage (will be slower).");
goto no_xshm;
}
wi->shminfo.shmid = shmget(IPC_PRIVATE,
wi->ximage->bytes_per_line * wi->ximage->height,
IPC_CREAT | 0700);
if (wi->shminfo.shmid == -1)
{
NSLog(@"Warning: shmget() failed: %m.");
NSLog(@"Falling back to normal XImage (will be slower).");
XDestroyImage(wi->ximage);
goto no_xshm;
}
wi->shminfo.shmaddr = wi->ximage->data = shmat(wi->shminfo.shmid, 0, 0);
if ((intptr_t)wi->shminfo.shmaddr == -1)
{
NSLog(@"Warning: shmat() failed: %m.");
NSLog(@"Falling back to normal XImage (will be slower).");
XDestroyImage(wi->ximage);
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
wi->shminfo.readOnly = 0;
if (!XShmAttach(wi->display, &wi->shminfo))
{
NSLog(@"Warning: XShmAttach() failed.");
NSLog(@"Falling back to normal XImage (will be slower).");
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
if (use_xshm_pixmaps)
{
/* We try to create a shared pixmap using the same buffer, and set
it as the background of the window. This allows X to handle expose
events all by itself, which avoids white flashing when things are
dragged across a window. */
/* TODO: we still get and handle expose events, although we don't
need to. */
wi->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
wi->ximage->data, &wi->shminfo,
wi->window->xframe.size.width,
wi->window->xframe.size.height,
drawing_depth);
if (wi->pixmap) /* TODO: this doesn't work */
{
XSetWindowBackgroundPixmap(wi->display, wi->window->ident,
wi->pixmap);
}
}
/* On some systems (eg. freebsd), X can't attach to the shared segment
if it's marked for destruction, so we make sure it's attached before
marking it. */
XSync(wi->display, False);
/* Mark the segment as destroyed now. Since we're attached, it won't
actually be destroyed, but if we crashed before doing this, it wouldn't
be destroyed despite nobody being attached anymore. */
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
#endif
if (!wi->ximage)
{
no_xshm:
wi->use_shm = 0;
wi->ximage = XCreateImage(wi->display, visual, drawing_depth,
ZPixmap, 0, NULL,
wi->window->xframe.size.width,
wi->window->xframe.size.height,
8, 0);
/* Normally, the data of an XImage is saved with the X server's
byte order. However, some backends (notably cairo) use the
native byte order of the client for the backend image, hence
we must set the image's byte order here. Without this, GNUstep
applications would display wrong colors on an X server that
is running on a machine with a different byte order than the
client (bug #28590). */
wi->ximage->byte_order = wi->DI.byte_order;
wi->ximage->data = malloc(wi->ximage->height * wi->ximage->bytes_per_line);
if (!wi->ximage->data)
{
XDestroyImage(wi->ximage);
wi->ximage = NULL;
}
/*TODO? wi->ximage = XGetImage(wi->display, wi->drawable,
0, 0, wi->window->xframe.size.width, wi->window->xframe.size.height,
-1, ZPixmap);*/
}
}
if (wi->ximage)
{
wi->sx = wi->ximage->width;
wi->sy = wi->ximage->height;
wi->data = (unsigned char *)wi->ximage->data;
wi->bytes_per_line = wi->ximage->bytes_per_line;
wi->bits_per_pixel = wi->ximage->bits_per_pixel;
wi->bytes_per_pixel = wi->bits_per_pixel / 8;
// NSLog(@"%@ ximage=%p data=%p\n", wi->ximage, wi->data);
}
else
{
NSLog(@"Warning: failed to create image for window!");
wi->data = NULL;
}
return AUTORELEASE(wi);
}
extern int XShmGetEventBase(Display *d);
- (void) _gotShmCompletion
{
#ifdef XSHM
if (!use_shm)
return;
pending_event = 0;
if (pending_put)
{
pending_put = 0;
if (pending_rect.x + pending_rect.w > window->xframe.size.width)
{
pending_rect.w = window->xframe.size.width - pending_rect.x;
if (pending_rect.w <= 0)
return;
}
if (pending_rect.y + pending_rect.h > window->xframe.size.height)
{
pending_rect.h = window->xframe.size.height - pending_rect.y;
if (pending_rect.h <= 0)
return;
}
if (!XShmPutImage(display, drawable, gc, ximage,
pending_rect.x, pending_rect.y,
pending_rect.x, pending_rect.y,
pending_rect.w, pending_rect.h,
1))
{
NSLog(@"XShmPutImage failed?");
}
else
{
pending_event = 1;
}
}
// XFlush(window->display);
#endif
}
- (void) _exposeRect: (NSRect)rect
{
/* TODO: Somehow, we can get negative coordinates in the rectangle. So far
I've tracked them back to [NSWindow flushWindow]. Should probably figure
out where they're coming from originally, and see if they really should be
negative. (Seems to happen when a window is created or resized, so possibly
something is refreshing while coordinates are still invalid.
Also, just about every resize of a window causes a few calls here with
rects in the new size before we are updated.
For now, we just intersect with our known size to avoid problems with X.
And, to avoid problems with clever optimizations and float vs. double
accuracy, we do the test using int: s.
*/
int x, y, w, h;
x = floor(rect.origin.x);
y = floor(rect.origin.y);
w = ceil(rect.size.width + rect.origin.x - x);
h = ceil(rect.size.height + rect.origin.y - y);
if (x < 0)
{
w += x;
x = 0;
}
if (y < 0)
{
h += y;
y = 0;
}
if (x + w > sx)
{
w = sx - x;
}
if (y + h > sy)
{
h = sy - y;
}
if (w <= 0 || h <= 0)
return;
#ifdef XSHM
if (use_shm)
{
#ifdef HAVE_XSHAPE
/* HACK: lets try to use shaped windows to get some use out of
destination alpha */
if (has_alpha && use_shape_hack)
{
static int warn = 0;
Pixmap p;
int dsize = ((sx + 7) / 8) * sy;
unsigned char *buf = malloc(dsize);
unsigned char *dst;
int bofs;
unsigned char *a;
int as;
int i, x;
if (!warn)
NSLog(@"Warning: activating shaped windows");
warn = 1;
memset(buf, 0xff, dsize);
#define CUTOFF 128
if (DI.inline_alpha)
{
a = data + DI.inline_alpha_ofs;
as = DI.bytes_per_pixel;
}
else
{
a = alpha;
as = 1;
}
for (bofs = 0, i = sx * sy, x = sx, dst = buf; i; i--, a += as)
{
if (*a < CUTOFF)
{
*dst = *dst & ~(1 << bofs);
}
bofs++;
if (bofs == 8)
{
dst++;
bofs = 0;
}
x--;
if (!x)
{
if (bofs)
{
bofs = 0;
dst++;
}
x = sx;
}
}
#undef CUTOFF
//NSLog(@"check shape");
if (old_shape_size == dsize && !memcmp(old_shape, buf, dsize))
{
free(buf);
// NSLog(@" same shape");
}
else
{
// NSLog(@" updating");
p = XCreatePixmapFromBitmapData(display, window->ident,
(char *)buf, sx, sy, 1, 0, 1);
free(old_shape);
old_shape = buf;
old_shape_size = dsize;
XShapeCombineMask(display, window->ident,
ShapeBounding, 0, 0, p, ShapeSet);
XFreePixmap(display, p);
}
}
#endif // HAVE_XSHAPE
if (pending_event)
{
if (!pending_put)
{
pending_put = 1;
pending_rect.x = x;
pending_rect.y = y;
pending_rect.w = w;
pending_rect.h = h;
}
else
{
if (x < pending_rect.x)
{
pending_rect.w += pending_rect.x - x;
pending_rect.x = x;
}
if (x + w > pending_rect.x + pending_rect.w)
{
pending_rect.w = x + w - pending_rect.x;
}
if (y < pending_rect.y)
{
pending_rect.h += pending_rect.y - y;
pending_rect.y = y;
}
if (y + h > pending_rect.y + pending_rect.h)
{
pending_rect.h = y + h - pending_rect.y;
}
}
}
else
{
pending_put = 0;
if (!XShmPutImage(display, drawable, gc, ximage,
x, y, x, y, w, h, 1))
{
NSLog(@"XShmPutImage failed?");
}
else
{
pending_event = 1;
}
}
/* Performance hack. Check right away for ShmCompletion
events. */
{
XEvent e;
while (XCheckTypedEvent(window->display,
XShmGetEventBase(window->display) + ShmCompletion, &e))
{
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
}
}
}
else
#endif
if (ximage)
{
XPutImage(display, drawable, gc, ximage, x, y, x, y, w, h);
}
}
- (void) needsAlpha
{
if (has_alpha)
return;
if (!data)
return;
// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy);
if (DI.inline_alpha)
{
int i;
unsigned char *s;
alpha = NULL;
has_alpha = 1;
/* fill the alpha channel */
for (i = 0, s = data + DI.inline_alpha_ofs; i < sx * sy;
i++, s += DI.bytes_per_pixel)
*s = 0xff;
return;
}
alpha = malloc(sx * sy);
if (!alpha)
{
NSLog(@"Warning! Failed to allocate alpha buffer for window!");
return;
}
// NSLog(@"got buffer at %p", alpha);
has_alpha = 1;
memset(alpha, 0xff, sx * sy);
}
- (void) dealloc
{
int i;
for (i = 0; i < num_window_buffers; i++)
if (window_buffers[i] == self) break;
if (i < num_window_buffers)
{
num_window_buffers--;
for (; i < num_window_buffers; i++)
window_buffers[i] = window_buffers[i + 1];
}
if (ximage)
{
if (pixmap)
{
XFreePixmap(display,pixmap);
pixmap=0;
}
#ifdef XSHM
if (use_shm)
{
XShmDetach(display, &shminfo);
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
}
else
#endif
XDestroyImage(ximage);
}
if (alpha)
free(alpha);
[super dealloc];
}
+ (void) _gotShmCompletion: (Drawable)d
{
int i;
for (i = 0; i < num_window_buffers; i++)
{
if (window_buffers[i]->drawable == d)
{
[window_buffers[i] _gotShmCompletion];
return;
}
}
}
@end

View file

@ -1,899 +0,0 @@
/* context.c - X context management
*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include "wrasterP.h"
#ifdef HAVE_HERMES
#include <Hermes/Hermes.h>
#endif
#include "x11/StdCmap.h"
#include "x11/wraster.h"
#ifdef XRENDER
#include <X11/extensions/Xrender.h>
#endif
extern void _wraster_change_filter(int type);
static Bool bestContext(Display *dpy, int screen_number, RContext *context);
static RContextAttributes DEFAULT_CONTEXT_ATTRIBS = {
RC_UseSharedMemory|RC_RenderMode|RC_ColorsPerChannel, /* flags */
RDitheredRendering, /* render_mode */
4, /* colors_per_channel */
0,
0,
0,
0,
True, /* use_shared_memory */
RMitchellFilter,
RUseStdColormap
};
char**
RSupportedFileFormats(void)
{
static char *tmp[2];
tmp[0] = NULL;
return tmp;
}
/*
*
* Colormap allocation for PseudoColor visuals:
*
*
* switch standardColormap:
* none:
* allocate colors according to colors_per_channel
*
* best/default:
* if there's a std colormap defined then use it
*
* else
* create a std colormap and set it
*/
/*
*----------------------------------------------------------------------
* allocateStandardPseudoColor
* Creates the internal colormap for PseudoColor, setting the
* color values according to the supplied standard colormap.
*
* Returns: -
*
* Side effects: -
*
* Notes: -
*----------------------------------------------------------------------
*/
static Bool
allocateStandardPseudoColor(RContext *ctx, XStandardColormap *stdcmap)
{
int i;
ctx->ncolors = stdcmap->red_max * stdcmap->red_mult
+ stdcmap->green_max * stdcmap->green_mult
+ stdcmap->blue_max * stdcmap->blue_mult + 1;
if (ctx->ncolors <= 1) {
RErrorCode = RERR_INTERNAL;
puts("wraster: bad standard colormap");
return False;
}
ctx->colors = malloc(sizeof(XColor)*ctx->ncolors);
if (!ctx->colors) {
RErrorCode = RERR_NOMEMORY;
return False;
}
ctx->pixels = malloc(sizeof(unsigned long)*ctx->ncolors);
if (!ctx->pixels) {
free(ctx->colors);
ctx->colors = NULL;
RErrorCode = RERR_NOMEMORY;
return False;
}
#define calc(max,mult) (((i / stdcmap->mult) % \
(stdcmap->max + 1)) * 65535) / stdcmap->max
for (i = 0; i < ctx->ncolors; i++) {
ctx->colors[i].pixel = i + stdcmap->base_pixel;
ctx->colors[i].red = calc(red_max, red_mult);
ctx->colors[i].green = calc(green_max, green_mult);
ctx->colors[i].blue = calc(blue_max, blue_mult);
ctx->pixels[i] = ctx->colors[i].pixel;
}
#undef calc
return True;
}
static Bool
setupStandardColormap(RContext *ctx, Atom property)
{
if (!XmuLookupStandardColormap(ctx->dpy, ctx->screen_number,
ctx->visual->visualid,
ctx->depth, property,
True, True)) {
RErrorCode = RERR_STDCMAPFAIL;
return False;
}
return True;
}
static Bool
allocatePseudoColor(RContext *ctx)
{
XColor *colors;
XColor avcolors[256];
int avncolors;
int i, ncolors, r, g, b;
int retries;
int cpc = ctx->attribs->colors_per_channel;
ncolors = cpc * cpc * cpc;
if (ncolors > (1<<ctx->depth)) {
/* reduce colormap size */
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
ncolors = cpc * cpc * cpc;
}
assert(cpc >= 2 && ncolors <= (1<<ctx->depth));
colors = malloc(sizeof(XColor)*ncolors);
if (!colors) {
RErrorCode = RERR_NOMEMORY;
return False;
}
ctx->pixels = malloc(sizeof(unsigned long)*ncolors);
if (!ctx->pixels) {
free(colors);
RErrorCode = RERR_NOMEMORY;
return False;
}
i=0;
if ((ctx->attribs->flags & RC_GammaCorrection) && ctx->attribs->rgamma > 0
&& ctx->attribs->ggamma > 0 && ctx->attribs->bgamma > 0) {
double rg, gg, bg;
double tmp;
/* do gamma correction */
rg = 1.0/ctx->attribs->rgamma;
gg = 1.0/ctx->attribs->ggamma;
bg = 1.0/ctx->attribs->bgamma;
for (r=0; r<cpc; r++) {
for (g=0; g<cpc; g++) {
for (b=0; b<cpc; b++) {
colors[i].red=(r*0xffff) / (cpc-1);
colors[i].green=(g*0xffff) / (cpc-1);
colors[i].blue=(b*0xffff) / (cpc-1);
colors[i].flags = DoRed|DoGreen|DoBlue;
tmp = (double)colors[i].red / 65536.0;
colors[i].red = (unsigned short)(65536.0*pow(tmp, rg));
tmp = (double)colors[i].green / 65536.0;
colors[i].green = (unsigned short)(65536.0*pow(tmp, gg));
tmp = (double)colors[i].blue / 65536.0;
colors[i].blue = (unsigned short)(65536.0*pow(tmp, bg));
i++;
}
}
}
} else {
for (r=0; r<cpc; r++) {
for (g=0; g<cpc; g++) {
for (b=0; b<cpc; b++) {
colors[i].red=(r*0xffff) / (cpc-1);
colors[i].green=(g*0xffff) / (cpc-1);
colors[i].blue=(b*0xffff) / (cpc-1);
colors[i].flags = DoRed|DoGreen|DoBlue;
i++;
}
}
}
}
/* try to allocate the colors */
for (i=0; i<ncolors; i++) {
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
colors[i].flags = 0; /* failed */
} else {
colors[i].flags = DoRed|DoGreen|DoBlue;
}
}
/* try to allocate close values for the colors that couldn't
* be allocated before */
avncolors = (1<<ctx->depth>256 ? 256 : 1<<ctx->depth);
for (i=0; i<avncolors; i++) avcolors[i].pixel = i;
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
for (i=0; i<ncolors; i++) {
if (colors[i].flags==0) {
int j;
unsigned long cdiff=0xffffffff, diff;
unsigned long closest=0;
retries = 2;
while (retries--) {
/* find closest color */
for (j=0; j<avncolors; j++) {
r = (colors[i].red - avcolors[i].red)>>8;
g = (colors[i].green - avcolors[i].green)>>8;
b = (colors[i].blue - avcolors[i].blue)>>8;
diff = r*r + g*g + b*b;
if (diff<cdiff) {
cdiff = diff;
closest = j;
}
}
/* allocate closest color found */
colors[i].red = avcolors[closest].red;
colors[i].green = avcolors[closest].green;
colors[i].blue = avcolors[closest].blue;
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
colors[i].flags = DoRed|DoGreen|DoBlue;
break; /* succeeded, don't need to retry */
}
#ifdef DEBUG
printf("close color allocation failed. Retrying...\n");
#endif
}
}
}
ctx->colors = colors;
ctx->ncolors = ncolors;
/* fill the pixels shortcut array */
for (i = 0; i < ncolors; i++) {
ctx->pixels[i] = ctx->colors[i].pixel;
}
return True;
}
static XColor*
allocateGrayScale(RContext *ctx)
{
XColor *colors;
XColor avcolors[256];
int avncolors;
int i, ncolors, r, g, b;
int retries;
int cpc = ctx->attribs->colors_per_channel;
ncolors = cpc * cpc * cpc;
if (ctx->vclass == StaticGray) {
/* we might as well use all grays */
ncolors = 1<<ctx->depth;
} else {
if ( ncolors > (1<<ctx->depth) ) {
/* reduce colormap size */
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
ncolors = cpc * cpc * cpc;
}
assert(cpc >= 2 && ncolors <= (1<<ctx->depth));
}
if (ncolors>=256 && ctx->vclass==StaticGray) {
/* don't need dithering for 256 levels of gray in StaticGray visual */
ctx->attribs->render_mode = RBestMatchRendering;
}
colors = malloc(sizeof(XColor)*ncolors);
if (!colors) {
RErrorCode = RERR_NOMEMORY;
return False;
}
for (i=0; i<ncolors; i++) {
colors[i].red=(i*0xffff) / (ncolors-1);
colors[i].green=(i*0xffff) / (ncolors-1);
colors[i].blue=(i*0xffff) / (ncolors-1);
colors[i].flags = DoRed|DoGreen|DoBlue;
}
/* try to allocate the colors */
for (i=0; i<ncolors; i++) {
#ifdef DEBUG
printf("trying:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
#endif
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
colors[i].flags = 0; /* failed */
#ifdef DEBUG
printf("failed:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
#endif
} else {
colors[i].flags = DoRed|DoGreen|DoBlue;
#ifdef DEBUG
printf("success:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
#endif
}
}
/* try to allocate close values for the colors that couldn't
* be allocated before */
avncolors = (1<<ctx->depth>256 ? 256 : 1<<ctx->depth);
for (i=0; i<avncolors; i++) avcolors[i].pixel = i;
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
for (i=0; i<ncolors; i++) {
if (colors[i].flags==0) {
int j;
unsigned long cdiff=0xffffffff, diff;
unsigned long closest=0;
retries = 2;
while (retries--) {
/* find closest color */
for (j=0; j<avncolors; j++) {
r = (colors[i].red - avcolors[i].red)>>8;
g = (colors[i].green - avcolors[i].green)>>8;
b = (colors[i].blue - avcolors[i].blue)>>8;
diff = r*r + g*g + b*b;
if (diff<cdiff) {
cdiff = diff;
closest = j;
}
}
/* allocate closest color found */
#ifdef DEBUG
printf("best match:%x,%x,%x => %x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue,avcolors[closest].red,avcolors[closest].green,avcolors[closest].blue);
#endif
colors[i].red = avcolors[closest].red;
colors[i].green = avcolors[closest].green;
colors[i].blue = avcolors[closest].blue;
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
colors[i].flags = DoRed|DoGreen|DoBlue;
break; /* succeeded, don't need to retry */
}
#ifdef DEBUG
printf("close color allocation failed. Retrying...\n");
#endif
}
}
}
return colors;
}
static Bool
setupPseudoColorColormap(RContext *context)
{
Atom property = 0;
if (context->attribs->standard_colormap_mode == RCreateStdColormap) {
property = XInternAtom(context->dpy, "RGB_DEFAULT_MAP", False);
if (!setupStandardColormap(context, property)) {
return False;
}
}
if (context->attribs->standard_colormap_mode != RIgnoreStdColormap) {
XStandardColormap *maps;
int count, i;
if (!property) {
property = XInternAtom(context->dpy, "RGB_BEST_MAP", False);
if (!XGetRGBColormaps(context->dpy,
DefaultRootWindow(context->dpy),
&maps, &count, property)) {
maps = NULL;
}
if (!maps) {
property = XInternAtom(context->dpy, "RGB_DEFAULT_MAP", False);
if (!XGetRGBColormaps(context->dpy,
DefaultRootWindow(context->dpy),
&maps, &count, property)) {
maps = NULL;
}
}
} else {
if (!XGetRGBColormaps(context->dpy,
DefaultRootWindow(context->dpy),
&maps, &count, property)) {
maps = NULL;
}
}
if (maps) {
int theMap = -1;
for (i = 0; i < count; i++) {
if (maps[i].visualid == context->visual->visualid) {
theMap = i;
break;
}
}
if (theMap < 0) {
puts("wrlib: no std cmap found");
}
if (theMap >= 0
&& allocateStandardPseudoColor(context, &maps[theMap])) {
context->std_rgb_map = XAllocStandardColormap();
*context->std_rgb_map = maps[theMap];
context->cmap = context->std_rgb_map->colormap;
XFree(maps);
return True;
}
XFree(maps);
}
}
context->attribs->standard_colormap_mode = RIgnoreStdColormap;
/* RIgnoreStdColormap and fallback */
return allocatePseudoColor(context);
}
static char*
mygetenv(char *var, int scr)
{
char *p;
char varname[64];
sprintf(varname, "%s%i", var, scr);
p = getenv(varname);
if (!p) {
p = getenv(var);
}
return p;
}
static void
gatherconfig(RContext *context, int screen_n)
{
char *ptr;
ptr = mygetenv("WRASTER_GAMMA", screen_n);
if (ptr) {
float g1,g2,g3;
if (sscanf(ptr, "%f/%f/%f", &g1, &g2, &g3)!=3
|| g1<=0.0 || g2<=0.0 || g3<=0.0) {
printf("wrlib: invalid value(s) for gamma correction \"%s\"\n",
ptr);
} else {
context->attribs->flags |= RC_GammaCorrection;
context->attribs->rgamma = g1;
context->attribs->ggamma = g2;
context->attribs->bgamma = g3;
}
}
ptr = mygetenv("WRASTER_COLOR_RESOLUTION", screen_n);
if (ptr) {
int i;
if (sscanf(ptr, "%d", &i)!=1 || i<2 || i>6) {
printf("wrlib: invalid value for color resolution \"%s\"\n",ptr);
} else {
context->attribs->flags |= RC_ColorsPerChannel;
context->attribs->colors_per_channel = i;
}
}
ptr = mygetenv("WRASTER_OPTIMIZE_FOR_SPEED", screen_n);
if (ptr) {
context->flags.optimize_for_speed = 1;
} else {
context->flags.optimize_for_speed = 0;
}
}
static void
getColormap(RContext *context, int screen_number)
{
Colormap cmap = None;
XStandardColormap *cmaps;
int ncmaps, i;
if (XGetRGBColormaps(context->dpy,
RootWindow(context->dpy, screen_number),
&cmaps, &ncmaps, XA_RGB_DEFAULT_MAP)) {
for (i=0; i<ncmaps; ++i) {
if (cmaps[i].visualid == context->visual->visualid) {
cmap = cmaps[i].colormap;
break;
}
}
XFree(cmaps);
}
if (cmap == None) {
XColor color;
cmap = XCreateColormap(context->dpy,
RootWindow(context->dpy, screen_number),
context->visual, AllocNone);
color.red = color.green = color.blue = 0;
XAllocColor(context->dpy, cmap, &color);
context->black = color.pixel;
color.red = color.green = color.blue = 0xffff;
XAllocColor(context->dpy, cmap, &color);
context->white = color.pixel;
}
context->cmap = cmap;
}
static int
count_offset(unsigned long mask)
{
int i;
i=0;
while ((mask & 1)==0) {
i++;
mask = mask >> 1;
}
return i;
}
RContext*
RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
{
RContext *context;
XGCValues gcv;
context = malloc(sizeof(RContext));
if (!context) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
memset(context, 0, sizeof(RContext));
context->dpy = dpy;
context->screen_number = screen_number;
context->attribs = malloc(sizeof(RContextAttributes));
if (!context->attribs) {
free(context);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
if (!attribs)
*context->attribs = DEFAULT_CONTEXT_ATTRIBS;
else
*context->attribs = *attribs;
if (!(context->attribs->flags & RC_StandardColormap)) {
context->attribs->standard_colormap_mode = RUseStdColormap;
}
if (!(context->attribs->flags & RC_ScalingFilter)) {
context->attribs->flags |= RC_ScalingFilter;
context->attribs->scaling_filter = RMitchellFilter;
}
/* get configuration from environment variables */
gatherconfig(context, screen_number);
#ifndef BENCH
_wraster_change_filter(context->attribs->scaling_filter);
#endif
if ((context->attribs->flags & RC_VisualID)) {
XVisualInfo *vinfo, templ;
int nret;
templ.screen = screen_number;
templ.visualid = context->attribs->visualid;
vinfo = XGetVisualInfo(context->dpy, VisualIDMask|VisualScreenMask,
&templ, &nret);
if (!vinfo || nret==0) {
free(context);
RErrorCode = RERR_BADVISUALID;
return NULL;
}
if (vinfo[0].visual == DefaultVisual(dpy, screen_number)) {
context->attribs->flags |= RC_DefaultVisual;
} else {
XSetWindowAttributes attr;
unsigned long mask;
context->visual = vinfo[0].visual;
context->depth = vinfo[0].depth;
context->vclass = vinfo[0].class;
getColormap(context, screen_number);
attr.colormap = context->cmap;
attr.override_redirect = True;
attr.border_pixel = 0;
attr.background_pixel = 0;
mask = CWBorderPixel|CWColormap|CWOverrideRedirect|CWBackPixel;
context->drawable =
XCreateWindow(dpy, RootWindow(dpy, screen_number), 1, 1,
1, 1, 0, context->depth, CopyFromParent,
context->visual, mask, &attr);
/* XSetWindowColormap(dpy, context->drawable, attr.colormap);*/
}
XFree(vinfo);
}
/* use default */
if (!context->visual) {
if ((context->attribs->flags & RC_DefaultVisual)
|| !bestContext(dpy, screen_number, context)) {
context->visual = DefaultVisual(dpy, screen_number);
context->depth = DefaultDepth(dpy, screen_number);
context->cmap = DefaultColormap(dpy, screen_number);
context->drawable = RootWindow(dpy, screen_number);
context->black = BlackPixel(dpy, screen_number);
context->white = WhitePixel(dpy, screen_number);
context->vclass = context->visual->class;
}
}
gcv.function = GXcopy;
gcv.graphics_exposures = False;
context->copy_gc = XCreateGC(dpy, context->drawable, GCFunction
|GCGraphicsExposures, &gcv);
#ifdef HAVE_HERMES
context->hermes_data = malloc(sizeof(RHermesData));
if (!context->hermes_data) {
RErrorCode = RERR_NOMEMORY;
free(context);
return NULL;
}
Hermes_Init();
context->hermes_data->palette = Hermes_PaletteInstance();
{
unsigned long flags = 0;
if (context->attribs->render_mode == RDitheredRendering) {
flags |= HERMES_CONVERT_DITHER;
}
context->hermes_data->converter = Hermes_ConverterInstance(flags);
}
#endif
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
if (!setupPseudoColorColormap(context)) {
free(context);
return NULL;
}
#ifdef HAVE_HERMES
{
int32 palette[256];
int i;
for (i = 0; i < context->ncolors; i++) {
palette[i] = ((context->colors[i].red >> 8) << 16) ||
((context->colors[i].green >> 8) << 8) ||
((context->colors[i].blue >> 8));
}
Hermes_PaletteSet(context->hermes_data->palette, palette);
}
#endif
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
context->colors = allocateGrayScale(context);
if (!context->colors) {
free(context);
return NULL;
}
#ifdef HAVE_HERMES
{
int32 palette[256];
int i;
for (i = 0; i < context->ncolors; i++) {
palette[i] = ((context->colors[i].red >> 8) << 16) ||
((context->colors[i].green >> 8) << 8) ||
((context->colors[i].blue >> 8));
}
Hermes_PaletteSet(context->hermes_data->palette, palette);
}
#endif
} else if (context->vclass == TrueColor) {
/* calc offsets to create a TrueColor pixel */
context->red_offset = count_offset(context->visual->red_mask);
context->green_offset = count_offset(context->visual->green_mask);
context->blue_offset = count_offset(context->visual->blue_mask);
/* disable dithering on 24 bits visuals */
if (context->depth >= 24)
context->attribs->render_mode = RBestMatchRendering;
}
#ifdef HAVE_HERMES
#endif
/* check avaiability of MIT-SHM */
#ifdef XSHM
if (!(context->attribs->flags & RC_UseSharedMemory)) {
context->attribs->flags |= RC_UseSharedMemory;
context->attribs->use_shared_memory = True;
}
if (context->attribs->use_shared_memory) {
int major, minor;
Bool sharedPixmaps;
context->flags.use_shared_pixmap = 0;
if (!XShmQueryVersion(context->dpy, &major, &minor, &sharedPixmaps)) {
context->attribs->use_shared_memory = False;
} else {
if (XShmPixmapFormat(context->dpy)==ZPixmap)
context->flags.use_shared_pixmap = sharedPixmaps;
}
}
#endif
return context;
}
static Bool
bestContext(Display *dpy, int screen_number, RContext *context)
{
XVisualInfo *vinfo=NULL, rvinfo;
int best = -1, numvis, i;
long flags;
XSetWindowAttributes attr;
rvinfo.class = TrueColor;
rvinfo.screen = screen_number;
#ifdef XRENDER
rvinfo.depth = 32;
flags = VisualClassMask | VisualScreenMask | VisualDepthMask;
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
if (vinfo)
{
for (i=numvis-1, best = -1; i>=0; i--)
{
XRenderPictFormat* pictFormat =
XRenderFindVisualFormat (dpy, vinfo[i].visual);
if ((pictFormat->type == PictTypeDirect)
&& (pictFormat->direct.alphaMask))
{
best = i;
}
}
}
#endif
if (best == -1)
{
flags = VisualClassMask | VisualScreenMask;
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
if (vinfo)
{ /* look for a TrueColor, 24-bit or more (pref 24) */
for (i=numvis-1, best = -1; i>=0; i--)
{
if (vinfo[i].depth == 24) best = i;
else if (vinfo[i].depth>24 && best<0) best = i;
}
}
}
#if 0
if (best == -1) { /* look for a DirectColor, 24-bit or more (pref 24) */
rvinfo.class = DirectColor;
if (vinfo) XFree((char *) vinfo);
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
if (vinfo) {
for (i=0, best = -1; i<numvis; i++) {
if (vinfo[i].depth == 24) best = i;
else if (vinfo[i].depth>24 && best<0) best = i;
}
}
}
#endif
if (best > -1) {
context->visual = vinfo[best].visual;
context->depth = vinfo[best].depth;
context->vclass = vinfo[best].class;
getColormap(context, screen_number);
attr.colormap = context->cmap;
attr.override_redirect = True;
attr.border_pixel = 0;
context->drawable =
XCreateWindow(dpy, RootWindow(dpy, screen_number),
1, 1, 1, 1, 0, context->depth,
CopyFromParent, context->visual,
CWBorderPixel|CWColormap|CWOverrideRedirect, &attr);
/* XSetWindowColormap(dpy, context->drawable, context->cmap);*/
}
if (vinfo) XFree((char *) vinfo);
if (best < 0)
return False;
else
return True;
}

File diff suppressed because it is too large Load diff

View file

@ -1,538 +0,0 @@
/* raster.c - main and other misc stuff
*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <X11/Xlib.h>
#include "x11/wraster.h"
#include <assert.h>
char *WRasterLibVersion="0.9";
int RErrorCode=RERR_NONE;
#define HAS_ALPHA(I) ((I)->format == RRGBAFormat)
#define MAX_WIDTH 20000
#define MAX_HEIGHT 20000
/* 20000^2*4 < 2G */
RImage*
RCreateImage(unsigned width, unsigned height, int alpha)
{
RImage *image=NULL;
assert(width>0 && height>0);
/* check for bogus image sizes (and avoid overflow as a bonus) */
if (width > MAX_WIDTH || height > MAX_HEIGHT) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
image = malloc(sizeof(RImage));
if (!image) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
memset(image, 0, sizeof(RImage));
image->width = width;
image->height = height;
image->format = alpha ? RRGBAFormat : RRGBFormat;
image->refCount = 1;
/* the +4 is to give extra bytes at the end of the buffer,
* so that we can optimize image conversion for MMX(tm).. see convert.c
*/
image->data = malloc(width * height * (alpha ? 4 : 3) + 4);
if (!image->data) {
RErrorCode = RERR_NOMEMORY;
free(image);
image = NULL;
}
return image;
}
RImage*
RRetainImage(RImage *image)
{
if (image)
image->refCount++;
return image;
}
void
RReleaseImage(RImage *image)
{
assert(image!=NULL);
image->refCount--;
if (image->refCount < 1) {
free(image->data);
free(image);
}
}
/* Obsoleted function. Use RReleaseImage() instead. This was kept only to
* allow a smoother transition and to avoid breaking existing programs, but
* it will be removed in a future release. Right now is just an alias to
* RReleaseImage(). Do _NOT_ use RDestroyImage() anymore in your programs.
* Being an alias to RReleaseImage() this function no longer actually
* destroys the image, unless the image is no longer retained in some other
* place.
*/
void
RDestroyImage(RImage *image)
{
RReleaseImage(image);
}
RImage*
RCloneImage(RImage *image)
{
RImage *new_image;
assert(image!=NULL);
new_image = RCreateImage(image->width, image->height, HAS_ALPHA(image));
if (!new_image)
return NULL;
new_image->background = image->background;
memcpy(new_image->data, image->data,
image->width*image->height*(HAS_ALPHA(image) ? 4 : 3));
return new_image;
}
RImage*
RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
{
int i, ofs;
RImage *new_image;
unsigned total_line_size, line_size;
assert(image!=NULL);
assert(x>=0 && y>=0);
assert(x<image->width && y<image->height);
assert(width>0 && height>0);
if (x+width > image->width)
width = image->width-x;
if (y+height > image->height)
height = image->height-y;
new_image = RCreateImage(width, height, HAS_ALPHA(image));
if (!new_image)
return NULL;
new_image->background = image->background;
total_line_size = image->width * (HAS_ALPHA(image) ? 4 : 3);
line_size = width * (HAS_ALPHA(image) ? 4 : 3);
ofs = x*(HAS_ALPHA(image) ? 4 : 3) + y*total_line_size;;
for (i=0; i<height; i++) {
memcpy(&new_image->data[i*line_size],
&image->data[i*total_line_size+ofs], line_size);
}
return new_image;
}
/*
*----------------------------------------------------------------------
* RCombineImages-
* Combines two equal sized images with alpha image. The second
* image will be placed on top of the first one.
*----------------------------------------------------------------------
*/
void
RCombineImages(RImage *image, RImage *src)
{
assert(image->width == src->width);
assert(image->height == src->height);
if (!HAS_ALPHA(src)) {
if (!HAS_ALPHA(image)) {
memcpy(image->data, src->data, image->height*image->width*3);
} else {
int x, y;
unsigned char *d, *s;
d = image->data;
s = src->data;
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
d++;
}
}
}
} else {
register int i;
unsigned char *d;
unsigned char *s;
int alpha, calpha;
d = image->data;
s = src->data;
if (!HAS_ALPHA(image)) {
for (i=0; i<image->height*image->width; i++) {
alpha = *(s+3);
calpha = 255 - alpha;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
s++;
}
} else {
for (i=0; i<image->height*image->width; i++) {
alpha = *(s+3);
calpha = 255 - alpha;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
*d++ |= *s++;
}
}
}
}
void
RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
{
register int i;
unsigned char *d;
unsigned char *s;
int c_opaqueness;
assert(image->width == src->width);
assert(image->height == src->height);
d = image->data;
s = src->data;
c_opaqueness = 255 - opaqueness;
#define OP opaqueness
#define COP c_opaqueness
if (!HAS_ALPHA(src)) {
int dalpha = HAS_ALPHA(image);
for (i=0; i < image->width*image->height; i++) {
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
if (dalpha) {
d++;
}
}
} else {
int tmp;
if (!HAS_ALPHA(image)) {
for (i=0; i<image->width*image->height; i++) {
tmp = (*(s+3) * opaqueness)/256;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
s++;
}
} else {
for (i=0; i<image->width*image->height; i++) {
tmp = (*(s+3) * opaqueness)/256;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d |= tmp;
d++; s++;
}
}
}
#undef OP
#undef COP
}
int
calculateCombineArea(RImage *des, RImage *src, int *sx, int *sy,
unsigned *swidth, unsigned *sheight, int *dx, int *dy)
{
if (*dx < 0) {
*sx = -*dx;
*swidth = *swidth + *dx;
*dx = 0;
}
if (*dx + *swidth > des->width) {
*swidth = des->width - *dx;
}
if (*dy < 0) {
*sy = -*dy;
*sheight = *sheight + *dy;
*dy = 0;
}
if (*dy + *sheight > des->height) {
*sheight = des->height - *dy;
}
if (*sheight > 0 && *swidth > 0) {
return True;
} else return False;
}
void
RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
unsigned height, int dx, int dy)
{
int x, y, dwi, swi;
unsigned char *d;
unsigned char *s;
int alpha, calpha;
if(!calculateCombineArea(image, src, &sx, &sy, &width, &height, &dx, &dy))
return;
if (!HAS_ALPHA(src)) {
if (!HAS_ALPHA(image)) {
swi = src->width * 3;
dwi = image->width * 3;
s = src->data + (sy*(int)src->width + sx) * 3;
d = image->data + (dy*(int)image->width + dx) * 3;
for (y=0; y < height; y++) {
memcpy(d, s, width*3);
d += dwi;
s += swi;
}
} else {
swi = (src->width - width) * 3;
dwi = (image->width - width) * 4;
s = src->data + (sy*(int)src->width + sx) * 3;
d = image->data + (dy*(int)image->width + dx) * 4;
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
d++;
}
d += dwi;
s += swi;
}
}
} else {
int dalpha = HAS_ALPHA(image);
swi = (src->width - width) * 4;
s = src->data + (sy*(int)src->width + sx) * 4;
if (dalpha) {
dwi = (image->width - width) * 4;
d = image->data + (dy*(int)image->width + dx) * 4;
} else {
dwi = (image->width - width) * 3;
d = image->data + (dy*(int)image->width + dx) * 3;
}
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
alpha = *(s+3);
calpha = 255 - alpha;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
s++;
if (dalpha)
d++;
}
d += dwi;
s += swi;
}
}
}
void
RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
unsigned width, unsigned height, int dx, int dy,
int opaqueness)
{
int x, y, dwi, swi;
int c_opaqueness;
unsigned char *s, *d;
int dalpha = HAS_ALPHA(image);
int dch = (dalpha ? 4 : 3);
if(!calculateCombineArea(image, src, &sx, &sy, &width, &height, &dx, &dy))
return;
d = image->data + (dy*image->width + dx) * dch;
dwi = (image->width - width)*dch;
c_opaqueness = 255 - opaqueness;
#define OP opaqueness
#define COP c_opaqueness
if (!HAS_ALPHA(src)) {
s = src->data + (sy*src->width + sx)*3;
swi = (src->width - width) * 3;
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
if (dalpha)
d++;
}
d += dwi; s += swi;
}
} else {
int tmp;
s = src->data + (sy*src->width + sx)*4;
swi = (src->width - width) * 4;
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
tmp = (*(s+3) * opaqueness)/256;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
s++;
if (dalpha)
d++;
}
d += dwi; s += swi;
}
}
#undef OP
#undef COP
}
void
RCombineImageWithColor(RImage *image, RColor *color)
{
register int i;
unsigned char *d;
int alpha, nalpha, r, g, b;
d = image->data;
if (!HAS_ALPHA(image)) {
/* Image has no alpha channel, so we consider it to be all 255.
* Thus there are no transparent parts to be filled. */
return;
}
r = color->red;
g = color->green;
b = color->blue;
for (i=0; i < image->width*image->height; i++) {
alpha = *(d+3);
nalpha = 255 - alpha;
*d = (((int)*d * alpha) + (r * nalpha))/256; d++;
*d = (((int)*d * alpha) + (g * nalpha))/256; d++;
*d = (((int)*d * alpha) + (b * nalpha))/256; d++;
d++;
}
}
RImage*
RMakeTiledImage(RImage *tile, unsigned width, unsigned height)
{
int x, y;
unsigned w;
unsigned long tile_size = tile->width * tile->height;
unsigned long tx = 0;
RImage *image;
unsigned char *s, *d;
if (width == tile->width && height == tile->height)
image = RCloneImage(tile);
else if (width <= tile->width && height <= tile->height)
image = RGetSubImage(tile, 0, 0, width, height);
else {
int has_alpha = HAS_ALPHA(tile);
image = RCreateImage(width, height, has_alpha);
d = image->data;
s = tile->data;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x += tile->width) {
w = (width - x < tile->width) ? width - x : tile->width;
if (has_alpha) {
w *= 4;
memcpy(d, s+tx*4, w);
} else {
w *= 3;
memcpy(d, s+tx*3, w);
}
d += w;
}
tx = (tx + tile->width) % tile_size;
}
}
return image;
}

View file

@ -1,624 +0,0 @@
/* scale.c - image scaling
*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <math.h>
#ifndef PI
#define PI 3.14159265358979323846
#endif
#include <assert.h>
#include "x11/wraster.h"
/*
*----------------------------------------------------------------------
* RScaleImage--
* Creates a scaled copy of an image.
*
* Returns:
* The new scaled image.
*
*----------------------------------------------------------------------
*/
#ifndef broken_code
RImage*
RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
{
int ox;
int px, py;
register int x, y, t;
int dx, dy;
unsigned char *s;
unsigned char *d;
RImage *img;
assert(new_width >= 0 && new_height >= 0);
if (new_width == image->width && new_height == image->height)
return RCloneImage(image);
img = RCreateImage(new_width, new_height, image->format==RRGBAFormat);
if (!img)
return NULL;
/* fixed point math idea taken from Imlib by
* Carsten Haitzler (Rasterman) */
dx = (image->width<<16)/new_width;
dy = (image->height<<16)/new_height;
py = 0;
d = img->data;
if (image->format == RRGBAFormat) {
for (y=0; y<new_height; y++) {
t = image->width*(py>>16);
s = image->data+(t<<2); /* image->data+t*4 */
ox = 0;
px = 0;
for (x=0; x<new_width; x++) {
px += dx;
*(d++) = *(s);
*(d++) = *(s+1);
*(d++) = *(s+2);
*(d++) = *(s+3);
t = (px - ox)>>16;
ox += t<<16;
s += t<<2; /* t*4 */
}
py += dy;
}
} else {
for (y=0; y<new_height; y++) {
t = image->width*(py>>16);
s = image->data+(t<<1)+t; /* image->data+t*3 */
ox = 0;
px = 0;
for (x=0; x<new_width; x++) {
px += dx;
*(d++) = *(s);
*(d++) = *(s+1);
*(d++) = *(s+2);
t = (px - ox)>>16;
ox += t<<16;
s += (t<<1)+t; /* t*3 */
}
py += dy;
}
}
return img;
}
#else
RImage*
RScaleImage(RImage *src, unsigned new_width, unsigned new_height)
{
int ddy, ee;
int h2;
int yd;
int xd, xs;
RImage *dst;
int e, xd2;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *dr, *dg, *db, *da;
int ys = 0;
dst = RCreateImage(new_width, new_height, src->data[3]!=NULL);
ddy = src->height/2;
ee = (ddy/2) - dst->height;
h2 = new_height/2;
xd = dst->width;
xs = src->width/2;
e = (src->width/2)-xd;
xd2 = xd/2;
sr = src->data[0];
sg = src->data[1];
sb = src->data[2];
sa = src->data[3];
dr = dst->data[0];
dg = dst->data[1];
db = dst->data[2];
da = dst->data[3];
if (sa == NULL) {
for (yd = 0; yd < new_height; yd++) {
int x;
sr = src->data[0] + ys * src->width;
sg = src->data[1] + ys * src->width;
sb = src->data[2] + ys * src->width;
for (x = 0; x < xd; x++) {
*(dr++) = *sr;
*(dg++) = *sg;
*(db++) = *sb;
while (e >= 0) {
sr++;
sg++;
sb++;
e -= xd2;
}
e += xs;
}
while (ee >= 0) {
ys++;
ee -= h2;
}
ee += ddy;
}
} else {
for (yd = 0; yd < new_height; yd++) {
int x;
sr = src->data[0] + ys * src->width;
sg = src->data[1] + ys * src->width;
sb = src->data[2] + ys * src->width;
sa = src->data[3] + ys * src->width;
for (x = 0; x < xd; x++) {
*(dr++) = *sr;
*(dg++) = *sg;
*(db++) = *sb;
*(da++) = *sa;
while (e >= 0) {
sr++;
sg++;
sb++;
sa++;
e -= xd2;
}
e += xs;
}
while (ee >= 0) {
ys++;
ee -= h2;
}
ee += ddy;
}
}
return dst;
}
#endif
/*
* Filtered Image Rescaling code copy/pasted from
* Graphics Gems III
* Public Domain 1991 by Dale Schumacher
*/
/*
* filter function definitions
*/
#if 0
#define filter_support (1.0)
static double
filter(t)
double t;
{
/* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
if(t < 0.0) t = -t;
if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
return(0.0);
}
#endif
#define box_support (0.5)
static double
box_filter(t)
double t;
{
if((t > -0.5) && (t <= 0.5)) return(1.0);
return(0.0);
}
#define triangle_support (1.0)
static double
triangle_filter(t)
double t;
{
if(t < 0.0) t = -t;
if(t < 1.0) return(1.0 - t);
return(0.0);
}
#define bell_support (1.5)
static double
bell_filter(t) /* box (*) box (*) box */
double t;
{
if(t < 0) t = -t;
if(t < .5) return(.75 - (t * t));
if(t < 1.5) {
t = (t - 1.5);
return(.5 * (t * t));
}
return(0.0);
}
#define B_spline_support (2.0)
static double
B_spline_filter(t) /* box (*) box (*) box (*) box */
double t;
{
double tt;
if(t < 0) t = -t;
if(t < 1) {
tt = t * t;
return((.5 * tt * t) - tt + (2.0 / 3.0));
} else if(t < 2) {
t = 2 - t;
return((1.0 / 6.0) * (t * t * t));
}
return(0.0);
}
static double
sinc(x)
double x;
{
x *= PI;
if(x != 0) return(sin(x) / x);
return(1.0);
}
#define Lanczos3_support (3.0)
static double
Lanczos3_filter(t)
double t;
{
if(t < 0) t = -t;
if(t < 3.0) return(sinc(t) * sinc(t/3.0));
return(0.0);
}
#define Mitchell_support (2.0)
#define B (1.0 / 3.0)
#define C (1.0 / 3.0)
static double
Mitchell_filter(t)
double t;
{
double tt;
tt = t * t;
if(t < 0) t = -t;
if(t < 1.0) {
t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
+ ((-18.0 + 12.0 * B + 6.0 * C) * tt)
+ (6.0 - 2 * B));
return(t / 6.0);
} else if(t < 2.0) {
t = (((-1.0 * B - 6.0 * C) * (t * tt))
+ ((6.0 * B + 30.0 * C) * tt)
+ ((-12.0 * B - 48.0 * C) * t)
+ (8.0 * B + 24 * C));
return(t / 6.0);
}
return(0.0);
}
static double (*filterf)() = Mitchell_filter;
static double fwidth = Mitchell_support;
void
_wraster_change_filter(int type)
{
switch (type) {
case RBoxFilter:
filterf = box_filter;
fwidth = box_support;
break;
case RTriangleFilter:
filterf = triangle_filter;
fwidth = triangle_support;
break;
case RBellFilter:
filterf = bell_filter;
fwidth = bell_support;
break;
case RBSplineFilter:
filterf = B_spline_filter;
fwidth = B_spline_support;
break;
case RLanczos3Filter:
filterf = Lanczos3_filter;
fwidth = Lanczos3_support;
break;
default:
case RMitchellFilter:
filterf = Mitchell_filter;
fwidth = Mitchell_support;
break;
}
}
/*
* image rescaling routine
*/
typedef struct {
int pixel;
double weight;
} CONTRIB;
typedef struct {
int n; /* number of contributors */
CONTRIB *p; /* pointer to list of contributions */
} CLIST;
CLIST *contrib; /* array of contribution lists */
/* clamp the input to the specified range */
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
/* return of calloc is not checked if NULL in the function below! */
RImage*
RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
{
RImage *tmp; /* intermediate image */
double xscale, yscale; /* zoom scale factors */
int i, j, k; /* loop variables */
int n; /* pixel number */
double center, left, right; /* filter calculation variables */
double width, fscale; /* filter calculation variables */
double rweight, gweight, bweight;
RImage *dst;
unsigned char *p;
unsigned char *sp;
int sch = src->format == RRGBAFormat ? 4 : 3;
dst = RCreateImage(new_width, new_height, False);
/* create intermediate image to hold horizontal zoom */
tmp = RCreateImage(dst->width, src->height, False);
xscale = (double)new_width / (double)src->width;
yscale = (double)new_height / (double)src->height;
/* pre-calculate filter contributions for a row */
contrib = (CLIST *)calloc(new_width, sizeof(CLIST));
if (xscale < 1.0) {
width = fwidth / xscale;
fscale = 1.0 / xscale;
for (i = 0; i < new_width; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB *)calloc((int)(width * 2 + 1),
sizeof(CONTRIB));
center = (double) i / xscale;
left = ceil(center - width);
right = floor(center + width);
for(j = left; j <= right; ++j) {
rweight = center - (double) j;
rweight = (*filterf)(rweight / fscale) / fscale;
if(j < 0) {
n = -j;
} else if(j >= src->width) {
n = (src->width - j) + src->width - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n*sch;
contrib[i].p[k].weight = rweight;
}
}
} else {
for(i = 0; i < new_width; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB *)calloc((int) (fwidth * 2 + 1),
sizeof(CONTRIB));
center = (double) i / xscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = left; j <= right; ++j) {
rweight = center - (double) j;
rweight = (*filterf)(rweight);
if(j < 0) {
n = -j;
} else if(j >= src->width) {
n = (src->width - j) + src->width - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n*sch;
contrib[i].p[k].weight = rweight;
}
}
}
/* apply filter to zoom horizontally from src to tmp */
p = tmp->data;
for(k = 0; k < tmp->height; ++k) {
CONTRIB *pp;
sp = src->data + src->width*k*sch;
for(i = 0; i < tmp->width; ++i) {
rweight = gweight = bweight = 0.0;
pp = contrib[i].p;
for(j = 0; j < contrib[i].n; ++j) {
rweight += sp[pp[j].pixel] * pp[j].weight;
gweight += sp[pp[j].pixel+1] * pp[j].weight;
bweight += sp[pp[j].pixel+2] * pp[j].weight;
}
*p++ = CLAMP(rweight, 0, 255);
*p++ = CLAMP(gweight, 0, 255);
*p++ = CLAMP(bweight, 0, 255);
}
}
/* free the memory allocated for horizontal filter weights */
for(i = 0; i < tmp->width; ++i) {
free(contrib[i].p);
}
free(contrib);
/* pre-calculate filter contributions for a column */
contrib = (CLIST *)calloc(dst->height, sizeof(CLIST));
if(yscale < 1.0) {
width = fwidth / yscale;
fscale = 1.0 / yscale;
for(i = 0; i < dst->height; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB *)calloc((int) (width * 2 + 1),
sizeof(CONTRIB));
center = (double) i / yscale;
left = ceil(center - width);
right = floor(center + width);
for(j = left; j <= right; ++j) {
rweight = center - (double) j;
rweight = (*filterf)(rweight / fscale) / fscale;
if(j < 0) {
n = -j;
} else if(j >= tmp->height) {
n = (tmp->height - j) + tmp->height - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n*3;
contrib[i].p[k].weight = rweight;
}
}
} else {
for(i = 0; i < dst->height; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB *)calloc((int) (fwidth * 2 + 1),
sizeof(CONTRIB));
center = (double) i / yscale;
left = ceil(center - fwidth);
right = floor(center + fwidth);
for(j = left; j <= right; ++j) {
rweight = center - (double) j;
rweight = (*filterf)(rweight);
if(j < 0) {
n = -j;
} else if(j >= tmp->height) {
n = (tmp->height - j) + tmp->height - 1;
} else {
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n*3;
contrib[i].p[k].weight = rweight;
}
}
}
/* apply filter to zoom vertically from tmp to dst */
sp = malloc(tmp->height*3);
for(k = 0; k < new_width; ++k) {
CONTRIB *pp;
p = dst->data + k*3;
/* copy a column into a row */
{
int i;
unsigned char *p, *d;
d = sp;
for(i = tmp->height, p = tmp->data + k*3; i-- > 0;
p += tmp->width*3) {
*d++ = *p;
*d++ = *(p+1);
*d++ = *(p+2);
}
}
for(i = 0; i < new_height; ++i) {
rweight = gweight = bweight = 0.0;
pp = contrib[i].p;
for(j = 0; j < contrib[i].n; ++j) {
rweight += sp[pp[j].pixel] * pp[j].weight;
gweight += sp[pp[j].pixel+1] * pp[j].weight;
bweight += sp[pp[j].pixel+2] * pp[j].weight;
}
*p = CLAMP(rweight, 0, 255);
*(p+1) = CLAMP(gweight, 0, 255);
*(p+2) = CLAMP(bweight, 0, 255);
p += new_width*3;
}
}
free(sp);
/* free the memory allocated for vertical filter weights */
for(i = 0; i < dst->height; ++i) {
free(contrib[i].p);
}
free(contrib);
RReleaseImage(tmp);
return dst;
}

View file

@ -1,42 +0,0 @@
/*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef WRASTERP_H_
#define WRASTERP_H_
#include <config.h>
#include "x11/wraster.h"
#ifdef HAVE_HERMES
# include <Hermes/Hermes.h>
typedef struct RHermesData {
HermesHandle palette;
HermesHandle converter;
} RHermesData;
#endif
#endif

View file

@ -1,284 +0,0 @@
/* xutil.c - utility functions for X
*
* Raster graphics library
*
* Copyright (c) 1997-2002 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifdef XSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#endif /* XSHM */
#include "x11/wraster.h"
#ifdef XSHM
static int shmError;
static int (*oldErrorHandler)();
static int
errorHandler(Display *dpy, XErrorEvent *err)
{
shmError=1;
if(err->error_code!=BadAccess)
(*oldErrorHandler)(dpy, err);
return 0;
}
#endif
RXImage*
RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
{
RXImage *rximg;
Visual *visual = context->visual;
rximg = malloc(sizeof(RXImage));
if (!rximg) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
#ifndef XSHM
rximg->image = XCreateImage(context->dpy, visual, depth,
ZPixmap, 0, NULL, width, height, 8, 0);
if (!rximg->image) {
free(rximg);
RErrorCode = RERR_XERROR;
return NULL;
}
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
if (!rximg->image->data) {
XDestroyImage(rximg->image);
free(rximg);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
#else /* XSHM */
if (!context->attribs->use_shared_memory) {
retry_without_shm:
context->attribs->use_shared_memory = 0;
rximg->is_shared = 0;
rximg->image = XCreateImage(context->dpy, visual, depth,
ZPixmap, 0, NULL, width, height, 8, 0);
if (!rximg->image) {
free(rximg);
RErrorCode = RERR_XERROR;
return NULL;
}
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
if (!rximg->image->data) {
XDestroyImage(rximg->image);
free(rximg);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
} else {
rximg->is_shared = 1;
rximg->info.readOnly = False;
rximg->image = XShmCreateImage(context->dpy, visual, depth,
ZPixmap, NULL, &rximg->info, width,
height);
rximg->info.shmid = shmget(IPC_PRIVATE,
rximg->image->bytes_per_line*height,
IPC_CREAT|0777);
if (rximg->info.shmid < 0) {
context->attribs->use_shared_memory = 0;
perror("wrlib: could not allocate shared memory segment");
XDestroyImage(rximg->image);
goto retry_without_shm;
}
rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
if (rximg->info.shmaddr == (void*)-1) {
context->attribs->use_shared_memory = 0;
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
perror("wrlib: shmctl");
perror("wrlib: could not allocate shared memory");
XDestroyImage(rximg->image);
goto retry_without_shm;
}
shmError = 0;
XSync(context->dpy, False);
oldErrorHandler = XSetErrorHandler(errorHandler);
XShmAttach(context->dpy, &rximg->info);
XSync(context->dpy, False);
XSetErrorHandler(oldErrorHandler);
rximg->image->data = rximg->info.shmaddr;
/* rximg->image->obdata = &(rximg->info);*/
if (shmError) {
context->attribs->use_shared_memory = 0;
XDestroyImage(rximg->image);
if (shmdt(rximg->info.shmaddr) < 0)
perror("wrlib: shmdt");
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
perror("wrlib: shmctl");
/* printf("wrlib:error attaching shared memory segment to XImage\n");
*/
goto retry_without_shm;
}
}
#endif /* XSHM */
return rximg;
}
void
RDestroyXImage(RContext *context, RXImage *rximage)
{
#ifndef XSHM
XDestroyImage(rximage->image);
#else /* XSHM */
if (rximage->is_shared) {
XSync(context->dpy, False);
XShmDetach(context->dpy, &rximage->info);
XDestroyImage(rximage->image);
if (shmdt(rximage->info.shmaddr) < 0)
perror("wrlib: shmdt");
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
perror("wrlib: shmctl");
} else {
XDestroyImage(rximage->image);
}
#endif
free(rximage);
}
static unsigned
getDepth(Display *dpy, Drawable d)
{
Window w;
int foo;
unsigned bar;
unsigned depth;
XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
return depth;
}
RXImage*
RGetXImage(RContext *context, Drawable d, int x, int y,
unsigned width, unsigned height)
{
RXImage *ximg = NULL;
#ifdef XSHM
if (context->attribs->use_shared_memory && 0) {
ximg = RCreateXImage(context, getDepth(context->dpy, d),
width, height);
if (ximg && !ximg->is_shared) {
RDestroyXImage(context, ximg);
ximg = NULL;
}
if (ximg) {
XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
}
}
if (!ximg) {
ximg = malloc(sizeof(RXImage));
if (!ximg) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
ximg->is_shared = 0;
ximg->image = XGetImage(context->dpy, d, x, y, width, height,
AllPlanes, ZPixmap);
}
return ximg;
#else /* !XSHM */
ximg = malloc(sizeof(RXImage));
if (!ximg) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
ximg->image = XGetImage(context->dpy, d, x, y, width, height,
AllPlanes, ZPixmap);
return ximg;
#endif /* !XSHM */
}
void
RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
int src_y, int dest_x, int dest_y,
unsigned int width, unsigned int height)
{
#ifndef XSHM
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
dest_y, width, height);
#else
if (ximage->is_shared) {
XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
dest_x, dest_y, width, height, False);
} else {
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
dest_y, width, height);
}
XFlush(context->dpy);
#endif /* XSHM */
}
#ifdef XSHM
Pixmap
R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
{
Pixmap pix;
pix = XShmCreatePixmap(context->dpy, context->drawable,
rximage->image->data, &rximage->info,
rximage->image->width, rximage->image->height,
rximage->image->depth);
return pix;
}
#endif /* XSHM */