static void
art_cb (RBExtDBKey *key, const char *filename, GValue *data, MxFrame *frame)
{
    ClutterActor *image;
    GdkPixbuf *pixbuf;

    if (data == NULL || G_VALUE_HOLDS (data, GDK_TYPE_PIXBUF) == FALSE) {
        return;
    }

    clutter_threads_enter ();

    image = gtk_clutter_texture_new ();
    pixbuf = GDK_PIXBUF (g_value_get_object (data));
    gtk_clutter_texture_set_from_pixbuf (GTK_CLUTTER_TEXTURE (image), pixbuf, NULL);
    if (clutter_actor_get_height (image) > MAX_IMAGE_HEIGHT) {
        clutter_actor_set_height (image, MAX_IMAGE_HEIGHT);
        clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (image), TRUE);
    }
    if (clutter_actor_get_width (image) > MAX_IMAGE_HEIGHT) {
        clutter_actor_set_width (image, MAX_IMAGE_HEIGHT);
    }
    mx_bin_set_child (MX_BIN (frame), image);
    clutter_actor_show_all (CLUTTER_ACTOR (frame));

    clutter_threads_leave ();
}
static void
prev_clicked_cb (MxButton *button, RBShellPlayer *player)
{
    clutter_threads_leave ();
    rb_shell_player_do_previous (player, NULL);
    clutter_threads_enter ();
}
static void
playpause_clicked_cb (MxButton *button, RBShellPlayer *player)
{
    clutter_threads_leave ();
    rb_shell_player_playpause (player, FALSE, NULL);
    clutter_threads_enter ();
}
static void
update_track_info_lock (MxLabel *label, RhythmDB *db, RhythmDBEntry *entry, const char *streaming_title)
{
    clutter_threads_enter ();
    update_track_info (label, db, entry, streaming_title);
    clutter_threads_leave ();
}
static void
elapsed_changed_cb (RBShellPlayer *player, guint elapsed, ClutterActor *label)
{
    clutter_threads_enter ();
    update_elapsed (label, player, elapsed);
    clutter_threads_leave ();
}
static gboolean
clutter_event_source_wayland_dispatch (GSource *base,
				       GSourceFunc callback,
				       gpointer data)
{
  ClutterEventSourceWayland *source = (ClutterEventSourceWayland *) base;
  ClutterEvent *event;

  clutter_threads_enter ();

  if (source->pfd.revents)
    {
      wl_display_iterate (source->display, WL_DISPLAY_READABLE);
      source->pfd.revents = 0;
    }

  event = clutter_event_get ();

  if (event)
    {
      /* forward the event into clutter for emission etc. */
      clutter_do_event (event);
      clutter_event_free (event);
    }

  clutter_threads_leave ();

  return TRUE;
}
예제 #7
0
static gboolean
clutter_event_dispatch (GSource     *source,
                        GSourceFunc  callback,
                        gpointer     user_data)
{
  ClutterBackend *backend = ((ClutterEventSource *) source)->backend;
  ClutterEvent *event;

  clutter_threads_enter ();

  /*  Grab the event(s), translate and figure out double click.
   *  The push onto queue (stack) if valid.
  */
  events_queue (backend);

  /* Pop an event off the queue if any */
  event = clutter_event_get ();

  if (event)
    {
      /* forward the event into clutter for emission etc. */
      clutter_do_event (event);
      clutter_event_free (event);
    }

  clutter_threads_leave ();

  return TRUE;
}
static gboolean
clutter_event_dispatch (GSource     *source,
                        GSourceFunc  callback,
                        gpointer     user_data)
{
  ClutterEvent *event;
  MSG msg;

  clutter_threads_enter ();

  /* Process Windows messages until we've got one that translates into
     the clutter event queue */
  while (!clutter_events_pending () && PeekMessageW (&msg, NULL,
						     0, 0, PM_REMOVE))
      DispatchMessageW (&msg);

  /* Pop an event off the queue if any */
  if ((event = clutter_event_get ()))
    {
      /* forward the event into clutter for emission etc. */
      clutter_do_event (event);
      clutter_event_free (event);
    }

  clutter_threads_leave ();

  return TRUE;
}
예제 #9
0
/**
 * clutter_x11_handle_event:
 * @xevent: pointer to XEvent structure
 *
 * This function processes a single X event; it can be used to hook
 * into external X11 event processing (for example, a GDK filter
 * function).
 *
 * If clutter_x11_disable_event_retrieval() has been called, you must
 * let this function process events to update Clutter's internal state.
 *
 * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE
 *  indicates that Clutter has internally handled the event and the
 *  caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE
 *  indicates that Clutter is either not interested in the event,
 *  or has used the event to update internal state without taking
 *  any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not
 *  occur.
 *
 * Since: 0.8
 */
ClutterX11FilterReturn
clutter_x11_handle_event (XEvent *xevent)
{
  ClutterX11FilterReturn result;
  ClutterBackend *backend;
  ClutterEvent *event;
  gint spin = 1;

  /* The return values here are someone approximate; we return
   * CLUTTER_X11_FILTER_REMOVE if a clutter event is
   * generated for the event. This mostly, but not entirely,
   * corresponds to whether other event processing should be
   * excluded. As long as the stage window is not shared with another
   * toolkit it should be safe, and never return
   * %CLUTTER_X11_FILTER_REMOVE when more processing is needed.
   */

  result = CLUTTER_X11_FILTER_CONTINUE;

  clutter_threads_enter ();

  backend = clutter_get_default_backend ();

  event = clutter_event_new (CLUTTER_NOTHING);

  if (_clutter_backend_translate_event (backend, xevent, event))
    {
      _clutter_event_push (event, FALSE);

      result = CLUTTER_X11_FILTER_REMOVE;
    }
  else
    {
      clutter_event_free (event);
      goto out;
    }

  /*
   * Motion events can generate synthetic enter and leave events, so if we
   * are processing a motion event, we need to spin the event loop at least
   * two extra times to pump the enter/leave events through (otherwise they
   * just get pushed down the queue and never processed).
   */
  if (event->type == CLUTTER_MOTION)
    spin += 2;

  while (spin > 0 && (event = clutter_event_get ()))
    {
      /* forward the event into clutter for emission etc. */
      clutter_do_event (event);
      clutter_event_free (event);
      --spin;
    }

out:
  clutter_threads_leave ();

  return result;
}
예제 #10
0
static void
playing_changed_cb (RBShellPlayer *player, gboolean playing, MxButton *button)
{

    clutter_threads_enter ();
    update_playing (button, playing);
    clutter_threads_leave ();
}
예제 #11
0
static void on_stage_destroyed(gpointer *user_data)
{
    TempiClutterStageNode *self = (TempiClutterStageNode *) user_data;
    (void) self;

    clutter_threads_enter();
    clutter_main_quit();
    clutter_threads_leave();
}
static gboolean
stage_key_release_cb (ClutterActor *stage, ClutterEvent *event, RBVisualizerPage *page)
{
    if (event->key.keyval == CLUTTER_KEY_Escape) {
        clutter_threads_leave ();
        stop_fullscreen (page);
        clutter_threads_enter ();
    }
    return FALSE;
}
예제 #13
0
static void
cover_art_entry_changed_cb (RBShellPlayer *player, RhythmDBEntry *entry, MxFrame *frame)
{
    clutter_threads_enter ();
    set_blank_image (frame);
    clutter_actor_show_all (CLUTTER_ACTOR (frame));
    clutter_threads_leave ();

    request_cover_art (frame, entry);
}
예제 #14
0
static gboolean
clutter_clock_check (GSource *source)
{
  ClutterClockSource *clock_source = (ClutterClockSource *) source;
  ClutterMasterClock *master_clock = clock_source->master_clock;
  int delay;

  clutter_threads_enter ();
  delay = master_clock_next_frame_delay (master_clock);
  clutter_threads_leave ();

  return delay == 0;
}
static gboolean
stage_button_press_cb (ClutterActor *stage, ClutterEvent *event, RBVisualizerPage *page)
{
    if (event->button.button == 1 && event->button.click_count == 2) {
        clutter_threads_leave ();
        toggle_fullscreen (page);
        clutter_threads_enter ();
    } else if (event->button.button == 3) {
        rb_display_page_show_popup (RB_DISPLAY_PAGE (page));
    }

    return FALSE;
}
static gboolean
clutter_event_source_wayland_check (GSource *base)
{
  ClutterEventSourceWayland *source = (ClutterEventSourceWayland *) base;
  gboolean retval;

  clutter_threads_enter ();

  retval = clutter_events_pending () || source->pfd.revents;

  clutter_threads_leave ();

  return retval;
}
static gboolean
clutter_event_prepare (GSource *source,
                       gint    *timeout)
{
  gboolean retval;

  clutter_threads_enter ();

  *timeout = -1;
  retval = (clutter_events_pending () || check_msg_pending ());

  clutter_threads_leave ();

  return retval;
}
예제 #18
0
void
rb_visualizer_fullscreen_add_widgets (GtkWidget *window, ClutterActor *stage, RBShell *shell)
{
    ClutterActor *track_info;
    ClutterActor *controls;
    GdkScreen *screen;
    GdkRectangle geom;
    int x;
    int y;
    int monitor;

    clutter_threads_enter ();

    /* get geometry for the monitor we're going to appear on */
    screen = gtk_widget_get_screen (window);
    monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (window));
    gdk_screen_get_monitor_geometry (screen, monitor, &geom);

    /* create and place the track info display */
    track_info = create_track_info (shell);

    clutter_container_add_actor (CLUTTER_CONTAINER (stage), track_info);
    g_object_set_data (G_OBJECT (stage), TRACK_INFO_DATA, track_info);

    /* XXX rtl? */
    clutter_actor_set_position (track_info, FULLSCREEN_BORDER_WIDTH, FULLSCREEN_BORDER_WIDTH);

    /* create and place the playback controls */
    controls = create_controls (shell);
    clutter_container_add_actor (CLUTTER_CONTAINER (stage), controls);
    g_object_set_data (G_OBJECT (stage), CONTROLS_DATA, controls);

    /* put this bit somewhere near the bottom */
    /* XXX rtl */
    x = FULLSCREEN_BORDER_WIDTH;
    y = geom.height - (clutter_actor_get_height (controls) + FULLSCREEN_BORDER_WIDTH);
    clutter_actor_set_position (controls, x, y);

    /* hide mouse cursor when not moving, hide playback controls when mouse not moving
     * and outside them
     */
    g_signal_connect_object (stage, "motion-event", G_CALLBACK (stage_motion_event_cb), controls, 0);
    g_signal_connect (controls, "leave-event", G_CALLBACK (controls_leave_event_cb), NULL);
    g_signal_connect (controls, "enter-event", G_CALLBACK (controls_enter_event_cb), NULL);
    start_hide_timer (controls);

    clutter_threads_leave ();
}
예제 #19
0
static gboolean
clutter_clock_prepare (GSource *source,
                       gint    *timeout)
{
  ClutterClockSource *clock_source = (ClutterClockSource *) source;
  ClutterMasterClock *master_clock = clock_source->master_clock;
  int delay;

  clutter_threads_enter ();
  delay = master_clock_next_frame_delay (master_clock);
  clutter_threads_leave ();

  *timeout = delay;

  return delay == 0;
}
예제 #20
0
static gboolean
clutter_event_prepare (GSource *source,
                       gint    *timeout)
{
  ClutterBackend *backend = ((ClutterEventSource *) source)->backend;
  gboolean retval;

  clutter_threads_enter ();

  *timeout = -1;
  retval = (clutter_events_pending () || check_xpending (backend));

  clutter_threads_leave ();

  return retval;
}
static gboolean
clutter_event_check (GSource *source)
{
  ClutterEventSource *event_source = (ClutterEventSource *) source;
  gboolean retval;

  clutter_threads_enter ();

  if ((event_source->event_poll_fd.revents & G_IO_IN))
    retval = (clutter_events_pending () || check_msg_pending ());
  else
    retval = FALSE;

  clutter_threads_leave ();

  return retval;
}
static gboolean
clutter_event_source_wayland_prepare (GSource *base, gint *timeout)
{
  ClutterEventSourceWayland *source = (ClutterEventSourceWayland *) base;
  gboolean retval;

  clutter_threads_enter ();

  *timeout = -1;

  /* We have to add/remove the GPollFD if we want to update our
   * poll event mask dynamically.  Instead, let's just flush all
   * writes on idle */
  wl_display_flush (source->display);

  retval = clutter_events_pending ();

  clutter_threads_leave ();

  return retval;
}
예제 #23
0
// starts the thread
void Worker::operator()()
{
    StageManager::ptr manager;

    g_thread_init(NULL);
    clutter_threads_init();

    int argc = 0;
    char **argv = NULL;

    if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS)
    {
        std::cerr << __FUNCTION__ << "(): Error calling clutter_init()\n";
        return;
    }
    clutter_threads_enter();

    manager->initStage();

    clutter_main();

    clutter_threads_leave();
    return; // done with this thread
}
예제 #24
0
int
main (int argc, char *argv[])
{
  ClutterActor *stage;
  ClutterActor *rect;
  ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
  ClutterColor rect_color = { 0xee, 0x55, 0x55, 0x99 };
  ClutterColor progress_color = { 0x55, 0xee, 0x55, 0xbb };
  ClutterBehaviour *r_behaviour, *p_behaviour;
  const ClutterKnot knots[] = {
    {  75, 150 },
    { 400, 150 }
  };

  g_thread_init (NULL);
  clutter_threads_init ();
  clutter_init (&argc, &argv);

  stage = clutter_stage_get_default ();
  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
  clutter_actor_set_size (stage, 600, 300);
  
  count_label = clutter_label_new_with_text ("Mono 12", "Counter");
  clutter_actor_set_position (count_label, 350, 50);

  help_label = clutter_label_new_with_text ("Mono 12", "Press 's' to start");
  clutter_actor_set_position (help_label, 50, 50);

  rect = clutter_rectangle_new_with_color (&rect_color);
  clutter_actor_set_position (rect, 75, 150);
  clutter_actor_set_size (rect, 50, 50);
  clutter_actor_set_anchor_point (rect, 25, 25);

  progress_rect = clutter_rectangle_new_with_color (&progress_color);
  clutter_actor_set_position (progress_rect, 50, 225);
  clutter_actor_set_size (progress_rect, 350, 50);

  clutter_container_add (CLUTTER_CONTAINER (stage),
                         count_label, help_label,
                         rect, progress_rect,
                         NULL);

  timeline = clutter_timeline_new (150, 50);
  clutter_timeline_set_loop (timeline, TRUE);
  r_behaviour = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
                                                                      CLUTTER_ALPHA_RAMP_INC,
                                                                      NULL, NULL),
                                              CLUTTER_Z_AXIS,
                                              CLUTTER_ROTATE_CW,
                                              0.0, 360.0);
  clutter_behaviour_apply (r_behaviour, rect);

  p_behaviour = clutter_behaviour_path_new (clutter_alpha_new_full (timeline,
                                                                    CLUTTER_ALPHA_SINE,
                                                                    NULL, NULL),
                                            knots,
                                            G_N_ELEMENTS (knots));
  clutter_behaviour_apply (p_behaviour, rect);

  g_signal_connect (stage,
                    "button-press-event", G_CALLBACK (clutter_main_quit),
                    NULL);
  g_signal_connect (stage,
                    "key-press-event", G_CALLBACK (on_key_press_event),
                    NULL);

  clutter_actor_show (stage);

  clutter_threads_enter ();
  clutter_main ();
  clutter_threads_leave ();

  g_object_unref (p_behaviour);
  g_object_unref (r_behaviour);
  g_object_unref (timeline);

  return EXIT_SUCCESS;
}
예제 #25
0
int main(int argc, char *argv[])
{
    ClutterActor *stage;
    WebKitWebView *web_view;
    
    ClutterConstraint *width_binding;
    ClutterConstraint *height_binding;
    ClutterConstraint *web_view_height_binding;
    
    gfloat stageWidth, stageHeight;
    ClutterActorBox stageAllocation;
    
    ClutterLayoutManager  *mainLayout;
    ClutterActor          *mainLayoutContainer;
    ClutterLayoutManager  *toolbarLayout;
    ClutterActor          *toolbarContainer;
    ClutterLayoutManager  *toolbarBinLayout;
    ClutterActor          *toolbarBinContainer;
    ClutterActor          *toolbarBgr;
    ClutterActor          *statusBar;
    ClutterActor *backFwdBtns;
    ClutterActor *backBtn;
    ClutterActor *fwdBtn;
    ClutterActor *uriGroup;
    ClutterActor *uriBgr;
    ClutterActor *uriText;
    ClutterActor *spacer;
    
    GError *error = NULL;
    
    ClutterColor whiteColor = { 255, 255, 255, 255 };
    ClutterColor blackColor = { 0, 0, 0, 255 };
    ClutterColor grayColor =  { 200, 200, 200, 255 };
    ClutterColor transparentColor = { 0, 0, 0, 0 };
    
    gchar *toolbarBgrPath = clutter_launcher_file_path("toolbar_bgr.png");
    gchar *backBtnPath = clutter_launcher_file_path("back_btn.png");
    gchar *fwdBtnPath = clutter_launcher_file_path("fwd_btn.png");
    
    g_thread_init(NULL);
    clutter_threads_init();
    
    clutter_init(&argc, &argv);
    
    stage = clutter_stage_get_default();
    clutter_actor_set_size(stage, 1024, 768);
    clutter_stage_set_color(CLUTTER_STAGE(stage), &stage_color);
    g_signal_connect (stage, "destroy", G_CALLBACK(clutter_main_quit), NULL);
    
    /* make the stage resizable */
    clutter_stage_set_user_resizable(CLUTTER_STAGE(stage), TRUE);
    
    clutter_actor_show(stage);
    
    mainLayout = clutter_box_layout_new();
    clutter_box_layout_set_vertical(CLUTTER_BOX_LAYOUT(mainLayout), TRUE);
    
    
    clutter_actor_get_allocation_box(stage, &stageAllocation);
    stageWidth = stageAllocation.x2 - stageAllocation.x1;
    stageHeight = stageAllocation.y2 - stageAllocation.y1;
    
    web_view = WEBKIT_WEB_VIEW(webkit_web_view_new((guint)stageWidth, (guint)stageHeight - (toolbarHeight + statusBarHeight)));
    g_object_set(web_view, "reactive", TRUE, NULL);
    
    mainLayoutContainer = clutter_box_new(mainLayout);
    clutter_actor_set_size(mainLayoutContainer, stageWidth, stageHeight);
    
    width_binding = clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0);
    height_binding = clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0);
/*    web_view_height_binding = clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, -(toolbarHeight + statusBarHeight));
  */  
    clutter_actor_add_constraint(mainLayoutContainer, width_binding);
    clutter_actor_add_constraint(mainLayoutContainer, height_binding);
/*    clutter_actor_add_constraint(CLUTTER_ACTOR(web_view), web_view_height_binding);
  */  
    toolbarBinLayout = clutter_bin_layout_new(CLUTTER_BIN_ALIGNMENT_FILL, CLUTTER_BIN_ALIGNMENT_CENTER);
    toolbarBinContainer = clutter_box_new(toolbarBinLayout);
    
    toolbarBgr = clutter_texture_new_from_file(toolbarBgrPath, &error);
    if (toolbarBgr == NULL) {
      fprintf(stderr, "Can't load file: %s. Aborting...\n", toolbarBgrPath);
      exit(1);
    }
    clutter_actor_set_height(toolbarBgr, toolbarHeight);
    clutter_texture_set_repeat(CLUTTER_TEXTURE(toolbarBgr), TRUE, FALSE);
    clutter_box_pack(CLUTTER_BOX(toolbarBinContainer), toolbarBgr, NULL, NULL);
    
    toolbarLayout = clutter_box_layout_new();
    clutter_box_layout_set_vertical(CLUTTER_BOX_LAYOUT(toolbarLayout), FALSE);
    clutter_box_layout_set_spacing(CLUTTER_BOX_LAYOUT(toolbarLayout), 16);
    toolbarContainer = clutter_box_new(toolbarLayout);
    
    spacer = clutter_rectangle_new_with_color(&transparentColor);
    clutter_actor_set_size(spacer, 1, 1);
    clutter_box_pack(CLUTTER_BOX(toolbarContainer), spacer, NULL, NULL);
    
    backFwdBtns = clutter_group_new();
    
    backBtn = clutter_texture_new_from_file(backBtnPath, &error);
    if (backBtn == NULL) {
      fprintf(stderr, "Can't load file: %s. Aborting...\n", backBtnPath);
      exit(1);
    }
    clutter_actor_set_reactive(backBtn, TRUE);
    /* connect the release event */
    g_signal_connect (backBtn,
                      "button-release-event",
                      G_CALLBACK (on_back_release_cb),
                      web_view);
    
    fwdBtn = clutter_texture_new_from_file(fwdBtnPath, &error);
    if (fwdBtn == NULL) {
      fprintf(stderr, "Can't load file: %s. Aborting...\n", fwdBtnPath);
      exit(1);
    }
    clutter_actor_set_reactive(fwdBtn, TRUE);
    /* connect the release event */
    g_signal_connect (fwdBtn,
                      "button-release-event",
                      G_CALLBACK (on_fwd_release_cb),
                      web_view);
    
    clutter_actor_set_position(fwdBtn, 
                               clutter_actor_get_width(backBtn), 0);
    clutter_container_add(CLUTTER_CONTAINER(backFwdBtns), backBtn, fwdBtn, NULL);
    clutter_box_pack(CLUTTER_BOX(toolbarContainer), backFwdBtns, NULL, NULL);
    
    uriGroup = clutter_group_new();
    
    uriBgr = clutter_rectangle_new_with_color(&whiteColor);
    clutter_rectangle_set_border_color(CLUTTER_RECTANGLE(uriBgr), &blackColor);
    clutter_rectangle_set_border_width(CLUTTER_RECTANGLE(uriBgr), 1);
    clutter_actor_set_size(uriBgr, 400, 25);
    
    uriText = clutter_text_new_full("Helvetica 11px", "http://www.google.com", &blackColor);
    clutter_text_set_editable(CLUTTER_TEXT(uriText), TRUE);
    clutter_text_set_single_line_mode(CLUTTER_TEXT(uriText), TRUE);
    clutter_actor_set_position(uriText, 5, 7);
    clutter_actor_set_size(uriText, 390, 17);
    clutter_actor_set_reactive(uriText, TRUE);
    g_signal_connect(uriText, "activate", G_CALLBACK(on_uri_activate_cb), web_view);
    
    clutter_container_add(CLUTTER_CONTAINER(uriGroup), uriBgr, uriText, NULL);
    clutter_box_pack(CLUTTER_BOX(toolbarContainer), uriGroup, NULL, NULL);
    
    clutter_box_pack(CLUTTER_BOX(toolbarBinContainer), toolbarContainer, NULL, NULL);
    
    clutter_box_pack(CLUTTER_BOX(mainLayoutContainer), toolbarBinContainer, 
                     "y-align", CLUTTER_BOX_ALIGNMENT_START, NULL);
    clutter_box_layout_set_expand(CLUTTER_BOX_LAYOUT(mainLayout), toolbarBinContainer, TRUE);
    clutter_box_layout_set_fill(CLUTTER_BOX_LAYOUT(mainLayout), toolbarBinContainer, TRUE, FALSE);
    
    statusBar = clutter_rectangle_new_with_color(&grayColor);
    clutter_actor_set_height(statusBar, statusBarHeight);
    
    clutter_box_pack(CLUTTER_BOX(mainLayoutContainer), statusBar, 
                     "y-align", CLUTTER_BOX_ALIGNMENT_END, NULL);
    clutter_box_layout_set_expand(CLUTTER_BOX_LAYOUT(mainLayout), statusBar, TRUE);
    clutter_box_layout_set_fill(CLUTTER_BOX_LAYOUT(mainLayout), statusBar, TRUE, FALSE);
    
    clutter_box_pack_after(CLUTTER_BOX(mainLayoutContainer), CLUTTER_ACTOR(web_view), toolbarBinContainer, 
                           "y-align", CLUTTER_BOX_ALIGNMENT_START, NULL);
    clutter_box_layout_set_expand(CLUTTER_BOX_LAYOUT(mainLayout), CLUTTER_ACTOR(web_view), TRUE);
    clutter_box_layout_set_fill(CLUTTER_BOX_LAYOUT(mainLayout), CLUTTER_ACTOR(web_view), TRUE, TRUE);

    clutter_container_add(CLUTTER_CONTAINER(stage), mainLayoutContainer, NULL);
    
    g_signal_connect(web_view, "webkit-load-finished", G_CALLBACK(load_finished_cb), web_view);
    g_signal_connect(web_view, "notify::progress", G_CALLBACK (notify_progress_cb), web_view);
    /*    g_signal_connect(stage, "delete-event", G_CALLBACK(delete_cb), web_view);*/
    g_signal_connect(web_view, "notify::uri", G_CALLBACK(notify_uri_cb), uriText);
    
    gchar *uri = (gchar*) (argc > 1 ? argv[1] : "http://www.google.com/");
    gchar *fileURL = filenameToURL(uri);

    webkit_web_view_load_uri(web_view, fileURL ? fileURL : uri);
    printf("%s\n", fileURL ? fileURL : uri);
    g_free(fileURL);
        
    g_timeout_add_full(G_PRIORITY_DEFAULT, 3000, timeout_cb, web_view, 0);
    
    clutter_threads_enter ();
    clutter_main();
    clutter_threads_leave ();
    
    return EXIT_SUCCESS;
}
예제 #26
0
파일: IoClutter.c 프로젝트: akimd/io
IO_METHOD(IoClutter, threadLeave) {
    clutter_threads_leave();
    return self;
}
예제 #27
0
/**
 * clutter_x11_handle_event:
 * @xevent: pointer to XEvent structure
 *
 * This function processes a single X event; it can be used to hook
 * into external X event retrieval (for example that done by GDK).
 *
 * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE
 *  indicates that Clutter has internally handled the event and the
 *  caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE
 *  indicates that Clutter is either not interested in the event,
 *  or has used the event to update internal state without taking
 *  any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not
 *  occur.
 *
 * Since:  0.8
 */
ClutterX11FilterReturn
clutter_x11_handle_event (XEvent *xevent)
{
  ClutterBackend      *backend;
  ClutterBackendX11Class *backend_x11_class;
  ClutterEvent        *event;
  ClutterMainContext  *clutter_context;
  ClutterX11FilterReturn result;
  gint                 spin = 1;

  /* The return values here are someone approximate; we return
   * CLUTTER_X11_FILTER_REMOVE if a clutter event is
   * generated for the event. This mostly, but not entirely,
   * corresponds to whether other event processing should be
   * excluded. As long as the stage window is not shared with another
   * toolkit it should be safe, and never return
   * %CLUTTER_X11_FILTER_REMOVE when more processing is needed.
   */

  result = CLUTTER_X11_FILTER_CONTINUE;

  clutter_threads_enter ();

  clutter_context = _clutter_context_get_default ();
  backend = clutter_context->backend;
  backend_x11_class = CLUTTER_BACKEND_X11_GET_CLASS (backend);

  /* If the backend just observed the event and didn't want it
   * removed it could return FALSE, so assume that a TRUE return
   * means that our caller should also do no further processing. */
  if (backend_x11_class->handle_event (CLUTTER_BACKEND_X11(backend), xevent))
    return CLUTTER_X11_FILTER_REMOVE;

  event = clutter_event_new (CLUTTER_NOTHING);

  if (event_translate (backend, event, xevent))
    {
      /* push directly here to avoid copy of queue_put */
      result = CLUTTER_X11_FILTER_REMOVE;
      g_queue_push_head (clutter_context->events_queue, event);
    }
  else
    {
      clutter_event_free (event);
      goto out;
    }

  /*
   * Motion events can generate synthetic enter and leave events, so if we
   * are processing a motion event, we need to spin the event loop at least
   * two extra times to pump the enter/leave events through (otherwise they
   * just get pushed down the queue and never processed).
   */
  if (event->type == CLUTTER_MOTION)
    spin += 2;

  while (spin > 0 && (event = clutter_event_get ()))
    {
      /* forward the event into clutter for emission etc. */
      clutter_do_event (event);
      clutter_event_free (event);
      --spin;
    }

 out:
  clutter_threads_leave ();

  return result;
}
예제 #28
0
static gboolean
clutter_clock_dispatch (GSource     *source,
                        GSourceFunc  callback,
                        gpointer     user_data)
{
  ClutterClockSource *clock_source = (ClutterClockSource *) source;
  ClutterMasterClock *master_clock = clock_source->master_clock;
  ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
  gboolean stages_updated = FALSE;
  GSList *stages, *l;

  CLUTTER_STATIC_TIMER (master_dispatch_timer,
                        "Mainloop",
                        "Master Clock",
                        "Master clock dispatch",
                        0);
  CLUTTER_STATIC_TIMER (master_event_process,
                        "Master Clock",
                        "Event Processing",
                        "The time spent processing events on all stages",
                        0);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_dispatch_timer);

  CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");

  clutter_threads_enter ();

  /* Get the time to use for this frame */
#if GLIB_CHECK_VERSION (2, 27, 3)
  master_clock->cur_tick = g_source_get_time (source);
#else
  {
    GTimeVal source_time;
    g_source_get_current_time (source, &source_time);
    master_clock->cur_tick = source_time.tv_sec * 1000000L
                           + source_time.tv_usec;
  }
#endif

  /* We need to protect ourselves against stages being destroyed during
   * event handling
   */
  stages = clutter_stage_manager_list_stages (stage_manager);
  g_slist_foreach (stages, (GFunc) g_object_ref, NULL);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_event_process);

  master_clock->idle = FALSE;

  /* Process queued events */
  for (l = stages; l != NULL; l = l->next)
    {
      /* NB: If a stage is busy waiting for a swap-buffers completion then
       * we don't process its events so we can maximize the benefits of
       * motion compression, and avoid multiple picks per frame.
       */
      if (_clutter_stage_get_pending_swaps (l->data) == 0)
        _clutter_stage_process_queued_events (l->data);
    }

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);

  _clutter_master_clock_advance (master_clock);

  _clutter_run_repaint_functions ();

  /* Update any stage that needs redraw/relayout after the clock
   * is advanced.
   */
  for (l = stages; l != NULL; l = l->next)
    {
      /* If a stage has a swap-buffers pending we don't want to draw to it
       * in case the driver may block the CPU while it waits for the next
       * backbuffer to become available.
       *
       * TODO: We should be able to identify if we are running triple or N
       * buffered and in these cases we can still draw if there is 1 swap
       * pending so we can hopefully always be ready to swap for the next
       * vblank and really match the vsync frequency.
       */
      if (_clutter_stage_get_pending_swaps (l->data) == 0)
        stages_updated |= _clutter_stage_do_update (l->data);
    }

  /* The master clock goes idle if no stages were updated and falls back
   * to polling for timeline progressions... */
  if (!stages_updated)
    master_clock->idle = TRUE;

  g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
  g_slist_free (stages);

  master_clock->prev_tick = master_clock->cur_tick;

  clutter_threads_leave ();

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_dispatch_timer);

  return TRUE;
}
예제 #29
0
파일: cluttershare.c 프로젝트: zsx/ossbuild
int
main (int argc, char *argv[])
{
  GLenum err = 0;
#ifdef WIN32
  HGLRC clutter_gl_context = 0;
  HDC clutter_dc = 0;
#else
  Display *clutter_display = NULL;
  Window clutter_win = 0;
  GLXContext clutter_gl_context = NULL;
#endif
  GstPipeline *pipeline = NULL;
  GstBus *bus = NULL;
  GstElement *glupload = NULL;
  GstState state = 0;
  ClutterActor *stage = NULL;
  ClutterActor *clutter_texture = NULL;
  GAsyncQueue *queue_input_buf = NULL;
  GAsyncQueue *queue_output_buf = NULL;
  GstElement *fakesink = NULL;

  /* init gstreamer then clutter */

  gst_init (&argc, &argv);
  clutter_threads_init ();
  clutter_init (&argc, &argv);
  clutter_threads_enter ();
  g_print ("clutter version: %s\n", CLUTTER_VERSION_S);

  /* init glew */

  err = glewInit ();
  if (err != GLEW_OK)
    g_debug ("failed to init GLEW: %s", glewGetErrorString (err));

  /* avoid to dispatch unecesary events */

  clutter_ungrab_keyboard ();
  clutter_ungrab_pointer ();

  /* retrieve and turn off clutter opengl context */

  stage = clutter_stage_get_default ();

  /* retrieve and turn off clutter opengl context */

#ifdef WIN32
  clutter_gl_context = wglGetCurrentContext ();
  clutter_dc = wglGetCurrentDC ();
  wglMakeCurrent (0, 0);
#else
  clutter_display = clutter_x11_get_default_display ();
  clutter_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
  clutter_gl_context = glXGetCurrentContext ();
  glXMakeCurrent (clutter_display, None, 0);
#endif

  /* setup gstreamer pipeline */

  pipeline =
      GST_PIPELINE (gst_parse_launch
      ("videotestsrc ! video/x-raw-yuv, width=320, height=240, framerate=(fraction)30/1 ! "
          "glupload ! gleffects effect=5 ! glfiltercube ! fakesink sync=1",
          NULL));

  /* setup bus */

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message::error", G_CALLBACK (end_stream_cb), NULL);
  g_signal_connect (bus, "message::warning", G_CALLBACK (end_stream_cb), NULL);
  g_signal_connect (bus, "message::eos", G_CALLBACK (end_stream_cb), NULL);
  gst_object_unref (bus);

  /* clutter_gl_context is an external OpenGL context with which gst-plugins-gl want to share textures */

  glupload = gst_bin_get_by_name (GST_BIN (pipeline), "glupload0");
  g_object_set (G_OBJECT (glupload), "external-opengl-context",
      clutter_gl_context, NULL);
  g_object_unref (glupload);

  /* NULL to PAUSED state pipeline to make sure the gst opengl context is created and
   * shared with the clutter one */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
  state = GST_STATE_PAUSED;
  if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
          GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
    g_debug ("failed to pause pipeline\n");
    return -1;
  }

  /* turn on back clutter opengl context */

#ifdef WIN32
  wglMakeCurrent (clutter_dc, clutter_gl_context);
#else
  glXMakeCurrent (clutter_display, clutter_win, clutter_gl_context);
#endif

  /* clutter stage */

  clutter_actor_set_size (stage, 640, 480);
  clutter_actor_set_position (stage, 0, 0);
  clutter_stage_set_title (CLUTTER_STAGE (stage), "clutter and gst-plugins-gl");
  clutter_texture = setup_stage (CLUTTER_STAGE (stage));

  /* append a gst-gl texture to this queue when you do not need it no more */

  queue_input_buf = g_async_queue_new ();
  queue_output_buf = g_async_queue_new ();
  g_object_set_data (G_OBJECT (clutter_texture), "queue_input_buf",
      queue_input_buf);
  g_object_set_data (G_OBJECT (clutter_texture), "queue_output_buf",
      queue_output_buf);

  /* set a callback to retrieve the gst gl textures */

  fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
  g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
  g_signal_connect (fakesink, "handoff", G_CALLBACK (on_gst_buffer),
      clutter_texture);
  g_object_unref (fakesink);

  /* play gst */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  /* main loop */

  clutter_main ();

  /* before to deinitialize the gst-gl-opengl context,
   * no shared context (here the clutter one) must be current
   */
#ifdef WIN32
  wglMakeCurrent (0, 0);
#else
  glXMakeCurrent (clutter_display, None, 0);
#endif

  clutter_threads_leave ();

  /* stop and clean up the pipeline */

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  g_object_unref (pipeline);

  /* make sure there is no pending gst gl buffer in the communication queues 
   * between clutter and gst-gl
   */

  while (g_async_queue_length (queue_input_buf) > 0) {
    GstBuffer *buf = g_async_queue_pop (queue_input_buf);
    gst_buffer_unref (buf);
  }

  while (g_async_queue_length (queue_output_buf) > 0) {
    GstBuffer *buf = g_async_queue_pop (queue_output_buf);
    gst_buffer_unref (buf);
  }

  return 0;
}