set(XRENDER_FEATURE_PURPOSE "rendering")
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
+set(XRANDR_FEATURE_TYPE "RECOMMENDED")
+set(XRANDR_FEATURE_PURPOSE "tracking output configuration")
+set(XRANDR_FEATURE_DESCRIPTION "X11 randr extension")
+
set(XFIXES_FEATURE_TYPE "RECOMMENDED")
set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension")
set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol")
find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION})
+find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION})
find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION})
if(WITH_XINERAMA)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
endif()
+if(NOT APPLE AND WITH_XRANDR)
+ add_definitions(-DWITH_XRANDR)
+ include_directories(${XRANDR_INCLUDE_DIRS})
+ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES})
+endif()
+
if(WITH_XFIXES)
add_definitions(-DWITH_XFIXES)
include_directories(${XFIXES_INCLUDE_DIRS})
* X11 Monitor Handling
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2017 David Fort <contact@hardening-consulting.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <X11/extensions/Xinerama.h>
#endif
+#ifdef WITH_XRANDR
+#include <X11/extensions/Xrandr.h>
+#include <X11/extensions/randr.h>
+#endif
+
#include "xf_monitor.h"
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */
int xf_list_monitors(xfContext* xfc)
{
-#ifdef WITH_XINERAMA
Display* display;
int major, minor;
int i, nmonitors = 0;
- XineramaScreenInfo* screen = NULL;
- display = XOpenDisplay(NULL);
+ display = XOpenDisplay(NULL);
if (!display)
{
WLog_ERR(TAG, "failed to open X display");
return -1;
}
+#ifdef WITH_XRANDR
+ if (XRRQueryExtension(xfc->display, &major, &minor))
+ {
+ XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &nmonitors);
+
+ for (i = 0; i < nmonitors; i++)
+ {
+ printf(" %s [%d] %hdx%hd\t+%hd+%hd\n",
+ monitors[i].primary ? "*" : " ", i,
+ monitors[i].width, monitors[i].height,
+ monitors[i].x, monitors[i].y);
+ }
+ XRRFreeMonitors(monitors);
+ } else
+#endif
+
+#ifdef WITH_XINERAMA
if (XineramaQueryExtension(display, &major, &minor))
{
if (XineramaIsActive(display))
{
- screen = XineramaQueryScreens(display, &nmonitors);
+ XineramaScreenInfo* screen = XineramaQueryScreens(display, &nmonitors);
for (i = 0; i < nmonitors; i++)
{
XFree(screen);
}
- }
+ } else
- XCloseDisplay(display);
#else
- Screen* screen;
- Display* display;
- display = XOpenDisplay(NULL);
-
- if (!display)
{
- WLog_ERR(TAG, "failed to open X display");
- return -1;
+ Screen* screen = ScreenOfDisplay(display, DefaultScreen(display));
+ printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen), HeightOfScreen(screen));
}
+#endif
- screen = ScreenOfDisplay(display, DefaultScreen(display));
- printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen),
- HeightOfScreen(screen));
XCloseDisplay(display);
-#endif
return 0;
}
Window _dummy_w;
int current_monitor = 0;
Screen* screen;
-#ifdef WITH_XINERAMA
+#if defined WITH_XINERAMA || defined WITH_XRANDR
int major, minor;
- XineramaScreenInfo* screenInfo = NULL;
#endif
vscreen = &xfc->vscreen;
*pMaxWidth = settings->DesktopWidth;
&_dummy_i, &_dummy_i, (void*) &_dummy_i))
mouse_x = mouse_y = 0;
-#ifdef WITH_XINERAMA
-
- if (XineramaQueryExtension(xfc->display, &major, &minor))
+#ifdef WITH_XRANDR
+ if (XRRQueryExtension(xfc->display, &major, &minor))
{
- if (XineramaIsActive(xfc->display))
- {
- screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
+ XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &vscreen->nmonitors);
- if (vscreen->nmonitors > 16)
- vscreen->nmonitors = 0;
+ if (vscreen->nmonitors > 16)
+ vscreen->nmonitors = 0;
- if (vscreen->nmonitors)
+ if (vscreen->nmonitors)
+ {
+ for (i = 0; i < vscreen->nmonitors; i++)
{
- for (i = 0; i < vscreen->nmonitors; i++)
- {
- vscreen->monitors[i].area.left = screenInfo[i].x_org;
- vscreen->monitors[i].area.top = screenInfo[i].y_org;
- vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
- vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height -
- 1;
-
- /* Determine which monitor that the mouse cursor is on */
- if ((mouse_x >= vscreen->monitors[i].area.left) &&
- (mouse_x <= vscreen->monitors[i].area.right) &&
- (mouse_y >= vscreen->monitors[i].area.top) &&
- (mouse_y <= vscreen->monitors[i].area.bottom))
- current_monitor = i;
- }
+ vscreen->monitors[i].area.left = monitors[i].x;
+ vscreen->monitors[i].area.top = monitors[i].y;
+ vscreen->monitors[i].area.right = monitors[i].x + monitors[i].width - 1;
+ vscreen->monitors[i].area.bottom = monitors[i].y + monitors[i].height - 1;
+ vscreen->monitors[i].primary = monitors[i].primary > 0;
}
+ }
+ XRRFreeMonitors(monitors);
+ } else
+#endif
- XFree(screenInfo);
+#ifdef WITH_XINERAMA
+ if (XineramaQueryExtension(xfc->display, &major, &minor) && XineramaIsActive(xfc->display))
+ {
+ XineramaScreenInfo* screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
+
+ if (vscreen->nmonitors > 16)
+ vscreen->nmonitors = 0;
+
+ if (vscreen->nmonitors)
+ {
+ for (i = 0; i < vscreen->nmonitors; i++)
+ {
+ vscreen->monitors[i].area.left = screenInfo[i].x_org;
+ vscreen->monitors[i].area.top = screenInfo[i].y_org;
+ vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
+ vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
+
+ /* Determine which monitor that the mouse cursor is on */
+ if ((mouse_x >= vscreen->monitors[i].area.left) &&
+ (mouse_x <= vscreen->monitors[i].area.right) &&
+ (mouse_y >= vscreen->monitors[i].area.top) &&
+ (mouse_y <= vscreen->monitors[i].area.bottom))
+ current_monitor = i;
+ }
}
- }
+ XFree(screenInfo);
+ }
#endif
+
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;