diff --git a/ChangeLog b/ChangeLog index f60e363..6761142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2008-08-19 Fred Kiefer + + * Source/art/ARTContext.m (-GSSetDevice:::): Only call + setupDrawInfo once. + * Source/art/ARTContext.m (-setupDrawInfo): Try to handle + endianess differance better. + * Source/art/ARTContext.m (-initializeBackend): Call + artcontext_setup_gamma(). + * Source/art/blit.h, + * Source/art/blit-main.m: New function artcontext_setup_gamma() + split off from artcontext_setup_draw_info(). + +2008-08-14 Fred Kiefer + + * Source/x11/XGServerWindow.m (-_ewmh_isMinimized:): Correct + indentation. + * Source/x11/XGServerEvent.m (-receivedEvent:type:extra:forMode:): + For PropertyNotify cache the window first. + +2008-07-19 Fred Kiefer + + * Source/x11/XGServerWindow.m (-window::::): For EWMH window + enable property change notifications. + * Source/x11/XGServerWindow.m (-_ewmh_isMinimized:): Check whether + the window is minimized. + * Headers/x11/XGServerWindow.h (-_ewmh_isMinimized:): Declare new + method. + * Source/x11/XGServerEvent.m: Handle case when window gets minimized. + * Headers/x11/XGGeneric.h: Add atom for hidden state. + Patch by Hubert Chathi . + 2008-07-12 Fred Kiefer * Source/xlib/GSXftFontInfo.m (-setupAttributes:), diff --git a/Headers/x11/XGGeneric.h b/Headers/x11/XGGeneric.h index cadbd59..399d3c8 100644 --- a/Headers/x11/XGGeneric.h +++ b/Headers/x11/XGGeneric.h @@ -63,6 +63,7 @@ typedef struct { Atom net_wm_state_skip_taskbar_atom; Atom net_wm_state_skip_pager_atom; Atom net_wm_state_sticky_atom; + Atom net_wm_state_hidden_atom; } XGWMNetStates; /* diff --git a/Headers/x11/XGServerWindow.h b/Headers/x11/XGServerWindow.h index 543a373..2ce47ff 100644 --- a/Headers/x11/XGServerWindow.h +++ b/Headers/x11/XGServerWindow.h @@ -129,6 +129,8 @@ typedef struct _gswindow_device_t { /* This needs to go in GSDisplayServer */ - (void) _DPSsetcursor: (Cursor)c : (BOOL)set; + +- (BOOL) _ewmh_isMinimized: (Window) win; @end extern Pixmap diff --git a/Source/art/ARTContext.m b/Source/art/ARTContext.m index f11919a..80f1e41 100644 --- a/Source/art/ARTContext.m +++ b/Source/art/ARTContext.m @@ -25,6 +25,7 @@ #include #include +#include #include "ARTGState.h" #include "blit.h" @@ -35,12 +36,18 @@ #endif // Could use NSSwapInt() instead -static unsigned int flip_bytes(unsigned int i) +static unsigned int flip_bytes32(unsigned int i) { return ((i >> 24) & 0xff) - |((i >> 8) & 0xff00) - |((i << 8) & 0xff0000) - |((i << 24) & 0xff000000); + |((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) @@ -58,10 +65,16 @@ static int byte_order(void) + (void)initializeBackend { + float gamma; + NSDebugLLog(@"back-art",@"Initializing libart/freetype backend"); [NSGraphicsContext setDefaultContextClass: [ARTContext class]]; [FTFontInfo initializeBackend]; + + gamma = [[NSUserDefaults standardUserDefaults] + floatForKey: @"back-art-text-gamma"]; + artcontext_setup_gamma(gamma); } + (Class) GStateClass @@ -126,9 +139,18 @@ static int byte_order(void) int them = ImageByteOrder(d); /* True iff the server is big-endian. */ if (us != them) { - visual->red_mask = flip_bytes(visual->red_mask); - visual->green_mask = flip_bytes(visual->green_mask); - visual->blue_mask = flip_bytes(visual->blue_mask); + 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); + } } } @@ -168,9 +190,18 @@ static int byte_order(void) @end @implementation ARTContext (ops) + - (void) GSSetDevice: (void*)device : (int)x : (int)y { - [self setupDrawInfo]; + // Currently all windows share the same drawing info. + // It is enough to initialize it once. + static BOOL serverInitialized = NO; + + if (!serverInitialized) + { + [self setupDrawInfo]; + serverInitialized = YES; + } [(ARTGState *)gstate GSSetDevice: device : x : y]; } diff --git a/Source/art/blit-main.m b/Source/art/blit-main.m index fb24344..f387f87 100644 --- a/Source/art/blit-main.m +++ b/Source/art/blit-main.m @@ -26,6 +26,7 @@ #include #include +#include #include "blit.h" @@ -389,9 +390,6 @@ static int byte_ofs_of_mask(unsigned int m) return -1; } - -#include - void artcontext_setup_draw_info(draw_info_t *di, unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask, int bpp) @@ -420,23 +418,23 @@ void artcontext_setup_draw_info(draw_info_t *di, b = byte_ofs_of_mask(blue_mask); if (bpp == 24) - { - if (r == 0 && g == 1 && b == 2) - t = DI_24_RGB; - else if (r == 2 && g == 1 && b == 0) - t = DI_24_BGR; - } + { + if (r == 0 && g == 1 && b == 2) + t = DI_24_RGB; + else if (r == 2 && g == 1 && b == 0) + t = DI_24_BGR; + } else if (bpp == 32) - { - if (r == 0 && g == 1 && b == 2) - t = DI_32_RGBA; - else if (r == 2 && g == 1 && b == 0) - t = DI_32_BGRA; - else if (r == 1 && g == 2 && b == 3) - t = DI_32_ARGB; - else if (r == 3 && g == 2 && b == 1) - t = DI_32_ABGR; - } + { + if (r == 0 && g == 1 && b == 2) + t = DI_32_RGBA; + else if (r == 2 && g == 1 && b == 0) + t = DI_32_BGRA; + else if (r == 1 && g == 2 && b == 3) + t = DI_32_ARGB; + else if (r == 3 && g == 2 && b == 1) + t = DI_32_ABGR; + } } NSDebugLLog(@"back-art", @"got t=%i", t); @@ -453,26 +451,27 @@ void artcontext_setup_draw_info(draw_info_t *di, @"Better: implement it and send a patch.)"); exit(1); } - - { - float gamma = [[NSUserDefaults standardUserDefaults] - floatForKey: @"back-art-text-gamma"]; - int i; - if (!gamma) - gamma = 1.4; - - NSDebugLLog(@"back-art",@"gamma=%g",gamma); - - gamma = 1.0 / gamma; - - for (i = 0; i < 256; i++) - { - gamma_table[i] = pow(i / 255.0, gamma) * 255 + .5; - inv_gamma_table[i] = pow(i / 255.0, 1.0 / gamma) * 255 + .5; - } - } } +void artcontext_setup_gamma(float gamma) +{ + int i; + + if (!gamma) + gamma = 1.4; + + NSDebugLLog(@"back-art",@"gamma=%g",gamma); + + gamma = 1.0 / gamma; + + for (i = 0; i < 256; i++) + { + gamma_table[i] = pow(i / 255.0, gamma) * 255 + .5; + inv_gamma_table[i] = pow(i / 255.0, 1.0 / gamma) * 255 + .5; + } +} + + /* diff --git a/Source/art/blit.h b/Source/art/blit.h index adf2c0a..928d815 100644 --- a/Source/art/blit.h +++ b/Source/art/blit.h @@ -160,6 +160,7 @@ typedef struct draw_info_s void artcontext_setup_draw_info(draw_info_t *di, unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask, int bpp); +void artcontext_setup_gamma(float gamma); #endif diff --git a/Source/x11/XGServerEvent.m b/Source/x11/XGServerEvent.m index 3da84a9..5a4f198 100644 --- a/Source/x11/XGServerEvent.m +++ b/Source/x11/XGServerEvent.m @@ -1298,12 +1298,45 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym) break; } - // a window property has changed or been deleted + // a window property has changed or been deleted case PropertyNotify: - NSDebugLLog(@"NSEvent", @"%d PropertyNotify - '%s'\n", - xEvent.xproperty.window, - XGetAtomName(dpy, xEvent.xproperty.atom)); - break; + NSDebugLLog(@"NSEvent", @"%d PropertyNotify - '%s'\n", + xEvent.xproperty.window, + XGetAtomName(dpy, xEvent.xproperty.atom)); + { + if (xEvent.xproperty.atom == generic.netstates.net_wm_state_atom && + xEvent.xproperty.state == PropertyNewValue) + { + if (cWin == 0 || xEvent.xproperty.window != cWin->ident) + { + generic.cachedWindow + = [XGServer _windowForXWindow: xEvent.xproperty.window]; + } + if (cWin != 0) + { + /* + * FIXME: we really should detect when the state changes from + * unminimized to minimized, or vice versa + */ + if ([self _ewmh_isMinimized: xEvent.xproperty.window]) + { + // Same event as when we get ClientMessage with the atom + // equal to generic.miniaturize_atom + eventLocation = NSMakePoint(0,0); + e = [NSEvent otherEventWithType: NSAppKitDefined + location: eventLocation + modifierFlags: 0 + timestamp: xEvent.xproperty.time / 1000 + windowNumber: cWin->number + context: gcontext + subtype: GSAppKitWindowMiniaturize + data1: 0 + data2: 0]; + } + } + } + } + break; // a client successfully reparents a window case ReparentNotify: diff --git a/Source/x11/XGServerWindow.m b/Source/x11/XGServerWindow.m index fc0c729..4e9fff2 100644 --- a/Source/x11/XGServerWindow.m +++ b/Source/x11/XGServerWindow.m @@ -1235,6 +1235,8 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False); generic.netstates.net_wm_state_sticky_atom = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False); + generic.netstates.net_wm_state_hidden_atom = + XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False); } if (win1) { @@ -1940,7 +1942,8 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg) | EnterWindowMask | LeaveWindowMask | FocusChangeMask -// | PropertyChangeMask + // enable property notifications under ewmh to detect window minimizing + | (generic.wm & XGWM_EWMH ? PropertyChangeMask : 0) // | ColormapChangeMask | KeymapStateMask | VisibilityChangeMask @@ -4573,4 +4576,36 @@ _computeDepth(int class, int bpp) return hasShadow; } +/* + * Check whether the window is miniaturized according to the EWMH window state + * property. We map the EWMH _NET_WM_STATE_HIDDEN state to GNUstep's + * miniaturized state. + */ +- (BOOL) _ewmh_isMinimized: (Window)win +{ + Atom *data; + int count; + int i; + + data = (Atom *)PropGetCheckProperty(dpy, win, + generic.netstates.net_wm_state_atom, + XA_ATOM, 32, -1, &count); + + if (!data) + // if we don't have any information, default to "No" + return NO; + + for (i = 0; i < count; i++) + { + if (data[i] == generic.netstates.net_wm_state_hidden_atom) + { + XFree(data); + return YES; + } + } + + XFree(data); + return NO; +} + @end