Example #1
0
int get_monitor_dims(int *ret_left_x, int *ret_right_x,
	int *ret_top_y, int *ret_bottom_y, int i) {

	Display *display;
	if (!(display = XOpenDisplay(0))) { return ERR_COULDNT_OPEN_X_DISPLAY; }

	XRRScreenResources *screen_res =
		XRRGetScreenResources(display, DefaultRootWindow(display));

	*ret_left_x = INT_MAX;
	*ret_right_x = INT_MIN;
	*ret_top_y = INT_MAX;
	*ret_bottom_y = INT_MIN;
	int nmonitors = 0;
	XRRGetMonitors(display, DefaultRootWindow(display), 1, &nmonitors);

	/* If the user requests a screen outside of the number of monitors, exit */
	if (i >= nmonitors) {
		return ERR_MONITOR_DNE;
	}

	XRRCrtcInfo *screen_info =
		XRRGetCrtcInfo(display, screen_res, screen_res->crtcs[i]);

	*ret_left_x = screen_info->x;
	*ret_right_x = screen_info->x + screen_info->width;
	*ret_top_y = screen_info->y;
	*ret_bottom_y = screen_info->y + screen_info->height;

	return 0;
}
Example #2
0
int get_monitor_dims_of_focused_screen(int use_anchors, int *ret_left_x, int *ret_right_x,
	int *ret_top_y, int *ret_bottom_y) {

	Display *dpy;
	if (!(dpy = XOpenDisplay(0))) { return ERR_COULDNT_OPEN_X_DISPLAY; }

	/* Get currently focused window */
	Window win = -1;
	int focus_status;
	XGetInputFocus(dpy, &win, &focus_status);
	if (win == PointerRoot || win == None) { return ERR_WIN_NOT_FOUND; }

	XRRScreenResources *screen_res =
		XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
	XWindowAttributes win_attr;
	XGetWindowAttributes(dpy, win, &win_attr);

	int det_x = 0;
	int det_y = 0;
	int nmonitors = 0;
	XRRGetMonitors(dpy, win, 1, &nmonitors);

	for (int i = 0; i < nmonitors; i++) {
		XRRCrtcInfo *screen_info =
			XRRGetCrtcInfo(dpy, screen_res, screen_res->crtcs[i]);

		/* option flag for using the "anchor" (top left corner)  of a window
		 * to determine what screen it belongs to */
		if (use_anchors == 1) {
			det_x = win_attr.x;
			det_y = win_attr.y;
		/* Use the center of the window to determine what screen it's on */
		} else {
			det_x = win_attr.x + ((win_attr.width)/2);
			det_y = win_attr.y + ((win_attr.height)/2);
		}

		/* If the window is on the ith screen in the x */
		if (det_x >= screen_info->x &&
			det_x < (screen_info->x + screen_info->width)) {
			/* If the window is on the ith screen in the y */
			if (det_y >= screen_info->y &&
				det_y < (screen_info->y + screen_info->height)) {

				*ret_left_x = screen_info->x;
				*ret_right_x = screen_info->x + screen_info->width;
				*ret_top_y = screen_info->y;
				*ret_bottom_y = screen_info->y + screen_info->height;
				return 0;
			}
		}
	}

	/* If the function has not returned yet, then it could not find a screen
	 * on which 'win' resides.
	 */
	return ERR_SCREEN_OF_WIN_NOT_FOUND;
}
Example #3
0
/** Returns an int of 0 if it succeeds in finding the screen number of a
 * given Window or an int representing the error it ran into.
 * win the Window we are trying to find the screen of.
 * *dpy pointer to the Display we will be searching on.
 * *return_screen_num pointer to an int where the function will fill in the
 *     screen number that 'win' belongs to, if it can be found.
 * This function will return 0 if it was able to find the screen 'win' belongs
 * to. If it cannot, then it will return the correct
 * error code for window-not-found.
 */
int get_screen_number_of_win(Window win, Display *dpy, int use_anchors, \
	int *return_screen_num) {

	XRRScreenResources *screen_res =
		XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
	XWindowAttributes win_attr;
	XGetWindowAttributes(dpy, win, &win_attr);

	int det_x = 0;
	int det_y = 0;
	int nmonitors = 0;
	XRRGetMonitors(dpy, win, 1, &nmonitors);

	for (int i = 0; i < nmonitors; i++) {
		XRRCrtcInfo *screen_info =
			XRRGetCrtcInfo(dpy, screen_res, screen_res->crtcs[i]);

		/* option flag for using the "anchor" (top left corner)  of a window
		 * to determine what screen it belongs to */
		if (use_anchors == 1) {
			det_x = win_attr.x;
			det_y = win_attr.y;
		/* Use the center of the window to determine what screen it's on */
		} else {
			det_x = win_attr.x + ((win_attr.width)/2);
			det_y = win_attr.y + ((win_attr.height)/2);
		}

		/* If the window is on the ith screen in the x */
		if (det_x >= screen_info->x &&
			det_x < (screen_info->x + screen_info->width)) {
			/* If the window is on the ith screen in the y */
			if (det_y >= screen_info->y &&
				det_y < (screen_info->y + screen_info->height)) {
				*return_screen_num = i;
				return 0;
			}
		}
	}

	/* If the function has not returned yet, then it could not find a screen
	 * on which 'win' resides.
	 */
	return ERR_SCREEN_OF_WIN_NOT_FOUND;
}
Example #4
0
int get_full_display_dims(int *ret_left_x, int *ret_right_x,
	int *ret_top_y, int *ret_bottom_y) {

	Display *display;
	if (!(display = XOpenDisplay(0))) { return ERR_COULDNT_OPEN_X_DISPLAY; }

	XRRScreenResources *screen_res =
		XRRGetScreenResources(display, DefaultRootWindow(display));

	*ret_left_x = INT_MAX;
	*ret_right_x = INT_MIN;
	*ret_top_y = INT_MAX;
	*ret_bottom_y = INT_MIN;
	int nmonitors = 0;
	XRRGetMonitors(display, DefaultRootWindow(display), 1, &nmonitors);

	for (int i = 0; i < nmonitors; i++) {
		XRRCrtcInfo *screen_info =
			XRRGetCrtcInfo(display, screen_res, screen_res->crtcs[i]);

		fprintf(stdout, "%d %d %d %d\n", screen_info->x, screen_info->y, screen_info->width, screen_info->height);

		if (screen_info->x < *ret_left_x) {
			*ret_left_x = screen_info->x;
		}
		if (((long) (screen_info->x + screen_info->width)) > *ret_right_x) {
			*ret_right_x = screen_info->x + screen_info->width;
		}
		if (screen_info->y < *ret_top_y) {
			*ret_top_y = screen_info->y;
		}
		if (((long) (screen_info->y + screen_info->height)) > *ret_bottom_y) {
			*ret_bottom_y = screen_info->y + screen_info->height;
		}
	}

	return 0;
}
Example #5
0
static gboolean
init_randr15 (GdkScreen *screen, gboolean *changed)
{
#ifdef HAVE_RANDR15
  GdkDisplay *display = gdk_screen_get_display (screen);
  GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
  GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
  XRRScreenResources *resources;
  RROutput primary_output = None;
  RROutput first_output = None;
  int i;
  gboolean randr12_compat = FALSE;
  XRRMonitorInfo *rr_monitors;
  int num_rr_monitors;
  int old_primary;

  if (!x11_display->have_randr15)
    return FALSE;

  resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay,
                                            x11_screen->xroot_window);
  if (!resources)
    return FALSE;

  rr_monitors = XRRGetMonitors (x11_screen->xdisplay,
                                x11_screen->xroot_window,
                                True,
                                &num_rr_monitors);
  if (!rr_monitors)
    return FALSE;

  for (i = 0; i < x11_display->monitors->len; i++)
    {
      GdkX11Monitor *monitor = x11_display->monitors->pdata[i];
      monitor->add = FALSE;
      monitor->remove = TRUE;
    }

  for (i = 0; i < num_rr_monitors; i++)
    {
      RROutput output = rr_monitors[i].outputs[0];
      XRROutputInfo *output_info;
      GdkX11Monitor *monitor;
      GdkRectangle geometry;
      GdkRectangle newgeo;
      char *name;
      int refresh_rate = 0;

      gdk_x11_display_error_trap_push (display);
      output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output);
      if (gdk_x11_display_error_trap_pop (display))
        continue;

      if (output_info == NULL)
        continue;

      /* Non RandR1.2+ X driver have output name "default" */
      randr12_compat |= !g_strcmp0 (output_info->name, "default");

      if (output_info->connection == RR_Disconnected)
        {
          XRRFreeOutputInfo (output_info);
          continue;
        }

      if (first_output == None)
        first_output = output;

      if (output_info->crtc)
        {
          XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
          int j;

          for (j = 0; j < resources->nmode; j++)
            {
              XRRModeInfo *xmode = &resources->modes[j];
              if (xmode->id == crtc->mode)
                {
                  if (xmode->hTotal != 0 && xmode->vTotal != 0)
                    refresh_rate = (1000 * xmode->dotClock) / (xmode->hTotal * xmode->vTotal);
                  break;
                }
            }

          XRRFreeCrtcInfo (crtc);
        }

      monitor = find_monitor_by_output (x11_display, output);
      if (monitor)
        monitor->remove = FALSE;
      else
        {
          monitor = g_object_new (GDK_TYPE_X11_MONITOR,
                                  "display", display,
                                  NULL);
          monitor->output = output;
          monitor->add = TRUE;
          g_ptr_array_add (x11_display->monitors, monitor);
        }

      gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
      name = g_strndup (output_info->name, output_info->nameLen);

      newgeo.x = rr_monitors[i].x / x11_screen->window_scale;
      newgeo.y = rr_monitors[i].y / x11_screen->window_scale;
      newgeo.width = rr_monitors[i].width / x11_screen->window_scale;
      newgeo.height = rr_monitors[i].height / x11_screen->window_scale;
      if (newgeo.x != geometry.x ||
          newgeo.y != geometry.y ||
          newgeo.width != geometry.width ||
          newgeo.height != geometry.height ||
          rr_monitors[i].mwidth != gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) ||
          rr_monitors[i].mheight != gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) ||
          g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))))
        *changed = TRUE;

      gdk_monitor_set_position (GDK_MONITOR (monitor), newgeo.x, newgeo.y);
      gdk_monitor_set_size (GDK_MONITOR (monitor), newgeo.width, newgeo.height);
      g_object_notify (G_OBJECT (monitor), "workarea");
      gdk_monitor_set_physical_size (GDK_MONITOR (monitor),
                                     rr_monitors[i].mwidth,
                                     rr_monitors[i].mheight);
      gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor),
                                       translate_subpixel_order (output_info->subpixel_order));
      gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh_rate);
      gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->window_scale);
      gdk_monitor_set_model (GDK_MONITOR (monitor), name);
      g_free (name);

      if (rr_monitors[i].primary)
        primary_output = monitor->output;

      XRRFreeOutputInfo (output_info);
    }

  XRRFreeMonitors (rr_monitors);
  XRRFreeScreenResources (resources);

  /* non RandR 1.2+ X driver doesn't return any usable multihead data */
  if (randr12_compat)
    {
      for (i = 0; i < x11_display->monitors->len; i++)
        {
          GdkX11Monitor *monitor = x11_display->monitors->pdata[i];
          if (monitor->remove)
            gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
        }
      g_ptr_array_remove_range (x11_display->monitors, 0, x11_display->monitors->len);
      return FALSE;
    }

  for (i = x11_display->monitors->len - 1; i >= 0; i--)
    {
      GdkX11Monitor *monitor = x11_display->monitors->pdata[i];
      if (monitor->add)
        {
          gdk_display_monitor_added (display, GDK_MONITOR (monitor));
          *changed = TRUE;
        }
      else if (monitor->remove)
        {
          g_object_ref (monitor);
          g_ptr_array_remove (x11_display->monitors, monitor);
          gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
          g_object_unref (monitor);
          *changed = TRUE;
        }
    }

  old_primary = x11_display->primary_monitor;
  x11_display->primary_monitor = 0;
  for (i = 0; i < x11_display->monitors->len; ++i)
    {
      GdkX11Monitor *monitor = x11_display->monitors->pdata[i];
      if (monitor->output == primary_output)
        {
          x11_display->primary_monitor = i;
          break;
        }

      /* No RandR1.3+ available or no primary set, fall back to prefer LVDS as primary if present */
      if (primary_output == None &&
          g_ascii_strncasecmp (gdk_monitor_get_model (GDK_MONITOR (monitor)), "LVDS", 4) == 0)
        {
          x11_display->primary_monitor = i;
          break;
        }

      /* No primary specified and no LVDS found */
      if (monitor->output == first_output)
        x11_display->primary_monitor = i;
    }

  if (x11_display->primary_monitor != old_primary)
    *changed = TRUE;

  return x11_display->monitors->len > 0;
#endif

  return FALSE;
}