void wInitXinerama(WScreen * scr) { scr->xine_info.primary_head = 0; scr->xine_info.screens = NULL; scr->xine_info.count = 0; #ifdef USE_XINERAMA # ifdef SOLARIS_XINERAMA if (XineramaGetState(dpy, scr->screen)) { WXineramaInfo *info = &scr->xine_info; XRectangle head[MAXFRAMEBUFFERS]; unsigned char hints[MAXFRAMEBUFFERS]; int i; if (XineramaGetInfo(dpy, scr->screen, head, hints, &info->count)) { info->screens = wmalloc(sizeof(WMRect) * (info->count + 1)); for (i = 0; i < info->count; i++) { info->screens[i].pos.x = head[i].x; info->screens[i].pos.y = head[i].y; info->screens[i].size.width = head[i].width; info->screens[i].size.height = head[i].height; } } } # else /* !SOLARIS_XINERAMA */ if (XineramaIsActive(dpy)) { XineramaScreenInfo *xine_screens; WXineramaInfo *info = &scr->xine_info; int i; xine_screens = XineramaQueryScreens(dpy, &info->count); info->screens = wmalloc(sizeof(WMRect) * (info->count + 1)); for (i = 0; i < info->count; i++) { info->screens[i].pos.x = xine_screens[i].x_org; info->screens[i].pos.y = xine_screens[i].y_org; info->screens[i].size.width = xine_screens[i].width; info->screens[i].size.height = xine_screens[i].height; } XFree(xine_screens); } # endif /* !SOLARIS_XINERAMA */ #endif /* USE_XINERAMA */ }
static XineramaScreenInfo * solaris_XineramaQueryScreens(Display *d, int *nscreens) { if (FScreenHaveSolarisXinerama) { XineramaScreenInfo *screens = NULL; XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; int result; /* dummy instructions to keep -Wall happy */ hints[0] = hints[0]; result = XineramaGetInfo( d, DefaultScreen(d), monitors, hints, nscreens); if (result) { int m; /* Note, malloced area later freed by XFree() */ screens = (XineramaScreenInfo *)malloc( sizeof(XineramaScreenInfo) * (*nscreens)); for (m = 0; m < *nscreens; ++m) { screens[m].screen_number = m; screens[m].x_org = monitors[m].x; screens[m].y_org = monitors[m].y; screens[m].width = monitors[m].width; screens[m].height = monitors[m].height; } } else { fprintf( stderr, "Error getting Xinerama information\n"); *nscreens = 0; } return screens; } else { return NULL; } }
static gboolean init_solaris_xinerama (GdkScreen *screen) { #ifdef HAVE_SOLARIS_XINERAMA Display *dpy = GDK_SCREEN_XDISPLAY (screen); int screen_no = gdk_screen_get_number (screen); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; gint result; int n_monitors; int i; if (!XineramaGetState (dpy, screen_no)) return FALSE; result = XineramaGetInfo (dpy, screen_no, monitors, hints, &n_monitors); /* Yes I know it should be Success but the current implementation * returns the num of monitor */ if (result == 0) { return FALSE; } x11_screen->monitors = g_new0 (GdkX11Monitor, n_monitors); x11_screen->n_monitors = n_monitors; for (i = 0; i < n_monitors; i++) { init_monitor_geometry (&x11_screen->monitors[i], monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); } x11_screen->primary_monitor = 0; return TRUE; #endif /* HAVE_SOLARIS_XINERAMA */ return FALSE; }
static void initXinerama(void) { xineInfo.screens = NULL; xineInfo.count = 0; #ifdef USE_XINERAMA # ifdef SOLARIS_XINERAMA if (XineramaGetState(dpy, scr)) { XRectangle head[MAXFRAMEBUFFERS]; unsigned char hints[MAXFRAMEBUFFERS]; int i; if (XineramaGetInfo(dpy, scr, head, hints, &xineInfo.count)) { xineInfo.screens = wmalloc(sizeof(WMRect) * (xineInfo.count + 1)); for (i = 0; i < xineInfo.count; i++) { xineInfo.screens[i].pos.x = head[i].x; xineInfo.screens[i].pos.y = head[i].y; xineInfo.screens[i].size.width = head[i].width; xineInfo.screens[i].size.height = head[i].height; } } } # else /* !SOLARIS_XINERAMA */ if (XineramaIsActive(dpy)) { XineramaScreenInfo *xine_screens; int i; xine_screens = XineramaQueryScreens(dpy, &xineInfo.count); xineInfo.screens = wmalloc(sizeof(WMRect) * (xineInfo.count + 1)); for (i = 0; i < xineInfo.count; i++) { xineInfo.screens[i].pos.x = xine_screens[i].x_org; xineInfo.screens[i].pos.y = xine_screens[i].y_org; xineInfo.screens[i].size.width = xine_screens[i].width; xineInfo.screens[i].size.height = xine_screens[i].height; } XFree(xine_screens); } # endif /* !SOLARIS_XINERAMA */ #endif /* USE_XINERAMA */ }
static gboolean init_solaris_xinerama_indices (GdkX11Screen *x11_screen) { #ifdef HAVE_SOLARIS_XINERAMA XRectangle x_monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; gint result; gint monitor_num; gint x_n_monitors; gint i; if (!XineramaGetState (x11_screen->xdisplay, x11_screen->screen_num)) return FALSE; result = XineramaGetInfo (x11_screen->xdisplay, x11_screen->screen_num, x_monitors, hints, &x_n_monitors); if (result == 0) return FALSE; for (monitor_num = 0; monitor_num < x11_screen->n_monitors; ++monitor_num) { for (i = 0; i < x_n_monitors; ++i) { if (x11_screen->monitors[monitor_num].geometry.x == x_monitors[i].x && x11_screen->monitors[monitor_num].geometry.y == x_monitors[i].y && x11_screen->monitors[monitor_num].geometry.width == x_monitors[i].width && x11_screen->monitors[monitor_num].geometry.height == x_monitors[i].height) { g_hash_table_insert (x11_screen->xinerama_matches, GINT_TO_POINTER (monitor_num), GINT_TO_POINTER (i)); } } } return TRUE; #endif /* HAVE_SOLARIS_XINERAMA */ return FALSE; }
static void reload_monitor_infos (CsScreen *screen) { GdkDisplay *gdk_display; Display *xdisplay; Window xroot; gdk_display = gdk_screen_get_display (screen->gdk_screen); xdisplay = gdk_x11_display_get_xdisplay (gdk_display); xroot = gdk_x11_window_get_xid (gdk_screen_get_root_window (screen->gdk_screen)); /* Any previous screen->monitor_infos is freed by the caller */ screen->monitor_infos = NULL; screen->n_monitor_infos = 0; /* Xinerama doesn't have a concept of primary monitor, however XRandR * does. However, the XRandR xinerama compat code always sorts the * primary output first, so we rely on that here. We could use the * native XRandR calls instead of xinerama, but that would be * slightly problematic for _NET_WM_FULLSCREEN_MONITORS support, as * that is defined in terms of xinerama monitor indexes. * So, since we don't need anything in xrandr except the primary * we can keep using xinerama and use the first monitor as the * primary. */ screen->primary_monitor_index = PRIMARY_MONITOR; #ifdef HAVE_XFREE_XINERAMA if (screen->n_monitor_infos == 0 && XineramaIsActive (xdisplay)) { XineramaScreenInfo *infos; int n_infos; int i; n_infos = 0; infos = XineramaQueryScreens (xdisplay, &n_infos); DEBUG ("Found %d Xinerama screens on display %s\n", n_infos, gdk_display_get_name (gdk_display)); if (n_infos > 0) { screen->monitor_infos = g_new0 (CsMonitorInfo, n_infos); screen->n_monitor_infos = n_infos; i = 0; while (i < n_infos) { screen->monitor_infos[i].number = infos[i].screen_number; screen->monitor_infos[i].rect.x = infos[i].x_org; screen->monitor_infos[i].rect.y = infos[i].y_org; screen->monitor_infos[i].rect.width = infos[i].width; screen->monitor_infos[i].rect.height = infos[i].height; DEBUG ("Monitor %d is %d,%d %d x %d\n", screen->monitor_infos[i].number, screen->monitor_infos[i].rect.x, screen->monitor_infos[i].rect.y, screen->monitor_infos[i].rect.width, screen->monitor_infos[i].rect.height); ++i; } } cs_XFree (infos); #ifdef HAVE_RANDR { XRRScreenResources *resources; resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); if (resources) { for (i = 0; i < resources->ncrtc; i++) { XRRCrtcInfo *crtc; CsMonitorInfo *info; crtc = XRRGetCrtcInfo (xdisplay, resources, resources->crtcs[i]); info = find_monitor_with_rect (screen, crtc->x, crtc->y, (int)crtc->width, (int)crtc->height); if (info) { info->output = find_main_output_for_crtc (resources, crtc, xdisplay, xroot); } XRRFreeCrtcInfo (crtc); } XRRFreeScreenResources (resources); } } #endif } else if (screen->n_monitor_infos > 0) { DEBUG ("No XFree86 Xinerama extension or XFree86 Xinerama inactive on display %s\n", gdk_display_get_name (gdk_display)); } #else DEBUG ("Muffin compiled without XFree86 Xinerama support\n"); #endif /* HAVE_XFREE_XINERAMA */ #ifdef HAVE_SOLARIS_XINERAMA /* This code from GDK, Copyright (C) 2002 Sun Microsystems */ if (screen->n_monitor_infos == 0 && XineramaGetState (xdisplay, gdk_screen_get_number (screen->gdk_screen))) { XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; int result; int n_monitors; int i; n_monitors = 0; result = XineramaGetInfo (xdisplay, gdk_screen_get_number (screen->gdk_screen), monitors, hints, &n_monitors); /* Yes I know it should be Success but the current implementation * returns the num of monitor */ if (result > 0) { g_assert (n_monitors > 0); screen->monitor_infos = g_new0 (CsMonitorInfo, n_monitors); screen->n_monitor_infos = n_monitors; i = 0; while (i < n_monitors) { screen->monitor_infos[i].number = i; screen->monitor_infos[i].rect.x = monitors[i].x; screen->monitor_infos[i].rect.y = monitors[i].y; screen->monitor_infos[i].rect.width = monitors[i].width; screen->monitor_infos[i].rect.height = monitors[i].height; DEBUG ("Monitor %d is %d,%d %d x %d\n", screen->monitor_infos[i].number, screen->monitor_infos[i].rect.x, screen->monitor_infos[i].rect.y, screen->monitor_infos[i].rect.width, screen->monitor_infos[i].rect.height); ++i; } } } else if (screen->n_monitor_infos == 0) { DEBUG ("No Solaris Xinerama extension or Solaris Xinerama inactive on display %s\n", gdk_display_get_name (gdk_display)); } #else DEBUG ("Cinnamon Screensaver compiled without Solaris Xinerama support\n"); #endif /* HAVE_SOLARIS_XINERAMA */ /* If no Xinerama, fill in the single screen info so * we can use the field unconditionally */ if (screen->n_monitor_infos == 0) { DEBUG ("No Xinerama screens, using default screen info\n"); screen->monitor_infos = g_new0 (CsMonitorInfo, 1); screen->n_monitor_infos = 1; screen->monitor_infos[0].number = 0; screen->monitor_infos[0].rect = screen->rect; } filter_mirrored_monitors (screen); screen->monitor_infos[screen->primary_monitor_index].is_primary = TRUE; apply_scale_factor (screen->monitor_infos, screen->n_monitor_infos, gdk_screen_get_monitor_scale_factor (screen->gdk_screen, PRIMARY_MONITOR)); g_assert (screen->n_monitor_infos > 0); g_assert (screen->monitor_infos != NULL); }