예제 #1
0
파일: gdkscreen-x11.c 프로젝트: GYGit/gtk
static guint32
get_netwm_cardinal_property (GdkScreen   *screen,
                             const gchar *name)
{
  GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
  GdkAtom atom;
  guint32 prop = 0;
  Atom type;
  gint format;
  gulong nitems;
  gulong bytes_after;
  guchar *data;

  atom = gdk_atom_intern_static_string (name);

  if (!gdk_x11_screen_supports_net_wm_hint (screen, atom))
    return 0;

  XGetWindowProperty (x11_screen->xdisplay,
                      x11_screen->xroot_window,
                      gdk_x11_get_xatom_by_name_for_display (GDK_SCREEN_DISPLAY (screen), name),
                      0, G_MAXLONG,
                      False, XA_CARDINAL, &type, &format, &nitems,
                      &bytes_after, &data);
  if (type == XA_CARDINAL)
    {
      prop = *(gulong *)data;
      XFree (data);
    }

  return prop;
}
예제 #2
0
static void
add_startup_timeout (GdkX11Screen *screen,
                     const char   *startup_id)
{
  StartupTimeoutData *data;
  StartupNotificationData *sn_data;

  data = g_object_get_data (G_OBJECT (screen), "appinfo-startup-data");

  if (data == NULL)
    {
      data = g_new (StartupTimeoutData, 1);
      data->contexts = NULL;
      data->timeout_id = 0;

      g_object_set_data_full (G_OBJECT (screen), "appinfo-startup-data",
                              data, free_startup_timeout);
    }

  sn_data = g_new (StartupNotificationData, 1);
  sn_data->display = g_object_ref (GDK_SCREEN_DISPLAY (screen));
  sn_data->startup_id = g_strdup (startup_id);
  g_get_current_time (&sn_data->time);

  data->contexts = g_slist_prepend (data->contexts, sn_data);

  if (data->timeout_id == 0) {
    data->timeout_id = g_timeout_add_seconds (STARTUP_TIMEOUT_LENGTH_SECONDS,
                                              startup_timeout, data);
    g_source_set_name_by_id (data->timeout_id, "[gtk+] startup_timeout");
  }
}
예제 #3
0
파일: gdkscreen-x11.c 프로젝트: GNOME/gtk
static void
init_randr_support (GdkX11Screen *x11_screen)
{
  /* NB: This is also needed for XSettings, so don't remove. */
  XSelectInput (GDK_SCREEN_XDISPLAY (x11_screen),
                x11_screen->xroot_window,
                StructureNotifyMask);

#ifdef HAVE_RANDR
  if (!GDK_X11_DISPLAY (GDK_SCREEN_DISPLAY (x11_screen))->have_randr12)
    return;

  XRRSelectInput (GDK_SCREEN_XDISPLAY (x11_screen),
                  x11_screen->xroot_window,
                  RRScreenChangeNotifyMask
                  | RRCrtcChangeNotifyMask
                  | RROutputPropertyNotifyMask);
#endif
}
예제 #4
0
파일: gdkscreen-x11.c 프로젝트: GNOME/gtk
void
_gdk_x11_screen_size_changed (GdkX11Screen *screen,
			      const XEvent *event)
{
#ifdef HAVE_RANDR
  GdkX11Display *display_x11;

  display_x11 = GDK_X11_DISPLAY (GDK_SCREEN_DISPLAY (screen));

  if (display_x11->have_randr13 && event->type == ConfigureNotify)
    return;

  XRRUpdateConfiguration ((XEvent *) event);
#else
  if (event->type != ConfigureNotify)
    return;
#endif

  process_monitors_change (screen);
}
예제 #5
0
파일: gdkscreen-x11.c 프로젝트: GNOME/gtk
static int
get_current_desktop (GdkX11Screen *screen)
{
  Display *display;
  Window win;
  Atom current_desktop, type;
  int format;
  unsigned long n_items, bytes_after;
  unsigned char *data_return = NULL;
  int workspace = 0;

  if (!gdk_x11_screen_supports_net_wm_hint (screen,
                                            g_intern_static_string ("_NET_CURRENT_DESKTOP")))
    return workspace;

  display = GDK_DISPLAY_XDISPLAY (GDK_SCREEN_DISPLAY (screen));
  win = XRootWindow (display, gdk_x11_screen_get_screen_number (screen));

  current_desktop = XInternAtom (display, "_NET_CURRENT_DESKTOP", True);

  XGetWindowProperty (display,
                      win,
                      current_desktop,
                      0, G_MAXLONG,
                      False, XA_CARDINAL,
                      &type, &format, &n_items, &bytes_after,
                      &data_return);

  if (type == XA_CARDINAL && format == 32 && n_items > 0)
    workspace = ((long *) data_return)[0];

  if (data_return)
    XFree (data_return);

  return workspace;
}
예제 #6
0
파일: gdkscreen-x11.c 프로젝트: GNOME/gtk
static gboolean
init_randr13 (GdkX11Screen *x11_screen, gboolean *changed)
{
#ifdef HAVE_RANDR
  GdkDisplay *display = GDK_SCREEN_DISPLAY (x11_screen);
  GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
  XRRScreenResources *resources;
  RROutput primary_output = None;
  RROutput first_output = None;
  int i;
  int old_primary;

  if (!x11_display->have_randr13)
      return FALSE;

  resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay,
                                            x11_screen->xroot_window);
  if (!resources)
    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 < resources->noutput; ++i)
    {
      RROutput output = resources->outputs[i];
      XRROutputInfo *output_info =
        XRRGetOutputInfo (x11_screen->xdisplay, resources, output);

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

      if (output_info->crtc)
	{
	  GdkX11Monitor *monitor;
	  XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
          char *name;
          GdkRectangle geometry;
          GdkRectangle newgeo;
          int j;
          int refresh_rate = 0;

          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;
                }
            }

          monitor = find_monitor_by_output (x11_display, output);
          if (monitor)
            monitor->remove = FALSE;
          else
            {
              monitor = g_object_new (gdk_x11_monitor_get_type (),
                                      "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 = crtc->x / x11_screen->surface_scale;
          newgeo.y = crtc->y / x11_screen->surface_scale;
          newgeo.width = crtc->width / x11_screen->surface_scale;
          newgeo.height = crtc->height / x11_screen->surface_scale;
          if (newgeo.x != geometry.x ||
              newgeo.y != geometry.y ||
              newgeo.width != geometry.width ||
              newgeo.height != geometry.height ||
              output_info->mm_width != gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) ||
              output_info->mm_height != gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) ||
              g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))) != 0)
            *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),
                                         output_info->mm_width,
                                         output_info->mm_height);
          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->surface_scale);
          gdk_monitor_set_model (GDK_MONITOR (monitor), name);

          g_free (name);

          XRRFreeCrtcInfo (crtc);
	}

      XRRFreeOutputInfo (output_info);
    }

  if (resources->noutput > 0)
    first_output = resources->outputs[0];

  XRRFreeScreenResources (resources);

  /* Which usable multihead data is not returned in non RandR 1.2+ X driver? */

  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;
  primary_output = XRRGetOutputPrimary (x11_screen->xdisplay,
                                        x11_screen->xroot_window);

  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;
}