コード例 #1
0
ファイル: call.c プロジェクト: boucman/darktable
int dt_lua_gtk_wrap(lua_State*L)
{ 
  lua_pushvalue(L,lua_upvalueindex(1));
  lua_insert(L,1);
  if(pthread_equal(darktable.control->gui_thread, pthread_self())) {
    return dt_lua_do_chunk_raise(L,lua_gettop(L)-1,LUA_MULTRET);
  } else {
    dt_lua_unlock();
    gtk_wrap_communication communication;
    g_mutex_init(&communication.end_mutex);
    g_cond_init(&communication.end_cond);
    communication.L = L;
    g_mutex_lock(&communication.end_mutex);
    g_main_context_invoke(NULL,dt_lua_gtk_wrap_callback,&communication);
    g_cond_wait(&communication.end_cond,&communication.end_mutex);
    g_mutex_unlock(&communication.end_mutex);
    g_mutex_clear(&communication.end_mutex);
    dt_lua_lock();
    if(communication.retval == LUA_OK) {
      return lua_gettop(L);
    } else {
      return lua_error(L);
    }
  }

}
コード例 #2
0
ファイル: control.c プロジェクト: CoreyChen922/darktable
void dt_ctl_switch_mode_to(const char *mode)
{
  const dt_view_t *current_view = dt_view_manager_get_current_view(darktable.view_manager);
  if(current_view && !strcmp(mode, current_view->module_name)) return;

  g_main_context_invoke(NULL, _dt_ctl_switch_mode_to, (gpointer)mode);
}
コード例 #3
0
ファイル: session.c プロジェクト: klauspetersen/trace_fast
/**
 * Stop a session.
 *
 * This requests the drivers of each device participating in the session to
 * abort the acquisition as soon as possible. Even after this function returns,
 * event processing still continues until all devices have actually stopped.
 *
 * Use sr_session_stopped_callback_set() to receive notification when the event
 * processing finished.
 *
 * This function is reentrant. That is, it may be called from a different
 * thread than the one executing the session, as long as it can be ensured
 * that the session object is valid.
 *
 * If the session is not running, sr_session_stop() silently does nothing.
 *
 * @param session The session to use. Must not be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid session passed.
 *
 * @since 0.4.0
 */
SR_API int sr_session_stop(struct sr_session *session)
{
	GMainContext *main_context;

	if (!session) {
		sr_err("%s: session was NULL", __func__);
		return SR_ERR_ARG;
	}

	g_mutex_lock(&session->main_mutex);

	main_context = (session->main_context)
		? g_main_context_ref(session->main_context)
		: NULL;

	g_mutex_unlock(&session->main_mutex);

	if (!main_context) {
		sr_dbg("No main context set; already stopped?");
		/* Not an error; as it would be racy. */
		return SR_OK;
	}
	g_main_context_invoke(main_context, &session_stop_sync, session);
	g_main_context_unref(main_context);

	return SR_OK;
}
コード例 #4
0
static GstFlowReturn
grd_vnc_sink_render (GstBaseSink *base_sink,
                     GstBuffer   *buffer)
{
  GrdVncSink *vnc_sink = GRD_VNC_SINK (base_sink);
  GrdSession *session;
  GrdContext *context;

  if (!vnc_sink->session_vnc)
    return GST_FLOW_OK;

  session = GRD_SESSION (vnc_sink->session_vnc);
  context = grd_session_get_context (session);

  g_mutex_lock (&vnc_sink->lock);
  g_clear_pointer (&vnc_sink->pending_buffer, gst_buffer_unref);
  vnc_sink->pending_buffer = gst_buffer_ref (buffer);
  g_mutex_unlock (&vnc_sink->lock);

  g_main_context_invoke (grd_context_get_main_context (context),
                         (GSourceFunc) grd_vnc_sink_render_on_main_thread,
                         gst_object_ref (vnc_sink));

  return GST_FLOW_OK;
}
コード例 #5
0
ファイル: call.c プロジェクト: rgo/darktable
static int gtk_wrap(lua_State*L)
{ 
  lua_pushvalue(L,lua_upvalueindex(1));
  lua_insert(L,1);
  if(pthread_equal(darktable.control->gui_thread, pthread_self())) {
    lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
    return lua_gettop(L);
  } else {
#ifdef _DEBUG
    dt_print(DT_DEBUG_LUA, "LUA DEBUG : %s called from %s %llu\n", __FUNCTION__,
             lua_tostring(L, lua_upvalueindex(2)), lua_tointeger(L, lua_upvalueindex(3)));
#endif
    dt_lua_unlock();
    gtk_wrap_communication communication;
    g_mutex_init(&communication.end_mutex);
    g_cond_init(&communication.end_cond);
    communication.L = L;
    g_mutex_lock(&communication.end_mutex);
    g_main_context_invoke(NULL,dt_lua_gtk_wrap_callback,&communication);
    g_cond_wait(&communication.end_cond,&communication.end_mutex);
    g_mutex_unlock(&communication.end_mutex);
    g_mutex_clear(&communication.end_mutex);
    dt_lua_lock();
#ifdef _DEBUG
    dt_print(DT_DEBUG_LUA, "LUA DEBUG : %s return for call from from %s %llu\n", __FUNCTION__,
             lua_tostring(L, lua_upvalueindex(2)), lua_tointeger(L, lua_upvalueindex(3)));
#endif
    if(communication.retval == LUA_OK) {
      return lua_gettop(L);
    } else {
      return lua_error(L);
    }
  }

}
コード例 #6
0
ファイル: control.c プロジェクト: AdamMajer/darktable
void dt_ctl_switch_mode_to(dt_control_gui_mode_t mode)
{
  dt_control_gui_mode_t oldmode = dt_conf_get_int("ui_last/view");
  if(oldmode == mode) return;

  g_main_context_invoke(NULL, _dt_ctl_switch_mode_to, GINT_TO_POINTER(mode));
}
コード例 #7
0
ファイル: callbacks.c プロジェクト: pwmt/zathura
void
cb_file_monitor(ZathuraFileMonitor* monitor, girara_session_t* session)
{
  g_return_if_fail(monitor  != NULL);
  g_return_if_fail(session  != NULL);

  g_main_context_invoke(NULL, file_monitor_reload, session);
}
コード例 #8
0
ファイル: thread.c プロジェクト: Fedict/eid-mw
void g_object_set_threaded_gvalue(GObject* obj, const gchar* property, GValue* value, void(*freefunc)(void*)) {
	struct gost_helper* help = malloc(sizeof(struct gost_helper));
	help->obj = obj;
	help->name = property;
	help->value = value;
	help->free = freefunc;
	g_main_context_invoke(NULL, gostv_helper, help);
}
コード例 #9
0
ファイル: midi.c プロジェクト: denemo/denemo
static gboolean
update_playbutton_callback (gboolean paused)
{

  g_main_context_invoke (NULL, (GSourceFunc)do_set_playbutton, GINT_TO_POINTER(paused));

  return FALSE;
}
コード例 #10
0
ファイル: thread.c プロジェクト: Fedict/eid-mw
void g_object_set_data_threaded(GObject* obj, const gchar* key, void* value, void(*freefunc)(void*)) {
	struct gost_helper *help = malloc(sizeof(struct gost_helper));
	help->obj = obj;
	help->name = key;
	help->value = value;
	help->free = freefunc;
	g_main_context_invoke(NULL, gosdt_helper, help);
}
コード例 #11
0
ファイル: signal.c プロジェクト: acarrasco/darktable
void dt_control_signal_raise(const dt_control_signal_t *ctlsig, dt_signal_t signal, ...)
{
  // ignore all signals on shutdown
  if(!dt_control_running()) return;

  dt_signal_description *signal_description = &_signal_description[signal];

  _signal_param_t *params = (_signal_param_t *)malloc(sizeof(_signal_param_t));
  if(!params) return;

  GValue *instance_and_params = calloc(1 + signal_description->n_params, sizeof(GValue));
  if(!instance_and_params)
  {
    free(params);
    return;
  }

  // 0th element has to be the instance to call
  g_value_init(instance_and_params, _signal_type);
  g_value_set_object(instance_and_params, ctlsig->sink);

  // the rest of instance_and_params will be the params for the callback
  va_list extra_args;
  va_start(extra_args, signal);

  for(int i = 1; i <= signal_description->n_params; i++)
  {
    GType type = signal_description->param_types[i-1];
    g_value_init(&instance_and_params[i], type);
    switch(type)
    {
      case G_TYPE_UINT:
        g_value_set_uint(&instance_and_params[i], va_arg(extra_args, guint));
        break;
      case G_TYPE_STRING:
        g_value_set_string(&instance_and_params[i], va_arg(extra_args, const char *));
        break;
      case G_TYPE_POINTER:
        g_value_set_pointer(&instance_and_params[i], va_arg(extra_args, void *));
        break;
      default:
        fprintf(stderr, "error: unsupported parameter type `%s' for signal `%s'\n", g_type_name(type), signal_description->name);
        va_end(extra_args);
        for(int j = 0; j <= i; j++) g_value_unset(&instance_and_params[j]);
        free(instance_and_params);
        free(params);
        return;
    }
  }

  va_end(extra_args);

  params->instance_and_params = instance_and_params;
  params->signal_id = g_signal_lookup(_signal_description[signal].name, _signal_type);
  params->n_params = signal_description->n_params;

  g_main_context_invoke(NULL, _signal_raise, params);
}
コード例 #12
0
ファイル: import.c プロジェクト: Acidburn0zzz/darktable
static void _camctl_camera_control_status_callback(dt_camctl_status_t status, void *data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)data;
  _control_status_params_t *params = (_control_status_params_t *)malloc(sizeof(_control_status_params_t));
  if(!params) return;
  params->status = status;
  params->self = self;
  g_main_context_invoke(NULL, _camctl_camera_control_status_callback_gui_thread, params);
}
コード例 #13
0
ファイル: autoar-private.c プロジェクト: GNOME/gnome-autoar
/**
 * autoar_common_g_signal_emit:
 * @instance: the instance the signal is being emitted on.
 * @in_thread: %TRUE if you are not call this function inside the main thread.
 * @signal_id: the signal id
 * @detail: the detail
 * @...: parameters to be passed to the signal.
 *
 * This is a wrapper for g_signal_emit(). If @in_thread is %FALSE, this
 * function is the same as g_signal_emit(). If @in_thread is %TRUE, the
 * signal will be emitted from the main thread. This function will send
 * the signal emission job via g_main_context_invoke(), but it does not
 * wait for the signal emission job to be completed. Hence, the signal
 * may emitted after autoar_common_g_signal_emit() is returned.
 **/
G_GNUC_INTERNAL void
autoar_common_g_signal_emit (gpointer instance,
                             gboolean in_thread,
                             guint signal_id,
                             GQuark detail,
                             ...)
{
  va_list ap;

  va_start (ap, detail);
  if (in_thread) {
    int i;
    gchar *error;
    GSignalQuery query;
    AutoarCommonSignalData *data;

    error = NULL;
    data = g_new0 (AutoarCommonSignalData, 1);
    data->signal_id = signal_id;
    data->detail = detail;
    data->used_values = 1;
    g_value_init (data->instance_and_params, G_TYPE_FROM_INSTANCE (instance));
    g_value_set_instance (data->instance_and_params, instance);

    g_signal_query (signal_id, &query);
    if (query.signal_id == 0) {
      autoar_common_signal_data_free (data);
      va_end (ap);
      return;
    }

    for (i = 0; i < query.n_params; i++) {
      G_VALUE_COLLECT_INIT (data->instance_and_params + i + 1,
                            query.param_types[i],
                            ap,
                            0,
                            &error);
      if (error != NULL)
        break;
      data->used_values++;
    }

    if (error == NULL) {
      g_main_context_invoke (NULL, autoar_common_g_signal_emit_main_context, data);
    } else {
      autoar_common_signal_data_free (data);
      g_debug ("G_VALUE_COLLECT_INIT: Error: %s", error);
      g_free (error);
      va_end (ap);
      return;
    }
  } else {
    g_signal_emit_valist (instance, signal_id, detail, ap);
  }
  va_end (ap);
}
コード例 #14
0
ファイル: certs.c プロジェクト: dagwieers/eid-mw
/* Set the given data on the tree model */
static void tst_set(char* w, gint* c, GValue* v, gint n) {
	struct tree_store_data* dat = malloc(sizeof(struct tree_store_data));
	dat->which = strdup(w);
	dat->columns = c;
	dat->values = v;
	dat->n_values = n;
	dat->free = tst_free_simple;
	/* GTK+ does not like it when you modify UI elements from a background
	 * thread, so ensure it's called on the main thread instead */
	g_main_context_invoke(NULL, tst_helper, dat);
}
コード例 #15
0
ファイル: invocation.c プロジェクト: mvollmer/storaged
static const gchar *
lookup_method_action_and_details (gpointer instance,
                                  InvocationClient *client,
                                  uid_t uid,
                                  const GDBusMethodInfo *method,
                                  PolkitDetails **details)
{
  GObjectClass *object_class;
  const gchar *message;

  /* Exception: The Job interface is not marked up like all our others */
  if (UDISKS_IS_JOB (instance) && g_str_equal (method->name, "Cancel"))
    {
      *details = polkit_details_new ();
      polkit_details_insert (*details, "polkit.message",
                             N_("Authentication is required to cancel a job"));

      /* This is a thread-safe call */
      if (uid != udisks_job_get_started_by_uid (instance))
        return "org.freedesktop.udisks2.cancel-job-other-user";
      else
        return "org.freedesktop.udisks2.cancel-job";
    }

  *details = NULL;

  object_class = G_OBJECT_GET_CLASS (instance);
  if (g_object_class_find_property (object_class, "polkit-details") != NULL)
    {
      ObjectGetDetails ogd = { instance, NULL };

      g_main_context_invoke (NULL, object_get_polkit_details, &details);

      g_mutex_lock (&inv.mutex);
      while (ogd.details == NULL)
        g_cond_wait (&inv.wait_cond, &inv.mutex);
      g_mutex_unlock (&inv.mutex);

      *details = ogd.details;
    }

  if (!*details || polkit_details_lookup (*details, "polkit.message"))
    {
      message = g_dbus_annotation_info_lookup (method->annotations, "polkit.message");
      if (message)
        {
          if (!*details)
            *details = polkit_details_new ();
          polkit_details_insert (*details, "polkit.message", message);
        }
    }

  return g_dbus_annotation_info_lookup (method->annotations, "polkit.action_id");
}
コード例 #16
0
ファイル: ostree-repo-pull.c プロジェクト: dnarvaez/ostree
static gboolean
on_metadata_objects_to_scan_ready (gint         fd,
                                   GIOCondition condition,
                                   gpointer     user_data)
{
  OtPullData *pull_data = user_data;
  PullWorkerMessage *msg;
  PullWorkerMessage *last_idle_msg = NULL;
  GError *local_error = NULL;
  GError **error = &local_error;

  while (ot_waitable_queue_pop (pull_data->metadata_objects_to_scan, (gpointer*)&msg))
    {
      if (msg->t == PULL_MSG_SCAN)
        {
          if (!scan_one_metadata_object_v_name (pull_data, msg->d.item,
                                                pull_data->cancellable, error))
            goto out;
          g_variant_unref (msg->d.item);
          g_free (msg);
        }
      else if (msg->t == PULL_MSG_MAIN_IDLE)
        {
          g_free (last_idle_msg);
          last_idle_msg = msg;
        }
      else if (msg->t == PULL_MSG_QUIT)
        {
          g_free (msg);
          g_main_loop_quit (pull_data->metadata_thread_loop);
        }
      else
        g_assert_not_reached ();
      }
    
  if (last_idle_msg)
    ot_waitable_queue_push (pull_data->metadata_objects_to_fetch,
                            last_idle_msg);
  
  /* When we have no queue to process, notify the main thread */
  ot_waitable_queue_push (pull_data->metadata_objects_to_fetch,
                          pull_worker_message_new (PULL_MSG_SCAN_IDLE, GUINT_TO_POINTER (0)));

 out:
  if (local_error)
    {
      IdleThrowErrorData *throwdata = g_new0 (IdleThrowErrorData, 1);
      throwdata->pull_data = pull_data;
      throwdata->error = local_error;
      g_main_context_invoke (NULL, idle_throw_error, throwdata);
    }
  return TRUE;
}
コード例 #17
0
ファイル: gstglwindow.c プロジェクト: luisbg/gst-plugins-bad
static void
gst_gl_window_default_send_message_async (GstGLWindow * window,
    GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
  GstGLWindowPrivate *priv = window->priv;
  GstGLAsyncMessage *message = g_slice_new (GstGLAsyncMessage);

  message->callback = callback;
  message->data = data;
  message->destroy = destroy;

  g_main_context_invoke (priv->main_context, (GSourceFunc) _run_message_async,
      message);
}
コード例 #18
0
static void
start_job (GTask *task,
	   gpointer source_object,
	   gpointer task_data,
	   GCancellable *cancellable)
{
	if (backup_op)
		backup (bk_file, cancellable);
	else if (restore_op)
		restore (res_file, cancellable);
	else if (check_op)
		check (chk_file, NULL);  /* not cancellable */

	g_main_context_invoke (NULL, finish_job, NULL);
}
コード例 #19
0
ファイル: main.c プロジェクト: dagwieers/eid-mw
/* Update the status bar and the spinner with a new status message. */
static void uistatus(gboolean spin, char* data, ...) {
	va_list ap, ac;
	struct statusupdate* update = g_new0(struct statusupdate, 1);

	if(data != NULL) {
		va_start(ap, data);
		va_copy(ac, ap);
		update->text = g_strdup_vprintf(data, ac);
		va_end(ac);
		va_end(ap);
	}
	update->spin = spin;
	/* Don't change UI elements from a background thread */
	g_main_context_invoke(NULL, realstatus, update);
}
コード例 #20
0
ファイル: callbacks.c プロジェクト: Louisvh/zathura
void
cb_file_monitor(GFileMonitor* monitor, GFile* file, GFile* UNUSED(other_file), GFileMonitorEvent event, girara_session_t* session)
{
  g_return_if_fail(monitor  != NULL);
  g_return_if_fail(file     != NULL);
  g_return_if_fail(session  != NULL);

  switch (event) {
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
    case G_FILE_MONITOR_EVENT_CREATED:
      g_main_context_invoke(NULL, file_monitor_reload, session);
      break;
    default:
      return;
  }
}
コード例 #21
0
void
gtk_gst_widget_set_buffer (GtkGstWidget * widget, GstBuffer * buffer)
{
  GMainContext *main_context = g_main_context_default ();

  g_return_if_fail (GTK_IS_GST_WIDGET (widget));
  g_return_if_fail (widget->priv->negotiated);

  g_mutex_lock (&widget->priv->lock);

  gst_buffer_replace (&widget->priv->buffer, buffer);

  g_mutex_unlock (&widget->priv->lock);

  g_main_context_invoke (main_context, (GSourceFunc) _queue_draw, widget);
}
コード例 #22
0
static void
gst_gl_dummy_window_send_message_async (GstGLWindow * window,
    GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
  GstGLDummyWindow *dummy;
  GstGLMessage *message;

  dummy = (GstGLDummyWindow *) window;
  message = g_slice_new (GstGLMessage);

  message->callback = callback;
  message->data = data;
  message->destroy = destroy;

  g_main_context_invoke (dummy->main_context, (GSourceFunc) _run_message,
      message);
}
static void
gst_gl_window_android_egl_send_message_async (GstGLWindow * window,
    GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
  GstGLWindowAndroidEGL *window_egl;
  GstGLMessage *message;

  window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
  message = g_slice_new (GstGLMessage);

  message->callback = callback;
  message->data = data;
  message->destroy = destroy;

  g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
      message);
}
コード例 #24
0
gboolean
gtk_gst_widget_set_caps (GtkGstWidget * widget, GstCaps * caps)
{
  GMainContext *main_context = g_main_context_default ();
  GstVideoInfo v_info;

  g_return_val_if_fail (GTK_IS_GST_WIDGET (widget), FALSE);
  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  if (widget->priv->caps && gst_caps_is_equal_fixed (widget->priv->caps, caps))
    return TRUE;

  if (!gst_video_info_from_caps (&v_info, caps))
    return FALSE;

  /* FIXME: support other formats */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&v_info) ==
      GST_VIDEO_FORMAT_BGRA || GST_VIDEO_INFO_FORMAT (&v_info) ==
      GST_VIDEO_FORMAT_BGRx, FALSE);
#else
  g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&v_info) ==
      GST_VIDEO_FORMAT_ARGB || GST_VIDEO_INFO_FORMAT (&v_info) ==
      GST_VIDEO_FORMAT_xRGB, FALSE);
#endif

  g_mutex_lock (&widget->priv->lock);

  if (!_calculate_par (widget, &v_info)) {
    g_mutex_unlock (&widget->priv->lock);
    return FALSE;
  }

  gst_caps_replace (&widget->priv->caps, caps);
  widget->priv->v_info = v_info;
  widget->priv->negotiated = TRUE;

  g_mutex_unlock (&widget->priv->lock);

  gtk_widget_queue_resize (GTK_WIDGET (widget));

  g_main_context_invoke (main_context, (GSourceFunc) _queue_resize, widget);

  return TRUE;
}
コード例 #25
0
ファイル: gvfsafpconnection.c プロジェクト: Alustriel/gvfs
void
g_vfs_afp_connection_send_command (GVfsAfpConnection   *afp_connection,
                                   GVfsAfpCommand      *command,
                                   char                *reply_buf,
                                   GAsyncReadyCallback  callback,
                                   GCancellable        *cancellable,
                                   gpointer             user_data)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;

  GError *err = NULL;
  RequestData *req_data;

  if (!check_open (afp_connection, &err))
  {
    g_simple_async_report_take_gerror_in_idle (G_OBJECT(afp_connection), callback,
                                               user_data, err);
    return;
  }
  
  req_data = g_slice_new0 (RequestData);
  req_data->type = REQUEST_TYPE_COMMAND;
  req_data->command = g_object_ref (command);
  req_data->reply_buf = reply_buf;

  req_data->simple = g_simple_async_result_new (G_OBJECT (afp_connection), callback,
                                                user_data,
                                                g_vfs_afp_connection_send_command);
  req_data->conn = afp_connection;
  
  if (cancellable)
    req_data->cancellable = g_object_ref (cancellable);

  /* Take lock */
  g_mutex_lock (&priv->mutex);
  
  g_queue_push_tail (priv->request_queue, req_data);
  if (!priv->send_loop_running)
  {
    g_main_context_invoke (priv->worker_context, start_send_loop_func,
                           afp_connection);
  }

  /* Release lock */
  g_mutex_unlock (&priv->mutex);
}
コード例 #26
0
ファイル: session.c プロジェクト: uwehermann/libsigrok
/**
 * Stop a session.
 *
 * The session is stopped immediately, with all acquisition sessions being
 * stopped and hardware drivers cleaned up.
 *
 * If the session is run in a separate thread, this function will not block
 * until the session is finished executing. It is the caller's responsibility
 * to wait for the session thread to return before assuming that the session is
 * completely decommissioned.
 *
 * @param session The session to use. Must not be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid session passed.
 * @retval SR_ERR Other error.
 *
 * @since 0.4.0
 */
SR_API int sr_session_stop(struct sr_session *session)
{
	if (!session) {
		sr_err("%s: session was NULL", __func__);
		return SR_ERR_ARG;
	}
	g_mutex_lock(&session->main_mutex);

	if (session->main_context) {
		g_main_context_invoke(session->main_context,
				&session_stop_sync, session);
	} else {
		sr_err("No main context set; already stopped?");
	}
	g_mutex_unlock(&session->main_mutex);

	return unset_main_context(session);
}
コード例 #27
0
/* This function is used to run UI on the main thread in order to ask the user
 * for an action during an operation. Since the operation cannot progress until
 * an action is provided by the user, the current thread needs to be blocked.
 * For this we wait on a condition on the shared data. We proceed further
 * unblocking the thread when the condition is set in the UI thread.
 */
static void
invoke_main_context_sync (GMainContext *main_context,
                          GSourceFunc   source_func,
                          gpointer      user_data)
{
    ContextInvokeData data;
    /* Allow only one thread at a time to invoke the main context so we
     * don't get race conditions which could lead to multiple dialogs being
     * displayed at the same time
     */
    G_LOCK (main_context_sync);

    data.source_func = source_func;
    data.user_data = user_data;

    g_mutex_init (&data.mutex);
    g_cond_init (&data.cond);
    data.completed = FALSE;

    g_mutex_lock (&data.mutex);

    g_main_context_invoke (main_context,
                           invoke_main_context_source_func_wrapper,
                           &data);

    while (!data.completed)
    {
        g_cond_wait (&data.cond, &data.mutex);
    }

    g_mutex_unlock (&data.mutex);

    G_UNLOCK (main_context_sync);

    g_mutex_clear (&data.mutex);
    g_cond_clear (&data.cond);
}
コード例 #28
0
ファイル: video.c プロジェクト: marek5050/Telescope-Guvcview
/* run in a thread (SDL overlay)*/
void *main_loop(void *data)
{
    struct ALL_DATA *all_data = (struct ALL_DATA *) data;

    struct VidState *s = all_data->s;
    struct paRecordData *pdata = all_data->pdata;
    struct GLOBAL *global = all_data->global;
    struct focusData *AFdata = all_data->AFdata;
    struct vdIn *videoIn = all_data->videoIn;

    struct particle* particles = NULL; //for the particles video effect

    SDL_Event event;
    /*the main SDL surface*/
    SDL_Surface *pscreen = NULL;
    SDL_Overlay *overlay = NULL;
    SDL_Rect drect;

    int width = global->width;
    int height = global->height;
    int format = global->format;

    SAMPLE vuPeak[2];  // The maximum vuLevel seen recently
    int vuPeakFreeze[2]; // The vuPeak values will be frozen for this many frames.
    vuPeak[0] = vuPeak[1] = 0;
    vuPeakFreeze[0] = vuPeakFreeze[1] = 0;

    BYTE *p = NULL;

    Control *focus_control = NULL;
    int last_focus = 0;

    if (global->AFcontrol)
    {
        focus_control = get_ctrl_by_id(s->control_list, AFdata->id);
        get_ctrl(videoIn->fd, s->control_list, AFdata->id, all_data);
        last_focus = focus_control->value;
        /*make sure we wait for focus to settle on first check*/
        if (last_focus < 0) last_focus = AFdata->f_max;
    }

    gboolean capVid = FALSE;
    gboolean signalquit = FALSE;

    /*------------------------------ SDL init video ---------------------*/
    if(!global->no_display)
    {
        overlay = video_init(data, &(pscreen));

        if(overlay == NULL)
        {
            g_print("FATAL: Couldn't create yuv overlay - please disable hardware accelaration\n");
            signalquit = TRUE; /*exit video thread*/
        }
        else
        {
            p = (unsigned char *) overlay->pixels[0];

            drect.x = 0;
            drect.y = 0;
            drect.w = pscreen->w;
            drect.h = pscreen->h;
        }
    }

    while (!signalquit)
    {
        __LOCK_MUTEX(__VMUTEX);
            capVid = videoIn->capVid;
            signalquit = videoIn->signalquit;
        __UNLOCK_MUTEX(__VMUTEX);

        /*-------------------------- Grab Frame ----------------------------------*/
        if (uvcGrab(videoIn, format, width, height, &global->fps, &global->fps_num) < 0)
        {
            g_printerr("Error grabbing image \n");
            continue;
        }
        else
        {
            if(!videoIn->timestamp)
            {
                global->skip_n++; //skip this frame
            }

            if(capVid)
            {
                if(global->framecount < 1)
                {
					/*reset video start time to first frame capture time */
					global->Vidstarttime = videoIn->timestamp;
					/** set current time for audio ts(0) reference (MONOTONIC)
					 *  only used if we have no audio capture before video
					 */
					__LOCK_MUTEX(__AMUTEX);
						pdata->ts_ref = ns_time_monotonic();
					__UNLOCK_MUTEX(__AMUTEX);
					//printf("video ts ref: %llu audio ts_ ref: %llu\n",global->Vidstarttime, pdata->ts_ref);
					global->v_ts = 0;
                }
                else
                {
                    global->v_ts = videoIn->timestamp - global->Vidstarttime;
                    /*always use the last frame time stamp for video stop time*/
                    global->Vidstoptime = videoIn->timestamp;
                }
            }

            if (global->FpsCount && !global->no_display)
            {/* sets fps count in window title bar */
                global->frmCount++;
                if (global->DispFps>0)
                { /*set every 2 sec*/
                    g_snprintf(global->WVcaption,24,"GUVCVideo - %3.2f fps",global->DispFps);
                    SDL_WM_SetCaption(global->WVcaption, NULL);

                    global->frmCount=0;/*resets*/
                    global->DispFps=0;
                }
            }

            /*---------------- autofocus control ------------------*/

            if (global->AFcontrol && (global->autofocus || AFdata->setFocus))
            { /*AFdata = NULL if no focus control*/
                if (AFdata->focus < 0)
                {
                    /*starting autofocus*/
                    AFdata->focus = AFdata->left; /*start left*/
                    focus_control->value = AFdata->focus;
                    if (set_ctrl (videoIn->fd, s->control_list, AFdata->id) != 0)
                        g_printerr("ERROR: couldn't set focus to %d\n", AFdata->focus);
                    /*number of frames until focus is stable*/
                    /*1.4 ms focus time - every 1 step*/
                    AFdata->focus_wait = (int) abs(AFdata->focus-last_focus)*1.4/(1000/global->fps)+1;
                    last_focus = AFdata->focus;
                }
                else
                {
                    if (AFdata->focus_wait == 0)
                    {
                        AFdata->sharpness=getSharpness (videoIn->framebuffer, width, height, 5);
                        if (global->debug)
                            g_print("sharp=%d focus_sharp=%d foc=%d right=%d left=%d ind=%d flag=%d\n",
                                AFdata->sharpness,AFdata->focus_sharpness,
                                AFdata->focus, AFdata->right, AFdata->left,
                                AFdata->ind, AFdata->flag);
                        AFdata->focus=getFocusVal (AFdata);
                        if ((AFdata->focus != last_focus))
                        {
                            focus_control->value = AFdata->focus;
                            if (set_ctrl (videoIn->fd, s->control_list, AFdata->id) != 0)
                                g_printerr("ERROR: couldn't set focus to %d\n",
                                    AFdata->focus);
                            /*number of frames until focus is stable*/
                            /*1.4 ms focus time - every 1 step*/
                            AFdata->focus_wait = (int) abs(AFdata->focus-last_focus)*1.4/(1000/global->fps)+1;
                        }
                        last_focus = AFdata->focus;
                    }
                    else
                    {
                        AFdata->focus_wait--;
                        if (global->debug) g_print("Wait Frame: %d\n",AFdata->focus_wait);
                    }
                }
            }
        }
        /*------------------------- Filter Frame ---------------------------------*/
        __LOCK_MUTEX(__GMUTEX);
        if(global->Frame_Flags>0)
        {
            if((global->Frame_Flags & YUV_PARTICLES)==YUV_PARTICLES)
                particles = particles_effect(videoIn->framebuffer, width, height, 20, 4, particles);

            if((global->Frame_Flags & YUV_MIRROR)==YUV_MIRROR)
                yuyv_mirror(videoIn->framebuffer, width, height);

            if((global->Frame_Flags & YUV_UPTURN)==YUV_UPTURN)
                yuyv_upturn(videoIn->framebuffer, width, height);

            if((global->Frame_Flags & YUV_NEGATE)==YUV_NEGATE)
                yuyv_negative (videoIn->framebuffer, width, height);

            if((global->Frame_Flags & YUV_MONOCR)==YUV_MONOCR)
                yuyv_monochrome (videoIn->framebuffer, width, height);

            if((global->Frame_Flags & YUV_PIECES)==YUV_PIECES)
                pieces (videoIn->framebuffer, width, height, 16 );

        }
        __UNLOCK_MUTEX(__GMUTEX);
        /*-------------------------capture Image----------------------------------*/
        if (videoIn->capImage)
        {
            /*
             * format and resolution can change(enabled) while capturing the frame
             * but you would need to be speedy gonzalez to press two buttons
             * at almost the same time :D
             */
            int ret = 0;
            if((ret=store_picture(all_data)) < 0)
                g_printerr("saved image to:%s ...Failed \n",videoIn->ImageFName);
            else if (!ret && global->debug) g_print("saved image to:%s ...OK \n",videoIn->ImageFName);

            videoIn->capImage=FALSE;
        }
        /*---------------------------capture Video---------------------------------*/
        if (capVid && !(global->skip_n))
        {
            __LOCK_MUTEX(__VMUTEX);
                if(videoIn->VidCapStop) videoIn->VidCapStop = FALSE;
            __UNLOCK_MUTEX(__VMUTEX);
            int res=0;

			/* format and resolution don't change(disabled) while capturing video
			 * store_video_frame may sleep if needed to avoid buffer overrun
			 */
            if((res=store_video_frame(all_data))<0) g_printerr("WARNING: droped frame (%i)\n",res);

        } /*video and audio capture have stopped */
        else
        {
            __LOCK_MUTEX(__VMUTEX);
                if(!(videoIn->VidCapStop)) videoIn->VidCapStop=TRUE;
            __UNLOCK_MUTEX(__VMUTEX);
        }

        /* decrease skip frame count */
        if (global->skip_n > 0)
        {
            if (global->debug && capVid) g_print("skiping frame %d...\n", global->skip_n);
            global->skip_n--;
        }

        __LOCK_MUTEX( __AMUTEX );
            if (global->Sound_enable && capVid) pdata->skip_n = global->skip_n;
        __UNLOCK_MUTEX( __AMUTEX );

        /*------------------------- Display Frame --------------------------------*/
        if(!global->no_display)
        {
			if (global->osdFlags && pdata->audio_buff[0])
			{
				draw_vu_meter(width, height, vuPeak, vuPeakFreeze, data);
			}
            SDL_LockYUVOverlay(overlay);
            memcpy(p, videoIn->framebuffer, width * height * 2);
            SDL_UnlockYUVOverlay(overlay);
            SDL_DisplayYUVOverlay(overlay, &drect);

            /*------------------------- Read Key events ------------------------------*/
            /* Poll for events */
            while( SDL_PollEvent(&event) )
            {
                //printf("event type:%i  event key:%i\n", event.type, event.key.keysym.scancode);
                if(event.type==SDL_KEYDOWN)
                {
                    if (videoIn->PanTilt)
                    {
                        switch( event.key.keysym.sym )
                        {
                            /* Keyboard event */
                            /* Pass the event data onto PrintKeyInfo() */
                            case SDLK_DOWN:
                                /*Tilt Down*/
                                uvcPanTilt (videoIn->fd, s->control_list, 0, 1);
                                break;

                            case SDLK_UP:
                                /*Tilt UP*/
                                uvcPanTilt (videoIn->fd, s->control_list, 0, -1);
                                break;

                            case SDLK_LEFT:
                                /*Pan Left*/
                                uvcPanTilt (videoIn->fd, s->control_list, 1, 1);
                                break;

                            case SDLK_RIGHT:
                                /*Pan Right*/
                                uvcPanTilt (videoIn->fd, s->control_list, 1, -1);
                                break;
                            default:
                                break;
                        }
                    }
                    switch( event.key.keysym.scancode )
                    {
                        case 220: /*webcam button*/
                            //gdk_threads_enter();
                           	if (all_data->global->default_action == 0)
                           		g_main_context_invoke(NULL, image_capture_callback, (gpointer) all_data);
							else
                            	g_main_context_invoke(NULL, video_capture_callback, (gpointer) all_data);
                       
                            break;
                    }
                    switch( event.key.keysym.sym )
                    {
                        case SDLK_q:
                            //shutDown
                            g_timeout_add(200, shutd_timer, all_data);
                            g_print("q pressed - Quiting...\n");
                            break;
                        case SDLK_SPACE:
							{
                            if(global->AFcontrol > 0)
                                setfocus_clicked(NULL, all_data);
							}
                            break;
                        case SDLK_i:
							g_main_context_invoke(NULL, image_capture_callback, (gpointer) all_data);
							break;
						case SDLK_v:
							g_main_context_invoke(NULL, video_capture_callback, (gpointer) all_data);
							break;
                        default:
                            break;
                    }
                }
                if(event.type==SDL_VIDEORESIZE)
                {
                    pscreen =
                        SDL_SetVideoMode(event.resize.w,
                                 event.resize.h,
                                 global->bpp,
                                 SDL_VIDEO_Flags);
                    drect.w = event.resize.w;
                    drect.h = event.resize.h;
                }
                if(event.type==SDL_QUIT)
                {
                    //shutDown
                    g_timeout_add(200, shutd_timer, all_data);
                }
            }
        }
        /* if set make the thread sleep - default no sleep (full throttle)*/
        if(global->vid_sleep) sleep_ms(global->vid_sleep);

        /*------------------------------------------*/
        /*  restart video (new resolution/format)   */
        /*------------------------------------------*/
        if (global->change_res)
        {
            g_print("setting new resolution (%d x %d)\n", global->width, global->height);
            /*clean up */

            if(particles) g_free(particles);
            particles = NULL;

            if (global->debug) g_print("cleaning buffer allocations\n");
            fflush(NULL);//flush all output buffers

            if(!global->no_display)
            {
                SDL_FreeYUVOverlay(overlay);
                overlay = NULL;
            }
            /*init device*/
            restart_v4l2(videoIn, global);
            /*set new resolution for video thread*/
            width = global->width;
            height = global->height;
            format = global->format;
            /* restart SDL with new values*/
            if(!global->no_display)
            {
                overlay = video_init(data, &(pscreen));
                if(overlay == NULL)
                {
                    g_print("FATAL: Couldn't create yuv overlay - please disable hardware accelaration\n");
                    signalquit = TRUE; /*exit video thread*/
                }
                else
                {
                    if (global->debug) g_print("yuv overlay created (%ix%i).\n", overlay->w, overlay->h);
                    p = (unsigned char *) overlay->pixels[0];

                    drect.x = 0;
                    drect.y = 0;
                    drect.w = pscreen->w;
                    drect.h = pscreen->h;

                    global->change_res = FALSE;
                }
            }
            else global->change_res = FALSE;
        }

    }/*loop end*/

    __LOCK_MUTEX(__VMUTEX);
        capVid = videoIn->capVid;
    __UNLOCK_MUTEX(__VMUTEX);
    /*check if thread exited while in Video capture mode*/
    if (capVid)
    {
        /*stop capture*/
        if (global->debug) g_print("stoping Video capture\n");
        //global->Vidstoptime = ns_time_monotonic(); /*this is set in IO thread*/
        videoIn->VidCapStop=TRUE;
        capVid = FALSE;
        __LOCK_MUTEX(__VMUTEX);
            videoIn->capVid = capVid;
        __UNLOCK_MUTEX(__VMUTEX);
        __LOCK_MUTEX(__AMUTEX);
            pdata->capVid = capVid;
        __UNLOCK_MUTEX(__AMUTEX);
        /*join IO thread*/
        if (global->debug) g_print("Shuting Down IO Thread\n");
        __THREAD_JOIN( all_data->IO_thread );
        if (global->debug) g_print("IO Thread finished\n");
    }

    if (global->debug) g_print("Thread terminated...\n");
    p = NULL;
    if(particles) g_free(particles);
    particles=NULL;

    if (global->debug) g_print("cleaning Thread allocations: 100%%\n");
    fflush(NULL);//flush all output buffers

    if(!global->no_display)
    {
        if(overlay)
            SDL_FreeYUVOverlay(overlay);
        //SDL_FreeSurface(pscreen);

        SDL_Quit();
    }

    if (global->debug) g_print("Video thread completed\n");

    global = NULL;
    AFdata = NULL;
    videoIn = NULL;
    return ((void *) 0);
}
コード例 #29
0
ファイル: control.c プロジェクト: AdamMajer/darktable
void dt_control_queue_redraw_widget(GtkWidget *widget)
{
  if(dt_control_running())
    g_main_context_invoke(NULL, _gtk_widget_queue_draw, widget);
}
コード例 #30
0
static gpointer
filechooser_win32_thread (gpointer _data)
{
  FilechooserWin32ThreadData *data = _data;
  HRESULT hr;
  IFileDialog *pfd = NULL;
  IFileDialog2 *pfd2 = NULL;
  DWORD flags;
  DWORD cookie;
  GSList *l;

  CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);

  if (data->save && !data->folder)
    hr = CoCreateInstance (&CLSID_FileSaveDialog,
                           NULL, CLSCTX_INPROC_SERVER,
                           &IID_IFileSaveDialog, (LPVOID *) &pfd);
  else
    hr = CoCreateInstance (&CLSID_FileOpenDialog,
                           NULL, CLSCTX_INPROC_SERVER,
                           &IID_IFileOpenDialog, (LPVOID *) &pfd);

  if (FAILED (hr))
    g_error ("Can't create FileOpenDialog: %s", g_win32_error_message (hr));

  hr = IFileDialog_GetOptions (pfd, &flags);
  if (FAILED (hr))
    g_error ("Can't get FileDialog options: %s", g_win32_error_message (hr));

  flags |= FOS_FORCEFILESYSTEM;

  if (data->folder)
    flags |= FOS_PICKFOLDERS;

  if (data->folder && data->save)
    flags &= ~(FOS_FILEMUSTEXIST);

  if (data->select_multiple)
    flags |= FOS_ALLOWMULTISELECT;

  if (data->show_hidden)
    flags |= FOS_FORCESHOWHIDDEN;

  if (data->overwrite_confirmation)
    flags |= FOS_OVERWRITEPROMPT;
  else
    flags &= ~(FOS_OVERWRITEPROMPT);

  hr = IFileDialog_SetOptions (pfd, flags);
  if (FAILED (hr))
    g_error ("Can't set FileDialog options: %s", g_win32_error_message (hr));

  if (data->title)
    {
      gunichar2 *label = g_utf8_to_utf16 (data->title, -1,
                                        NULL, NULL, NULL);
      IFileDialog_SetTitle (pfd, label);
      g_free (label);
    }

  if (data->accept_label)
    {
      gunichar2 *label = g_utf8_to_utf16 (data->accept_label, -1,
                                        NULL, NULL, NULL);
      IFileDialog_SetOkButtonLabel (pfd, label);
      g_free (label);
    }

  if (data->cancel_label)
    {
      gunichar2 *label = g_utf8_to_utf16 (data->cancel_label, -1,
                                        NULL, NULL, NULL);
      hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialog2, (LPVOID *) &pfd2);
      if (SUCCEEDED (hr))
        {
          IFileDialog2_SetCancelButtonLabel (pfd2, label);
          IFileDialog2_Release (pfd2);
        }
      g_free (label);
    }

  for (l = data->shortcut_uris; l != NULL; l = l->next)
    {
      IShellItem *item = get_shell_item_for_uri (l->data);
      if (item)
        {
          hr = IFileDialog_AddPlace (pfd, item, FDAP_BOTTOM);
          if (FAILED (hr))
            g_warning_hr ("Can't add dialog shortcut", hr);
          IShellItem_Release (item);
        }
    }

  if (data->current_file)
    {
      IFileSaveDialog *pfsd;
      hr = IFileDialog_QueryInterface (pfd, &IID_IFileSaveDialog, (LPVOID *) &pfsd);
      if (SUCCEEDED (hr))
        {
          IShellItem *item = get_shell_item_for_file (data->current_file);
          if (item)
            {
              hr = IFileSaveDialog_SetSaveAsItem (pfsd, item);
              if (FAILED (hr))
                g_warning_hr ("Can't set save as item", hr);
              IShellItem_Release (item);
            }
          IFileSaveDialog_Release (pfsd);
        }
    }

  if (data->current_folder)
    {
      IShellItem *item = get_shell_item_for_file (data->current_folder);
      if (item)
        {
          hr = IFileDialog_SetFolder (pfd, item);
          if (FAILED (hr))
            g_warning_hr ("Can't set folder", hr);
          IShellItem_Release (item);
        }
    }

  if (data->current_name)
    {
      gunichar2 *name = g_utf8_to_utf16 (data->current_name, -1, NULL, NULL, NULL);
      hr = IFileDialog_SetFileName (pfd, name);
      if (FAILED (hr))
        g_warning_hr ("Can't set file name", hr);
      g_free (name);
    }

  if (data->filters)
    {
      int n;
      for (n = 0; data->filters[n].pszName != NULL; n++)
        {}
      hr = IFileDialog_SetFileTypes (pfd, n, data->filters);
      if (FAILED (hr))
        g_warning_hr ("Can't set file types", hr);

      if (data->self->current_filter)
        {
          GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
	  gint current_filter_index = g_slist_index (filters, data->self->current_filter);
	  g_slist_free (filters);

	  if (current_filter_index >= 0)
	    hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
	  else
	    hr = IFileDialog_SetFileTypeIndex (pfd, 1);
        }
      else
        {
	  hr = IFileDialog_SetFileTypeIndex (pfd, 1);
        }
      if (FAILED (hr))
        g_warning_hr ("Can't set current file type", hr);
    }

  data->response = GTK_RESPONSE_CANCEL;

  hr = IFileDialog_Advise (pfd, data->events, &cookie);
  if (FAILED (hr))
    g_error ("Can't Advise FileDialog: %s", g_win32_error_message (hr));

  hr = IFileDialog_Show (pfd, data->parent);
  if (SUCCEEDED (hr))
    {
      IFileOpenDialog *pfod = NULL;
      hr = IFileDialog_QueryInterface (pfd,&IID_IFileOpenDialog, (LPVOID *) &pfod);

      if (SUCCEEDED (hr))
        {
          IShellItemArray *res;
          DWORD i, count;

          hr = IFileOpenDialog_GetResults (pfod, &res);
          if (FAILED (hr))
            g_error ("Can't get FileOpenDialog results: %s", g_win32_error_message (hr));

          hr = IShellItemArray_GetCount (res, &count);
          if (FAILED (hr))
            g_error ("Can't get FileOpenDialog count: %s", g_win32_error_message (hr));

          for (i = 0; i < count; i++)
            {
              IShellItem *item;
              hr = IShellItemArray_GetItemAt (res, i, &item);
              if (FAILED (hr))
                g_error ("Can't get item at %lu: %s", i, g_win32_error_message (hr));
              data_add_shell_item (data, item);
              IShellItem_Release (item);
            }
          IShellItemArray_Release (res);

          IFileOpenDialog_Release (pfod);
        }
      else
        {
          IShellItem *item;
          hr = IFileDialog_GetResult (pfd, &item);
          if (FAILED (hr))
            g_error ("Can't get FileDialog result: %s", g_win32_error_message (hr));

          data_add_shell_item (data, item);
          IShellItem_Release (item);
        }
    }

  hr = IFileDialog_Unadvise (pfd, cookie);
  if (FAILED (hr))
    g_error ("Can't Unadvise FileDialog: %s", g_win32_error_message (hr));

  IFileDialog_Release ((IUnknown *)pfd);

  g_main_context_invoke (NULL,
                         filechooser_win32_thread_done,
                         data);

  return NULL;
}