Merge pull request #18 from gnustep/randr

Dynamic screen resolution change support
This commit is contained in:
Sergii Stoian 2020-01-29 14:55:09 +02:00 committed by GitHub
commit 88bc2a4efd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 192 additions and 15 deletions

View file

@ -1,3 +1,47 @@
2020-01-26 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (boundsForScreen:): use `screen` variable
to identify output in RandR screen resources. Use `boundsRect` local
variable as return vaalue storage. Cleanup.
* Source/x11/XGServerEvent.m (processEvent:),
* Source/x11/XGServer.m (_initXContext): catch and process RandR event
on default screen.
2020-01-24 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_OSFrameToXFrame:for:): use
-boundsForScreen: to get correct screen dimensions if RandR is supported.
(_OSFrameToXHints:for:): ditto.
(_XFrameToOSFrame:for:): ditto.
(movewindow::): ditto.
(windowbounds:): ditto.
(setMouseLocation:onScreen:): ditto.
* Source/x11/XGDragView.m: ditto.
* Source/x11/XGServerEvent.m (processEvent:): destroy NSScreen screens
list to be regenereated on next call. This change updates ivars of
NSScreen (_frame, _depth) by recreating NSScreen instances.
(mouseLocationOnScreen:window:): use -boundsForScreen: to get correct
screen dimensions if RandR is supported.
2020-01-23 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServer.h (GSDisplayServer): RandR event and error base
ivars were added.
* Source/x11/XGServer.m (_initXContext): get RandR event and error base.
* Source/x11/XGServerWindow.m (boundsForScreen:): if Xrandr support
enabled get screen dimensions using Xrandr objects.
* Source/x11/XGServerEvent.m (processEvent:): process Xrandr event and
send NSApplicationDidChangeScreenParametersNotification.
* Source/x11/XGServer.m (_initXContext): subscribe to the Xrandr event.
2020-01-22 Sergii Stoian <stoyan255@gmail.com>
* configure.ac: check for availability of Xrandr library.
* config.h.in: added default value for Xrandr usage.
* configure: regenerate.
2020-01-17 Sergii Stoian <stoyan255@gmail.com>
* Source/art/shfill.m:,

View file

@ -60,6 +60,8 @@ typedef enum {
Window grabWindow;
struct XGGeneric generic;
id inputServer;
int randrEventBase;
int randrErrorBase;
}
+ (Display*) currentXDisplay;

View file

@ -54,7 +54,7 @@
#define DRAGWINDEV [XGServer _windowWithTag: [_window windowNumber]]
#define XX(P) (P.x)
#define XY(P) (DisplayHeight(XDPY, DRAGWINDEV->screen) - P.y)
#define XY(P) ([GSCurrentServer() boundsForScreen: DRAGWINDEV->screen].size.height - P.y)
@interface XGRawWindow : NSWindow
@end

View file

@ -69,6 +69,10 @@ terminate(int sig)
#include "x11/XGOpenGL.h"
#endif
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@ -465,6 +469,11 @@ _parse_display_name(NSString *name, int *dn, int *sn)
[self _setupRootWindow];
inputServer = [[XIMInputServer allocWithZone: [self zone]]
initWithDelegate: nil display: dpy name: @"XIM"];
#ifdef HAVE_XRANDR
XRRQueryExtension(dpy, &randrEventBase, &randrErrorBase);
XRRSelectInput(dpy, RootWindow(dpy, defScreen), RRScreenChangeNotifyMask);
#endif
return self;
}

View file

@ -32,6 +32,7 @@
#include <AppKit/NSMenu.h>
#include <AppKit/NSPasteboard.h>
#include <AppKit/NSWindow.h>
#include <AppKit/NSScreen.h>
#include <Foundation/NSException.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDictionary.h>
@ -55,6 +56,9 @@
#else
#include "x11/wraster.h"
#endif
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#include "math.h"
#include <X11/keysym.h>
@ -1894,6 +1898,25 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
((XShmCompletionEvent *)&xEvent)->drawable];
break;
}
#endif
#ifdef HAVE_XRANDR
int randr_event_type = randrEventBase + RRScreenChangeNotify;
if (xEvent.type == randr_event_type
&& (xEvent.xconfigure.window == RootWindow(dpy, defScreen)))
{
// Check if other RandR events are waiting in the queue.
XSync(dpy, 0);
while (XCheckTypedEvent(dpy, randr_event_type, &xEvent)) {;}
XRRUpdateConfiguration(event);
// Regenerate NSScreens
[NSScreen resetScreens];
// Notify application about screen parameters change
[[NSNotificationCenter defaultCenter]
postNotificationName: NSApplicationDidChangeScreenParametersNotification
object: NSApp];
}
break;
#endif
NSLog(@"Received an untrapped event\n");
break;
@ -2669,7 +2692,7 @@ process_modifier_flags(unsigned int state)
height = attribs.height;
}
else
height = DisplayHeight(dpy, screen_number);
height = [self boundsForScreen: screen_number].size.height;
p = NSMakePoint(currentX, height - currentY);
if (win)
{

View file

@ -66,6 +66,9 @@
#if HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#include "x11/XGDragView.h"
#include "x11/XGInputServer.h"
@ -506,7 +509,7 @@ BOOL AtomPresentAndPointsToItself(Display *dpy, Atom atom, Atom type)
x.size.height = o.size.height - t - b;
x.origin.x = o.origin.x + l;
x.origin.y = o.origin.y + o.size.height - t;
x.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
x.origin.y = [self boundsForScreen: win->screen].size.height - x.origin.y;
NSDebugLLog(@"Frame", @"O2X %lu, %x, %@, %@", win->number, style,
NSStringFromRect(o), NSStringFromRect(x));
return x;
@ -531,7 +534,7 @@ BOOL AtomPresentAndPointsToItself(Display *dpy, Atom atom, Atom type)
x.size.height = o.size.height - t - b;
x.origin.x = o.origin.x;
x.origin.y = o.origin.y + o.size.height;
x.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
x.origin.y = [self boundsForScreen: win->screen].size.height - x.origin.y;
NSDebugLLog(@"Frame", @"O2H %lu, %x, %@, %@", win->number, style,
NSStringFromRect(o), NSStringFromRect(x));
return x;
@ -573,7 +576,7 @@ BOOL AtomPresentAndPointsToItself(Display *dpy, Atom atom, Atom type)
[self styleoffsets: &l : &r : &t : &b : style : win->ident];
o = x;
o.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
o.origin.y = [self boundsForScreen: win->screen].size.height - x.origin.y;
o.origin.y = o.origin.y - x.size.height - b;
o.origin.x -= l;
o.size.width += l + r;
@ -3162,7 +3165,7 @@ swapColors(unsigned char *image_data, int width, int height,
}
window->siz_hints.x = (int)loc.x;
window->siz_hints.y = (int)(DisplayHeight(dpy, window->screen) -
window->siz_hints.y = (int)([self boundsForScreen: window->screen].size.height -
loc.y - window->siz_hints.height);
XMoveWindow (dpy, window->ident, window->siz_hints.x, window->siz_hints.y);
setNormalHints(dpy, window);
@ -3296,7 +3299,7 @@ swapColors(unsigned char *image_data, int width, int height,
&x, &y, &width, &height, &window->border, &window->depth);
window->xframe = NSMakeRect(x, y, width, height);
screenHeight = DisplayHeight(dpy, window->screen);
screenHeight = [self boundsForScreen: window->screen].size.height;
rect = window->xframe;
rect.origin.y = screenHeight - NSMaxY(window->xframe);
return rect;
@ -3803,7 +3806,7 @@ swapColors(unsigned char *image_data, int width, int height,
int height;
int destX, destY;
height = DisplayHeight(dpy, aScreen);
height = [self boundsForScreen: aScreen].size.height;
destY = height - mouseLocation.y;
destX = mouseLocation.x;
@ -4509,13 +4512,33 @@ _computeDepth(int class, int bpp)
- (NSRect) boundsForScreen: (int)screen
{
if (screen < 0 || screen >= ScreenCount(dpy))
{
NSLog(@"Invalidparam: no screen %d", screen);
return NSZeroRect;
}
return NSMakeRect(0, 0, DisplayWidth(dpy, screen),
DisplayHeight(dpy, screen));
NSRect boundsRect = NSZeroRect;
if (screen < 0 || screen >= ScreenCount(dpy))
{
NSLog(@"Invalidparam: no screen %d", screen);
return NSZeroRect;
}
#ifdef HAVE_XRANDR
XRRScreenResources *screen_res;
XRROutputInfo *output_info;
screen_res = XRRGetScreenResources(dpy, RootWindow(dpy, screen));
output_info = XRRGetOutputInfo(dpy, screen_res, screen_res->outputs[screen]);
if (output_info->crtc)
{
XRRCrtcInfo *crtc_info;
crtc_info = XRRGetCrtcInfo(dpy, screen_res, output_info->crtc);
boundsRect = NSMakeRect(crtc_info->x, crtc_info->y,
crtc_info->width, crtc_info->height);
}
XRRFreeScreenResources(screen_res);
#else
boundsRect = NSMakeRect(0, 0, DisplayWidth(dpy, screen),
DisplayHeight(dpy, screen));
#endif
return boundsRect;
}
- (NSImage *) iconTileImage

View file

@ -123,6 +123,9 @@
/* Define to 1 if you have the `Xutf8LookupString' function. */
#undef HAVE_XUTF8LOOKUPSTRING
/* Define to enable Xrandr support */
#undef HAVE_XRANDR
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

62
configure vendored
View file

@ -5131,6 +5131,68 @@ fi
done
have_xrandr=no
for ac_header in X11/extensions/Xrandr.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "X11/extensions/Xrandr.h" "ac_cv_header_X11_extensions_Xrandr_h" "$ac_includes_default"
if test "x$ac_cv_header_X11_extensions_Xrandr_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_X11_EXTENSIONS_XRANDR_H 1
_ACEOF
have_xrandr=yes
fi
done
if test $have_xrandr = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRUpdateConfiguration in -lXrandr" >&5
$as_echo_n "checking for XRRUpdateConfiguration in -lXrandr... " >&6; }
if ${ac_cv_lib_Xrandr_XRRUpdateConfiguration+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lXrandr $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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 XRRUpdateConfiguration ();
int
main ()
{
return XRRUpdateConfiguration ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_Xrandr_XRRUpdateConfiguration=yes
else
ac_cv_lib_Xrandr_XRRUpdateConfiguration=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrandr_XRRUpdateConfiguration" >&5
$as_echo "$ac_cv_lib_Xrandr_XRRUpdateConfiguration" >&6; }
if test "x$ac_cv_lib_Xrandr_XRRUpdateConfiguration" = xyes; then :
LIBS="-lXrandr $LIBS"
$as_echo "#define HAVE_XRANDR 1" >>confdefs.h
fi
fi
LIBS="$X_LIBS $LIBS"
fi

View file

@ -220,6 +220,17 @@ if test $set_x_paths = yes; then
#include <X11/Xutil.h>
])
have_xrandr=no
AC_CHECK_HEADERS(X11/extensions/Xrandr.h, have_xrandr=yes,,)
if test $have_xrandr = yes; then
AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
[
LIBS="-lXrandr $LIBS"
AC_DEFINE(HAVE_XRANDR, 1, [Define to enable Xrandr support])
]
,)
fi
LIBS="$X_LIBS $LIBS"
fi
AC_SUBST(X_PRE_LIBS)