Exemple #1
0
static void
clutter_stage_x11_get_geometry (ClutterStageWindow    *stage_window,
                                cairo_rectangle_int_t *geometry)
{
  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);

  geometry->x = geometry->y = 0;

  /* If we're fullscreen, return the size of the display.
   *
   * FIXME - this is utterly broken for anything that is not a single
   * head set up; the window manager will give us the right size in a
   * ConfigureNotify, but between the fullscreen signal emission on the
   * stage and the following frame, the size returned by the stage will
   * be wrong.
   */
  if (_clutter_stage_is_fullscreen (stage_cogl->wrapper) &&
      stage_x11->fullscreening)
    {
      geometry->width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
      geometry->height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);

      return;
    }

  geometry->width = stage_x11->xwin_width;
  geometry->height = stage_x11->xwin_height;
}
static ClutterStageWindow *
clutter_backend_glx_create_stage (ClutterBackend  *backend,
                                  ClutterStage    *wrapper,
                                  GError         **error)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterStageWindow *stage_window;
  ClutterStageX11 *stage_x11;

  CLUTTER_NOTE (BACKEND, "Creating stage of type '%s'",
                g_type_name (CLUTTER_STAGE_TYPE));

  stage_window = g_object_new (CLUTTER_TYPE_STAGE_GLX, NULL);

  /* copy backend data into the stage */
  stage_x11 = CLUTTER_STAGE_X11 (stage_window);
  stage_x11->wrapper = wrapper;

  CLUTTER_NOTE (BACKEND,
                "GLX stage created[%p] (dpy:%p, screen:%d, root:%u, wrap:%p)",
                stage_window,
                backend_x11->xdpy,
                backend_x11->xscreen_num,
                (unsigned int) backend_x11->xwin_root,
                wrapper);

  return stage_window;
}
Exemple #3
0
static inline void
set_wm_title (ClutterStageX11 *stage_x11)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);

  if (stage_x11->xwin == None || stage_x11->is_foreign_xwin)
    return;

  if (stage_x11->title == NULL)
    {
      XDeleteProperty (backend_x11->xdpy,
                       stage_x11->xwin, 
                       backend_x11->atom_NET_WM_NAME);
    }
  else
    {
      XChangeProperty (backend_x11->xdpy,
                       stage_x11->xwin, 
                       backend_x11->atom_NET_WM_NAME,
                       backend_x11->atom_UTF8_STRING,
                       8, 
                       PropModeReplace, 
                       (unsigned char *) stage_x11->title,
                       (int) strlen (stage_x11->title));
    }
}
static ClutterStageWindow *
clutter_backend_egl_create_stage (ClutterBackend  *backend,
                                  ClutterStage    *wrapper,
                                  GError         **error)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterStageX11 *stage_x11;
  ClutterStageWindow *stage;

  CLUTTER_NOTE (BACKEND, "Creating stage of type '%s'",
                g_type_name (CLUTTER_STAGE_TYPE));
  
  stage = g_object_new (CLUTTER_TYPE_STAGE_EGL, NULL);
  
  /* copy backend data into the stage */
  stage_x11 = CLUTTER_STAGE_X11 (stage);
  stage_x11->wrapper = wrapper;
  
  CLUTTER_NOTE (MISC, "EGLX stage created (display:%p, screen:%d, root:%u)",
                backend_x11->xdpy,
                backend_x11->xscreen_num,
                (unsigned int) backend_x11->xwin_root);
  
  return stage;
}
static ClutterStageWindow *
clutter_backend_x11_create_stage (ClutterBackend  *backend,
				  ClutterStage    *wrapper,
				  GError         **error)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterEventTranslator *translator;
  ClutterStageWindow *stage;

  stage = g_object_new (CLUTTER_TYPE_STAGE_X11,
			"backend", backend,
			"wrapper", wrapper,
			NULL);

  /* the X11 stage does event translation */
  translator = CLUTTER_EVENT_TRANSLATOR (stage);
  _clutter_backend_add_event_translator (backend, translator);

  CLUTTER_NOTE (MISC, "X11 stage created (display:%p, screen:%d, root:%u)",
                backend_x11->xdpy,
                backend_x11->xscreen_num,
                (unsigned int) backend_x11->xwin_root);

  return stage;
}
Exemple #6
0
gboolean
_clutter_stage_x11_get_root_coords (ClutterStageX11 *stage_x11,
                                    gint            *root_x,
                                    gint            *root_y)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
  gint return_val;
  Window child;
  gint tx, ty;

  return_val = XTranslateCoordinates (backend_x11->xdpy,
                                      stage_x11->xwin,
                                      backend_x11->xwin_root,
                                      0, 0, &tx, &ty,
                                      &child);

  if (root_x)
    *root_x = tx;

  if (root_y)
    *root_y = ty;

  return (return_val == 0);
}
static void
events_queue (ClutterBackend *backend)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterBackendX11Class *backend_x11_class =
    CLUTTER_BACKEND_X11_GET_CLASS (backend_x11);
  ClutterEvent      *event;
  Display           *xdisplay = backend_x11->xdpy;
  XEvent             xevent;
  ClutterMainContext  *clutter_context;

  clutter_context = _clutter_context_get_default ();

  while (!clutter_events_pending () && XPending (xdisplay))
    {
      XNextEvent (xdisplay, &xevent);

      if (backend_x11_class->handle_event (backend_x11, &xevent))
        continue;

      event = clutter_event_new (CLUTTER_NOTHING);

      if (event_translate (backend, event, &xevent))
        {
	  /* push directly here to avoid copy of queue_put */
	  g_queue_push_head (clutter_context->events_queue, event);
        }
      else
        {
          clutter_event_free (event);
        }
    }
}
/**
 * clutter_x11_add_filter: (skip)
 * @func: a filter function
 * @data: user data to be passed to the filter function, or %NULL
 *
 * Adds an event filter function.
 *
 * Since: 0.6
 */
void
clutter_x11_add_filter (ClutterX11FilterFunc func,
                        gpointer             data)
{
  ClutterX11EventFilter *filter;
  ClutterBackend *backend = clutter_get_default_backend ();
  ClutterBackendX11 *backend_x11;

  g_return_if_fail (func != NULL);

  if (backend == NULL)
    {
      g_critical ("The Clutter backend has not been initialised");
      return;
    }

  if (!CLUTTER_IS_BACKEND_X11 (backend))
    {
      g_critical ("The Clutter backend is not a X11 backend");
      return;
    }

  backend_x11 = CLUTTER_BACKEND_X11 (backend);

  filter = g_new0 (ClutterX11EventFilter, 1);
  filter->func = func;
  filter->data = data;

  backend_x11->event_filters =
    g_slist_append (backend_x11->event_filters, filter);

  return;
}
/**
 * clutter_x11_get_current_event_time: (skip)
 *
 * Retrieves the timestamp of the last X11 event processed by
 * Clutter. This might be different from the timestamp returned
 * by clutter_get_current_event_time(), as Clutter may synthesize
 * or throttle events.
 *
 * Return value: a timestamp, in milliseconds
 *
 * Since: 1.0
 */
Time
clutter_x11_get_current_event_time (void)
{
  ClutterBackend *backend = clutter_get_default_backend ();

  return CLUTTER_BACKEND_X11 (backend)->last_event_time;
}
static void
clutter_backend_glx_dispose (GObject *gobject)
{
  ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (gobject);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);

  /* Unrealize all shaders, since the GL context is going away */
  _clutter_shader_release_all ();

  if (backend_glx->gl_context)
    {
      glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
      glXDestroyContext (backend_x11->xdpy, backend_glx->gl_context);
      backend_glx->gl_context = None;
    }

  if (backend_glx->dummy_glxwin)
    {
      glXDestroyWindow (backend_x11->xdpy, backend_glx->dummy_glxwin);
      backend_glx->dummy_glxwin = None;
    }

  if (backend_glx->dummy_xwin)
    {
      XDestroyWindow (backend_x11->xdpy, backend_glx->dummy_xwin);
      backend_glx->dummy_xwin = None;
    }

  G_OBJECT_CLASS (clutter_backend_glx_parent_class)->dispose (gobject);
}
Exemple #11
0
static void
clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
{
  ClutterBackend *backend = clutter_get_default_backend ();
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
  ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window);

  /* Note unrealize should free up any backend stage related resources */
  CLUTTER_NOTE (BACKEND, "Unrealizing stage");

  clutter_x11_trap_x_errors ();

  if (stage_glx->glxwin != None)
    {
      glXDestroyWindow (backend_x11->xdpy, stage_glx->glxwin);
      stage_glx->glxwin = None;
    }

  if (!stage_x11->is_foreign_xwin && stage_x11->xwin != None)
    {
      XDestroyWindow (backend_x11->xdpy, stage_x11->xwin);
      stage_x11->xwin = None;
    }
  else
    stage_x11->xwin = None;

  XSync (backend_x11->xdpy, False);

  clutter_x11_untrap_x_errors ();

  CLUTTER_MARK ();
}
Exemple #12
0
void
_clutter_backend_x11_events_init (ClutterBackend *backend)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  GSource *source;
  ClutterEventSource *event_source;
  int connection_number;
  gchar *name;

  connection_number = ConnectionNumber (backend_x11->xdpy);
  CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);

  source = backend_x11->event_source = clutter_event_source_new (backend);
  event_source = (ClutterEventSource *) source;
  g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);

  name = g_strdup_printf ("Clutter X11 Event (connection: %d)",
                          connection_number);
  g_source_set_name (source, name);
  g_free (name);

  event_source->event_poll_fd.fd = connection_number;
  event_source->event_poll_fd.events = G_IO_IN;

  event_sources = g_list_prepend (event_sources, event_source);

  g_source_add_poll (source, &event_source->event_poll_fd);
  g_source_set_can_recurse (source, TRUE);
  g_source_attach (source, NULL);
}
static XkbDescPtr
get_xkb (ClutterKeymapX11 *keymap_x11)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);

  if (keymap_x11->max_keycode == 0)
    XDisplayKeycodes (backend_x11->xdpy,
                      &keymap_x11->min_keycode,
                      &keymap_x11->max_keycode);

  if (keymap_x11->xkb_desc == NULL)
    {
      int flags = XkbKeySymsMask
                | XkbKeyTypesMask
                | XkbModifierMapMask
                | XkbVirtualModsMask;

      keymap_x11->xkb_desc = XkbGetMap (backend_x11->xdpy, flags, XkbUseCoreKbd);
      if (G_UNLIKELY (keymap_x11->xkb_desc == NULL))
        {
          g_error ("Failed to get the keymap from XKB");
          return NULL;
        }

      flags = XkbGroupNamesMask | XkbVirtualModNamesMask;
      XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc);

      update_modmap (backend_x11->xdpy, keymap_x11);
    }
  else if (keymap_x11->xkb_map_serial != backend_x11->keymap_serial)
    {
      int flags = XkbKeySymsMask
                | XkbKeyTypesMask
                | XkbModifierMapMask
                | XkbVirtualModsMask;

      CLUTTER_NOTE (BACKEND, "Updating XKB keymap");

      XkbGetUpdatedMap (backend_x11->xdpy, flags, keymap_x11->xkb_desc);

      flags = XkbGroupNamesMask | XkbVirtualModNamesMask;
      XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc);

      update_modmap (backend_x11->xdpy, keymap_x11);

      keymap_x11->xkb_map_serial = backend_x11->keymap_serial;
    }

  if (keymap_x11->num_lock_mask == 0)
    keymap_x11->num_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
                                                      XK_Num_Lock);

  if (keymap_x11->scroll_lock_mask == 0)
    keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
                                                         XK_Scroll_Lock);

  return keymap_x11->xkb_desc;
}
Exemple #14
0
void
_clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11,
                                  guint32          user_time)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);

  set_user_time (backend_x11, stage_x11, user_time);
}
static PangoDirection
clutter_backend_x11_get_keymap_direction (ClutterBackend *backend)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);

  if (G_UNLIKELY (backend_x11->keymap == NULL))
    return PANGO_DIRECTION_NEUTRAL;

  return _clutter_keymap_x11_get_direction (backend_x11->keymap);
}
Exemple #16
0
static void
clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
                                   gint             new_width,
                                   gint             new_height)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);

  if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin)
    {
      guint min_width, min_height;
      XSizeHints *size_hints;
      gboolean resize;

      resize = clutter_stage_get_user_resizable (stage_cogl->wrapper);

      size_hints = XAllocSizeHints();

      clutter_stage_get_minimum_size (stage_cogl->wrapper,
                                      &min_width,
                                      &min_height);

      if (new_width <= 0)
        new_width = min_width;

      if (new_height <= 0)
        new_height = min_height;

      size_hints->flags = 0;

      /* If we are going fullscreen then we don't want any
         restrictions on the window size */
      if (!stage_x11->fullscreening)
        {
          if (resize)
            {
              size_hints->min_width = min_width;
              size_hints->min_height = min_height;
              size_hints->flags = PMinSize;
            }
          else
            {
              size_hints->min_width = new_width;
              size_hints->min_height = new_height;
              size_hints->max_width = new_width;
              size_hints->max_height = new_height;
              size_hints->flags = PMinSize | PMaxSize;
            }
        }

      XSetWMNormalHints (backend_x11->xdpy, stage_x11->xwin, size_hints);

      XFree(size_hints);
    }
}
static void
clutter_keymap_x11_constructed (GObject *gobject)
{
  ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (gobject);
  ClutterBackendX11 *backend_x11;

  g_assert (keymap_x11->backend != NULL);
  backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);

#ifdef HAVE_XKB
  {
    gint xkb_major = XkbMajorVersion;
    gint xkb_minor = XkbMinorVersion;

    if (XkbLibraryVersion (&xkb_major, &xkb_minor))
      {
        xkb_major = XkbMajorVersion;
        xkb_minor = XkbMinorVersion;

        if (XkbQueryExtension (backend_x11->xdpy,
                               NULL,
                               &keymap_x11->xkb_event_base,
                               NULL,
                               &xkb_major, &xkb_minor))
          {
            Bool detectable_autorepeat_supported;

            backend_x11->use_xkb = TRUE;

            XkbSelectEvents (backend_x11->xdpy,
                             XkbUseCoreKbd,
                             XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
                             XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);

            XkbSelectEventDetails (backend_x11->xdpy,
                                   XkbUseCoreKbd, XkbStateNotify,
                                   XkbAllStateComponentsMask,
                                   XkbGroupLockMask | XkbModifierLockMask);

            /* enable XKB autorepeat */
            XkbSetDetectableAutoRepeat (backend_x11->xdpy,
                                        True,
                                        &detectable_autorepeat_supported);

            backend_x11->have_xkb_autorepeat = detectable_autorepeat_supported;

            CLUTTER_NOTE (BACKEND, "Detectable autorepeat: %s",
                          backend_x11->have_xkb_autorepeat ? "supported"
                                                           : "not supported");
          }
      }
  }
#endif /* HAVE_XKB */
}
Exemple #18
0
static void
clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
  Atom protocols[2];
  int n = 0;
  
  protocols[n++] = backend_x11->atom_WM_DELETE_WINDOW;
  protocols[n++] = backend_x11->atom_NET_WM_PING;

  XSetWMProtocols (backend_x11->xdpy, stage_x11->xwin, protocols, n);
}
static gboolean
clutter_backend_glx_create_context (ClutterBackend  *backend,
                                    gboolean         is_offscreen,
                                    GError         **error)
{
  ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);

  if (backend_glx->gl_context == None)
    {
      XVisualInfo *xvisinfo;

      xvisinfo =
        clutter_backend_x11_get_visual_info (backend_x11, is_offscreen);

      CLUTTER_NOTE (GL, "Creating GL Context (display: %p, %s)",
                    backend_x11->xdpy,
                    is_offscreen ? "offscreen" : "onscreen");

      backend_glx->gl_context = glXCreateContext (backend_x11->xdpy,
                                                  xvisinfo,
                                                  0,
                                                  is_offscreen ? False : True);

      XFree (xvisinfo);

      if (backend_glx->gl_context == None)
        {
          g_set_error (error, CLUTTER_INIT_ERROR,
                       CLUTTER_INIT_ERROR_BACKEND,
                       "Unable to create suitable %s GL context",
                       is_offscreen ? "offscreen" : "onscreen");
          return FALSE;
        }

      if (!is_offscreen)
        {
          gboolean is_direct;

          is_direct = glXIsDirect (backend_x11->xdpy,
                                   backend_glx->gl_context);

          CLUTTER_NOTE (GL, "Setting %s context",
                        is_direct ? "direct" : "indirect");
          _cogl_set_indirect_context (!is_direct);
        }
    }

  return TRUE;
}
Exemple #20
0
gboolean
_clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
                                                  gint                stage_root_x,
                                                  gint                stage_root_y,
                                                  guint               index_,
                                                  gdouble             value,
                                                  gdouble            *axis_value)
{
  ClutterAxisInfo *info;
  ClutterBackendX11 *backend_x11;
  gdouble width, scale, offset;
  
  backend_x11 = CLUTTER_BACKEND_X11 (device->backend);

  if (device->axes == NULL || index_ >= device->axes->len)
    return FALSE;

  info = &g_array_index (device->axes, ClutterAxisInfo, index_);
  if (info->axis != CLUTTER_INPUT_AXIS_X ||
      info->axis != CLUTTER_INPUT_AXIS_Y)
    {
      return FALSE;
    }

  width = info->max_value - info->min_value;

  if (info->axis == CLUTTER_INPUT_AXIS_X)
    {
      if (width > 0)
        scale = backend_x11->xscreen_width / width;
      else
        scale = 1;

      offset = - stage_root_x;
    }
  else
    {
      if (width > 0)
        scale = backend_x11->xscreen_height / width;
      else
        scale = 1;

      offset = - stage_root_y;
    }

  if (axis_value)
    *axis_value = offset + scale * (value - info->min_value);

  return TRUE;
}
PangoDirection
_clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap)
{
  g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), PANGO_DIRECTION_NEUTRAL);

#ifdef HAVE_XKB
  if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb)
    {
      if (!keymap->has_direction)
        {
          Display *xdisplay = CLUTTER_BACKEND_X11 (keymap->backend)->xdpy;
          XkbStateRec state_rec;

          XkbGetState (xdisplay, XkbUseCoreKbd, &state_rec);
          update_direction (keymap, XkbStateGroup (&state_rec));
        }

      return keymap->current_direction;
    }
  else
#endif
    return PANGO_DIRECTION_NEUTRAL;
}
static ClutterTranslateReturn
clutter_keymap_x11_translate_event (ClutterEventTranslator *translator,
                                    gpointer                native,
                                    ClutterEvent           *event)
{
  ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (translator);
  ClutterBackendX11 *backend_x11;
  ClutterTranslateReturn retval;
  XEvent *xevent;

  backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
  if (!backend_x11->use_xkb)
    return CLUTTER_TRANSLATE_CONTINUE;

  xevent = native;

  retval = CLUTTER_TRANSLATE_CONTINUE;

#ifdef HAVE_XKB
  if (xevent->type == keymap_x11->xkb_event_base)
    {
      XkbEvent *xkb_event = (XkbEvent *) xevent;

      switch (xkb_event->any.xkb_type)
        {
        case XkbStateNotify:
          CLUTTER_NOTE (EVENT, "Updating keyboard state");
          update_direction (keymap_x11, XkbStateGroup (&xkb_event->state));
          update_locked_mods (keymap_x11, xkb_event->state.locked_mods);
          retval = CLUTTER_TRANSLATE_REMOVE;
          break;

        case XkbNewKeyboardNotify:
        case XkbMapNotify:
          CLUTTER_NOTE (EVENT, "Updating keyboard mapping");
          XkbRefreshKeyboardMapping (&xkb_event->map);
          backend_x11->keymap_serial += 1;
          retval = CLUTTER_TRANSLATE_REMOVE;
          break;

        default:
          break;
        }
    }
#endif /* HAVE_XKB */

  return retval;
}
static gboolean
clutter_backend_x11_translate_event (ClutterBackend *backend,
                                     gpointer        native,
                                     ClutterEvent   *event)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterBackendClass *parent_class;
  XEvent *xevent = native;

  /* X11 filter functions have a higher priority */
  if (backend_x11->event_filters != NULL)
    {
      GSList *node = backend_x11->event_filters;

      while (node != NULL)
        {
          ClutterX11EventFilter *filter = node->data;

          switch (filter->func (xevent, event, filter->data))
            {
            case CLUTTER_X11_FILTER_CONTINUE:
              break;

            case CLUTTER_X11_FILTER_TRANSLATE:
              return TRUE;

            case CLUTTER_X11_FILTER_REMOVE:
              return FALSE;

            default:
              break;
            }

          node = node->next;
        }
    }

  /* we update the event time only for events that can
   * actually reach Clutter's event queue
   */
  update_last_event_time (backend_x11, xevent);

  /* chain up to the parent implementation, which will handle
   * event translators
   */
  parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class);
  return parent_class->translate_event (backend, native, event);
}
static void
clutter_backend_x11_finalize (GObject *gobject)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);

  g_free (backend_x11->display_name);

  clutter_x11_remove_filter (cogl_xlib_filter, gobject);

  clutter_x11_remove_filter (xsettings_filter, backend_x11);
  _clutter_xsettings_client_destroy (backend_x11->xsettings);

  XCloseDisplay (backend_x11->xdpy);

  G_OBJECT_CLASS (clutter_backend_x11_parent_class)->finalize (gobject);
}
Exemple #25
0
static inline void
set_cursor_visible (ClutterStageX11 *stage_x11)
{
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);

  if (stage_x11->xwin == None)
    return;

  CLUTTER_NOTE (BACKEND, "setting cursor state ('%s') over stage window (%u)",
                stage_x11->is_cursor_visible ? "visible" : "invisible",
                (unsigned int) stage_x11->xwin);

  if (stage_x11->is_cursor_visible)
    {
#if HAVE_XFIXES
      if (stage_x11->cursor_hidden_xfixes)
        {
          XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin);
          stage_x11->cursor_hidden_xfixes = FALSE;
        }
#else
      XUndefineCursor (backend_x11->xdpy, stage_x11->xwin);
#endif /* HAVE_XFIXES */
    }
  else
    {
#if HAVE_XFIXES
      XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin);
      stage_x11->cursor_hidden_xfixes = TRUE;
#else
      XColor col;
      Pixmap pix;
      Cursor curs;

      pix = XCreatePixmap (backend_x11->xdpy, stage_x11->xwin, 1, 1, 1);
      memset (&col, 0, sizeof (col));
      curs = XCreatePixmapCursor (backend_x11->xdpy,
                                  pix, pix,
                                  &col, &col,
                                  1, 1);
      XFreePixmap (backend_x11->xdpy, pix);
      XDefineCursor (backend_x11->xdpy, stage_x11->xwin, curs);
#endif /* HAVE_XFIXES */
    }
}
Exemple #26
0
void
_clutter_backend_x11_events_uninit (ClutterBackend *backend)
{
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);

  if (backend_x11->event_source)
    {
      CLUTTER_NOTE (EVENT, "Destroying the event source");

      event_sources = g_list_remove (event_sources,
                                     backend_x11->event_source);

      g_source_destroy (backend_x11->event_source);
      g_source_unref (backend_x11->event_source);
      backend_x11->event_source = NULL;
    }
}
Exemple #27
0
void
_clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen,
                                              guint32 event_mask,
                                              void *user_data)
{
  ClutterStageX11 *stage_x11 = user_data;
  ClutterStageCogl *stage_cogl = user_data;
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
  XSetWindowAttributes attrs;

  attrs.event_mask = event_mask | CLUTTER_STAGE_X11_EVENT_MASK;

  XChangeWindowAttributes (backend_x11->xdpy,
                           stage_x11->xwin,
                           CWEventMask,
                           &attrs);
}
/**
 * clutter_x11_get_visual_info: (skip)
 *
 * Retrieves the `XVisualInfo` used by the Clutter X11 backend.
 *
 * Return value: (transfer full): a `XVisualInfo`, or `None`.
 *   The returned value should be freed using `XFree()` when done
 *
 * Since: 1.2
 */
XVisualInfo *
clutter_x11_get_visual_info (void)
{
  ClutterBackendX11 *backend_x11;
  ClutterBackend *backend;

  backend = clutter_get_default_backend ();
  if (!CLUTTER_IS_BACKEND_X11 (backend))
    {
      g_critical ("The Clutter backend is not a X11 backend.");
      return NULL;
    }

  backend_x11 = CLUTTER_BACKEND_X11 (backend);

  return _clutter_backend_x11_get_visual_info (backend_x11);
}
/**
 * clutter_x11_remove_filter: (skip)
 * @func: a filter function
 * @data: user data to be passed to the filter function, or %NULL
 *
 * Removes the given filter function.
 *
 * Since: 0.6
 */
void
clutter_x11_remove_filter (ClutterX11FilterFunc func,
                           gpointer             data)
{
  GSList                *tmp_list, *this;
  ClutterX11EventFilter *filter;
  ClutterBackend *backend = clutter_get_default_backend ();
  ClutterBackendX11 *backend_x11;

  g_return_if_fail (func != NULL);

  if (backend == NULL)
    {
      g_critical ("The Clutter backend has not been initialised");
      return;
    }

  if (!CLUTTER_IS_BACKEND_X11 (backend))
    {
      g_critical ("The Clutter backend is not a X11 backend");
      return;
    }

  backend_x11 = CLUTTER_BACKEND_X11 (backend);

  tmp_list = backend_x11->event_filters;

  while (tmp_list)
    {
      filter   = tmp_list->data;
      this     =  tmp_list;
      tmp_list = tmp_list->next;

      if (filter->func == func && filter->data == data)
        {
          backend_x11->event_filters =
            g_slist_remove_link (backend_x11->event_filters, this);

          g_slist_free_1 (this);
          g_free (filter);

          return;
        }
    }
}
G_GNUC_END_IGNORE_DEPRECATIONS

gint
_clutter_keymap_x11_translate_key_state (ClutterKeymapX11    *keymap,
                                         guint                hardware_keycode,
                                         ClutterModifierType *modifier_state_p,
                                         ClutterModifierType *mods_p)
{
  ClutterBackendX11 *backend_x11;
  ClutterModifierType unconsumed_modifiers = 0;
  ClutterModifierType modifier_state = *modifier_state_p;
  gint retval;

  g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), 0);

  backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend);

#ifdef HAVE_XKB
  if (backend_x11->use_xkb)
    {
      XkbDescRec *xkb = get_xkb (keymap);
      KeySym tmp_keysym;

      if (XkbTranslateKeyCode (xkb, hardware_keycode, modifier_state,
                               &unconsumed_modifiers,
                               &tmp_keysym))
        {
          retval = tmp_keysym;
        }
      else
        retval = 0;
    }
  else
#endif /* HAVE_XKB */
    retval = translate_keysym (keymap, hardware_keycode);

  if (mods_p)
    *mods_p = unconsumed_modifiers;

  *modifier_state_p = modifier_state & ~(keymap->num_lock_mask |
                                         keymap->scroll_lock_mask |
                                         LockMask);

  return retval;
}