Backport changes from trunk

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/branches/stable@27078 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2008-11-17 04:35:10 +00:00
parent ca1277e635
commit 633767e9fc
19 changed files with 840 additions and 791 deletions

View file

@ -8,6 +8,84 @@
in XNextEvent and other applications contacting the pasteboard
server become unresponsive.
2008-11-06 Fred Kiefer <FredKiefer@gmx.de>
* Source/cairo/CairoContext.m (-GSDrawImage::): Convert the
bitmap, when the format is unsupported.
2008-10-26 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XWindowBuffer.m (test_xshm): Check whether the X
server supports shm pixmaps.
2008-10-24 Fred Kiefer <FredKiefer@gmx.de>
* Source/win32/WIN32Server.m (-setalpha::): Implement transparent
windows.
* Source/winlib/WIN32GState.m (-DPSimage:...:): Call
SetStretchBltMode() before scaling a bitmap.
2008-10-24 Fred Kiefer <FredKiefer@gmx.de>
* Tools/xpbs.m (+initializePasteboard): Use XInternAtom when
XInternAtoms isn't available.
Patch by Riccardo Mottola <multix@ngi.it>.
* configure.ac: Check for XInternAtoms.
* configure,
* config.h.in: Regenerate.
2008-10-24 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServer.m (-visualForScreen:, -depthForScreen:):
New methods that hide RContext details.
* Headers/x11/XGServer.h: Declare these new methods.
* Source/x11/XWindowBuffer.m: Get the default visual and depth
from the XGServer.
2008-10-22 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (-_checkStyle:): Correct code
for double parent handling.
Patch by Wolfgang Lux <wolfgang.lux@gmail.com>.
2008-10-17 Fred Kiefer <FredKiefer@gmx.de>
* Headers/win32/WIN32Geometry.h (MSScreenRectToGS, GSScreenRectToMS),
* Source/win32/WIN32Server.m,
* Source/win32/w32_movesize.m:
Remove unused parameters from these functions and adjust callers.
2008-10-17 Fred Kiefer <FredKiefer@gmx.de>
* Headers/win32/WIN32Server.h,
* Source/win32/WIN32Server.m,
* Source/win32/w32_activate.m,
* Source/win32/w32_movesize.m,
* Source/win32/w32_general.m: Removed unused and unneeded code
left over from the last cleanup. This code was mostly setting
server flags that never got read or using falgs that never were set.
2008-10-14 Fred Kiefer <FredKiefer@gmx.de>
* Source/winlib/WIN32GState.m: Removed unneeded code. General cleanup.
* Source/winlib/WIN32GState.m (-DPSimage:...:): Scale and rotate
images correctly.
* Source/winlib/WIN32GState.m (-compositeGState:...fraction:):
Position images on scaled views better.
2008-09-14 Fred Kiefer <FredKiefer@gmx.de>
* Source/art/ARTContext.m (-setupDrawInfo): Moved code from here
to...
* Source/x11/XGServer.m (-getForScreen:pixelFormat:masks:::):
... here, including helper functions. Commented out this code and
replaced it by a different approach.
* Headers/x11/XGServer.h: Declare this new method.
2008-09-14 13:17-EDT Gregory John Casamento <greg_casamento@yahoo.com>
* install.sh: Adding install script for use by compile-all.
2008-08-19 Fred Kiefer <FredKiefer@gmx.de>
* Source/art/ARTContext.m (-GSSetDevice:::): Only call

View file

@ -142,7 +142,7 @@ NSPoint MSScreenPointToGS(int x, int y)
}
static inline
NSRect MSScreenRectToGS(RECT r, unsigned int styleMask, WIN32Server *self)
NSRect MSScreenRectToGS(RECT r)
{
NSRect r1;
int screen_height = GetSystemMetrics(SM_CYSCREEN);
@ -167,7 +167,7 @@ POINT GSScreenPointToMS(NSPoint p)
}
static inline
RECT GSScreenRectToMS(NSRect r, unsigned int styleMask, WIN32Server *self)
RECT GSScreenRectToMS(NSRect r)
{
RECT r1;
int screen_height = GetSystemMetrics(SM_CYSCREEN);

View file

@ -72,24 +72,8 @@
DWORD windowStyleForGSStyle(unsigned int style);
typedef struct w32serverFlags {
int _last_WM_ACTIVATE;
int menuRef; // reference to menu window
unsigned int currentGS_Style; // what style is current event window
BOOL HOLD_MENU_FOR_MOVE; // override GS move event on hide
BOOL HOLD_MENU_FOR_SIZE; // override GS size event on hide
BOOL HOLD_MINI_FOR_SIZE; // override GS size event on miniturize
BOOL HOLD_MINI_FOR_MOVE; // override GS move event on miniturize
BOOL HOLD_TRANSIENT_FOR_SIZE; // override GS size event on popup context
BOOL HOLD_TRANSIENT_FOR_MOVE; // override GS move event on popup context
BOOL HAVE_MAIN_MENU; // do we have a main menu?
BOOL HOLD_PAINT_FOR_SIZING;
BOOL _is_menu; // is event window the main menu?
BOOL _eventHandled; // did we handle the event?
BOOL _is_cache; // is the event window a cache rep
BOOL _hasGSClassName; // does the event window have a GSclassName
int lastEventType;
int hold;
} serverFlags;
@interface WIN32Server : GSDisplayServer
@ -104,11 +88,6 @@ typedef struct w32serverFlags {
HWND desiredFocus;
HWND currentActive;
HICON currentAppIcon;
// config window
NSWindow *configWindow;
NSPopUpButton * styleButton;
NSButton * taskbarButton;
NSButton * saveButton;
}
- (BOOL) handlesWindowDecorations;

View file

@ -63,7 +63,12 @@ typedef enum {
- (Window) xAppRootWindow;
- (void *) xrContextForScreen: (int)screen_number;
- (Visual *) visualForScreen: (int)screen_number;
- (int) depthForScreen: (int)screen_number;
- (XGDrawMechanism) drawMechanismForScreen: (int)screen_number;
- (void) getForScreen: (int)screen_number pixelFormat: (int *)bpp_number
masks: (int *)red_mask : (int *)green_mask : (int *)blue_mask;
- (Window) xDisplayRootWindowForScreen: (int)screen_number;
- (XColor) xColorFromColor: (XColor)color forScreen: (int)screen_number;

View file

@ -35,32 +35,6 @@
#include "x11/XWindowBuffer.h"
#endif
// 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;
}
@implementation ARTContext
+ (void)initializeBackend
@ -82,83 +56,22 @@ static int byte_order(void)
return [ARTGState class];
}
- (void) setupDrawInfo
- (void) setupDrawInfo: (void*)device
{
int bpp;
int red_mask, green_mask, blue_mask;
#ifdef RDS
{
RDSServer *s = (RDSServer *)server;
int bpp;
int red_mask, green_mask, blue_mask;
[s getPixelFormat: &bpp masks: &red_mask : &green_mask : &blue_mask];
artcontext_setup_draw_info(&DI, red_mask, green_mask, blue_mask, bpp);
}
RDSServer *s = (RDSServer *)server;
[s getPixelFormat: &bpp masks: &red_mask : &green_mask : &blue_mask];
#else
{
Display *d = [(XGServer *)server xDisplay];
int bpp;
Visual *visual;
XVisualInfo template;
XVisualInfo *visualInfo;
int numMatches;
XImage *i;
gswindow_device_t *gs_win;
/*
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(d, VisualClassMask, &template, &numMatches);
if (!visualInfo)
{
template.class = TrueColor;
visualInfo = XGetVisualInfo(d, VisualClassMask, &template, &numMatches);
}
if (visualInfo)
{
visual = visualInfo->visual;
bpp = visualInfo->depth;
XFree(visualInfo);
}
else
{
visual = DefaultVisual(d, DefaultScreen(d));
bpp = DefaultDepth(d, DefaultScreen(d));
}
i = XCreateImage(d, visual, bpp, ZPixmap, 0, NULL, 8, 8, 8, 0);
bpp = i->bits_per_pixel;
XDestroyImage(i);
/* 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(d); /* True iff the server is big-endian. */
if (us != them)
{
if ((bpp == 32) || (bpp == 24))
{
visual->red_mask = flip_bytes32(visual->red_mask);
visual->green_mask = flip_bytes32(visual->green_mask);
visual->blue_mask = flip_bytes32(visual->blue_mask);
}
else if (bpp == 16)
{
visual->red_mask = flip_bytes16(visual->red_mask);
visual->green_mask = flip_bytes16(visual->green_mask);
visual->blue_mask = flip_bytes16(visual->blue_mask);
}
}
}
/* Only returns if the visual was usable. */
artcontext_setup_draw_info(&DI, visual->red_mask, visual->green_mask,
visual->blue_mask, bpp);
}
gs_win = device;
[(XGServer *)server getForScreen: gs_win->screen pixelFormat: &bpp
masks: &red_mask : &green_mask : &blue_mask];
#endif
artcontext_setup_draw_info(&DI, red_mask, green_mask, blue_mask, bpp);
}
- (void) flushGraphics
@ -195,11 +108,12 @@ static int byte_order(void)
{
// Currently all windows share the same drawing info.
// It is enough to initialize it once.
// This will fail when different screen use different visuals.
static BOOL serverInitialized = NO;
if (!serverInitialized)
{
[self setupDrawInfo];
[self setupDrawInfo: device];
serverInitialized = YES;
}
[(ARTGState *)gstate GSSetDevice: device : x : y];

View file

@ -25,6 +25,9 @@
Boston, MA 02110-1301, USA.
*/
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSGraphics.h>
#include "cairo/CairoContext.h"
#include "cairo/CairoGState.h"
#include "cairo/CairoSurface.h"
@ -62,6 +65,16 @@
# error Invalid server for Cairo backend : non implemented
#endif /* BUILD_SERVER */
@interface NSBitmapImageRep (GSPrivate)
- (NSBitmapImageRep *) _convertToFormatBitsPerSample: (int)bps
samplesPerPixel: (int)spp
hasAlpha: (BOOL)alpha
isPlanar: (BOOL)isPlanar
colorSpaceName: (NSString*)colorSpaceName
bitmapFormat: (NSBitmapFormat)bitmapFormat
bytesPerRow: (int)rowBytes
bitsPerPixel: (int)pixelBits;
@end
@implementation CairoContext
@ -118,6 +131,50 @@
@implementation CairoContext (Ops)
- (void) GSDrawImage: (NSRect)rect: (void *)imageref
{
NSBitmapImageRep *bitmap;
const unsigned char *data[5];
NSString *colorSpaceName;
bitmap = (NSBitmapImageRep*)imageref;
colorSpaceName = [bitmap colorSpaceName];
if ([bitmap isPlanar] || ([bitmap bitmapFormat] != 0)
|| ([bitmap bitsPerPixel] != 8) ||
(![colorSpaceName isEqualToString: NSDeviceRGBColorSpace] &&
![colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]))
{
int bitsPerSample = 8;
BOOL isPlanar = NO;
int samplesPerPixel = [bitmap hasAlpha] ? 4 : 3;
NSString *colorSpaceName = NSCalibratedRGBColorSpace;
NSBitmapImageRep *new;
new = [bitmap _convertToFormatBitsPerSample: bitsPerSample
samplesPerPixel: samplesPerPixel
hasAlpha: [bitmap hasAlpha]
isPlanar: isPlanar
colorSpaceName: colorSpaceName
bitmapFormat: 0
bytesPerRow: 0
bitsPerPixel: 0];
if (new == nil)
{
NSLog(@"Could not convert bitmap data");
return;
}
bitmap = new;
}
[bitmap getBitmapDataPlanes: (unsigned char **)&data];
[self NSDrawBitmap: rect : [bitmap pixelsWide] : [bitmap pixelsHigh]
: [bitmap bitsPerSample] : [bitmap samplesPerPixel]
: [bitmap bitsPerPixel] : [bitmap bytesPerRow] : [bitmap isPlanar]
: [bitmap hasAlpha] : [bitmap colorSpaceName]
: data];
}
- (void) GSCurrentDevice: (void **)device : (int *)x : (int *)y
{
CairoSurface *surface;

View file

@ -531,18 +531,7 @@ NSLog(@"Callback");
{
flags._eventHandled = NO;
flags._is_menu = NO;
if ((HWND)flags.menuRef == hwnd && flags.HAVE_MAIN_MENU == YES)
flags._is_menu = YES;
// note some cache windows are needed..... just get the zeros
flags._is_cache = [[EVENT_WINDOW(hwnd) className] isEqual: @"GSCacheW"];
flags._hasGSClassName = NO;
if ([EVENT_WINDOW(hwnd) className] != nil)
flags._hasGSClassName = YES;
// future house keeping can go here
}
- (LRESULT) windowEventProc: (HWND)hwnd : (UINT)uMsg
@ -869,17 +858,11 @@ NSLog(@"Callback");
DWORD wstyle;
DWORD estyle;
flags.currentGS_Style = style;
wstyle = [self windowStyleForGSStyle: style];
estyle = [self exwindowStyleForGSStyle: style];
r = GSScreenRectToMS(frame, style, self);
r = GSScreenRectToMS(frame);
/*
* from here down is reused and unmodified from WIN32EventServer.m
* which has been removed form the subproject
*/
NSDebugLLog(@"WTrace", @"window: %@ : %d : %d : %d", NSStringFromRect(frame),
type, style, screen);
NSDebugLLog(@"WTrace", @" device frame: %d, %d, %d, %d",
@ -1233,11 +1216,10 @@ NSLog(@"Callback");
RECT r;
RECT r2;
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
NSWindow *window = GSWindowWithNumber(winNum);
NSDebugLLog(@"WTrace", @"placewindow: %@ : %d", NSStringFromRect(frame),
winNum);
r = GSScreenRectToMS(frame, [window styleMask], self);
r = GSScreenRectToMS(frame);
GetWindowRect((HWND)winNum, &r2);
SetWindowPos((HWND)winNum, NULL,
@ -1277,10 +1259,9 @@ NSLog(@"Callback");
- (NSRect) windowbounds: (int) winNum
{
RECT r;
NSWindow *window = GSWindowWithNumber(winNum);
GetWindowRect((HWND)winNum, &r);
return MSScreenRectToGS(r, [window styleMask], self);
return MSScreenRectToGS(r);
}
- (void) setwindowlevel: (int) level : (int) winNum
@ -1461,6 +1442,23 @@ NSLog(@"Callback");
SetFocus((HWND)winNum);
}
- (void) setalpha: (float)alpha: (int) win
{
if (alpha > 0.99)
{
SetWindowLong((HWND)win, GWL_EXSTYLE,
GetWindowLong((HWND)win, GWL_EXSTYLE) & ~WS_EX_LAYERED);
RedrawWindow((HWND)win, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
else
{
SetWindowLong((HWND)win, GWL_EXSTYLE,
GetWindowLong((HWND)win, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes((HWND)win, 0, 255 * alpha, LWA_ALPHA);
}
}
- (NSPoint) mouselocation
{
POINT p;

View file

@ -34,10 +34,10 @@
- (LRESULT) decodeWM_ACTIVEParams:(WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
{
// decode our params
flags._last_WM_ACTIVATE = LOWORD(wParam);
int last_WM_ACTIVATE = LOWORD(wParam);
//int minimized = HIWORD(wParam);
switch (flags._last_WM_ACTIVATE)
switch (last_WM_ACTIVATE)
{
case WA_ACTIVE: //deactivate
{
@ -66,48 +66,16 @@
- (LRESULT) decodeWM_ACTIVEAPPParams: (HWND)hwnd : (WPARAM)wParam
: (LPARAM)lParam
{
BOOL active = [NSApp isActive];
switch ((int)wParam)
{
case TRUE:
{
if (active==YES)
{
if (flags._is_menu==YES) // have menu and app active
{
// future implimentation if needed
}
else // Not a menu and app is active
{
// window is Visable
if ([EVENT_WINDOW(hwnd) isVisible]==YES)
{
// future implimentation if needed
}
else
{
// future implimentation if needed
}
}
}
else // app is not active
{
[NSApp activateIgnoringOtherApps:YES];
flags._eventHandled=YES;
}
[NSApp activateIgnoringOtherApps: YES];
flags._eventHandled = YES;
}
break;
case FALSE:
{
if (flags._is_menu==YES)
{
// future implimentation if needed
}
else
{
// future implimentation if needed
}
}
break;

View file

@ -102,7 +102,6 @@
break;
case SC_MINIMIZE:
flags.HOLD_MINI_FOR_SIZE=TRUE;
flags.HOLD_MINI_FOR_MOVE=TRUE;
break;
case SC_MONITORPOWER:
break;

View file

@ -39,7 +39,7 @@
NSEvent *ev = nil;
GetWindowRect(hwnd, &r);
rect = MSScreenRectToGS(r, [EVENT_WINDOW(hwnd) styleMask], self);
rect = MSScreenRectToGS(r);
eventLocation = rect.origin;
ev = [NSEvent otherEventWithType: NSAppKitDefined
@ -53,164 +53,79 @@
data2: rect.origin.y];
if (hwnd == (HWND)flags.menuRef)
{
//need native code here?
if (flags.HOLD_MENU_FOR_MOVE == FALSE)
{
[EVENT_WINDOW(hwnd) sendEvent: ev];
}
}
else
{
if (flags.HOLD_TRANSIENT_FOR_MOVE == FALSE)
[EVENT_WINDOW(hwnd) sendEvent: ev];
}
//need native code here?
[EVENT_WINDOW(hwnd) sendEvent: ev];
flags.HOLD_MENU_FOR_MOVE=FALSE;
flags.HOLD_MINI_FOR_MOVE=FALSE;
flags.HOLD_TRANSIENT_FOR_MOVE=FALSE;
return 0;
}
- (LRESULT) decodeWM_SIZEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam
{
NSPoint eventLocation;
NSRect rect;
RECT r;
NSEvent *ev =nil;
GetWindowRect(hwnd, &r);
rect = MSScreenRectToGS(r, [EVENT_WINDOW(hwnd) styleMask], self);
eventLocation = rect.origin;
switch ((int)wParam)
{
case SIZE_MAXHIDE:
{
// stubbed for future development
}
break;
{
// stubbed for future development
}
break;
case SIZE_MAXIMIZED:
{
// stubbed for future development
}
break;
{
// stubbed for future development
}
break;
case SIZE_MAXSHOW:
{
// stubbed for future development
}
break;
{
// stubbed for future development
}
break;
case SIZE_MINIMIZED:
{
if (flags.HOLD_MINI_FOR_SIZE == TRUE) //// this is fix for [5, 25 bug]
break;
{
if (flags.HOLD_MINI_FOR_SIZE == TRUE) // this is fix for [5, 25 bug]
break;
/* FIXME ... RFM 06-Mr-2008....
* I don't understand the following code sending
* a resize event to the gui when a window is minimised.
* Minimising a GNUstep window does NOT change its size,
* rather it causes it to be hidden and replace by its
* miniwindow counterpart.
* Probably the correct action therefore is to ensure that the
* gui knows the window is miniaturised and do nothing else.
* If we send a resize event telling the gui that its window is
* now tiny, it will most likely mess up most drawing in the
* window.
*/
if (1)
{
[EVENT_WINDOW(hwnd) miniaturize: self];
break;
}
/* Original unused code follows: */
// make event
ev = [NSEvent otherEventWithType: NSAppKitDefined
location: eventLocation
modifierFlags: 0
timestamp: 0
windowNumber: (int)hwnd
context: GSCurrentContext()
subtype: GSAppKitWindowResized
data1: rect.size.width
data2: rect.size.height];
if (hwnd == (HWND)flags.menuRef)
{
if (flags.HOLD_MENU_FOR_SIZE == FALSE)
{
[[NSApp mainMenu] setMenuChangedMessagesEnabled: YES];
[EVENT_WINDOW(hwnd) sendEvent: ev];
[self resizeBackingStoreFor: hwnd];
[EVENT_WINDOW(hwnd) miniaturize: self];
[[NSApp mainMenu] setMenuChangedMessagesEnabled: NO];
}
}
else
{
if (flags.HOLD_TRANSIENT_FOR_SIZE == FALSE)
{
[EVENT_WINDOW(hwnd) sendEvent:ev];
[self resizeBackingStoreFor: hwnd];
if ([self usesNativeTaskbar])
{
[EVENT_WINDOW(hwnd) miniaturize: self];
}
}
}
}
break;
[EVENT_WINDOW(hwnd) miniaturize: self];
break;
}
break;
case SIZE_RESTORED:
{
// make event
ev = [NSEvent otherEventWithType: NSAppKitDefined
location: eventLocation
modifierFlags: 0
timestamp: 0
windowNumber: (int)hwnd
context: GSCurrentContext()
subtype: GSAppKitWindowResized
data1: rect.size.width
data2: rect.size.height];
{
NSPoint eventLocation;
NSRect rect;
RECT r;
NSEvent *ev =nil;
GetWindowRect(hwnd, &r);
rect = MSScreenRectToGS(r);
eventLocation = rect.origin;
// make event
ev = [NSEvent otherEventWithType: NSAppKitDefined
location: eventLocation
modifierFlags: 0
timestamp: 0
windowNumber: (int)hwnd
context: GSCurrentContext()
subtype: GSAppKitWindowResized
data1: rect.size.width
data2: rect.size.height];
if (hwnd == (HWND)flags.menuRef)
{
if (flags.HOLD_MENU_FOR_SIZE == FALSE)
{
[EVENT_WINDOW(hwnd) _setVisible: YES];
[EVENT_WINDOW(hwnd) sendEvent: ev];
[self resizeBackingStoreFor: hwnd];
//[EVENT_WINDOW(hwnd) deminiaturize:self];
}
}
else
{
if (flags.HOLD_TRANSIENT_FOR_SIZE == FALSE)
{
[EVENT_WINDOW(hwnd) sendEvent: ev];
[self resizeBackingStoreFor: hwnd];
// fixes part one of bug [5, 25] see notes
if ([self usesNativeTaskbar])
[EVENT_WINDOW(hwnd) deminiaturize:self];
}
}
}
break;
[EVENT_WINDOW(hwnd) sendEvent: ev];
[self resizeBackingStoreFor: hwnd];
// fixes part one of bug [5, 25] see notes
if ([self usesNativeTaskbar])
[EVENT_WINDOW(hwnd) deminiaturize:self];
}
break;
default:
break;
break;
}
ev = nil;
flags.HOLD_MENU_FOR_SIZE = FALSE;
flags.HOLD_MINI_FOR_SIZE = FALSE;
flags.HOLD_TRANSIENT_FOR_SIZE = FALSE;
return 0;
}
@ -234,7 +149,7 @@
drect=newRects->rgrc[1];
//create a size event and send it to the window
rect = MSScreenRectToGS(drect, [EVENT_WINDOW(hwnd) styleMask], self);
rect = MSScreenRectToGS(drect);
eventLocation = rect.origin;
// make event
@ -456,8 +371,6 @@ NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll);
{
// stub for future dev
flags.HOLD_PAINT_FOR_SIZING=TRUE;
//[EVENT_WINDOW(hwnd) displayIfNeeded];
//[self decodeWM_SIZEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam];
//printf("SIZING called\n");

View file

@ -53,13 +53,6 @@
#define AC_SRC_ALPHA 0x01
#endif
// There is a bug in Win32 GDI drawing with lines wider than 0
// before and after a bezier path forming an oblique
// angle. The solution is to insert extra MoveToEx()'s
// before and after the PolyBezierTo().
// FK: I switched this off, as I think the treatment is worse than the illness.
#define GDI_WIDELINE_BEZIERPATH_BUG 0
static inline
int WindowHeight(HWND window)
{
@ -175,38 +168,17 @@ RECT GSViewRectToWin(WIN32GState *s, NSRect r)
wscolor = RGB(color.field[0]*255, color.field[1]*255, color.field[2]*255);
}
static inline
RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
{
RECT r1;
int h;
h = WindowHeight([s window]);
// r.origin.x += s->offset.x;
// r.origin.y += s->offset.y;
r1.left = r.origin.x;
r1.right = r.origin.x + r.size.width;
r1.bottom = h - r.origin.y;
r1.top = h - r.origin.y - r.size.height;
return r1;
}
- (void) compositeGState: (WIN32GState *) source
fromRect: (NSRect) sourceRect
toPoint: (NSPoint) destPoint
op: (NSCompositingOperation) op
- (void) compositeGState: (WIN32GState *)source
fromRect: (NSRect)sourceRect
toPoint: (NSPoint)destPoint
op: (NSCompositingOperation)op
fraction: (float)delta
{
NSAffineTransformStruct sctms;
NSAffineTransformStruct ctms;
HDC sourceDC;
HDC hDC;
RECT rectFrom;
RECT rectTo;
int h;
int h, w;
int x;
int y;
NSRect destRect;
@ -216,23 +188,28 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
@"compositeGState: fromRect: %@ toPoint: %@ op: %d",
NSStringFromRect(sourceRect), NSStringFromPoint(destPoint), op);
rectFrom = GSViewRectToWin(source, sourceRect);
//rectFrom = GSXWindowRectToMS(sourceRect);
h = rectFrom.bottom - rectFrom.top;
if (viewIsFlipped && (self != source))
{
destPoint.y -= sourceRect.size.height;
}
destRect.size = sourceRect.size;
destRect.origin = destPoint;
rectTo = GSViewRectToWin(self, destRect);
destRect.size = sourceRect.size;
[ctm boundingRectFor: destRect result: &destRect];
rectTo = GSWindowRectToMS(self, destRect);
x = rectTo.left;
y = rectTo.top;
y = rectTo.bottom - sourceRect.size.height;
sctms = [source->ctm transformStruct];
ctms = [ctm transformStruct];
if (sctms.m22 < 0 && ctms.m22 > 0) y += h;
if (sctms.m22 > 0 && ctms.m22 < 0) y -= h;
{
NSRect newRect;
[source->ctm boundingRectFor: sourceRect result: &newRect];
rectFrom = GSWindowRectToMS(source, newRect);
}
h = rectFrom.bottom - rectFrom.top;
w = rectFrom.right - rectFrom.left;
sourceDC = [source getHDC];
if (!sourceDC)
{
return;
@ -247,8 +224,8 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
hDC = [self getHDC];
if (!hDC)
{
[source releaseHDC: sourceDC];
return;
[source releaseHDC: sourceDC];
return;
}
}
@ -257,35 +234,35 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
case NSCompositeSourceOver:
{
#ifdef USE_ALPHABLEND
// Use (0..1) fraction to set a (0..255) alpha constant value
BYTE SourceConstantAlpha = (BYTE)(delta * 255);
BLENDFUNCTION blendFunc
= {AC_SRC_OVER, 0, SourceConstantAlpha, AC_SRC_ALPHA};
success = AlphaBlend(hDC,
x, y, (rectFrom.right - rectFrom.left), h,
sourceDC,
rectFrom.left, rectFrom.top,
(rectFrom.right - rectFrom.left), h, blendFunc);
/* There is actually a very real chance this could fail, even on
computers that supposedly support it. It's not known why it
fails though... */
if (success)
break;
// Use (0..1) fraction to set a (0..255) alpha constant value
BYTE SourceConstantAlpha = (BYTE)(delta * 255);
BLENDFUNCTION blendFunc
= {AC_SRC_OVER, 0, SourceConstantAlpha, AC_SRC_ALPHA};
success = AlphaBlend(hDC,
x, y, w, h,
sourceDC,
rectFrom.left, rectFrom.top,
w, h, blendFunc);
/* There is actually a very real chance this could fail, even on
computers that supposedly support it. It's not known why it
fails though... */
if (success)
break;
#endif
}
case NSCompositeCopy:
{
success = BitBlt(hDC, x, y, (rectFrom.right - rectFrom.left), h,
sourceDC, rectFrom.left, rectFrom.top, SRCCOPY);
break;
success = BitBlt(hDC, x, y, w, h,
sourceDC, rectFrom.left, rectFrom.top, SRCCOPY);
break;
}
case NSCompositeClear:
{
break;
break;
}
default:
success = BitBlt(hDC, x, y, (rectFrom.right - rectFrom.left), h,
sourceDC, rectFrom.left, rectFrom.top, SRCCOPY);
success = BitBlt(hDC, x, y, w, h,
sourceDC, rectFrom.left, rectFrom.top, SRCCOPY);
break;
}
@ -293,9 +270,9 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
{
NSLog(@"Blit operation failed %d", GetLastError());
NSLog(@"Orig Copy Bits to %@ from %@", NSStringFromPoint(destPoint),
NSStringFromRect(destRect));
NSStringFromRect(destRect));
NSLog(@"Copy bits to {%d, %d} from {%d, %d} size {%d, %d}", x, y,
rectFrom.left, rectFrom.top, (rectFrom.right - rectFrom.left), h);
rectFrom.left, rectFrom.top, w, h);
}
if (self != source)
@ -314,7 +291,7 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
fromRect: aRect
toPoint: aPoint
op: op
fraction: 1];
fraction: 1.0];
}
- (void) dissolveGState: (GSGState *)source
@ -334,6 +311,7 @@ RECT GSXWindowRectToMS(WIN32GState *s, NSRect r)
{
float gray;
// FIXME: This is taken from the xlib backend
[self DPScurrentgray: &gray];
if (fabs(gray - 0.667) < 0.005)
[self DPSsetgray: 0.333];
@ -607,9 +585,7 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
HBITMAP hbitmap;
HGDIOBJ old;
HDC hDC2;
POINT p;
int h;
int y1;
POINT pa[3];
/*
NSDebugLLog(@"WIN32GState", @"DPSImage : pixelsWide = %d : pixelsHigh = %d"
@ -664,31 +640,41 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
hDC = [self getHDC];
h = pixelsHigh;
// Apply the additional transformation
if (matrix)
{
old_ctm = [ctm copy];
[ctm prependTransform: matrix];
}
p = GSViewPointToWin(self, NSMakePoint(0, 0));
pa[0] = GSViewPointToWin(self, NSMakePoint(0, pixelsHigh));
pa[1] = GSViewPointToWin(self, NSMakePoint(pixelsWide, pixelsHigh));
pa[2] = GSViewPointToWin(self, NSMakePoint(0, 0));
if (viewIsFlipped)
{
pa[0].y += pixelsHigh;
pa[1].y += pixelsHigh;
pa[2].y += pixelsHigh;
}
if (old_ctm != nil)
{
RELEASE(ctm);
// old_ctm is already retained
ctm = old_ctm;
}
if (viewIsFlipped)
y1 = p.y;
else
y1 = p.y - h;
if (!BitBlt(hDC, p.x, y1, pixelsWide, pixelsHigh,
hDC2, 0, 0, SRCCOPY))
if ((GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT))
{
NSLog(@"Copy bitmap failed %d", GetLastError());
NSLog(@"DPSimage with %d %d %d %d to %d, %d", pixelsWide, pixelsHigh,
bytesPerRow, bitsPerPixel, p.x, y1);
SetStretchBltMode(hDC, COLORONCOLOR);
if (!PlgBlt(hDC, pa, hDC2, 0, 0, pixelsWide, pixelsHigh, 0, 0, 0))
{
NSLog(@"Copy bitmap failed %d", GetLastError());
NSLog(@"DPSimage with %d %d %d %d to %d, %d", pixelsWide, pixelsHigh,
bytesPerRow, bitsPerPixel, pa[0].x, pa[0].y);
}
}
[self releaseHDC: hDC];
@ -741,43 +727,15 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
{
POINT bp[3];
#if GDI_WIDELINE_BEZIERPATH_BUG
if (drawType == path_stroke && lineWidth > 1)
{
if (j != 0)
{
NSPoint movePoints[3];
[path elementAtIndex: j-1 associatedPoints:
movePoints];
p = GSWindowPointToMS(self, movePoints[0]);
MoveToEx(hDC, p.x, p.y, NULL);
}
}
#endif
for (i = 0; i < 3; i++)
{
bp[i] = GSWindowPointToMS(self, points[i]);
}
PolyBezierTo(hDC, bp, 3);
#if GDI_WIDELINE_BEZIERPATH_BUG
if (drawType == path_stroke && lineWidth > 1)
MoveToEx(hDC, bp[2].x, bp[2].y, NULL);
#endif
}
break;
case NSClosePathBezierPathElement:
#if GDI_WIDELINE_BEZIERPATH_BUG
// CloseFigure works from the last MoveTo point which is
// a problem when we need to insert gratuitious moves
// before and after bezier curves to fix draw problems.
[path elementAtIndex: 0 associatedPoints: points];
p = GSWindowPointToMS(self, points[0]);
// FIXME This may also give one pixel too few
LineTo(hDC, p.x, p.y);
#else
CloseFigure(hDC);
#endif
break;
default:
break;
@ -874,7 +832,6 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
[self _paintPath: path_stroke];
}
- (void) DPSinitclip;
{
if (clipRegion)
@ -884,58 +841,6 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
}
}
- (void)DPSrectfill: (float)x : (float)y : (float)w : (float)h
{
HDC hDC;
HBRUSH brush;
RECT rect;
hDC = [self getHDC];
if (!hDC)
{
return;
}
brush = GetCurrentObject(hDC, OBJ_BRUSH);
rect = GSViewRectToWin(self, NSMakeRect(x, y, w, h));
FillRect(hDC, &rect, brush);
[self releaseHDC: hDC];
}
- (void)DPSrectstroke: (float)x : (float)y : (float)w : (float)h
{
NSRect rect = [ctm rectInMatrixSpace: NSMakeRect(x, y, w, h)];
/* // Samll adjustment so that the line is visible
if (rect.size.width > 0)
rect.size.width--;
if (rect.size.height > 0)
rect.size.height--;
rect.origin.y += 1; */
[path appendBezierPathWithRect: rect];
[self DPSstroke];
}
- (void)DPSrectclip: (float)x : (float)y : (float)w : (float)h
{
RECT rect;
HRGN region;
rect = GSViewRectToWin(self, NSMakeRect(x, y, w, h));
region = CreateRectRgnIndirect(&rect);
if (clipRegion)
{
CombineRgn(clipRegion, clipRegion, region, RGN_AND);
DeleteObject(region);
}
else
{
clipRegion = region;
}
[self DPSnewpath];
}
- (void)DPSshow: (const char *)s
{
NSPoint current = [path currentPoint];
@ -990,6 +895,7 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
path = [NSBezierPath new];
}
// FIXME: Convert to ctm first
[path setLineDash: thePattern count: count phase: phase];
}
@ -1000,6 +906,7 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
- (void)DPSsetmiterlimit: (float)limit
{
// FIXME: Convert to ctm first
miterlimit = limit;
}
@ -1030,6 +937,7 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
- (void)DPSsetlinewidth: (float)width
{
// FIXME: Convert to ctm first
lineWidth = width;
}

View file

@ -518,6 +518,16 @@ _parse_display_name(NSString *name, int *dn, int *sn)
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
@ -528,6 +538,112 @@ _parse_display_name(NSString *name, int *dn, int *sn)
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
*/

View file

@ -996,15 +996,8 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
XGetWindowAttributes(dpy, parent, &wattr);
NSDebugLLog(@"Offset", @"Parent border,width,height %d,%d,%d\n",
wattr.border_width, wattr.width, wattr.height);
l = wattr.border_width;
t = wattr.border_width;
/* Find total parent size and subtract window size and
* top-left-corner offset to determine bottom-right-corner
* offset.
*/
r = wattr.width + wattr.border_width * 2;
b = wattr.height + wattr.border_width * 2;
l = repx + wattr.border_width;
t = repy + wattr.border_width;
// Some window manager e.g. KDE2 put in multiple windows,
// so we have to find the right parent, closest to root
@ -1019,14 +1012,16 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
|| (repx == 0 && repy == 0))
{
Window new_parent = parent;
Window root = window->root;
while (new_parent && (new_parent != window->root))
{
Window root;
Window *children = 0;
unsigned int nchildren;
parent = new_parent;
repx = wattr.x;
repy = wattr.y;
NSLog(@"QueryTree window is %d (root %d cwin root %d)",
parent, root, window->root);
if (!XQueryTree(dpy, parent, &root, &new_parent,
@ -1045,20 +1040,21 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
}
if (new_parent && new_parent != window->root)
{
XGetWindowAttributes(dpy, parent, &wattr);
XGetWindowAttributes(dpy, new_parent, &wattr);
l += repx + wattr.border_width;
t += repy + wattr.border_width;
r = wattr.width + wattr.border_width * 2;
b = wattr.height + wattr.border_width * 2;
repx = wattr.x;
repy = wattr.y;
}
} /* while */
} /* generic.flags.doubleParentWindow */
/* Find total parent size and subtract window size and
* top-left-corner offset to determine bottom-right-corner
* offset.
*/
r = wattr.width + wattr.border_width * 2;
r -= (window->xframe.size.width + l);
b = wattr.height + wattr.border_width * 2;
b -= (window->xframe.size.height + t);
l += repx;
t += repy;
o->l = l;
o->r = r;

View file

@ -12,7 +12,7 @@
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
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
@ -49,7 +49,7 @@ static int use_xshm = 1;
static int num_xshm_test_errors = 0;
static NSString *xshm_warning
= @"Falling back to normal XImage: s (will be slower).";
= @"Falling back to normal XImage: s (will be slower).";
static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
{
@ -57,7 +57,7 @@ static int test_xshm_error_handler(Display *d, XErrorEvent *ev)
return 0;
}
static void test_xshm(Display *display, int drawing_depth)
static void test_xshm(Display *display, Visual *visual, int drawing_depth)
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@ -81,6 +81,19 @@ static void test_xshm(Display *display, int drawing_depth)
return;
}
{
int major, minor;
Bool pixmaps;
if (!XShmQueryVersion(display, &major, &minor, &pixmaps) || !pixmaps)
{
NSLog(@"XShm pixmaps not supported by X server.");
NSLog(xshm_warning);
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
@ -93,39 +106,38 @@ static void test_xshm(Display *display, int drawing_depth)
old_error_handler = XSetErrorHandler(test_xshm_error_handler);
ximage = XShmCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
drawing_depth, ZPixmap, NULL, &shminfo,
1, 1);
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;
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);
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;
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;
NSLog(@"XShm not supported, shmat() failed: %m.");
XDestroyImage(ximage);
shmctl(shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
shminfo.readOnly = 0;
@ -134,11 +146,11 @@ static void test_xshm(Display *display, int drawing_depth)
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;
NSLog(@"XShm not supported, XShmAttach() failed.");
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
XShmDetach(display, &shminfo);
@ -154,10 +166,10 @@ static void test_xshm(Display *display, int drawing_depth)
if (num_xshm_test_errors)
{
NSLog(@"XShm not supported.");
NSLog(@"XShm not supported.");
no_xshm:
NSLog(xshm_warning);
use_xshm = 0;
NSLog(xshm_warning);
use_xshm = 0;
}
XSetErrorHandler(old_error_handler);
}
@ -166,16 +178,24 @@ no_xshm:
@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;
break;
}
if (i == num_window_buffers)
{
@ -184,11 +204,11 @@ no_xshm:
window_buffers = realloc(window_buffers,
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
if (!window_buffers)
{
NSLog(@"Out of memory (failed to allocate %i bytes)",
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
exit(1);
}
{
NSLog(@"Out of memory (failed to allocate %i bytes)",
sizeof(XWindowBuffer *) * (num_window_buffers + 1));
exit(1);
}
window_buffers[num_window_buffers++] = wi;
}
else
@ -205,6 +225,15 @@ no_xshm:
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
@ -225,33 +254,32 @@ no_xshm:
wi->sx != awindow->xframe.size.width ||
wi->sy != awindow->xframe.size.height)
{
wi->sx = wi->window->xframe.size.width;
/* printf("%@ updating image for %p (%gx%g)\n", wi, wi->window,
wi->window->xframe.size.width, wi->window->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)
{
if (wi->use_shm)
{
XShmDetach(wi->display, &wi->shminfo);
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
}
else
XDestroyImage(wi->ximage);
}
{
if (wi->use_shm)
{
XShmDetach(wi->display, &wi->shminfo);
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
}
else
XDestroyImage(wi->ximage);
}
if (wi->pixmap)
{
XFreePixmap(wi->display,wi->pixmap);
XSetWindowBackground(wi->display,wi->window->ident,None);
wi->pixmap=0;
}
{
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;
}
{
free(wi->alpha);
wi->alpha = NULL;
}
wi->pending_put = wi->pending_event = 0;
@ -269,73 +297,72 @@ no_xshm:
goto no_xshm;
if (!did_test_xshm)
test_xshm(wi->display, aDI->drawing_depth);
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,
DefaultVisual(wi->display, DefaultScreen(wi->display)),
aDI->drawing_depth, ZPixmap, NULL, &wi->shminfo,
wi->window->xframe.size.width,
wi->window->xframe.size.height);
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(xshm_warning);
goto no_xshm;
}
{
NSLog(@"Warning: XShmCreateImage failed!");
NSLog(xshm_warning);
goto no_xshm;
}
wi->shminfo.shmid = shmget(IPC_PRIVATE,
wi->ximage->bytes_per_line * wi->ximage->height,
IPC_CREAT | 0700);
wi->ximage->bytes_per_line * wi->ximage->height,
IPC_CREAT | 0700);
if (wi->shminfo.shmid == -1)
{
NSLog(@"Warning: shmget() failed: %m.");
NSLog(xshm_warning);
XDestroyImage(wi->ximage);
goto no_xshm;
}
{
NSLog(@"Warning: shmget() failed: %m.");
NSLog(xshm_warning);
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(xshm_warning);
XDestroyImage(wi->ximage);
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
{
NSLog(@"Warning: shmat() failed: %m.");
NSLog(xshm_warning);
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(xshm_warning);
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
{
NSLog(@"Warning: XShmAttach() failed.");
NSLog(xshm_warning);
XDestroyImage(wi->ximage);
shmdt(wi->shminfo.shmaddr);
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
goto no_xshm;
}
/* 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. */
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. */
need to. */
wi->pixmap = XShmCreatePixmap(wi->display, wi->drawable,
wi->ximage->data, &wi->shminfo,
wi->window->xframe.size.width,
wi->window->xframe.size.height,
aDI->drawing_depth);
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);
}
{
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
@ -348,24 +375,25 @@ no_xshm:
shmctl(wi->shminfo.shmid, IPC_RMID, 0);
if (!wi->ximage)
{
{
no_xshm:
wi->use_shm = 0;
wi->ximage = XCreateImage(wi->display, DefaultVisual(wi->display,
DefaultScreen(wi->display)), aDI->drawing_depth, ZPixmap, 0, NULL,
wi->window->xframe.size.width, wi->window->xframe.size.height,
8, 0);
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);
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);*/
}
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)
@ -376,7 +404,7 @@ no_xshm:
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);
// NSLog(@"%@ ximage=%p data=%p\n", wi->ximage, wi->data);
}
else
{
@ -400,31 +428,31 @@ extern int XShmGetEventBase(Display *d);
{
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;
}
{
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;
}
{
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?");
}
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;
}
{
pending_event = 1;
}
}
// XFlush(window->display);
// XFlush(window->display);
}
- (void) _exposeRect: (NSRect)rect
@ -476,138 +504,138 @@ accuracy, we do the test using int: s.
{
/* HACK: lets try to use shaped windows to get some use out of
destination alpha */
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;
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;
if (!warn)
NSLog(@"Warning: activating shaped windows");
warn = 1;
memset(buf, 0xff, dsize);
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;
}
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;
}
}
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);
}
}
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);
}
}
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;
}
}
}
{
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;
}
}
{
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. */
events. */
{
XEvent e;
XEvent e;
while (XCheckTypedEvent(window->display,
XShmGetEventBase(window->display) + ShmCompletion, &e))
{
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
}
while (XCheckTypedEvent(window->display,
XShmGetEventBase(window->display) + ShmCompletion, &e))
{
[isa _gotShmCompletion: ((XShmCompletionEvent *)&e)->drawable];
}
}
}
else if (ximage)
@ -624,7 +652,7 @@ static int warn = 0;
if (!data)
return;
// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy);
// NSLog(@"needs alpha for %p: %ix%i", self, sx, sy);
if (DI.inline_alpha)
{
@ -634,8 +662,8 @@ static int warn = 0;
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;
i++, s += DI.bytes_per_pixel)
*s = 0xff;
return;
}
@ -646,7 +674,7 @@ static int warn = 0;
return;
}
// NSLog(@"got buffer at %p", alpha);
// NSLog(@"got buffer at %p", alpha);
has_alpha = 1;
memset(alpha, 0xff, sx * sy);
@ -662,25 +690,25 @@ static int warn = 0;
{
num_window_buffers--;
for (; i < num_window_buffers; i++)
window_buffers[i] = window_buffers[i + 1];
window_buffers[i] = window_buffers[i + 1];
}
if (ximage)
{
if (pixmap)
{
XFreePixmap(display,pixmap);
pixmap=0;
}
{
XFreePixmap(display,pixmap);
pixmap=0;
}
if (use_shm)
{
XShmDetach(display, &shminfo);
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
}
{
XShmDetach(display, &shminfo);
XDestroyImage(ximage);
shmdt(shminfo.shmaddr);
}
else
XDestroyImage(ximage);
XDestroyImage(ximage);
}
if (alpha)
free(alpha);
@ -688,23 +716,16 @@ static int warn = 0;
}
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
use_shape_hack = [ud boolForKey: @"XWindowBuffer-shape-hack"];
}
+ (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;
}
{
[window_buffers[i] _gotShmCompletion];
return;
}
}
}

View file

@ -216,8 +216,17 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
/*
* Set up atoms for use in X selection mechanism.
*/
XInternAtoms(xDisplay, atom_names, sizeof(atom_names)/sizeof(char*),
False, atoms);
#ifdef HAVE_XINTERNATOMS
XInternAtoms(xDisplay, atom_names, sizeof(atom_names)/sizeof(char*),
False, atoms);
#else
{
int atomCount;
for (atomCount = 0; atomCount < sizeof(atom_names)/sizeof(char*); atomCount++)
atoms[atomCount] = XInternAtom(xDisplay, atom_names[atomCount], False);
}
#endif
xRootWin = RootWindow(xDisplay, DefaultScreen(xDisplay));
xAppWin = XCreateSimpleWindow(xDisplay, xRootWin,

View file

@ -32,9 +32,6 @@
/* Define if you have the glx library */
#undef HAVE_GLX
/* Define if you have the glx library */
#undef HAVE_WGL
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@ -47,6 +44,9 @@
/* Define to 1 if you have the `Xmu' library (-lXmu). */
#undef HAVE_LIBXMU
/* Define to 1 if you have the `Xt' library (-lXt). */
#undef HAVE_LIBXT
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@ -96,6 +96,9 @@
*/
#undef HAVE_XFT
/* Define to 1 if you have 'XInternAtoms' function. */
#undef HAVE_XINTERNATOMS
/* Define to 1 if you have the `Xutf8LookupString' function. */
#undef HAVE_XUTF8LOOKUPSTRING
@ -123,11 +126,11 @@
/* Define to enable XIM support */
#undef USE_XIM
/* Define if you have X11 XRender extension */
#undef XRENDER
/* Define if you have X11 XShm extensions */
#undef XSHM
/* Define if you have X11 Xrender extensions */
#undef XRENDER
/* Define to 1 if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING

70
configure vendored
View file

@ -6957,6 +6957,76 @@ _ACEOF
fi
{ echo "$as_me:$LINENO: checking for XInternAtoms in -lX11" >&5
echo $ECHO_N "checking for XInternAtoms in -lX11... $ECHO_C" >&6; }
if test "${ac_cv_lib_X11_XInternAtoms+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lX11 $X_LIBS $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char XInternAtoms ();
int
main ()
{
return XInternAtoms ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_lib_X11_XInternAtoms=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_X11_XInternAtoms=no
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_X11_XInternAtoms" >&5
echo "${ECHO_T}$ac_cv_lib_X11_XInternAtoms" >&6; }
if test $ac_cv_lib_X11_XInternAtoms = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_XINTERNATOMS 1
_ACEOF
fi
#--------------------------------------------------------------------
# Window's graphics library
#--------------------------------------------------------------------

View file

@ -298,6 +298,12 @@ if test "$ac_cv_header_X11_extensions_XShm_h" = yes -a "$ac_cv_func_shmctl" = ye
AC_DEFINE(XSHM,1,[Define if you have X11 XShm extensions])
fi
AC_CHECK_LIB(X11, XInternAtoms,
AC_DEFINE([HAVE_XINTERNATOMS], 1,
[Define to 1 if you have 'XInternAtoms' function.]),
,
$X_LIBS)
#--------------------------------------------------------------------
# Window's graphics library
#--------------------------------------------------------------------

9
install.sh Executable file
View file

@ -0,0 +1,9 @@
#/bin/sh
PREFIX=$1
MAKE=$2
. $PREFIX/System/Library/Makefiles/GNUstep.sh
$MAKE install
exit 0