int main (int argc, char **argv) { int event_number, error_number; int major, minor; int nscreens = 0; XineramaScreenInfo *xsi; int i; XtAppContext app; Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, &argc, argv, 0, 0, 0); Display *dpy = XtDisplay (toplevel_shell); XtGetApplicationNameAndClass (dpy, &progname, &progclass); if (!XineramaQueryExtension(dpy, &event_number, &error_number)) { fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> False\n", blurb()); fprintf(stderr, "%s: server does not support the Xinerama extension.\n", blurb()); exit(1); } else fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...) ==> %d, %d\n", blurb(), event_number, error_number); if (!XineramaIsActive(dpy)) { fprintf(stderr, "%s: XineramaIsActive(dpy) ==> False\n", blurb()); fprintf(stderr, "%s: server says Xinerama is turned off.\n", blurb()); exit(1); } else fprintf(stderr, "%s: XineramaIsActive(dpy) ==> True\n", blurb()); if (!XineramaQueryVersion(dpy, &major, &minor)) { fprintf(stderr, "%s: XineramaQueryVersion(dpy, ...) ==> False\n", blurb()); fprintf(stderr, "%s: server didn't report Xinerama version numbers?\n", blurb()); } else fprintf(stderr, "%s: XineramaQueryVersion(dpy, ...) ==> %d, %d\n", blurb(), major, minor); xsi = XineramaQueryScreens (dpy, &nscreens); fprintf(stderr, "%s: %d Xinerama screens\n", blurb(), nscreens); for (i = 0; i < nscreens; i++) fprintf (stderr, "%s: screen %d: %dx%d+%d+%d\n", blurb(), xsi[i].screen_number, xsi[i].width, xsi[i].height, xsi[i].x_org, xsi[i].y_org); XFree (xsi); XSync (dpy, False); exit (0); }
bool AugmentationEnvironment::getScreenSizes() { Display *d=XOpenDisplay(NULL); if (d) { int dummy1, dummy2; if (XineramaQueryExtension(d, &dummy1, &dummy2)) { if (XineramaIsActive(d)) { int heads=0; XineramaScreenInfo *p=XineramaQueryScreens(d, &heads); if (heads>0) { for (int x=0; x<heads; ++x) { cout << "Head " << x+1 << " of " << heads << ": " << p[x].width << "x" << p[x].height << " at " << p[x].x_org << "," << p[x].y_org << endl; screenRect.push_back(cv::Rect(p[x].x_org, p[x].y_org, p[x].width, p[x].height)); } return true; } else cout << "XineramaQueryScreens says there aren't any" << endl; XFree(p); } else cout << "Xinerama not active" << endl; } else cout << "No Xinerama extension" << endl; XCloseDisplay(d); } else cout << "Can't open display" << endl; return false; }
void init_xinerama(void) { int evbase, errbase, major, minor; rp_have_xinerama = 0; #ifdef XINERAMA if (xine_screens) XFree(xine_screens); if (!XineramaQueryExtension(dpy, &evbase, &errbase)) { return; } if (!XineramaQueryVersion(dpy, &major, &minor) != Success) { return; } if (major != 1) { fprintf (stderr, "Warning: Xinerama version %d.%d not supported\n", major, minor); return; } if (!XineramaIsActive(dpy)) { return; } xine_screens = XineramaQueryScreens(dpy, &xine_screen_count); if ((xine_screens == NULL) || (xine_screen_count < 2)) { return; } rp_have_xinerama = 1; #endif }
int xf_list_monitors(xfInfo* xfi) { #ifdef WITH_XINERAMAZ int i, nmonitors = 0; int ignored, ignored2; XineramaScreenInfo* screen = NULL; if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) { if (XineramaIsActive(xfi->display)) { screen = XineramaQueryScreens(xfi->display, &nmonitors); for (i = 0; i < nmonitors; i++) { DEBUG_MSG(" %s [%d] %dx%d\t+%d+%d\n", (i == 0) ? "*" : " ", i, screen[i].width, screen[i].height, screen[i].x_org, screen[i].y_org); } XFree(screen); } } #else Screen* screen; screen = ScreenOfDisplay(xfi->display, DefaultScreen(xfi->display)); DEBUG_MSG(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); #endif return 0; }
static void _al_xsys_xinerama_init(ALLEGRO_SYSTEM_XGLX *s) { int event_base = 0; int error_base = 0; /* init xinerama info to defaults */ s->xinerama_available = 0; s->xinerama_screen_count = 0; s->xinerama_screen_info = NULL; _al_mutex_lock(&s->lock); if (XineramaQueryExtension(s->x11display, &event_base, &error_base)) { int minor_version = 0, major_version = 0; int status = XineramaQueryVersion(s->x11display, &major_version, &minor_version); ALLEGRO_INFO("Xinerama version: %i.%i\n", major_version, minor_version); if (status && !XineramaIsActive(s->x11display)) { ALLEGRO_WARN("Xinerama is not active\n"); } else { ALLEGRO_INFO("Xinerama is active\n"); s->xinerama_available = 1; } } else { ALLEGRO_WARN("Xinerama extension is not available.\n"); } _al_mutex_unlock(&s->lock); }
int OS_X11::get_screen_count() const { // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return 0; int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); XFree(xsi); return count; }
int MythXDisplay::GetNumberXineramaScreens(void) { MythXLocker locker(this); int nr_xinerama_screens = 0; int event_base = 0, error_base = 0; if (XineramaQueryExtension(m_disp, &event_base, &error_base) && XineramaIsActive(m_disp)) { XFree(XineramaQueryScreens(m_disp, &nr_xinerama_screens)); } return nr_xinerama_screens; }
static XineramaScreenInfo *x11_query_screens(Display *dpy, int *num_screens) { int major, minor; if (!XineramaQueryExtension(dpy, &major, &minor)) return NULL; XineramaQueryVersion(dpy, &major, &minor); RARCH_LOG("[X11]: Xinerama version: %d.%d.\n", major, minor); if (!XineramaIsActive(dpy)) return NULL; return XineramaQueryScreens(dpy, num_screens); }
static int map_output_xinerama(Display *dpy, int deviceid, const char *output_name) { const char *prefix = "HEAD-"; XineramaScreenInfo *screens = NULL; int rc = EXIT_FAILURE; int event, error; int nscreens; int head; Matrix m; if (!XineramaQueryExtension(dpy, &event, &error)) { fprintf(stderr, "Unable to set screen mapping. Xinerama extension not found\n"); goto out; } if (strlen(output_name) < strlen(prefix) + 1 || strncmp(output_name, prefix, strlen(prefix)) != 0) { fprintf(stderr, "Please specify the output name as HEAD-X," "where X is the screen number\n"); goto out; } head = output_name[strlen(prefix)] - '0'; screens = XineramaQueryScreens(dpy, &nscreens); if (nscreens == 0) { fprintf(stderr, "Xinerama failed to query screens.\n"); goto out; } else if (nscreens <= head) { fprintf(stderr, "Found %d screens, but you requested %s.\n", nscreens, output_name); goto out; } matrix_set_unity(&m); set_transformation_matrix(dpy, &m, screens[head].x_org, screens[head].y_org, screens[head].width, screens[head].height); rc = apply_matrix(dpy, deviceid, &m); out: XFree(screens); return rc; }
Size2 OS_X11::get_screen_size(int p_screen) const { // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Size2i(0,0); int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) return Size2i(0,0); Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height); XFree(xsi); return size; }
void enumDisplayMonitors(DeviceInfo displays[], int& displayCounter) { ::Display* dpy = XOpenDisplay(NULL); if (dpy == NULL) { fatalError("Could not open display"); return; } int eventBase; int errorBase; if (XineramaQueryExtension(dpy, &eventBase, &errorBase)) { if (XineramaIsActive(dpy)) { int heads = 0; XineramaScreenInfo* queried = XineramaQueryScreens(dpy, &heads); for (int head = 0; head < heads; ++head) { ++displayCounter; XineramaScreenInfo& info = queried[head]; //log(Info, "Head %i: %ix%i @%i;%i", head + 1, info.width, info.height, info.x_org, info.y_org); DeviceInfo& di = displays[displayCounter]; di.isAvailable = true; di.x = info.x_org; di.y = info.y_org; di.width = info.width; di.height = info.height; // TODO (DK) // -is this always correct? if i switch screens on deb8/jessie with gnome it works ok // -what about other *nix or window managers? di.isPrimary = displayCounter == 0; // TODO (DK) // -this doesn't work yet, whatever is configured as primary is the first screen returned, // not what shows up in the config tool as [1], [2], ... // -and info.screen_number just seems to be useless (0 for first returned, 1 for next, ...) di.number = info.screen_number + 1; } XFree(queried); } else { log(Warning, "Xinerama is not active"); } } else { log(Warning, "Xinerama extension is not installed"); } }
int x11_shadow_xinerama_init(x11ShadowSubsystem* subsystem) { #ifdef WITH_XINERAMA int index; int numMonitors; int major, minor; int xinerama_event; int xinerama_error; MONITOR_DEF* monitor; XineramaScreenInfo* screen; XineramaScreenInfo* screens; if (!XineramaQueryExtension(subsystem->display, &xinerama_event, &xinerama_error)) return -1; if (!XDamageQueryVersion(subsystem->display, &major, &minor)) return -1; if (!XineramaIsActive(subsystem->display)) return -1; screens = XineramaQueryScreens(subsystem->display, &numMonitors); if (numMonitors > 16) numMonitors = 16; if (!screens || (numMonitors < 1)) return -1; subsystem->monitorCount = numMonitors; for (index = 0; index < numMonitors; index++) { screen = &screens[index]; monitor = &(subsystem->monitors[index]); monitor->left = screen->x_org; monitor->top = screen->y_org; monitor->right = monitor->left + screen->width; monitor->bottom = monitor->top + screen->height; monitor->flags = (index == 0) ? 1 : 0; } XFree(screens); #endif return 1; }
int xf_list_monitors(xfContext* xfc) { #ifdef WITH_XINERAMA Display* display; int i, nmonitors = 0; int ignored, ignored2; XineramaScreenInfo* screen = NULL; display = XOpenDisplay(NULL); if (XineramaQueryExtension(display, &ignored, &ignored2)) { if (XineramaIsActive(display)) { screen = XineramaQueryScreens(display, &nmonitors); for (i = 0; i < nmonitors; i++) { printf(" %s [%d] %dx%d\t+%d+%d\n", (i == 0) ? "*" : " ", i, screen[i].width, screen[i].height, screen[i].x_org, screen[i].y_org); } XFree(screen); } } XCloseDisplay(display); #else Screen* screen; Display* display; display = XOpenDisplay(NULL); screen = ScreenOfDisplay(display, DefaultScreen(display)); printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); XCloseDisplay(display); #endif return 0; }
Point2 OS_X11::get_screen_position(int p_screen) const { // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) { return Point2i(0,0); } int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) { return Point2i(0,0); } Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); XFree(xsi); return position; }
EAPI int ecore_x_xinerama_screen_count_get(void) { #ifdef ECORE_XINERAMA int event_base, error_base; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (_xin_info) XFree(_xin_info); _xin_info = NULL; if (XineramaQueryExtension(_ecore_x_disp, &event_base, &error_base)) { _xin_info = XineramaQueryScreens(_ecore_x_disp, &_xin_scr_num); if (_xin_info) return _xin_scr_num; } #endif /* ifdef ECORE_XINERAMA */ return 0; }
void screens_get(void) { #if defined(USE_XINERAMA) || defined(DEBUG) int i; #endif #ifdef USE_XINERAMA int event, error; XineramaScreenInfo *screeninfo; if(XineramaQueryExtension(dpy, &event, &error)) { screeninfo = XineramaQueryScreens(dpy, &nscreens); if(nscreens) { screens = _realloc((void *) screens, nscreens * sizeof(screen_dimensions)); for(i = 0; i < nscreens; i++) { screens[i].x = screeninfo[i].x_org; screens[i].y = screeninfo[i].y_org; screens[i].width = screeninfo[i].width; screens[i].height = screeninfo[i].height; } XFree((void *) screeninfo); goto ok; } } #endif nscreens = 1; screens = _realloc(screens, sizeof(screen_dimensions)); screens[0].x = 0; screens[0].y = 0; screens[0].width = XDisplayWidth(dpy, screen); screens[0].height = XDisplayHeight(dpy, screen); ok: screens_update_current(); ewmh_update_geometry(); ewmh_update_strut(); if(wlist_screen > nscreens) wlist_screen = nscreens - 1; #ifdef DEBUG printf(NAME ": screens_get(): loaded screen info\n"); for(i = 0; i < nscreens; i++) printf("\tscreen %i: %ix%i+%i+%i\n", i, screens[i].width, screens[i].height, screens[i].x, screens[i].y); #endif }
static int x11_shadow_xinerama_init(x11ShadowSubsystem* subsystem) { #ifdef WITH_XINERAMA int major, minor; int xinerama_event; int xinerama_error; x11_shadow_subsystem_base_init(subsystem); if (!XineramaQueryExtension(subsystem->display, &xinerama_event, &xinerama_error)) return -1; if (!XDamageQueryVersion(subsystem->display, &major, &minor)) return -1; if (!XineramaIsActive(subsystem->display)) return -1; return 1; #else return -1; #endif }
int x11_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors) { int index; Display* display; int displayWidth; int displayHeight; int numMonitors = 0; MONITOR_DEF* monitor; if (!getenv("DISPLAY")) setenv("DISPLAY", ":0", 1); display = XOpenDisplay(NULL); if (!display) { WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL)); return -1; } displayWidth = WidthOfScreen(DefaultScreenOfDisplay(display)); displayHeight = HeightOfScreen(DefaultScreenOfDisplay(display)); #ifdef WITH_XINERAMA { int major, minor; int xinerama_event; int xinerama_error; XineramaScreenInfo* screen; XineramaScreenInfo* screens; if (XineramaQueryExtension(display, &xinerama_event, &xinerama_error) && XDamageQueryVersion(display, &major, &minor) && XineramaIsActive(display)) { screens = XineramaQueryScreens(display, &numMonitors); if (numMonitors > maxMonitors) numMonitors = maxMonitors; if (screens && (numMonitors > 0)) { for (index = 0; index < numMonitors; index++) { screen = &screens[index]; monitor = &monitors[index]; monitor->left = screen->x_org; monitor->top = screen->y_org; monitor->right = monitor->left + screen->width; monitor->bottom = monitor->top + screen->height; monitor->flags = (index == 0) ? 1 : 0; } } XFree(screens); } } #endif XCloseDisplay(display); if (numMonitors < 1) { index = 0; numMonitors = 1; monitor = &monitors[index]; monitor->left = 0; monitor->top = 0; monitor->right = displayWidth; monitor->bottom = displayHeight; monitor->flags = 1; } return numMonitors; }
// Initialize X11 display and look for supported X11 extensions // static GLFWbool initExtensions(void) { // Find or create window manager atoms _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); #if defined(_GLFW_HAS_XF86VM) // Check for XF86VidMode extension _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); #endif /*_GLFW_HAS_XF86VM*/ // Check for RandR extension if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase)) { if (XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) _glfw.x11.randr.available = GLFW_TRUE; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); } } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is either a headless system or an older Nvidia binary driver // with broken gamma support // Flag it as useless and fall back to Xf86VidMode gamma, if // available _glfwInputError(GLFW_PLATFORM_ERROR, "X11: RandR gamma ramp support seems broken"); _glfw.x11.randr.gammaBroken = GLFW_TRUE; } XRRFreeScreenResources(sr); XRRSelectInput(_glfw.x11.display, _glfw.x11.root, RROutputChangeNotifyMask); } if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GLFW_TRUE; } #if defined(_GLFW_HAS_XINPUT) if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.major = 2; _glfw.x11.xi.minor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.major, &_glfw.x11.xi.minor) != BadRequest) { _glfw.x11.xi.available = GLFW_TRUE; } } #endif /*_GLFW_HAS_XINPUT*/ // Check if Xkb is supported on this display _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GLFW_TRUE; } } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // Find or create string format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Find or create selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // Find or create standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Find or create clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Find Xdnd (drag and drop) atoms, if available _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True); _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); return GLFW_TRUE; }
// Initialize X11 display and look for supported X11 extensions // static GLFWbool initExtensions(void) { _glfw.x11.vidmode.handle = dlopen("libXxf86vm.so.1", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize) dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); } _glfw.x11.xi.handle = dlopen("libXi.so", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents) dlsym(_glfw.x11.xi.handle, "XISelectEvents"); if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.major = 2; _glfw.x11.xi.minor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.major, &_glfw.x11.xi.minor) == Success) { _glfw.x11.xi.available = GLFW_TRUE; } } } // Check for RandR extension if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase)) { if (XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) _glfw.x11.randr.available = GLFW_TRUE; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); } } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is either a headless system or an older Nvidia binary driver // with broken gamma support // Flag it as useless and fall back to Xf86VidMode gamma, if // available _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Detected broken RandR gamma ramp support"); _glfw.x11.randr.gammaBroken = GLFW_TRUE; } if (!sr->ncrtc || !sr->noutput || !sr->nmode) { // This is either a headless system or broken Cygwin/X RandR // Flag it as useless and fall back to Xlib display functions _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Detected broken RandR monitor support"); _glfw.x11.randr.monitorBroken = GLFW_TRUE; } XRRFreeScreenResources(sr); XRRSelectInput(_glfw.x11.display, _glfw.x11.root, RROutputChangeNotifyMask); } if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GLFW_TRUE; } // Check if Xkb is supported on this display _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GLFW_TRUE; } } _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so.1", RTLD_LAZY | RTLD_GLOBAL); if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection) dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // String format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.COMPOUND_STRING = XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Custom selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // ICCCM standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Xdnd (drag and drop) atoms _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False); // ICCCM, EWMH and Motif window property atoms // These can be set safely even without WM support // The EWMH atoms that require WM support are handled in detectEWMH _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.NET_WM_ICON = XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False); _glfw.x11.NET_WM_PING = XInternAtom(_glfw.x11.display, "_NET_WM_PING", False); _glfw.x11.NET_WM_PID = XInternAtom(_glfw.x11.display, "_NET_WM_PID", False); _glfw.x11.NET_WM_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False); _glfw.x11.NET_WM_ICON_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False); _glfw.x11.NET_WM_BYPASS_COMPOSITOR = XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); return GLFW_TRUE; }
tbool xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) { int i; VIRTUAL_SCREEN* vscreen; #ifdef WITH_XINERAMA int ignored, ignored2; XineramaScreenInfo* screen_info = NULL; #endif vscreen = &xfi->vscreen; if (xf_GetWorkArea(xfi) != true) { xfi->workArea.x = 0; xfi->workArea.y = 0; xfi->workArea.width = WidthOfScreen(xfi->screen); xfi->workArea.height = HeightOfScreen(xfi->screen); } if (settings->fullscreen) { settings->width = WidthOfScreen(xfi->screen); settings->height = HeightOfScreen(xfi->screen); } else if (settings->workarea) { settings->width = xfi->workArea.width; settings->height = xfi->workArea.height; } else if (settings->percent_screen) { settings->width = (xfi->workArea.width * settings->percent_screen) / 100; settings->height = (xfi->workArea.height * settings->percent_screen) / 100; } if (settings->fullscreen != true && settings->workarea != true) return true; #ifdef WITH_XINERAMA if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) { if (XineramaIsActive(xfi->display)) { screen_info = XineramaQueryScreens(xfi->display, &vscreen->nmonitors); if (vscreen->nmonitors > 16) vscreen->nmonitors = 0; vscreen->monitors = xzalloc(sizeof(MONITOR_INFO) * vscreen->nmonitors); if (vscreen->nmonitors) { for (i = 0; i < vscreen->nmonitors; i++) { vscreen->monitors[i].area.left = screen_info[i].x_org; vscreen->monitors[i].area.top = screen_info[i].y_org; vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1; vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1; if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0)) vscreen->monitors[i].primary = true; } } XFree(screen_info); } } #endif settings->num_monitors = vscreen->nmonitors; for (i = 0; i < vscreen->nmonitors; i++) { settings->monitors[i].x = vscreen->monitors[i].area.left; settings->monitors[i].y = vscreen->monitors[i].area.top; settings->monitors[i].width = vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1; settings->monitors[i].height = vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1; settings->monitors[i].is_primary = vscreen->monitors[i].primary; vscreen->area.left = MIN(vscreen->monitors[i].area.left, vscreen->area.left); vscreen->area.right = MAX(vscreen->monitors[i].area.right, vscreen->area.right); vscreen->area.top = MIN(vscreen->monitors[i].area.top, vscreen->area.top); vscreen->area.bottom = MAX(vscreen->monitors[i].area.bottom, vscreen->area.bottom); } if (settings->num_monitors) { settings->width = vscreen->area.right - vscreen->area.left + 1; settings->height = vscreen->area.bottom - vscreen->area.top + 1; } return true; }
int main(int argc, char *argv[]) { XGCValues xgcv; memset( &xgcv, 0, sizeof( xgcv ) ); xgcv.graphics_exposures = False; system( "killall -o 1s boxer" ); if( argc != 5 ) { fprintf( stderr, "Error: expects four parameters ./boxer [x] [y] [w] [h]\n" ); return -1; } x = atoi( argv[1] ); y = atoi( argv[2] ); w = atoi( argv[3] ); h = atoi( argv[4] ); int event_basep, error_basep, a, b; int xinerama_screen; XineramaScreenInfo *screeninfo = NULL; if (setlocale(LC_ALL, "") == NULL || !XSupportsLocale()) fprintf(stderr, "Locale not available, expect problems with fonts.\n"); char * dpy = getenv("DISPLAY"); Display * display = XOpenDisplay(dpy); if (!display) { fprintf( stderr, "Error: Cannot open display.\n" ); return -1; } int screen = XDefaultScreen(display); if (!XShapeQueryExtension(display, &event_basep, &error_basep)) { fprintf( stderr, "X-Server does not support shape extension" ); return -1; } Visual * visual = DefaultVisual(display, screen); depth = DefaultDepth(display, screen); if (XineramaQueryExtension(display, &a, &b ) && (screeninfo = XineramaQueryScreens(display, &screens)) && XineramaIsActive(display) && xinerama_screen >= 0 && xinerama_screen < screens ) { width = screeninfo[xinerama_screen].width; height = screeninfo[xinerama_screen].height; xpos = screeninfo[xinerama_screen].x_org; } else { width = XDisplayWidth(display, screen); height = XDisplayHeight(display, screen); xpos = 0; } if (screeninfo) XFree(screeninfo); XSetWindowAttributes setwinattr; setwinattr.override_redirect = 1; window = XCreateWindow(display, XRootWindow(display, screen), 0, 0, width, height, 0, depth, CopyFromParent, visual, CWOverrideRedirect, &setwinattr); XSelectInput(display, window, ExposureMask); //printf( "Window: %p (%d x %d @ %d)\n", window, width, height, depth ); XStoreName(display, window, "xzbar"); int mask_bitmap = XCreatePixmap(display, window, width, height, 1); int line_bitmap = XCreatePixmap(display, window, width, height, depth); gc = XCreateGC(display, window, GCGraphicsExposures, &xgcv); mask_gc = XCreateGC( display, mask_bitmap, GCGraphicsExposures, &xgcv); mask_gc_back = XCreateGC( display, mask_bitmap, GCGraphicsExposures, &xgcv); XSetBackground(display, gc, WhitePixel(display, screen)); XSetForeground(display, mask_gc_back, BlackPixel(display, screen)); XSetBackground(display, mask_gc_back, WhitePixel(display, screen)); XSetForeground(display, mask_gc, WhitePixel(display, screen)); XSetBackground(display, mask_gc, BlackPixel(display, screen)); stay_on_top( display, window ); XMapRaised(display, window); char **missing; int nmissing; char *defstr; _XOC * fontset = XCreateFontSet( display, default_font, &missing, &nmissing, &defstr); while(1) { XEvent e; int i; XSetForeground(display, gc, 0); XFillRectangle(display, mask_bitmap, mask_gc_back, 0, 0, width, height); XSetForeground(display, gc, 0xFF00FF); /* for (i = 0; i < 100; i++ ) { XRectangle t; t.x = rand()%1000; t.y = 100; t.width = 5; t.height = 20; XFillRectangles(display, mask_bitmap, mask_gc, &t, 1); XFillRectangles(display, line_bitmap, gc, &t, 1); } */ /* XRectangle t; t.x = x; t.y = y; t.width = w; t.height = h; */ int addx = x + w; int addy = y + h; int ox = x; int oy = y; if( ox > 0 ) XDrawLine( display, mask_bitmap, mask_gc, ox, addy, ox, oy ); else ox = 0; if( oy > 0 ) XDrawLine( display, mask_bitmap, mask_gc, ox, oy, addx, oy ); else oy = 0; XDrawLine( display, mask_bitmap, mask_gc, addx, oy, addx, addy ); XDrawLine( display, mask_bitmap, mask_gc, addx, addy, ox, addy ); if( ox > 0 ) XDrawLine( display, line_bitmap, gc, ox, addy, ox, oy ); else ox = 0; if( oy > 0 ) XDrawLine( display, line_bitmap, gc, ox, oy, addx, oy ); else oy = 0; XDrawLine( display, line_bitmap, gc, addx, oy, addx, addy ); XDrawLine( display, line_bitmap, gc, addx, addy, ox, addx ); // XDrawRectangles(display, mask_bitmap, mask_gc, &t, 1); // XDrawRectangles(display, line_bitmap, gc, &t, 1); //Combine the mask again. XShapeCombineMask(display, window, ShapeBounding, 0, 0, mask_bitmap, ShapeSet); // XNextEvent(display, &e); // if (e.type == Expose) { //printf( "Expose\n" ); XCopyArea(display, line_bitmap, window, gc, 0, 0, width, height, 0, 0); // } XFlush(display); usleep(100000); } }
void CNFGSetupFullscreen( const char * WindowName, int screen_no ) { #ifdef HAS_XINERAMA XineramaScreenInfo *screeninfo = NULL; int screens; int event_basep, error_basep, a, b; CNFGDisplay = XOpenDisplay(NULL); int screen = XDefaultScreen(CNFGDisplay); int xpos, ypos; if (!XShapeQueryExtension(CNFGDisplay, &event_basep, &error_basep)) { fprintf( stderr, "X-Server does not support shape extension" ); exit( 1 ); } CNFGVisual = DefaultVisual(CNFGDisplay, screen); CNFGWinAtt.depth = DefaultDepth(CNFGDisplay, screen); if (XineramaQueryExtension(CNFGDisplay, &a, &b ) && (screeninfo = XineramaQueryScreens(CNFGDisplay, &screens)) && XineramaIsActive(CNFGDisplay) && screen_no >= 0 && screen_no < screens ) { CNFGWinAtt.width = screeninfo[screen_no].width; CNFGWinAtt.height = screeninfo[screen_no].height; xpos = screeninfo[screen_no].x_org; ypos = screeninfo[screen_no].y_org; } else { CNFGWinAtt.width = XDisplayWidth(CNFGDisplay, screen); CNFGWinAtt.height = XDisplayHeight(CNFGDisplay, screen); xpos = 0; ypos = 0; } if (screeninfo) XFree(screeninfo); XSetWindowAttributes setwinattr; setwinattr.override_redirect = 1; setwinattr.save_under = 1; setwinattr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonPressMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask |KeyPressMask |KeyReleaseMask | SubstructureNotifyMask | FocusChangeMask; setwinattr.border_pixel = 0; CNFGWindow = XCreateWindow(CNFGDisplay, XRootWindow(CNFGDisplay, screen), xpos, ypos, CNFGWinAtt.width, CNFGWinAtt.height, 0, CNFGWinAtt.depth, InputOutput, CNFGVisual, CWBorderPixel | CWEventMask | CWOverrideRedirect | CWSaveUnder, &setwinattr); XMapWindow(CNFGDisplay, CNFGWindow); XSetInputFocus( CNFGDisplay, CNFGWindow, RevertToParent, CurrentTime ); XFlush(CNFGDisplay); FullScreen = 1; //printf( "%d %d %d %d\n", xpos, ypos, CNFGWinAtt.width, CNFGWinAtt.height ); InternalLinkScreenAndGo( WindowName ); /* setwinattr.override_redirect = 1; XChangeWindowAttributes( CNFGDisplay, CNFGWindow, CWBorderPixel | CWEventMask | CWOverrideRedirect, &setwinattr); */ #else CNFGSetup( WindowName, 640, 480 ); #endif }
int main(int argc, char** argv) { int width, height; int i; int fd; const char* display_name; display_name = getenv("DISPLAY"); display = XOpenDisplay(display_name); // This program may be installed as setuid root, so we don't want the // environment to affect the behavior of this program in unexpected, // potentially insecure, ways. environ = 0; // Move out of the way so that this process never holds up umount. if (-1 == chdir("/")) err(EXIT_FAILURE, "Failed to switch directory to the root directory"); // SysRq+F and runaway processes can activate the OOM killer, which may very // well kill this process. This is, of course, very bad for a screen locking // program, so we try to tell the OOM killer to kill us last. if (-1 != (fd = open("/proc/self/oom_adj", O_WRONLY))) { write(fd, "-17", 3); close(fd); } user_name = get_user_name(); host_name = get_host_name(); get_password_hash(); // Drop super-user privileges if we have to. if (0 == geteuid()) { setgid(getuid()); setuid(getuid()); } if (!display) errx(EXIT_FAILURE, "Failed to open display %s", display_name); if (!glXQueryExtension(display, 0, 0)) errx(EXIT_FAILURE, "No GLX extension present"); int attributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, None }; visual = glXChooseVisual(display, DefaultScreen(display), attributes); if (!visual) errx(EXIT_FAILURE, "glXChooseVisual failed"); XWindowAttributes root_window_attr; XGetWindowAttributes(display, RootWindow(display, DefaultScreen(display)), &root_window_attr); GLXContext glx_context = glXCreateContext(display, visual, 0, GL_TRUE); if (!glx_context) errx(EXIT_FAILURE, "Failed creating OpenGL context"); Colormap color_map = XCreateColormap( display, RootWindow(display, visual->screen), visual->visual, AllocNone); Pixmap mask = XCreatePixmap(display, XRootWindow(display, 0), 1, 1, 1); XGCValues xgc; xgc.function = GXclear; GC gc = XCreateGC(display, mask, GCFunction, &xgc); XFillRectangle(display, mask, gc, 0, 0, 1, 1); XColor color; color.pixel = 0; color.red = 0; color.flags = 4; Cursor cursor = XCreatePixmapCursor(display, mask, mask, &color, &color, 0, 0); XFreePixmap(display, mask); XFreeGC(display, gc); XSetWindowAttributes attr; attr.colormap = color_map; attr.border_pixel = 0; attr.event_mask = KeyPressMask | VisibilityChangeMask | ExposureMask | StructureNotifyMask | FocusChangeMask; attr.cursor = cursor; attr.override_redirect = True; width = root_window_attr.width; height = root_window_attr.height; window = XCreateWindow( display, RootWindow(display, visual->screen), 0, 0, width, height, 0, visual->depth, InputOutput, visual->visual, CWOverrideRedirect | CWCursor | CWColormap | CWEventMask, &attr); XMapRaised(display, window); attempt_grab(); XSetInputFocus(display, window, RevertToParent, CurrentTime); XFlush(display); char* p; if ((p = XSetLocaleModifiers("")) && *p) xim = XOpenIM(display, 0, 0, 0); if (!xim && (p = XSetLocaleModifiers("@im=none")) && *p) xim = XOpenIM(display, 0, 0, 0); if (!xim) errx(EXIT_FAILURE, "Failed to open X Input Method"); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, window, XNFocusWindow, window, NULL); if (!xic) errx(EXIT_FAILURE, "Failed to create X Input Context"); XEvent event; XIfEvent(display, &event, wait_for_map_notify, (char*)window); if (!glXMakeCurrent(display, window, glx_context)) errx(EXIT_FAILURE, "glXMakeCurrent returned false"); if (XineramaQueryExtension(display, &i, &i) && XineramaIsActive(display)) screens = XineramaQueryScreens(display, &screen_count); if (!screen_count) { screen_count = 1; screens = malloc(sizeof(XineramaScreenInfo) * 1); screens[0].x_org = 0; screens[0].y_org = 0; screens[0].width = root_window_attr.width; screens[0].height = root_window_attr.height; } LOCK_init(); int done = 0; struct timeval start; gettimeofday(&start, 0); while (!done) { struct timeval now; double delta_time; gettimeofday(&now, 0); while (now.tv_sec < start.tv_sec) now.tv_sec += 24 * 60 * 60; while (XPending(display)) { XNextEvent(display, &event); switch (event.type) { case KeyPress: { char text[32]; Status status; KeySym key_sym; int len = Xutf8LookupString(xic, &event.xkey, text, sizeof(text) - 1, &key_sym, &status); text[len] = 0; LOCK_handle_key(key_sym, text); } break; case ConfigureNotify: width = event.xconfigure.width; height = event.xconfigure.height; glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); break; case FocusOut: // If keyboard grabs have been unsuccessful so far, a FocusOut event // may occur. If so, we change the focus right back. XSetInputFocus(display, window, RevertToParent, CurrentTime); break; case VisibilityNotify: if (event.xvisibility.state != VisibilityUnobscured) XRaiseWindow(display, window); break; } } delta_time = (now.tv_sec - start.tv_sec) + (now.tv_usec - start.tv_usec) * 1.0e-6; start = now; LOCK_process_frame(width, height, delta_time); glXSwapBuffers(display, window); attempt_grab(); } return EXIT_SUCCESS; }
// Look for and initialize supported X11 extensions // static GLFWbool initExtensions(void) { _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1"); if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension"); _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp"); _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp"); _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize) _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize"); _glfw.x11.vidmode.available = XF86VidModeQueryExtension(_glfw.x11.display, &_glfw.x11.vidmode.eventBase, &_glfw.x11.vidmode.errorBase); } #if defined(__CYGWIN__) _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so"); #else _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6"); #endif if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) _glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents) _glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents"); if (XQueryExtension(_glfw.x11.display, "XInputExtension", &_glfw.x11.xi.majorOpcode, &_glfw.x11.xi.eventBase, &_glfw.x11.xi.errorBase)) { _glfw.x11.xi.major = 2; _glfw.x11.xi.minor = 0; if (XIQueryVersion(_glfw.x11.display, &_glfw.x11.xi.major, &_glfw.x11.xi.minor) == Success) { _glfw.x11.xi.available = GLFW_TRUE; } } } #if defined(__CYGWIN__) _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so"); #else _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2"); #endif if (_glfw.x11.randr.handle) { _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources) _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources"); _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo"); _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent) _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension) _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension"); _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion) _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion"); _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput"); _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma) _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration) _glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, &_glfw.x11.randr.errorBase)) { if (XRRQueryVersion(_glfw.x11.display, &_glfw.x11.randr.major, &_glfw.x11.randr.minor)) { // The GLFW RandR path requires at least version 1.3 if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) _glfw.x11.randr.available = GLFW_TRUE; } else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); } } } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { // This is likely an older Nvidia driver with broken gamma support // Flag it as useless and fall back to xf86vm gamma, if available _glfw.x11.randr.gammaBroken = GLFW_TRUE; } if (!sr->ncrtc) { // A system without CRTCs is likely a system with broken RandR // Disable the RandR monitor path and fall back to core functions _glfw.x11.randr.monitorBroken = GLFW_TRUE; } XRRFreeScreenResources(sr); } if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRSelectInput(_glfw.x11.display, _glfw.x11.root, RROutputChangeNotifyMask); } #if defined(__CYGWIN__) _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so"); #else _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1"); #endif if (_glfw.x11.xcursor.handle) { _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate"); _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy"); _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor"); } #if defined(__CYGWIN__) _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so"); #else _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1"); #endif if (_glfw.x11.xinerama.handle) { _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive"); _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension"); _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens) _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens"); if (XineramaQueryExtension(_glfw.x11.display, &_glfw.x11.xinerama.major, &_glfw.x11.xinerama.minor)) { if (XineramaIsActive(_glfw.x11.display)) _glfw.x11.xinerama.available = GLFW_TRUE; } } _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = XkbQueryExtension(_glfw.x11.display, &_glfw.x11.xkb.majorOpcode, &_glfw.x11.xkb.eventBase, &_glfw.x11.xkb.errorBase, &_glfw.x11.xkb.major, &_glfw.x11.xkb.minor); if (_glfw.x11.xkb.available) { Bool supported; if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported)) { if (supported) _glfw.x11.xkb.detectable = GLFW_TRUE; } } #if defined(__CYGWIN__) _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so"); #else _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1"); #endif if (_glfw.x11.x11xcb.handle) { _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection) _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); } #if defined(__CYGWIN__) _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so"); #else _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1"); #endif if (_glfw.x11.xrender.handle) { _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension"); _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion"); _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat) _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat"); if (XRenderQueryExtension(_glfw.x11.display, &_glfw.x11.xrender.errorBase, &_glfw.x11.xrender.eventBase)) { if (XRenderQueryVersion(_glfw.x11.display, &_glfw.x11.xrender.major, &_glfw.x11.xrender.minor)) { _glfw.x11.xrender.available = GLFW_TRUE; } } } // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); // String format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False); _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False); _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False); // Custom selection property atom _glfw.x11.GLFW_SELECTION = XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False); // ICCCM standard clipboard atoms _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False); _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False); _glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False); _glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False); _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False); // Clipboard manager atoms _glfw.x11.CLIPBOARD_MANAGER = XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False); _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Xdnd (drag and drop) atoms _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False); _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False); _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False); _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False); _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False); _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False); _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False); // ICCCM, EWMH and Motif window property atoms // These can be set safely even without WM support // The EWMH atoms that require WM support are handled in detectEWMH _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False); _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False); _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False); _glfw.x11.NET_WM_ICON = XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False); _glfw.x11.NET_WM_PING = XInternAtom(_glfw.x11.display, "_NET_WM_PING", False); _glfw.x11.NET_WM_PID = XInternAtom(_glfw.x11.display, "_NET_WM_PID", False); _glfw.x11.NET_WM_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False); _glfw.x11.NET_WM_ICON_NAME = XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False); _glfw.x11.NET_WM_BYPASS_COMPOSITOR = XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False); _glfw.x11.NET_WM_WINDOW_OPACITY = XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False); _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); // The compositing manager selection name contains the screen number { char name[32]; snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen); _glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False); } return GLFW_TRUE; }
void FScreenInit(Display *dpy) { static Bool is_initialised = False; int dummy_rc; SUPPRESS_UNUSED_VAR_WARNING(dummy_rc); if (is_initialised) { return; } is_initialised = True; disp = dpy; if (FScreenXineramaEmulation) { int count; int w; int h; int ws; unsigned long scr; Window root; XSetWindowAttributes attributes; scr = DefaultScreen(disp); root = RootWindow(disp, scr); /* xinerama emulation simulates xinerama on a single screen: * * actual screen * +---------------------+--------------+ * | | | * | | | * | | | * | | simulated | * | | screen 2 | * | simulated screen 1 | | * | | | * | | | * | | | * | | | * +---------------------+ | * | blank area | | * | | | * +---------------------+--------------+ */ count = 2; total_screens_xi = count; screens_xi = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (1 + count)); /* calculate the faked sub screen dimensions */ w = DisplayWidth(disp, scr); ws = 3 * w / 5; h = DisplayHeight(disp, scr); screens_xi[1].screen_number = 0; screens_xi[1].x_org = 0; screens_xi[1].y_org = h / 16; screens_xi[1].width = ws; screens_xi[1].height = 7 * h / 8; screens_xi[2].screen_number = 1; screens_xi[2].x_org = ws; screens_xi[2].y_org = 0; screens_xi[2].width = w - ws; screens_xi[2].height = 7 * h / 8; /* add delimiter */ attributes.background_pixel = PictureWhitePixel(); attributes.override_redirect = True; blank_w = XCreateWindow( disp, root, 0, screens_xi[1].y_org - 1, screens_xi[1].width, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); blank2_w = XCreateWindow( disp, root, 0, screens_xi[1].y_org + screens_xi[1].height - 1, screens_xi[1].width, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); blank3_w = XCreateWindow( disp, root, screens_xi[2].x_org, screens_xi[2].height - 1, w - screens_xi[2].x_org, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); vert_w = XCreateWindow( disp, root, screens_xi[2].x_org - 1, 0, 2, h, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); } else if (FScreenHaveXinerama && XineramaQueryExtension(disp, &dummy_rc, &dummy_rc) && XineramaIsActive(disp)) { int count; XineramaScreenInfo *info; info = FXineramaQueryScreens(disp, &count); total_screens_xi = count; screens_xi = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (1 + count)); memcpy(screens_xi + 1, info, sizeof(XineramaScreenInfo) * count); XFree(info); } else { total_screens_xi = 0; screens_xi = (XineramaScreenInfo *)safemalloc( sizeof(XineramaScreenInfo)*1); } total_screens = total_screens_xi; screens = screens_xi; /* Now, fill screens[0] with global screen parameters */ screens_xi[0].screen_number = -1; screens_xi[0].x_org = 0; screens_xi[0].y_org = 0; screens_xi[0].width = DisplayWidth (disp, DefaultScreen(disp)); screens_xi[0].height = DisplayHeight(disp, DefaultScreen(disp)); /* Fill in the screen range */ FScreenSetState(is_xinerama_enabled); return; }
MainWin * mainwin_create(Display *dpy, dlist *config) { const char *tmp; XColor screen_color, exact_color; XSetWindowAttributes wattr; XWindowAttributes rootattr; unsigned long valuemask = CWEventMask; #ifdef XINERAMA int event_base, error_base; #endif /* XINERAMA */ MainWin *mw = (MainWin *)malloc(sizeof(MainWin)); mw->screen = DefaultScreen(dpy); mw->visual = imlib_get_best_visual(dpy, mw->screen, &mw->depth); mw->colormap = DefaultColormap(dpy, mw->screen); mw->root = RootWindow(dpy, mw->screen); mw->background = 0; mw->bg_pixmap = None; #ifdef XINERAMA mw->xin_info = mw->xin_active = 0; mw->xin_screens = 0; #endif /* XINERAMA */ mw->x = mw->y = 0; mw->no_free_color = 0; mw->pressed = mw->focus = 0; mw->tooltip = 0; mw->cod = 0; mw->cm_normal = mw->cm_highlight = 0; mw->key_up = XKeysymToKeycode(dpy, XK_Up); mw->key_down = XKeysymToKeycode(dpy, XK_Down); mw->key_left = XKeysymToKeycode(dpy, XK_Left); mw->key_right = XKeysymToKeycode(dpy, XK_Right); mw->key_enter = XKeysymToKeycode(dpy, XK_Return); mw->key_space = XKeysymToKeycode(dpy, XK_space); mw->key_escape = XKeysymToKeycode(dpy, XK_Escape); mw->key_q = XKeysymToKeycode(dpy, XK_q); XGetWindowAttributes(dpy, mw->root, &rootattr); mw->width = rootattr.width; mw->height = rootattr.height; mw->dpy = dpy; valuemask |= CWBackPixel; wattr.background_pixel = BlackPixel(dpy, mw->screen); wattr.event_mask = VisibilityChangeMask | ButtonReleaseMask; mw->window = XCreateWindow(dpy, mw->root, 0, 0, mw->width, mw->height, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &wattr); if(mw->window == None) { free(mw); return 0; } #ifdef XINERAMA # ifdef DEBUG fprintf(stderr, "--> checking for Xinerama extension... "); # endif /* DEBUG */ if(XineramaQueryExtension(dpy, &event_base, &error_base)) { # ifdef DEBUG fprintf(stderr, "yes\n--> checking if Xinerama is enabled... "); # endif /* DEBUG */ if(XineramaIsActive(dpy)) { # ifdef DEBUG fprintf(stderr, "yes\n--> fetching Xinerama info... "); # endif /* DEBUG */ mw->xin_info = XineramaQueryScreens(mw->dpy, &mw->xin_screens); # ifdef DEBUG fprintf(stderr, "done (%i screens)\n", mw->xin_screens); # endif /* DEBUG */ } # ifdef DEBUG else fprintf(stderr, "no\n"); # endif /* DEBUG */ } # ifdef DEBUG else fprintf(stderr, "no\n"); # endif /* DEBUG */ #endif /* XINERAMA */ tmp = config_get(config, "normal", "border", "black"); if(! XAllocNamedColor(mw->dpy, mw->colormap, tmp, &screen_color, &exact_color)) { fprintf(stderr, "WARNING: Invalid color '%s', reverting to black.\n", tmp); BORDER_COLOR(mw) = BlackPixel(mw->dpy, mw->screen); mw->no_free_color = 1; } else BORDER_COLOR(mw) = screen_color.pixel; tmp = config_get(config, "highlight", "border", "#d0d0ff"); if(! XAllocNamedColor(mw->dpy, mw->colormap, tmp, &screen_color, &exact_color)) { fprintf(stderr, "WARNING: Invalid color '%s', reverting to white.\n", tmp); HIGHLIGHT_COLOR(mw) = WhitePixel(mw->dpy, mw->screen); mw->no_free_color |= 2; } else HIGHLIGHT_COLOR(mw) = screen_color.pixel; tmp = config_get(config, "general", "distance", "50"); DISTANCE(mw) = MAX(1, strtol(tmp, 0, 10)); if(! strcasecmp(config_get(config, "tooltip", "show", "true"), "true")) mw->tooltip = tooltip_create(mw, config); mw->cm_normal = create_modifier(mw, config, "normal", "0.0", "white", "200"); mw->cm_highlight = create_modifier(mw, config, "highlight", "0.05", "#d0d0ff", "255"); return mw; }
BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings) { int i, j; int nmonitors; int primaryMonitor; int vWidth, vHeight; int maxWidth, maxHeight; VIRTUAL_SCREEN* vscreen; #ifdef WITH_XINERAMA int ignored, ignored2; XineramaScreenInfo* screen_info = NULL; #endif vscreen = &xfc->vscreen; #ifdef WITH_XINERAMA if (XineramaQueryExtension(xfc->display, &ignored, &ignored2)) { if (XineramaIsActive(xfc->display)) { screen_info = XineramaQueryScreens(xfc->display, &vscreen->nmonitors); if (vscreen->nmonitors > 16) vscreen->nmonitors = 0; vscreen->monitors = malloc(sizeof(MONITOR_INFO) * vscreen->nmonitors); ZeroMemory(vscreen->monitors, sizeof(MONITOR_INFO) * vscreen->nmonitors); if (vscreen->nmonitors) { for (i = 0; i < vscreen->nmonitors; i++) { vscreen->monitors[i].area.left = screen_info[i].x_org; vscreen->monitors[i].area.top = screen_info[i].y_org; vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1; vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1; if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0)) vscreen->monitors[i].primary = TRUE; } } XFree(screen_info); } } #endif if (!xf_GetWorkArea(xfc)) { xfc->workArea.x = 0; xfc->workArea.y = 0; xfc->workArea.width = WidthOfScreen(xfc->screen); xfc->workArea.height = HeightOfScreen(xfc->screen); } if (settings->Fullscreen) { settings->DesktopWidth = WidthOfScreen(xfc->screen); settings->DesktopHeight = HeightOfScreen(xfc->screen); maxWidth = settings->DesktopWidth; maxHeight = settings->DesktopHeight; } else if (settings->Workarea) { settings->DesktopWidth = xfc->workArea.width; settings->DesktopHeight = xfc->workArea.height; maxWidth = settings->DesktopWidth; maxHeight = settings->DesktopHeight; } else if (settings->PercentScreen) { settings->DesktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100; settings->DesktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100; maxWidth = settings->DesktopWidth; maxHeight = settings->DesktopHeight; } else { maxWidth = WidthOfScreen(xfc->screen); maxHeight = HeightOfScreen(xfc->screen); } if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon) return TRUE; if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) || (settings->Workarea && !settings->RemoteApplicationMode)) { /* Select a single monitor */ if (settings->NumMonitorIds != 1) { settings->NumMonitorIds = 1; settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds); settings->MonitorIds[0] = 0; for (i = 0; i < vscreen->nmonitors; i++) { if (vscreen->monitors[i].primary) { settings->MonitorIds[0] = i; break; } } } } nmonitors = 0; primaryMonitor = 0; for (i = 0; i < vscreen->nmonitors; i++) { if (settings->NumMonitorIds) { BOOL found = FALSE; for (j = 0; j < settings->NumMonitorIds; j++) { if (settings->MonitorIds[j] == i) found = TRUE; } if (!found) continue; } settings->MonitorDefArray[nmonitors].x = vscreen->monitors[i].area.left; settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top; settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, settings->DesktopWidth); settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, settings->DesktopHeight); settings->MonitorDefArray[nmonitors].is_primary = vscreen->monitors[i].primary; primaryMonitor |= vscreen->monitors[i].primary; nmonitors++; } settings->MonitorCount = nmonitors; vWidth = vHeight = 0; settings->DesktopPosX = maxWidth - 1; settings->DesktopPosY = maxHeight - 1; for (i = 0; i < settings->MonitorCount; i++) { settings->DesktopPosX = MIN(settings->DesktopPosX, settings->MonitorDefArray[i].x); settings->DesktopPosY = MIN(settings->DesktopPosY, settings->MonitorDefArray[i].y); vWidth += settings->MonitorDefArray[i].width; vHeight = MAX(vHeight, settings->MonitorDefArray[i].height); } vscreen->area.left = 0; vscreen->area.right = vWidth - 1; vscreen->area.top = 0; vscreen->area.bottom = vHeight - 1; if (settings->Workarea) { vscreen->area.top = xfc->workArea.y; vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1; } if (nmonitors && !primaryMonitor) settings->MonitorDefArray[0].is_primary = TRUE; if (settings->MonitorCount) { settings->DesktopWidth = vscreen->area.right - vscreen->area.left + 1; settings->DesktopHeight = vscreen->area.bottom - vscreen->area.top + 1; } return TRUE; }