/**
 * mate_bg_crossfade_start:
 * @fade: a #MateBGCrossfade
 * @window: The #GdkWindow to draw crossfade on
 *
 * This function initiates a quick crossfade between two surfaces on
 * the background of @window. Before initiating the crossfade both
 * mate_bg_crossfade_set_start_surface() and
 * mate_bg_crossfade_set_end_surface() need to be called. If animations
 * are disabled, the crossfade is skipped, and the window background is
 * set immediately to the end surface.
 **/
void
mate_bg_crossfade_start (MateBGCrossfade *fade,
                         GdkWindow       *window)
{
	GSource *source;
	GMainContext *context;

	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
	g_return_if_fail (window != NULL);
	g_return_if_fail (fade->priv->start_surface != NULL);
	g_return_if_fail (fade->priv->end_surface != NULL);
	g_return_if_fail (!mate_bg_crossfade_is_started (fade));
	g_return_if_fail (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN);

	/* If drawing is done on the root window,
	 * it is essential to have the root pixmap.
	 */
	if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT) {
		GdkDisplay *display = gdk_window_get_display (window);
		cairo_surface_t *surface = get_root_pixmap_id_surface (display);

		g_return_if_fail (surface != NULL);
		cairo_surface_destroy (surface);
	}

	if (fade->priv->fading_surface != NULL) {
		cairo_surface_destroy (fade->priv->fading_surface);
		fade->priv->fading_surface = NULL;
	}

	fade->priv->window = window;
	if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) {
		fade->priv->fading_surface = tile_surface (fade->priv->start_surface,
		                                           fade->priv->width,
		                                           fade->priv->height);
		if (fade->priv->widget != NULL) {
			g_signal_connect (fade->priv->widget, "draw",
			                  (GCallback) on_widget_draw, fade);
		}
	} else {
		cairo_t   *cr;
		GdkDisplay *display = gdk_window_get_display (fade->priv->window);

		fade->priv->fading_surface = get_root_pixmap_id_surface (display);
		cr = cairo_create (fade->priv->fading_surface);
		cairo_set_source_surface (cr, fade->priv->start_surface, 0, 0);
		cairo_paint (cr);
		cairo_destroy (cr);
	}
	draw_background (fade);

	source = g_timeout_source_new (1000 / 60.0);
	g_source_set_callback (source,
			       (GSourceFunc) on_tick,
			       fade,
			       (GDestroyNotify) on_finished);
	context = g_main_context_default ();
	fade->priv->timeout_id = g_source_attach (source, context);
	g_source_unref (source);

	fade->priv->is_first_frame = TRUE;
	fade->priv->total_duration = .75;
	fade->priv->start_time = get_current_time ();
}
Example #2
0
/**
 * gda_worker_do_job: (skip)
 * @worker: a #GdaWorker object
 * @context: (allow-none): a #GMainContext to execute a main loop in (while waiting), or %NULL
 * @timeout_ms: the maximum number of milisecons to wait before returning, or %0 for unlimited wait
 * @out_result: (allow-none): a place to store the result, if any, of @func's execution, or %NULL
 * @out_job_id: (allow-none): a place to store the ID of the job having been submitted, or %NULL
 * @func: the function to call from the worker thread
 * @data: (allow-none): the data to pass to @func, or %NULL
 * @data_destroy_func: (allow-none): a function to destroy @data, or %NULL
 * @result_destroy_func: (allow-none): a function to destroy the result, if any, of @func's execution, or %NULL
 * @error: (allow-none): a place to store errors, or %NULL.
 *
 * Request that the worker thread call @func with the @data argument, much like gda_worker_submit_job(),
 * but waits (starting a #GMainLoop) for a maximum of @timeout_ms miliseconds for @func to be executed.
 *
 * If this function is called from within @worker's worker thread, then this function simply calls @func with @data and does not
 * use @context.
 *
 * The following cases are possible if this function is not called from within @worker's worker thread:
 * <itemizedlist>
 *  <listitem><para>the call to @func took less than @timeout_ms miliseconds: the return value is %TRUE and 
 *    @out_result contains the result of the @func's execution, and @out_job_id contains %NULL. Note in this
 *    case that @error may still contain an error code if @func's execution produced an error. Also note that in this case
 *    any setting defined by gda_worker_set_callback() is not applied (as the result is immediately returned)</para></listitem>
 *  <listitem><para>The call to @func takes more then @timeout_ms miliseconds: the return value is %TRUE and
 *    @out_result is %NULL and @out_job_id contains the ID of the job as if it had been submitted using gda_worker_submit_job().
 *    If @out_job_id is %NULL, and if no setting has been defined using gda_worker_set_callback(), then the job will be discarded
 *    (as if gda_worker_forget_job() had been called).
 *    </para></listitem>
 *  <listitem><para>The call to @func could not be done (some kind of plumbing error for instance): the returned value is %FALSE
 *    and @out_result and @out_job_id are set to %NULL (if they are not %NULL)</para></listitem>
 * </itemizedlist>
 *
 * Notes:
 * <itemizedlist>
 *  <listitem><para>@result_destroy_func is needed in case @out_result is %NULL (to avoid memory leaks)</para></listitem>
 *  <listitem><para>passing %NULL for @context is similar to passing the result of g_main_context_ref_thread_default()</para></listitem>
 * </itemizedlist>
 *
 * Returns: %TRUE if no error occurred
 *
 * Since: 6.0
 */
gboolean
gda_worker_do_job (GdaWorker *worker, GMainContext *context, gint timeout_ms,
		   gpointer *out_result, guint *out_job_id,
		   GdaWorkerFunc func, gpointer data, GDestroyNotify data_destroy_func,
		   GDestroyNotify result_destroy_func,
		   GError **error)
{
	if (out_result)
		*out_result = NULL;
	if (out_job_id)
		*out_job_id = 0;

	g_return_val_if_fail (worker, FALSE);
	g_return_val_if_fail (func, FALSE);
	if (!worker->callbacks_hash || !worker->jobs_hash) {
		g_warning ("GdaWorker has been destroyed\n");
		return FALSE;
	}

	if (gda_worker_thread_is_worker (worker)) {
		/* we are called from within the worker thread => call the function directly */
		gpointer result;
		result = func (data, error);
		if (data_destroy_func)
			data_destroy_func (data);
		if (out_result)
			*out_result = result;
		else if (result && result_destroy_func)
			result_destroy_func (result);
		return TRUE;
	}

	guint jid, itsid, timer = 0;

	/* determine which GMainContext to use */
	GMainContext *co;
	gboolean unref_co = FALSE;

	co = context;
	if (!co) {
		co = g_main_context_ref_thread_default ();
		unref_co = TRUE;
	}

	/* prepare main loop */
	GMainLoop *loop;
        loop = g_main_loop_new (co, FALSE);

	/* prepare ITSignaler to be notified */
	ITSignaler *its;
	its = itsignaler_new ();
	itsid = itsignaler_add (its, co, (ITSignalerFunc) do_itsignaler_cb,
				g_main_loop_ref (loop), (GDestroyNotify) g_main_loop_unref);

	/* push job */
	g_rec_mutex_lock (& worker->rmutex); /* required to call _gda_worker_submit_job_with_its() */
	jid = _gda_worker_submit_job_with_its (worker, its,
					       func, data, data_destroy_func, result_destroy_func, error);
	g_rec_mutex_unlock (& worker->rmutex);
	if (jid == 0) {
		/* an error occurred */
		g_assert (itsignaler_remove (its, co, itsid));
		itsignaler_unref (its);
		g_main_loop_unref (loop);

		if (unref_co)
			g_main_context_unref (co);

		return FALSE;
	}

	/* check if result is already here */
	WorkerJob *job;
	job = itsignaler_pop_notification (its, 0);
	if (!job) {
		if (timeout_ms > 0) {
			/* start timer to limit waiting time */
			GSource *timer_src;
			timer_src = g_timeout_source_new (timeout_ms);
			g_source_set_callback (timer_src, (GSourceFunc) do_timer_cb, loop, NULL);
			timer = g_source_attach (timer_src, co);
			g_source_unref (timer_src);
		}
		g_main_loop_run (loop);

		/* either timer has arrived or job has been done */
		job = itsignaler_pop_notification (its, 0);
	}
	g_main_loop_unref (loop);

	g_assert (itsignaler_remove (its, co, itsid));
	itsignaler_unref (its);

	if (job) {
		/* job done before the timer, if any, elapsed */

		if (timer > 0)
			g_assert (g_source_remove (timer));

		g_assert (gda_worker_fetch_job_result (worker, jid, out_result, error));
	}
	else {
		/* timer came first, job is not yet finished */

		/* apply settings from gda_worker_set_callback(), if any */
		g_rec_mutex_lock (&worker->rmutex);
		DeclaredCallback *dc;
		dc = g_hash_table_lookup (worker->callbacks_hash, co);
		if (dc) {
			job = g_hash_table_lookup (worker->jobs_hash, &jid);
			g_assert (job);
			g_assert (!job->reply_its);
			job->reply_its = itsignaler_ref (dc->its);
		}
		g_rec_mutex_unlock (& worker->rmutex);

		/* cleanups */
		if (out_job_id)
			*out_job_id = jid;
		else if (!dc)
			/* forget all about the job */
			gda_worker_forget_job (worker, jid);
	}

	if (unref_co)
		g_main_context_unref (co);

	return TRUE;
}
Example #3
0
/* called when we're done running the command line */
static void
udisks_spawned_job_release_resources (UlSpawnedJob *self)
{
  /* Nuke the child, if necessary */
  if (self->child_watch_source != NULL)
    {
      g_source_destroy (self->child_watch_source);
      self->child_watch_source = NULL;
    }

  if (self->child_pid != 0)
    {
      GSource *source;

      g_debug ("ugh, need to kill %d", (gint) self->child_pid);
      kill (self->child_pid, SIGTERM);

      /* OK, we need to reap for the child ourselves - we don't want
       * to use waitpid() because that might block the calling
       * thread (the child might handle SIGTERM and use several
       * seconds for cleanup/rollback).
       *
       * So we use GChildWatch instead.
       *
       * Note that we might be called from the finalizer so avoid
       * taking references to ourselves. We do need to pass the
       * GSource so we can nuke it once handled.
       */
      source = g_child_watch_source_new (self->child_pid);
      g_source_set_callback (source,
                             (GSourceFunc) child_watch_from_release_cb,
                             source,
                             (GDestroyNotify) g_source_destroy);
      g_source_attach (source, self->main_context);
      g_source_unref (source);

      self->child_pid = 0;
    }

  if (self->child_stdout != NULL)
    {
      g_string_free (self->child_stdout, TRUE);
      self->child_stdout = NULL;
    }

  if (self->child_stderr != NULL)
    {
      g_string_free (self->child_stderr, TRUE);
      self->child_stderr = NULL;
    }

  if (self->child_stdin_channel != NULL)
    {
      g_io_channel_unref (self->child_stdin_channel);
      self->child_stdin_channel = NULL;
    }
  if (self->child_stdout_channel != NULL)
    {
      g_io_channel_unref (self->child_stdout_channel);
      self->child_stdout_channel = NULL;
    }
  if (self->child_stderr_channel != NULL)
    {
      g_io_channel_unref (self->child_stderr_channel);
      self->child_stderr_channel = NULL;
    }

  if (self->child_stdin_source != NULL)
    {
      g_source_destroy (self->child_stdin_source);
      self->child_stdin_source = NULL;
    }
  if (self->child_stdout_source != NULL)
    {
      g_source_destroy (self->child_stdout_source);
      self->child_stdout_source = NULL;
    }
  if (self->child_stderr_source != NULL)
    {
      g_source_destroy (self->child_stderr_source);
      self->child_stderr_source = NULL;
    }

  if (self->child_stdin_fd != -1)
    {
      g_warn_if_fail (close (self->child_stdin_fd) == 0);
      self->child_stdin_fd = -1;
    }
  if (self->child_stdout_fd != -1)
    {
      g_warn_if_fail (close (self->child_stdout_fd) == 0);
      self->child_stdout_fd = -1;
    }
  if (self->child_stderr_fd != -1)
    {
      g_warn_if_fail (close (self->child_stderr_fd) == 0);
      self->child_stderr_fd = -1;
    }

  if (self->cancellable_handler_id > 0)
    {
      g_cancellable_disconnect (ul_job_get_cancellable (UL_JOB (self)),
                                self->cancellable_handler_id);
      self->cancellable_handler_id = 0;
    }
}
Example #4
0
guint
egg_spawn_async_with_callbacks (const gchar *working_directory, gchar **argv,
                                gchar **envp, GSpawnFlags flags, GPid *child_pid,
                                EggSpawnCallbacks *cbs, gpointer user_data,
                                GMainContext *context, GError **error)
{
	gint in_fd, out_fd, err_fd;
	CallbackSource *cb_source;
	GSource *source;
	guint tag;

	g_return_val_if_fail (argv != NULL, FALSE);
	g_return_val_if_fail ((cbs && cbs->standard_input == NULL) ||
	                      !(flags & G_SPAWN_CHILD_INHERITS_STDIN), 0);
	g_return_val_if_fail ((cbs && cbs->standard_output == NULL) ||
	                      !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), 0);
	g_return_val_if_fail ((cbs && cbs->standard_error == NULL) ||
	                      !(flags & G_SPAWN_STDERR_TO_DEV_NULL), 0);

	in_fd = out_fd = err_fd = -1;

	if (!g_spawn_async_with_pipes (working_directory, argv, envp, flags,
	                               cbs ? cbs->child_setup : NULL,
	                               user_data, child_pid,
	                               cbs && cbs->standard_input ? &in_fd : NULL,
	                               cbs && cbs->standard_output ? &out_fd : NULL,
	                               cbs && cbs->standard_error ? &err_fd : NULL,
	                               error))
		return 0;

	source = g_source_new (&cb_source_funcs, sizeof (CallbackSource));

	cb_source = (CallbackSource*)source;
	if (cbs != NULL)
		memcpy (&cb_source->callbacks, cbs, sizeof (EggSpawnCallbacks));

	cb_source->polls[0].fd = in_fd;
	if (in_fd >= 0) {
		g_assert (cb_source->callbacks.standard_input);
		cb_source->polls[0].events = G_IO_ERR | G_IO_OUT;
		g_source_add_poll (source, &cb_source->polls[0]);
	}
	cb_source->polls[1].fd = out_fd;
	if (out_fd >= 0) {
		g_assert (cb_source->callbacks.standard_output);
		cb_source->polls[1].events = G_IO_ERR | G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &cb_source->polls[1]);
	}
	cb_source->polls[2].fd = err_fd;
	if (err_fd >= 0) {
		g_assert (cb_source->callbacks.standard_error);
		cb_source->polls[2].events = G_IO_ERR | G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &cb_source->polls[2]);
	}

	if (context == NULL)
		context = g_main_context_default ();
	g_source_set_callback (source, unused_callback, user_data,
	                       cbs ? cbs->finalize_func : NULL);
	tag = g_source_attach (source, context);
	g_source_unref (source);

	return tag;
}
Example #5
0
void glibcurl_set_callback(GlibcurlCallback function, void* data) {
  g_source_set_callback(&curlSrc->source, (GSourceFunc)function, data,
                        NULL);
}
Example #6
0
/**
 * _gcr_gnupg_process_run_async:
 * @self: The process
 * @argv: (array zero-terminated=1): The arguments for the process, not including executable, terminated with %NULL.
 * @envp: (allow-none) (array zero-terminated=1): The environment for new process, terminated with %NULL.
 * @flags: Flags for starting the process.
 * @cancellable: (allow-none): Cancellation object
 * @callback: Will be called when operation completes.
 * @user_data: (closure): Data passed to callback.
 *
 * Run the gpg process. Only one 'run' operation can run per GcrGnupgProcess
 * object. The GcrGnupgProcess:output_data and GcrGnupgProcess:error_line
 * signals will be emitted when data is received from the gpg process.
 *
 * Unless the %GCR_GNUPG_PROCESS_RESPECT_LOCALE flag is specified, the process
 * will be run in the 'C' locale. If the %GCR_GNUPG_PROCESS_WITH_STATUS or
 * %GCR_GNUPG_PROCESS_WITH_ATTRIBUTES flags are set, then the gpg process
 * will be status and attribute output respectively. The
 * GcrGnupgProcess:status_record and GcrGnupgProcess:attribute_data signals
 * will provide this data.
 */
void
_gcr_gnupg_process_run_async (GcrGnupgProcess *self, const gchar **argv, const gchar **envp,
                              GcrGnupgProcessFlags flags, GCancellable *cancellable,
                              GAsyncReadyCallback callback, gpointer user_data)
{
	GError *error = NULL;
	GPtrArray *args;
	GPtrArray *envs;
	int child_fds[NUM_FDS];
	int status_fds[2] = { -1, -1 };
	int attribute_fds[2] = { -1, -1 };
	int output_fd = -1;
	int error_fd = -1;
	int input_fd = -1;
	GnupgSource *gnupg_source;
	GSource *source;
	GPid pid;
	guint i;

	g_return_if_fail (GCR_IS_GNUPG_PROCESS (self));
	g_return_if_fail (argv);
	g_return_if_fail (callback);
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

	g_return_if_fail (self->pv->running == FALSE);
	g_return_if_fail (self->pv->complete == FALSE);
	g_return_if_fail (self->pv->executable);

	self->pv->async_callback = callback;
	self->pv->user_data = user_data;

	for (i = 0; i < NUM_FDS; i++)
		child_fds[i] = -1;

	/* The command needs to be updated with these status and attribute fds */
	args = g_ptr_array_new_with_free_func (g_free);
	g_ptr_array_add (args, g_strdup (self->pv->executable));

	/* Spawn/child will close all other attributes, besides thesthose in child_fds */
	child_fds[FD_INPUT] = 0;
	child_fds[FD_OUTPUT] = 1;
	child_fds[FD_ERROR] = 2;

	if (flags & GCR_GNUPG_PROCESS_WITH_STATUS) {
		if (pipe (status_fds) < 0)
			g_return_if_reached ();
		child_fds[FD_STATUS] = status_fds[1];
		g_ptr_array_add (args, g_strdup ("--status-fd"));
		g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_STATUS]));
	}
	if (flags & GCR_GNUPG_PROCESS_WITH_ATTRIBUTES) {
		if (pipe (attribute_fds) < 0)
			g_return_if_reached ();
		child_fds[FD_ATTRIBUTE] = attribute_fds[1];
		g_ptr_array_add (args, g_strdup ("--attribute-fd"));
		g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_ATTRIBUTE]));
	}

	if (self->pv->directory) {
		g_ptr_array_add (args, g_strdup ("--homedir"));
		g_ptr_array_add (args, g_strdup (self->pv->directory));
	}

	/* All the remaining arguments */
	for (i = 0; argv[i] != NULL; i++)
		g_ptr_array_add (args, g_strdup (argv[i]));
	g_ptr_array_add (args, NULL);

	envs = g_ptr_array_new ();
	for (i = 0; envp && envp[i] != NULL; i++) {
		if (flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE ||
		    !g_str_has_prefix (envp[i], "LOCALE="))
			g_ptr_array_add (envs, (gpointer)envp[i]);
	}
	if (!(flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE))
		g_ptr_array_add (envs, (gpointer)"LOCALE=C");
	g_ptr_array_add (envs, NULL);

	gchar *command = g_strjoinv (" ", (gchar**)args->pdata);
	gchar *environ = g_strjoinv (", ", (gchar**)envs->pdata);
	g_debug ("running command: %s", command);
	g_debug ("process environment: %s", environ);
	g_free (command);
	g_free (environ);

	g_spawn_async_with_pipes (self->pv->directory, (gchar**)args->pdata,
	                          (gchar**)envs->pdata, G_SPAWN_DO_NOT_REAP_CHILD,
	                          on_gnupg_process_child_setup, child_fds,
	                          &pid, &input_fd, &output_fd, &error_fd, &error);

	g_ptr_array_free (args, TRUE);
	g_ptr_array_free (envs, TRUE);

	/* Close 'wrong' ends of extra file descriptors */
	close_fd (&(status_fds[1]));
	close_fd (&(attribute_fds[1]));

	self->pv->complete = FALSE;
	self->pv->running = TRUE;

	if (error) {
		close_fd (&(status_fds[0]));
		close_fd (&(attribute_fds[0]));
		g_assert (!self->pv->error);
		self->pv->error = error;
		complete_run_process (self);
		run_async_ready_callback_later (self);
		return;
	}

	g_debug ("process started: %d", (int)pid);

	source = g_source_new (&gnupg_source_funcs, sizeof (GnupgSource));

	/* Initialize the source */
	gnupg_source = (GnupgSource*)source;
	for (i = 0; i < NUM_FDS; i++)
		gnupg_source->polls[i].fd = -1;
	gnupg_source->error_buf = g_string_sized_new (128);
	gnupg_source->status_buf = g_string_sized_new (128);
	gnupg_source->process = g_object_ref (self);
	gnupg_source->child_pid = pid;

	gnupg_source->polls[FD_INPUT].fd = input_fd;
	if (input_fd >= 0) {
		gnupg_source->polls[FD_INPUT].events = G_IO_HUP | G_IO_OUT;
		g_source_add_poll (source, &gnupg_source->polls[FD_INPUT]);
	}
	gnupg_source->polls[FD_OUTPUT].fd = output_fd;
	if (output_fd >= 0) {
		gnupg_source->polls[FD_OUTPUT].events = G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &gnupg_source->polls[FD_OUTPUT]);
	}
	gnupg_source->polls[FD_ERROR].fd = error_fd;
	if (error_fd >= 0) {
		gnupg_source->polls[FD_ERROR].events = G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &gnupg_source->polls[FD_ERROR]);
	}
	gnupg_source->polls[FD_STATUS].fd = status_fds[0];
	if (status_fds[0] >= 0) {
		gnupg_source->polls[FD_STATUS].events = G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &gnupg_source->polls[FD_STATUS]);
	}
	gnupg_source->polls[FD_ATTRIBUTE].fd = attribute_fds[0];
	if (attribute_fds[0] >= 0) {
		gnupg_source->polls[FD_ATTRIBUTE].events = G_IO_HUP | G_IO_IN;
		g_source_add_poll (source, &gnupg_source->polls[FD_ATTRIBUTE]);
	}

	if (cancellable) {
		gnupg_source->cancellable = g_object_ref (cancellable);
		gnupg_source->cancel_sig = g_cancellable_connect (cancellable,
		                                                  G_CALLBACK (on_cancellable_cancelled),
		                                                  g_source_ref (source),
		                                                  (GDestroyNotify)g_source_unref);
	}

	g_assert (self->pv->source_sig == 0);
	g_source_set_callback (source, unused_callback, NULL, NULL);
	self->pv->source_sig = g_source_attach (source, g_main_context_default ());

	/* This assumes the outstanding reference to source */
	g_assert (gnupg_source->child_sig == 0);
	gnupg_source->child_sig = g_child_watch_add_full (G_PRIORITY_DEFAULT, pid,
	                                                  on_gnupg_process_child_exited,
	                                                  g_source_ref (source),
	                                                  (GDestroyNotify)g_source_unref);

	/* source is unreffed in complete_if_source_is_done() */
}
/*
 * owr_local_media_source_get_pad
 *
 * The beginning of a media source chain in the pipeline looks like this:
 *                                                             +------------+
 *                                                         /---+ inter*sink |
 * +--------+    +--------+   +------------+   +-----+    /    +------------+
 * | source +----+ scale? +---+ capsfilter +---+ tee +---/
 * +--------+    +--------+   +------------+   +-----+   \
 *                                                        \    +------------+
 *                                                         \---+ inter*sink |
 *                                                             +------------+
 *
 * For each newly requested pad a new inter*sink is added to the tee.
 * Note that this is a completely independent pipeline, and the complete
 * pipeline is only created once for a specific media source.
 *
 * Then for each newly requested pad another bin with a inter*src is
 * created, which is then going to be part of the transport agent
 * pipeline. The ghostpad of it is what we return here.
 *
 * +-----------+   +-------------------------------+   +----------+
 * | inter*src +---+ converters/queues/capsfilters +---+ ghostpad |
 * +-----------+   +-------------------------------+   +----------+
 *
 */
static GstElement *owr_local_media_source_request_source(OwrMediaSource *media_source, GstCaps *caps)
{
    OwrLocalMediaSource *local_source;
    OwrLocalMediaSourcePrivate *priv;
    GstElement *source_element = NULL;
    GstElement *source_pipeline;
    GHashTable *event_data;
    GValue *value;
#if defined(__linux__) && !defined(__ANDROID__)
    gchar *tmp;
#endif

    g_assert(media_source);
    local_source = OWR_LOCAL_MEDIA_SOURCE(media_source);
    priv = local_source->priv;

    /* only create the source bin for this media source once */
    if ((source_pipeline = _owr_media_source_get_source_bin(media_source)))
        GST_DEBUG_OBJECT(media_source, "Re-using existing source element/bin");
    else {
        OwrMediaType media_type = OWR_MEDIA_TYPE_UNKNOWN;
        OwrSourceType source_type = OWR_SOURCE_TYPE_UNKNOWN;
        GstElement *source, *source_process = NULL, *capsfilter = NULL, *tee;
        GstPad *sinkpad, *source_pad;
        GEnumClass *media_enum_class, *source_enum_class;
        GEnumValue *media_enum_value, *source_enum_value;
        gchar *bin_name;
        GstCaps *source_caps;
        GstBus *bus;
        GSource *bus_source;

        event_data = _owr_value_table_new();
        value = _owr_value_table_add(event_data, "start_time", G_TYPE_INT64);
        g_value_set_int64(value, g_get_monotonic_time());

        g_object_get(media_source, "media-type", &media_type, "type", &source_type, NULL);

        media_enum_class = G_ENUM_CLASS(g_type_class_ref(OWR_TYPE_MEDIA_TYPE));
        source_enum_class = G_ENUM_CLASS(g_type_class_ref(OWR_TYPE_SOURCE_TYPE));
        media_enum_value = g_enum_get_value(media_enum_class, media_type);
        source_enum_value = g_enum_get_value(source_enum_class, source_type);

        bin_name = g_strdup_printf("local-%s-%s-source-bin-%u",
            media_enum_value ? media_enum_value->value_nick : "unknown",
            source_enum_value ? source_enum_value->value_nick : "unknown",
            g_atomic_int_add(&unique_bin_id, 1));

        g_type_class_unref(media_enum_class);
        g_type_class_unref(source_enum_class);

        source_pipeline = gst_pipeline_new(bin_name);
        gst_pipeline_use_clock(GST_PIPELINE(source_pipeline), gst_system_clock_obtain());
        gst_element_set_base_time(source_pipeline, _owr_get_base_time());
        gst_element_set_start_time(source_pipeline, GST_CLOCK_TIME_NONE);
        g_free(bin_name);
        bin_name = NULL;

#ifdef OWR_DEBUG
        g_signal_connect(source_pipeline, "deep-notify", G_CALLBACK(_owr_deep_notify), NULL);
#endif

        bus = gst_pipeline_get_bus(GST_PIPELINE(source_pipeline));
        bus_source = gst_bus_create_watch(bus);
        g_source_set_callback(bus_source, (GSourceFunc) bus_call, media_source, NULL);
        g_source_attach(bus_source, _owr_get_main_context());
        g_source_unref(bus_source);

        GST_DEBUG_OBJECT(local_source, "media_type: %d, type: %d", media_type, source_type);

        if (media_type == OWR_MEDIA_TYPE_UNKNOWN || source_type == OWR_SOURCE_TYPE_UNKNOWN) {
            GST_ERROR_OBJECT(local_source,
                "Cannot connect source with unknown type or media type to other component");
            goto done;
        }

        switch (media_type) {
        case OWR_MEDIA_TYPE_AUDIO:
            {
            switch (source_type) {
            case OWR_SOURCE_TYPE_CAPTURE:
                CREATE_ELEMENT(source, AUDIO_SRC, "audio-source");
#if !defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR
/*
    Default values for buffer-time and latency-time on android are 200ms and 20ms.
    The minimum latency-time that can be used on Android is 20ms, and using
    a 40ms buffer-time with a 20ms latency-time causes crackling audio.
    So let's just stick with the defaults.
*/
#if !defined(__ANDROID__)
                g_object_set(source, "buffer-time", G_GINT64_CONSTANT(40000),
                    "latency-time", G_GINT64_CONSTANT(10000), NULL);
#endif
                if (priv->device_index > -1) {
#ifdef __APPLE__
                    g_object_set(source, "device", priv->device_index, NULL);
#elif defined(__linux__) && !defined(__ANDROID__)
                    tmp = g_strdup_printf("%d", priv->device_index);
                    g_object_set(source, "device", tmp, NULL);
                    g_free(tmp);
#endif
                }
#endif
                break;
            case OWR_SOURCE_TYPE_TEST:
                CREATE_ELEMENT(source, "audiotestsrc", "audio-source");
                g_object_set(source, "is-live", TRUE, NULL);
                break;
            case OWR_SOURCE_TYPE_UNKNOWN:
            default:
                g_assert_not_reached();
                goto done;
            }

            break;
            }
        case OWR_MEDIA_TYPE_VIDEO:
        {
            GstPad *srcpad;
            GstCaps *device_caps;

            switch (source_type) {
            case OWR_SOURCE_TYPE_CAPTURE:
                CREATE_ELEMENT(source, VIDEO_SRC, "video-source");
                if (priv->device_index > -1) {
#if defined(__APPLE__) && !TARGET_IPHONE_SIMULATOR
                    g_object_set(source, "device-index", priv->device_index, NULL);
#elif defined(__ANDROID__)
                    g_object_set(source, "cam-index", priv->device_index, NULL);
#elif defined(__linux__)
                    tmp = g_strdup_printf("/dev/video%d", priv->device_index);
                    g_object_set(source, "device", tmp, NULL);
                    g_free(tmp);
#endif
                }
                break;
            case OWR_SOURCE_TYPE_TEST: {
                GstElement *src, *time;
                GstPad *srcpad;

                source = gst_bin_new("video-source");

                CREATE_ELEMENT(src, "videotestsrc", "videotestsrc");
                g_object_set(src, "is-live", TRUE, NULL);
                gst_bin_add(GST_BIN(source), src);

                time = gst_element_factory_make("timeoverlay", "timeoverlay");
                if (time) {
                    g_object_set(time, "font-desc", "Sans 60", NULL);
                    gst_bin_add(GST_BIN(source), time);
                    gst_element_link(src, time);
                    srcpad = gst_element_get_static_pad(time, "src");
                } else
                    srcpad = gst_element_get_static_pad(src, "src");

                gst_element_add_pad(source, gst_ghost_pad_new("src", srcpad));
                gst_object_unref(srcpad);

                break;
            }
            case OWR_SOURCE_TYPE_UNKNOWN:
            default:
                g_assert_not_reached();
                goto done;
            }

            /* First try to see if we can just get the format we want directly */

            source_caps = gst_caps_new_empty();
#if GST_CHECK_VERSION(1, 5, 0)
            gst_caps_foreach(caps, fix_video_caps_framerate, source_caps);
#else
            _owr_gst_caps_foreach(caps, fix_video_caps_framerate, source_caps);
#endif
            /* Now see what the device can really produce */
            srcpad = gst_element_get_static_pad(source, "src");
            gst_element_set_state(source, GST_STATE_READY);
            device_caps = gst_pad_query_caps(srcpad, source_caps);

            if (gst_caps_is_empty(device_caps)) {
                /* Let's see if it works when we drop format constraints (which can be dealt with downsteram) */
                GstCaps *tmp = source_caps;
                source_caps = gst_caps_new_empty();
#if GST_CHECK_VERSION(1, 5, 0)
                gst_caps_foreach(tmp, fix_video_caps_format, source_caps);
#else
                _owr_gst_caps_foreach(tmp, fix_video_caps_format, source_caps);
#endif
                gst_caps_unref(tmp);

                gst_caps_unref(device_caps);
                device_caps = gst_pad_query_caps(srcpad, source_caps);

                if (gst_caps_is_empty(device_caps)) {
                    /* Accepting any format didn't work, we're going to hope that scaling fixes it */
                    CREATE_ELEMENT(source_process, "videoscale", "video-source-scale");
                    gst_bin_add(GST_BIN(source_pipeline), source_process);
                }
            }

            gst_caps_unref(device_caps);
            gst_object_unref(srcpad);

#if defined(__APPLE__) && TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
            /* Force NV12 on iOS else the source can negotiate BGRA
             * ercolorspace can do NV12 -> BGRA and NV12 -> I420 which is what
             * is needed for Bowser */
            gst_caps_set_simple(source_caps, "format", G_TYPE_STRING, "NV12", NULL);
#endif

            CREATE_ELEMENT(capsfilter, "capsfilter", "video-source-capsfilter");
            g_object_set(capsfilter, "caps", source_caps, NULL);
            gst_caps_unref(source_caps);
            gst_bin_add(GST_BIN(source_pipeline), capsfilter);

            break;
        }
        case OWR_MEDIA_TYPE_UNKNOWN:
        default:
            g_assert_not_reached();
            goto done;
        }
        g_assert(source);

        source_pad = gst_element_get_static_pad(source, "src");
        g_signal_connect(source_pad, "notify::caps", G_CALLBACK(on_caps), media_source);
        gst_object_unref(source_pad);

        CREATE_ELEMENT(tee, "tee", "source-tee");
        g_object_set(tee, "allow-not-linked", TRUE, NULL);

        gst_bin_add_many(GST_BIN(source_pipeline), source, tee, NULL);

        /* Many sources don't like reconfiguration and it's pointless
         * here anyway right now. No need to reconfigure whenever something
         * is added to the tee or removed.
         * We will have to implement reconfiguration differently later by
         * selecting the best caps based on all consumers.
         */
        sinkpad = gst_element_get_static_pad(tee, "sink");
        gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, drop_reconfigure_event, NULL, NULL);
        gst_object_unref(sinkpad);

        if (!source)
            GST_ERROR_OBJECT(media_source, "Failed to create source element!");

        if (capsfilter) {
            LINK_ELEMENTS(capsfilter, tee);
            if (source_process) {
                LINK_ELEMENTS(source_process, capsfilter);
                LINK_ELEMENTS(source, source_process);
            } else
                LINK_ELEMENTS(source, capsfilter);
        } else if (source_process) {
            LINK_ELEMENTS(source_process, tee);
            LINK_ELEMENTS(source, source_process);
        } else
            LINK_ELEMENTS(source, tee);

        gst_element_sync_state_with_parent(tee);
        if (capsfilter)
            gst_element_sync_state_with_parent(capsfilter);
        if (source_process)
            gst_element_sync_state_with_parent(source_process);
        gst_element_sync_state_with_parent(source);

        _owr_media_source_set_source_bin(media_source, source_pipeline);
        _owr_media_source_set_source_tee(media_source, tee);
        if (gst_element_set_state(source_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
            GST_ERROR("Failed to set local source pipeline %s to playing", GST_OBJECT_NAME(source_pipeline));
            /* FIXME: We should handle this and don't expose the source */
        }

        value = _owr_value_table_add(event_data, "end_time", G_TYPE_INT64);
        g_value_set_int64(value, g_get_monotonic_time());
        OWR_POST_EVENT(media_source, LOCAL_SOURCE_STARTED, event_data);

        g_signal_connect(tee, "pad-removed", G_CALLBACK(tee_pad_removed_cb), media_source);
    }
    gst_object_unref(source_pipeline);

    source_element = OWR_MEDIA_SOURCE_CLASS(owr_local_media_source_parent_class)->request_source(media_source, caps);

done:
    return source_element;
}
static gboolean
gst_soup_http_client_sink_start (GstBaseSink * sink)
{
  GstSoupHttpClientSink *souphttpsink = GST_SOUP_HTTP_CLIENT_SINK (sink);

  if (souphttpsink->prop_session) {
    souphttpsink->session = souphttpsink->prop_session;
  } else {
    GSource *source;
    GError *error = NULL;

    souphttpsink->context = g_main_context_new ();

    /* set up idle source to signal when the main loop is running and
     * it's safe for ::stop() to call g_main_loop_quit() */
    source = g_idle_source_new ();
    g_source_set_callback (source, thread_ready_idle_cb, sink, NULL);
    g_source_attach (source, souphttpsink->context);
    g_source_unref (source);

    souphttpsink->loop = g_main_loop_new (souphttpsink->context, TRUE);

    g_mutex_lock (&souphttpsink->mutex);

    souphttpsink->thread = g_thread_try_new ("souphttpclientsink-thread",
        thread_func, souphttpsink, &error);

    if (error != NULL) {
      GST_DEBUG_OBJECT (souphttpsink, "failed to start thread, %s",
          error->message);
      g_error_free (error);
      g_mutex_unlock (&souphttpsink->mutex);
      return FALSE;
    }

    GST_LOG_OBJECT (souphttpsink, "waiting for main loop thread to start up");
    g_cond_wait (&souphttpsink->cond, &souphttpsink->mutex);
    g_mutex_unlock (&souphttpsink->mutex);
    GST_LOG_OBJECT (souphttpsink, "main loop thread running");

    if (souphttpsink->proxy == NULL) {
      souphttpsink->session =
          soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT,
          souphttpsink->context, SOUP_SESSION_USER_AGENT,
          souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout,
          SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT,
          NULL);
    } else {
      souphttpsink->session =
          soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT,
          souphttpsink->context, SOUP_SESSION_USER_AGENT,
          souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout,
          SOUP_SESSION_PROXY_URI, souphttpsink->proxy, NULL);
    }

    g_signal_connect (souphttpsink->session, "authenticate",
        G_CALLBACK (authenticate), souphttpsink);
  }

  /* Set up logging */
  gst_soup_util_log_setup (souphttpsink->session, souphttpsink->log_level,
      GST_ELEMENT (souphttpsink));

  return TRUE;
}
Example #9
0
static void
auth_fn (SMBCCTX    *smb_context,
         const char *server,
         const char *share,
         char       *workgroup,
         int         wgmaxlen,
         char       *username,
         int         unmaxlen,
         char       *password,
         int         pwmaxlen)
{
  PpSamba *samba;
  GSource *source;
  SMBData *data;

  data = (SMBData *) smbc_getOptionUserData (smb_context);
  samba = data->samba;

  if (!data->cancelled)
    {
      samba->priv->server = g_strdup (server);
      samba->priv->share = g_strdup (share);
      samba->priv->workgroup = g_strdup (workgroup);
      samba->priv->username = g_strdup (username);
      samba->priv->password = g_strdup (password);

      source = g_idle_source_new ();
      g_source_set_callback (source,
                             get_auth_info,
                             data,
                             NULL);
      g_source_attach (source, data->context);
      g_source_unref (source);

      samba->priv->waiting = TRUE;

      /*
       * smbclient needs to get authentication data
       * from this synchronous callback so we are blocking
       * until we get them
       */
      while (samba->priv->waiting)
        {
          g_usleep (POLL_DELAY);
        }

      /* Samba tries to call the auth_fn again if we just set the values
       * to NULL when we want to cancel the authentication 
       */
      if (samba->priv->username == NULL && samba->priv->password == NULL)
        data->cancelled = TRUE;

      if (samba->priv->username != NULL)
        {
          if (g_strcmp0 (username, samba->priv->username) != 0)
            g_strlcpy (username, samba->priv->username, unmaxlen);
        }
      else
        {
          username[0] = '\0';
        }

      if (samba->priv->password != NULL)
        {
          if (g_strcmp0 (password, samba->priv->password) != 0)
            g_strlcpy (password, samba->priv->password, pwmaxlen);
        }
      else
        {
          password[0] = '\0';
        }

    }
}
static gint
nm_openconnect_start_openconnect_binary (NMOPENCONNECTPlugin *plugin,
                                         NMSettingVPN *s_vpn,
                                         GError **error)
{
	NMOPENCONNECTPluginPrivate *priv = NM_OPENCONNECT_PLUGIN_GET_PRIVATE (plugin);
	GPid	pid;
	const char **openconnect_binary = NULL;
	GPtrArray *openconnect_argv;
	GSource *openconnect_watch;
	gint	stdin_fd;
	const char *props_vpn_gw, *props_cookie, *props_cacert, *props_mtu, *props_gwcert, *props_proxy;
	
	/* Find openconnect */
	openconnect_binary = openconnect_binary_paths;
	while (*openconnect_binary != NULL) {
		if (g_file_test (*openconnect_binary, G_FILE_TEST_EXISTS))
			break;
		openconnect_binary++;
	}

	if (!*openconnect_binary) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		             "%s",
		             _("Could not find openconnect binary."));
		return -1;
	}

	/* The actual gateway to use (after redirection) comes from the auth
	   dialog, so it's in the secrets hash not the properties */
	props_vpn_gw = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_GATEWAY);
	if (!props_vpn_gw || !strlen (props_vpn_gw) ) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		             "%s",
		             _("No VPN gateway specified."));
		return -1;
	}

	props_cookie = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_COOKIE);
	if (!props_cookie || !strlen (props_cookie)) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		             "%s",
		             _("No WebVPN cookie provided."));
		return -1;
	}
	props_gwcert = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_GWCERT);

	props_cacert = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_CACERT);
	props_mtu = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_MTU);

	props_proxy = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_PROXY);

	openconnect_argv = g_ptr_array_new ();
	g_ptr_array_add (openconnect_argv, (gpointer) (*openconnect_binary));

	if (props_gwcert && strlen(props_gwcert)) {
		g_ptr_array_add (openconnect_argv, (gpointer) "--servercert");
		g_ptr_array_add (openconnect_argv, (gpointer) props_gwcert);
	} else if (props_cacert && strlen(props_cacert)) {
		g_ptr_array_add (openconnect_argv, (gpointer) "--cafile");
		g_ptr_array_add (openconnect_argv, (gpointer) props_cacert);
	}

	if (props_mtu && strlen(props_mtu)) {
		g_ptr_array_add (openconnect_argv, (gpointer) "--mtu");
		g_ptr_array_add (openconnect_argv, (gpointer) props_mtu);
	}

	if (props_proxy && strlen(props_proxy)) {
		g_ptr_array_add (openconnect_argv, (gpointer) "--proxy");
		g_ptr_array_add (openconnect_argv, (gpointer) props_proxy);
	}
		
	g_ptr_array_add (openconnect_argv, (gpointer) "--syslog");
	g_ptr_array_add (openconnect_argv, (gpointer) "--cookie-on-stdin");

	g_ptr_array_add (openconnect_argv, (gpointer) "--script");
	g_ptr_array_add (openconnect_argv, (gpointer) NM_OPENCONNECT_HELPER_PATH);

	priv->tun_name = create_persistent_tundev ();
	if (priv->tun_name) {
		g_ptr_array_add (openconnect_argv, (gpointer) "--interface");
		g_ptr_array_add (openconnect_argv, (gpointer) priv->tun_name);
	}

	g_ptr_array_add (openconnect_argv, (gpointer) props_vpn_gw);

	if (debug)
		g_ptr_array_add (openconnect_argv, (gpointer) "--verbose");

	g_ptr_array_add (openconnect_argv, NULL);

	if (!g_spawn_async_with_pipes (NULL, (char **) openconnect_argv->pdata, NULL,
	                               G_SPAWN_DO_NOT_REAP_CHILD,
	                               openconnect_drop_child_privs, priv->tun_name,
	                               &pid, &stdin_fd, NULL, NULL, error)) {
		g_ptr_array_free (openconnect_argv, TRUE);
		g_warning ("openconnect failed to start.  error: '%s'", (*error)->message);
		return -1;
	}
	g_ptr_array_free (openconnect_argv, TRUE);

	g_message ("openconnect started with pid %d", pid);

	if (write(stdin_fd, props_cookie, strlen(props_cookie)) != strlen(props_cookie) ||
	    write(stdin_fd, "\n", 1) != 1) {
		g_warning ("openconnect didn't eat the cookie we fed it");
		return -1;
	}

	close(stdin_fd);

	NM_OPENCONNECT_PLUGIN_GET_PRIVATE (plugin)->pid = pid;
	openconnect_watch = g_child_watch_source_new (pid);
	g_source_set_callback (openconnect_watch, (GSourceFunc) openconnect_watch_cb, plugin, NULL);
	g_source_attach (openconnect_watch, NULL);
	g_source_unref (openconnect_watch);

	return 0;
}
static gboolean
update_clock (gpointer data)
{
	GnomeWallClock   *self = data;
	CDesktopClockFormat clock_format;
	const char *format_string;
	gboolean show_full_date;
	gboolean show_weekday;
	gboolean show_seconds;
	GSource *source;
	GDateTime *now;
	GDateTime *expiry;

	clock_format = g_settings_get_enum (self->priv->desktop_settings, "clock-format");
	show_weekday = !self->priv->time_only;
	show_full_date = show_weekday && g_settings_get_boolean (self->priv->desktop_settings, "clock-show-date");
	show_seconds = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-seconds");

	now = g_date_time_new_now_local ();
	if (show_seconds)
		expiry = g_date_time_add_seconds (now, 1);
	else
		expiry = g_date_time_add_seconds (now, 60 - g_date_time_get_second (now));
  
	if (self->priv->clock_update_id)
		g_source_remove (self->priv->clock_update_id);
  
	source = _gnome_datetime_source_new (now, expiry, TRUE);
	g_source_set_priority (source, G_PRIORITY_HIGH);
	g_source_set_callback (source, update_clock, self, NULL);
	self->priv->clock_update_id = g_source_attach (source, NULL);
	g_source_unref (source);

	if (clock_format == C_DESKTOP_CLOCK_FORMAT_24H) {
		if (show_full_date) {
			/* Translators: This is the time format with full date used
			   in 24-hour mode. */
			format_string = show_seconds ? _("%a %b %e, %R:%S")
				: _("%a %b %e, %R");
		} else if (show_weekday) {
			/* Translators: This is the time format with day used
			   in 24-hour mode. */
			format_string = show_seconds ? _("%a %R:%S")
				: _("%a %R");
		} else {
			/* Translators: This is the time format without date used
			   in 24-hour mode. */
			format_string = show_seconds ? _("%R:%S") : _("%R");
		}
	} else {
		if (show_full_date) {
			/* Translators: This is a time format with full date used
			   for AM/PM. */
			format_string = show_seconds ? _("%a %b %e, %l:%M:%S %p")
				: _("%a %b %e, %l:%M %p");
		} else if (show_weekday) {
			/* Translators: This is a time format with day used
			   for AM/PM. */
			format_string = show_seconds ? _("%a %l:%M:%S %p")
				: _("%a %l:%M %p");
		} else {
			/* Translators: This is a time format without date used
			   for AM/PM. */
			format_string = show_seconds ? _("%l:%M:%S %p")
				: _("%l:%M %p");
		}
	}

	g_free (self->priv->clock_string);
	self->priv->clock_string = g_date_time_format (now, format_string);

	g_date_time_unref (now);
	g_date_time_unref (expiry);
      
	g_object_notify ((GObject*)self, "clock");

	return FALSE;
}
Example #12
0
/*
 * Forks a ssh to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runssh(
    struct tcp_conn *	rc,
    const char *	amandad_path,
    const char *	client_username,
    const char *	ssh_keys,
    const char *        client_port)
{
    int rpipe[2], wpipe[2];
    char *xamandad_path = (char *)amandad_path;
    char *xclient_username = (char *)client_username;
    char *xssh_keys = (char *)ssh_keys;
    char *xclient_port = (char *)client_port;
    GPtrArray *myargs;
    gchar *ssh_options[100] = {SSH_OPTIONS, NULL};
    gchar **ssh_option;
    gchar *cmd;

    memset(rpipe, -1, sizeof(rpipe));
    memset(wpipe, -1, sizeof(wpipe));
    if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
	g_free(rc->errmsg);
	rc->errmsg = g_strdup_printf(_("pipe: %s"), strerror(errno));
	return (-1);
    }

    if(!xamandad_path || strlen(xamandad_path) <= 1) 
	xamandad_path = g_strjoin(NULL, amlibexecdir, "/", "amandad", NULL);
    if(!xclient_username || strlen(xclient_username) <= 1)
	xclient_username = CLIENT_LOGIN;
    if(!xclient_port || strlen(xclient_port) <= 1)
	xclient_port = NULL;

    myargs = g_ptr_array_sized_new(20);
    g_ptr_array_add(myargs, SSH);
    for (ssh_option = ssh_options; *ssh_option != NULL; ssh_option++) {
	g_ptr_array_add(myargs, *ssh_option);
    }
    g_ptr_array_add(myargs, "-l");
    g_ptr_array_add(myargs, xclient_username);
    if (xclient_port) {
	g_ptr_array_add(myargs, "-p");
	g_ptr_array_add(myargs, xclient_port);
    }
    if (ssh_keys && strlen(ssh_keys) > 1) {
	g_ptr_array_add(myargs, "-i");
	g_ptr_array_add(myargs, xssh_keys);
    }
    g_ptr_array_add(myargs, rc->hostname);
    g_ptr_array_add(myargs, xamandad_path);
    g_ptr_array_add(myargs, "-auth=ssh");
    g_ptr_array_add(myargs, NULL);

    cmd = g_strjoinv(" ", (gchar **)myargs->pdata);
    g_debug("exec: %s", cmd);
    g_free(cmd);

    switch (rc->pid = fork()) {
    case -1:
	g_free(rc->errmsg);
	rc->errmsg = g_strdup_printf(_("fork: %s"), strerror(errno));
	aclose(rpipe[0]);
	aclose(rpipe[1]);
	aclose(wpipe[0]);
	aclose(wpipe[1]);
	return (-1);
    case 0:
	dup2(wpipe[0], 0);
	dup2(rpipe[1], 1);
	break;
    default:
	rc->read = rpipe[0];
	aclose(rpipe[1]);
	rc->write = wpipe[1];
	aclose(wpipe[0]);
	rc->child_watch = new_child_watch_source(rc->pid);
	g_source_set_callback(rc->child_watch,
            (GSourceFunc)ssh_child_watch_callback, rc, NULL);
	g_source_attach(rc->child_watch, NULL);
	g_source_unref(rc->child_watch);

	return (0);
    }

    /* drop root privs for good */
    set_root_privs(-1);

    safe_fd(-1, 0);

    execvp(SSH, (gchar **)myargs->pdata);

    error("error: couldn't exec %s: %s", SSH, strerror(errno));

    /* should never go here, shut up compiler warning */
    return(-1);
}
Example #13
0
gboolean
fs_rawudp_component_gather_local_candidates (FsRawUdpComponent *self,
    GError **error)
{
  if (self->priv->gathered)
  {
    g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
        "Call gather local candidates twice on the same component");
    return FALSE;
  }

  if (!self->priv->udpport)
  {   g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS,
        "You can not call gather_local_candidate() after the stream has"
        " been stopped");
    return FALSE;
  }

#ifdef HAVE_GUPNP

  if (self->priv->upnp_igd  &&
      (self->priv->upnp_mapping || self->priv->upnp_discovery))
  {
    guint port;
    GList *ips;

    port = fs_rawudp_transmitter_udpport_get_port (self->priv->udpport);

    ips = nice_interfaces_get_local_ips (FALSE);
    ips = filter_ips (ips, TRUE, FALSE);

    if (ips)
    {
      gchar *ip = g_list_first (ips)->data;
      GMainContext *ctx;

      if (self->priv->upnp_discovery)
      {
        FS_RAWUDP_COMPONENT_LOCK (self);
        self->priv->upnp_signal_id = g_signal_connect (self->priv->upnp_igd,
            "mapped-external-port",
            G_CALLBACK (_upnp_mapped_external_port), self);
        FS_RAWUDP_COMPONENT_UNLOCK (self);
      }

      GST_DEBUG ("Doing UPnP Discovery for local ip:%s port:%u", ip, port);

      gupnp_simple_igd_add_port (GUPNP_SIMPLE_IGD (self->priv->upnp_igd),
          "UDP", port, ip, port, self->priv->upnp_mapping_timeout,
          "Farstream Raw UDP transmitter " PACKAGE_VERSION);


      if (self->priv->upnp_discovery)
      {
        FS_RAWUDP_COMPONENT_LOCK (self);
        self->priv->upnp_discovery_timeout_src = g_timeout_source_new_seconds (
            self->priv->upnp_discovery_timeout);
        g_source_set_callback (self->priv->upnp_discovery_timeout_src,
            _upnp_discovery_timeout, self, NULL);
        g_object_get (self->priv->upnp_igd, "main-context", &ctx, NULL);
        g_source_attach (self->priv->upnp_discovery_timeout_src, ctx);
        FS_RAWUDP_COMPONENT_UNLOCK (self);
      }
    }
    else
    {
      FS_RAWUDP_COMPONENT_LOCK (self);
      fs_rawudp_component_stop_upnp_discovery_locked (self);
      FS_RAWUDP_COMPONENT_UNLOCK (self);
    }

    /* free list of ips */
    g_list_foreach (ips, (GFunc) g_free, NULL);
    g_list_free (ips);

  }
#endif

  if (self->priv->stun_ip)
    return fs_rawudp_component_start_stun (self, error);
#ifdef HAVE_GUPNP
  else if (!self->priv->upnp_signal_id)
    return fs_rawudp_component_emit_local_candidates (self, error);
  else
    return TRUE;
#else
  else
    return fs_rawudp_component_emit_local_candidates (self, error);
static void*
plain_sockets_thread_func (void *data)
{
  GMainContext *context;
  ClientData cd;
  int fd;
  struct sockaddr_un addr;
  GIOChannel *channel;
  GSource *gsource;
  
  g_printerr ("Starting client thread %p\n",
              g_thread_self());
  
  fd = socket (PF_UNIX, SOCK_STREAM, 0);
  
  if (fd < 0)
    {
      g_printerr ("Failed to create socket: %s",
                  strerror (errno)); 
      exit (1);
    }

  _DBUS_ZERO (addr);
  addr.sun_family = AF_UNIX;

#ifdef HAVE_ABSTRACT_SOCKETS
  /* remember that abstract names aren't nul-terminated so we rely
   * on sun_path being filled in with zeroes above.
   */
  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
  strncpy (&addr.sun_path[1], plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 2);
  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
#else /* HAVE_ABSTRACT_SOCKETS */
  strncpy (addr.sun_path, plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 1);
#endif /* ! HAVE_ABSTRACT_SOCKETS */
  
  if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
    {      
      g_printerr ("Failed to connect to socket %s: %s",
                  plain_sockets_address, strerror (errno));
      exit (1);
    }

  context = g_main_context_new ();

  cd.iterations = 1;
  cd.loop = g_main_loop_new (context, FALSE);
  cd.vtable = data;

  channel = g_io_channel_unix_new (fd);
  
  gsource = g_io_create_watch (channel,
                               G_IO_IN | G_IO_OUT |
                               G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI);

  g_source_set_callback (gsource,
                         (GSourceFunc)plain_sockets_client_side_watch,
                         &cd, NULL);

  g_source_attach (gsource, context);

  g_io_channel_unref (channel);

  g_printerr ("Client thread writing to prime pingpong\n");
  write_junk (fd, echo_call_size, cd.vtable->fake_malloc_overhead);
  g_printerr ("Client thread done writing primer\n");

  g_printerr ("Client thread entering main loop\n");
  g_main_loop_run (cd.loop);
  g_printerr ("Client thread %p exiting main loop\n",
              g_thread_self());

  g_source_destroy (gsource);
  
  close (fd);
  
  g_main_loop_unref (cd.loop);
  g_main_context_unref (context);

  return NULL;
}
Example #15
0
/* program main */
int main()
{
    char* tmsg = NULL;
    int   main_tmo = 5;
    int   loop1_tmo = 2 * main_tmo;
    int   loop2_tmo = 3;

    twmsg(__func__, "STARTING");


    /* setup the main loop structure */
    tmsg=g_strdup_printf("creating main context, TMO=%d", main_tmo);
    twmsg(__func__, tmsg);
    g_free(tmsg);

    loop_main.name         = g_strdup("MAIN");
    loop_main.tmo          = main_tmo;  /* seconds for callback */
    loop_main.main_context = NULL;   /* use default */
    loop_main.main_loop    = g_main_loop_new (loop_main.main_context, FALSE);
    loop_main.idle         = g_idle_source_new();
    g_source_set_callback(loop_main.idle, idle_func, &loop_main, NULL);
    g_source_attach(loop_main.idle, loop_main.main_context);
    loop_main.main_context = NULL;  /* use default */
    loop_main.Q            = NULL;  /* no queue, for now */
    loop_main.TH           = NULL; /* this is the main thread so no thread info */

    /* interval, function callback, userdata 
     * - internally creates source and attaches to main context */
    g_timeout_add_seconds(loop_main.tmo, tmo_callback, "tmo_callback");


    /* create info for the worker thread and set up its context, then run it */
    tmsg=g_strdup_printf("creating loop1 context, TMO=%d", loop1_tmo);
    twmsg(__func__, tmsg);
    g_free(tmsg);
   
    loop_main.name         = g_strdup("LOOP_1");
    loop_1.tmo = loop1_tmo;
    loop_1.main_context    = g_main_context_new();
    loop_1.main_loop       = g_main_loop_new(loop_1.main_context, FALSE);
    loop_1.idle            = g_idle_source_new();
    g_source_set_callback(loop_1.idle, idle_func, &loop_1, NULL);
    g_source_attach(loop_1.idle, loop_1.main_context);
    loop_1.Q               = g_async_queue_new();

    /* manually create new timeout source and attach to main context of nth Loop 
     * - timeout is in ms so multiply seconds by 1000
     * - set priority to 1 or 2
     * - optionally set name 
     */
    GSource *source1 = g_timeout_source_new (loop_1.tmo*1000);
    g_source_set_priority (source1, 1);
    g_source_set_callback (source1, tmo_callback, "tmo_loop1_callback", NULL);
    g_source_set_name (source1, "LOOP1_TMO"); 
    g_source_attach (source1, loop_1.main_context);

    /* run the thread which will run the main context */
    loop_1.TH           = g_thread_new("LOOP1_TH", loop_thread, &loop_1);  



    /* create info for the second worker thread and set up its context, then run it */
    tmsg=g_strdup_printf("creating loop2 context, TMO=%d", loop2_tmo);
    twmsg(__func__, tmsg);
    g_free(tmsg);

    /* init the data for the context */
    loop_2.name         = g_strdup("LOOP_2");
    loop_2.tmo = loop2_tmo;
    loop_2.main_context = g_main_context_new();
    loop_2.main_loop    = g_main_loop_new(loop_2.main_context, FALSE);
    loop_2.idle         = g_idle_source_new();
    g_source_set_callback(loop_2.idle, idle_func, &loop_2, NULL);
    g_source_attach(loop_2.idle, loop_2.main_context);
    loop_2.Q            = g_async_queue_new();

    /* manually create new timeout source and attach to main context of nth Loop 
     * - timeout is in ms so multiply seconds by 1000
     * - set priority to 1 or 2
     * - optionally set name 
     */
    GSource *source2 = g_timeout_source_new (loop_2.tmo*1000);
    g_source_set_priority (source2, 1);
    g_source_set_callback (source2, tmo_callback, "tmo_loop2_callback", NULL);
    g_source_set_name (source2, "LOOP2_TMO"); 
    g_source_attach (source2, loop_2.main_context);

    /* run the second thread */
    loop_2.TH           = g_thread_new("LOOP2_TH", loop_thread, &loop_2);

  
    /* run the main loop */
    g_main_loop_run(loop_main.main_loop);

    
    return 0;
}
Example #16
0
int main(){
	int usbErr = 0;
	int iface_num[NUM_IFACES];
	iface_num[0]= 1; // bulk interface
	libusb_context *imu_host = NULL;
	libusb_device_handle *imu_handle = NULL;
	libusbSource * usb_source = NULL;
	struct libusb_transfer * bulkIO[2]; //todo: have something like endpoint[numendpoints] and place each transfer at the ep they correspond to?
	struct libusb_transfer * bulk_in  = NULL;//bulkIO[0];
	struct libusb_transfer * bulk_out = NULL;//bulkIO[1];
	unsigned char * bulk_in_buffer = NULL;
	unsigned char * bulk_out_buffer = NULL;

	GMainContext * edfc_context = NULL;
	GIOChannel * g_stdin = NULL;
	GSource * gs_stdin = NULL;

	sfd = open_port();

	usbErr = libusb_init(&imu_host);
	if(usbErr){
		print_libusb_error(usbErr, "libusb_init");
		exit(EXIT_FAILURE);
	}
	libusb_set_debug(imu_host, 3);

	imu_handle = open_usb_device_handle(imu_host, is_imu_device, iface_num, NUM_IFACES);
	if(!imu_handle){
		printf("**imu_handle acquisition error\n");
		libusb_exit(imu_host);
		exit(EXIT_FAILURE);
	}

	usb_source = libusb_source_new(imu_host);
//	g_source_set_callback((GSource*) usb_source, (GSourceFunc)libusb_mainloop_error_cb, &edfc_main, NULL);

	bulk_in  = libusb_alloc_transfer(0);
	bulk_out = libusb_alloc_transfer(0);
	bulk_in_buffer  = calloc(MAX_PACKET_SIZE, sizeof(unsigned char)); //todo: slice allocate?
	bulk_out_buffer = calloc(MAX_PACKET_SIZE, sizeof(unsigned char)); //todo: slice allocate?
	libusb_fill_bulk_transfer(bulk_in,
							  imu_handle,
							  BULK_IN_EP,
							  bulk_in_buffer,
							  MAX_PACKET_SIZE,
							  bulk_in_cb,
							  NULL,
							  0);
	libusb_fill_bulk_transfer(bulk_out,
							  imu_handle,
							  BULK_OUT_EP,
							  bulk_out_buffer,
							  MAX_PACKET_SIZE,
							  bulk_out_cb,
							  NULL,
							  0);
	bulkIO[0] = bulk_in;
	bulkIO[1] = bulk_out;

	edfc_context = g_main_context_new(); //edfc == event driven flight computer
	edfc_main = g_main_loop_new(edfc_context, FALSE);
	g_stdin = g_io_channel_unix_new(fileno(stdin));
	if(!g_stdin){
		printf("error creating g_stdin\n");
	}

	g_source_attach((GSource*) usb_source, edfc_context);
	gs_stdin = g_io_create_watch(g_stdin, G_IO_IN | G_IO_ERR | G_IO_HUP);
	g_source_set_callback(gs_stdin, (GSourceFunc)read_g_stdin, bulkIO, NULL);
	g_source_attach(gs_stdin, edfc_context);

	printf("beginning main loop\n");
	g_main_loop_run(edfc_main);
	printf("main loop finished\n");
//cleanup
	g_source_destroy(gs_stdin);
	g_io_channel_shutdown(g_stdin, TRUE, NULL); //todo: fix null
	free(bulk_in_buffer);
	free(bulk_out_buffer);
	libusb_free_transfer(bulk_in);
	libusb_free_transfer(bulk_out);
	g_source_destroy((GSource*) usb_source);

	g_main_loop_unref(edfc_main);
	g_main_context_unref(edfc_context);

	usbErr = libusb_release_interface(imu_handle, iface_num[0]);
	if(usbErr) print_libusb_error(usbErr, "exit libusb_release_interface");
	usbErr = libusb_attach_kernel_driver(imu_handle, iface_num[0]);
	if(usbErr) print_libusb_error(usbErr, "exit libusb_attach_kernel_driver");
	libusb_close(imu_handle);
	libusb_exit(imu_host);

	exit(EXIT_SUCCESS);
}
Example #17
0
File: main.c Project: Tilka/ncdc
int main(int argc, char **argv) {
  setlocale(LC_ALL, "");
  // Early logging goes to stderr
  stderrlog = stderr;

  // parse commandline options
  GOptionContext *optx = g_option_context_new("- NCurses Direct Connect");
  g_option_context_add_main_entries(optx, cli_options, NULL);
  GError *err = NULL;
  if(!g_option_context_parse(optx, &argc, &argv, &err)) {
    puts(err->message);
    exit(1);
  }
  g_option_context_free(optx);

  // check that the current locale is UTF-8. Things aren't going to work otherwise
  if(!g_get_charset(NULL)) {
    puts("WARNING: Your current locale is not set to UTF-8.");
    puts("Non-ASCII characters may not display correctly.");
    puts("Hit Ctrl+c to abort ncdc, or the return key to continue anyway.");
    getchar();
  }

  // init stuff
  init_crypt();
  g_thread_init(NULL);

  // Create main loop
  main_loop = g_main_loop_new(NULL, FALSE);

  // setup logging
  g_log_set_handler(NULL, G_LOG_FATAL_MASK | G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR, log_fatal, NULL);
  g_log_set_default_handler(log_redirect, NULL);

  // Init database & variables
  db_init();
  vars_init();

  // open log file
  char *errlog = g_build_filename(db_dir, "stderr.log", NULL);
  if(!(stderrlog = fopen(errlog, "w"))) {
    fprintf(stderr, "ERROR: Couldn't open %s for writing: %s\n", errlog, strerror(errno));
    exit(1);
  }
  g_free(errlog);

  // Init more stuff
  hub_init_global();
  net_init_global();
  listen_global_init();
  cc_global_init();
  dl_init_global();
  ui_cmdhist_init("history");
  ui_init(bracketed_paste);
  geoip_reinit(4);
  geoip_reinit(6);

  // setup SIGWINCH
  struct sigaction act;
  sigemptyset(&act.sa_mask);
  act.sa_flags = SA_RESTART;
  act.sa_handler = catch_sigwinch;
  if(sigaction(SIGWINCH, &act, NULL) < 0)
    g_error("Can't setup SIGWINCH: %s", g_strerror(errno));

  // setup SIGTERM
  act.sa_handler = catch_sigterm;
  if(sigaction(SIGTERM, &act, NULL) < 0)
    g_error("Can't setup SIGTERM: %s", g_strerror(errno));

  // setup SIGHUP
  act.sa_handler = catch_sighup;
  if(sigaction(SIGHUP, &act, NULL) < 0)
    g_error("Can't setup SIGHUP: %s", g_strerror(errno));

  // setup SIGUSR1
  act.sa_handler = catch_sigusr1;
  if(sigaction(SIGUSR1, &act, NULL) < 0)
    g_error("Can't setup SIGUSR1: %s", g_strerror(errno));

  // setup SIGPIPE
  act.sa_handler = catch_sigpipe;
  if(sigaction(SIGPIPE, &act, NULL) < 0)
    g_error("Can't setup SIGPIPE: %s", g_strerror(errno));

  fl_init();
  if(auto_open)
    open_autoconnect();

  // add some watches and start the main loop
  GIOChannel *in = g_io_channel_unix_new(STDIN_FILENO);
  g_io_add_watch(in, G_IO_IN, stdin_read, NULL);

  GSource *sighandle = g_source_new(&sighandle_funcs, sizeof(GSource));
  g_source_set_priority(sighandle, G_PRIORITY_HIGH);
  g_source_set_callback(sighandle, sighandle_sourcefunc, NULL, NULL);
  g_source_attach(sighandle, NULL);
  g_source_unref(sighandle);

  g_timeout_add_seconds_full(G_PRIORITY_HIGH, 1, one_second_timer, NULL, NULL);
  g_timeout_add(100, screen_update_check, NULL);
  int maxage = var_get_int(0, VAR_filelist_maxage);
  g_timeout_add_seconds_full(G_PRIORITY_LOW, CLAMP(maxage, 3600, 24*3600), dl_fl_clean, NULL, NULL);

  g_main_loop_run(main_loop);

  // cleanup
  if(!main_noterm) {
    erase();
    refresh();
    endwin();
    if(bracketed_paste)
      ui_set_bracketed_paste(0);

    printf("Flushing unsaved data to disk...");
    fflush(stdout);
  }
  ui_cmdhist_close();
  cc_global_close();
  fl_flush(NULL);
  dl_close_global();
  db_close();
  gnutls_global_deinit();
  if(!main_noterm)
    printf(" Done!\n");

  g_debug("Clean shutdown.");
  return 0;
}
    /**
     * CommandIfaceStartNB(): _non-blocking_ start request
     * 
     * @param pMgr Pointer to the parent test command manager (e.g.,
     *             for stopping test execution)
     * @param pMgrRd Command Manager's RuntimeDispatcher instance; 
     *               the command handler may use it for running its
     *               own logic, if needed.
     */
    void CommandIfaceStartNB(TestCmdMgr* pMgr,
                             wsf::RuntimeDispatcher* pMgrRd)
    {
        UTIL_PRINT_LINE("%s: Starting...", args_[0]);

        class StartRaii {
        public:
            StartRaii()
            :   pThreadCtx(NULL)
            {
            }

            ~StartRaii()
            {
                if (pThreadCtx) {
                    PmSockThreadCtxUnref(pThreadCtx);
                }

            }
        public:
            PmSockThreadContext*    pThreadCtx;
        };//class StartRaii

        StartRaii raii;

        GMainLoop* const gmainloop =
            (GMainLoop*)wsf::RuntimeDispatcher::GetInternalLoop(*pMgrRd);
        assert(gmainloop);

        GMainContext* const gmainctx = ::g_main_loop_get_context(gmainloop);
        assert(gmainctx);

        /// Create a palmsocket thread context
        PslError pslErr = ::PmSockThreadCtxNewFromGMain(
            gmainctx, args_[0], &raii.pThreadCtx);
        if (pslErr) {
            const std::string errorMsg =
                std::string("PmSockThreadCtxNewFromGMain failed: ") +
                ::PmSockErrStringFromError(pslErr);
            UTIL_THROW_FATAL(args_[0], errorMsg.c_str());
        }

        pslErr = ::PmSockCreateChannel(
            raii.pThreadCtx,
            (PmSockOptionFlags)0/*options*/,
            args_[0],
            &pChan_);
        if (!pslErr) {
            assert(pChan_);
        }
        else {
            const std::string errorMsg(
                std::string("PmSockCreateChannel failed: ") +
                ::PmSockErrStringFromError(pslErr));
            UTIL_THROW_FATAL(args_[0], errorMsg.c_str());
        }

        GSource* pTimeout = g_timeout_source_new(0/*interval*/);
        g_source_set_priority(pTimeout, G_PRIORITY_LOW);
        g_source_set_callback(pTimeout, &TimeoutGSourceFunc, this,
                              NULL/*GDestroyNotify*/);
        g_source_attach(pTimeout, gmainctx);
        g_source_unref(pTimeout);
    }//CommandIfaceStartNB
Example #19
0
/* Called in new thread */
static gboolean
on_run (GSocketService    *service,
        GSocketConnection *socket_connection,
        GObject           *source_object,
        gpointer           user_data)
{
  GDBusServer *server = G_DBUS_SERVER (user_data);
  GDBusConnection *connection;
  GDBusConnectionFlags connection_flags;

  if (server->nonce != NULL)
    {
      gchar buf[16];
      gsize bytes_read;

      if (!g_input_stream_read_all (g_io_stream_get_input_stream (G_IO_STREAM (socket_connection)),
                                    buf,
                                    16,
                                    &bytes_read,
                                    NULL,  /* GCancellable */
                                    NULL)) /* GError */
        goto out;

      if (bytes_read != 16)
        goto out;

      if (memcmp (buf, server->nonce, 16) != 0)
        goto out;
    }

  connection_flags =
    G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
    G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING;
  if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS)
    connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;

  connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
                                           server->guid,
                                           connection_flags,
                                           server->authentication_observer,
                                           NULL,  /* GCancellable */
                                           NULL); /* GError */
  if (connection == NULL)
      goto out;

  if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD)
    {
      gboolean claimed;

      claimed = FALSE;
      g_signal_emit (server,
                     _signals[NEW_CONNECTION_SIGNAL],
                     0,
                     connection,
                     &claimed);
      if (claimed)
        g_dbus_connection_start_message_processing (connection);
      g_object_unref (connection);
    }
  else
    {
      GSource *idle_source;
      EmitIdleData *data;

      data = g_new0 (EmitIdleData, 1);
      data->server = g_object_ref (server);
      data->connection = g_object_ref (connection);

      idle_source = g_idle_source_new ();
      g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
      g_source_set_callback (idle_source,
                             emit_new_connection_in_idle,
                             data,
                             (GDestroyNotify) emit_idle_data_free);
      g_source_attach (idle_source, server->main_context_at_construction);
      g_source_unref (idle_source);
    }

 out:
  return TRUE;
}
Example #20
0
static void *
glib_ctx_add(void *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
    glib_ev *gev = NULL;
    GIOCondition cond = 0;
    verto_ev_type type = verto_get_type(ev);

    gev = g_new0(glib_ev, 1);
    if (!gev)
        return NULL;

    switch (type) {
        case VERTO_EV_TYPE_IO:
#ifdef WIN32
            gev->chan = g_io_channel_win32_new_socket(verto_get_fd(ev));
#else
            gev->chan = g_io_channel_unix_new(verto_get_fd(ev));
#endif
            if (!gev->chan)
                goto error;
            g_io_channel_set_close_on_unref(gev->chan, FALSE);

            if (*flags & VERTO_EV_FLAG_IO_READ)
                cond |= G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
            if (*flags & VERTO_EV_FLAG_IO_WRITE)
                cond |= G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
            gev->src = g_io_create_watch(gev->chan, cond);
            break;
        case VERTO_EV_TYPE_TIMEOUT:
            gev->src = g_timeout_source_new(verto_get_interval(ev));
            break;
        case VERTO_EV_TYPE_IDLE:
            gev->src = g_idle_source_new();
            break;
        case VERTO_EV_TYPE_CHILD:
            gev->src = g_child_watch_source_new(verto_get_proc(ev));
            *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */
            break;
        case VERTO_EV_TYPE_SIGNAL:
#if GLIB_MAJOR_VERSION >= 2
#if GLIB_MINOR_VERSION >= 29
#ifdef G_OS_UNIX /* Not supported on Windows */
            gev->src = g_unix_signal_source_new(verto_get_signal(ev));
            break;
#endif
#endif /* GLIB_MINOR_VERSION >= 29 */
#endif /* GLIB_MAJOR_VERSION >= 2 */
        default:
            return NULL; /* Not supported */
    }

    if (!gev->src)
        goto error;

    if (type == VERTO_EV_TYPE_IO)
        g_source_set_callback(gev->src, (GSourceFunc) glib_callback_io, (void *) ev, NULL);
    else if (type == VERTO_EV_TYPE_CHILD)
        g_source_set_callback(gev->src, (GSourceFunc) glib_callback_child, (void *) ev, NULL);
    else
        g_source_set_callback(gev->src, glib_callback, (void *) ev, NULL);

    if (*flags & VERTO_EV_FLAG_PRIORITY_HIGH)
        g_source_set_priority(gev->src, G_PRIORITY_HIGH);
    else if (*flags & VERTO_EV_FLAG_PRIORITY_MEDIUM)
        g_source_set_priority(gev->src, G_PRIORITY_DEFAULT_IDLE);
    else if (*flags & VERTO_EV_FLAG_PRIORITY_LOW)
        g_source_set_priority(gev->src, G_PRIORITY_LOW);

    g_source_set_can_recurse(gev->src, FALSE);
    if (g_source_attach(gev->src, ((glib_ev_ctx*) ctx)->context) == 0)
        goto error;

    return gev;

    error:
        if (gev) {
            if (gev->chan)
                g_io_channel_unref(gev->chan);
            if (gev->src) {
                g_source_destroy(gev->src);
                g_source_unref(gev->src);
            }
            g_free(gev);
        }
        return NULL;
}
Example #21
0
gboolean
gimp_plug_in_open (GimpPlugIn         *plug_in,
                   GimpPlugInCallMode  call_mode,
                   gboolean            synchronous)
{
  gchar        *progname;
  gint          my_read[2];
  gint          my_write[2];
  gchar       **envp;
  const gchar  *args[9];
  gchar       **argv;
  gint          argc;
  gchar        *interp, *interp_arg;
  gchar        *read_fd, *write_fd;
  const gchar  *mode;
  gchar        *stm;
  GError       *error = NULL;
  gboolean      debug;
  guint         debug_flag;
  guint         spawn_flags;

  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
  g_return_val_if_fail (plug_in->call_mode == GIMP_PLUG_IN_CALL_NONE, FALSE);

  /* Open two pipes. (Bidirectional communication).
   */
  if ((pipe (my_read) == -1) || (pipe (my_write) == -1))
    {
      gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "Unable to run plug-in \"%s\"\n(%s)\n\npipe() failed: %s",
                    gimp_object_get_name (plug_in),
                    gimp_file_get_utf8_name (plug_in->file),
                    g_strerror (errno));
      return FALSE;
    }

#if defined(G_WITH_CYGWIN)
  /* Set to binary mode */
  setmode (my_read[0], _O_BINARY);
  setmode (my_write[0], _O_BINARY);
  setmode (my_read[1], _O_BINARY);
  setmode (my_write[1], _O_BINARY);
#endif

#ifdef G_OS_WIN32
  /* Prevent the plug-in from inheriting our ends of the pipes */
  SetHandleInformation ((HANDLE) _get_osfhandle (my_read[0]), HANDLE_FLAG_INHERIT, 0);
  SetHandleInformation ((HANDLE) _get_osfhandle (my_write[1]), HANDLE_FLAG_INHERIT, 0);
#endif

  plug_in->my_read   = g_io_channel_unix_new (my_read[0]);
  plug_in->my_write  = g_io_channel_unix_new (my_write[1]);
  plug_in->his_read  = g_io_channel_unix_new (my_write[0]);
  plug_in->his_write = g_io_channel_unix_new (my_read[1]);

  g_io_channel_set_encoding (plug_in->my_read, NULL, NULL);
  g_io_channel_set_encoding (plug_in->my_write, NULL, NULL);
  g_io_channel_set_encoding (plug_in->his_read, NULL, NULL);
  g_io_channel_set_encoding (plug_in->his_write, NULL, NULL);

  g_io_channel_set_buffered (plug_in->my_read, FALSE);
  g_io_channel_set_buffered (plug_in->my_write, FALSE);
  g_io_channel_set_buffered (plug_in->his_read, FALSE);
  g_io_channel_set_buffered (plug_in->his_write, FALSE);

  g_io_channel_set_close_on_unref (plug_in->my_read, TRUE);
  g_io_channel_set_close_on_unref (plug_in->my_write, TRUE);
  g_io_channel_set_close_on_unref (plug_in->his_read, TRUE);
  g_io_channel_set_close_on_unref (plug_in->his_write, TRUE);

  /* Remember the file descriptors for the pipes.
   */
  read_fd  = g_strdup_printf ("%d",
                              g_io_channel_unix_get_fd (plug_in->his_read));
  write_fd = g_strdup_printf ("%d",
                              g_io_channel_unix_get_fd (plug_in->his_write));

  switch (call_mode)
    {
    case GIMP_PLUG_IN_CALL_QUERY:
      mode = "-query";
      debug_flag = GIMP_DEBUG_WRAP_QUERY;
      break;

    case GIMP_PLUG_IN_CALL_INIT:
      mode = "-init";
      debug_flag = GIMP_DEBUG_WRAP_INIT;
      break;

    case GIMP_PLUG_IN_CALL_RUN:
      mode = "-run";
      debug_flag = GIMP_DEBUG_WRAP_RUN;
      break;

    default:
      g_assert_not_reached ();
    }

  stm = g_strdup_printf ("%d", plug_in->manager->gimp->stack_trace_mode);

  progname = g_file_get_path (plug_in->file);

  interp = gimp_interpreter_db_resolve (plug_in->manager->interpreter_db,
                                        progname, &interp_arg);

  argc = 0;

  if (interp)
    args[argc++] = interp;

  if (interp_arg)
    args[argc++] = interp_arg;

  args[argc++] = progname;
  args[argc++] = "-gimp";
  args[argc++] = read_fd;
  args[argc++] = write_fd;
  args[argc++] = mode;
  args[argc++] = stm;
  args[argc++] = NULL;

  argv = (gchar **) args;
  envp = gimp_environ_table_get_envp (plug_in->manager->environ_table);
  spawn_flags = (G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
                 G_SPAWN_DO_NOT_REAP_CHILD      |
                 G_SPAWN_CHILD_INHERITS_STDIN);

  debug = FALSE;

  if (plug_in->manager->debug)
    {
      gchar **debug_argv = gimp_plug_in_debug_argv (plug_in->manager->debug,
                                                    progname,
                                                    debug_flag, args);

      if (debug_argv)
        {
          debug = TRUE;
          argv = debug_argv;
          spawn_flags |= G_SPAWN_SEARCH_PATH;
        }
    }

  /* Fork another process. We'll remember the process id so that we
   * can later use it to kill the filter if necessary.
   */
  if (! g_spawn_async (NULL, argv, envp, spawn_flags,
                       gimp_plug_in_prep_for_exec, plug_in,
                       &plug_in->pid,
                       &error))
    {
      gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "Unable to run plug-in \"%s\"\n(%s)\n\n%s",
                    gimp_object_get_name (plug_in),
                    gimp_file_get_utf8_name (plug_in->file),
                    error->message);
      g_clear_error (&error);
      g_free (progname);
      goto cleanup;
    }

  g_io_channel_unref (plug_in->his_read);
  plug_in->his_read = NULL;

  g_io_channel_unref (plug_in->his_write);
  plug_in->his_write = NULL;

  if (! synchronous)
    {
      GSource *source;

      source = g_io_create_watch (plug_in->my_read,
                                  G_IO_IN  | G_IO_PRI | G_IO_ERR | G_IO_HUP);

      g_source_set_callback (source,
                             (GSourceFunc) gimp_plug_in_recv_message, plug_in,
                             NULL);

      g_source_set_can_recurse (source, TRUE);

      plug_in->input_id = g_source_attach (source, NULL);
      g_source_unref (source);
    }

  plug_in->open      = TRUE;
  plug_in->call_mode = call_mode;

  gimp_plug_in_manager_add_open_plug_in (plug_in->manager, plug_in);

 cleanup:

  if (debug)
    g_free (argv);

  g_free (read_fd);
  g_free (write_fd);
  g_free (stm);
  g_free (interp);
  g_free (interp_arg);
  g_free (progname);

  return plug_in->open;
}
osync_bool osync_queue_connect(OSyncQueue *queue, OSyncQueueType type, OSyncError **error)
{
#ifdef _WIN32
  return FALSE;
#else //_WIN32
  OSyncQueue **queueptr = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, queue, type, error);
  osync_assert(queue);
  osync_assert(queue->connected == FALSE);
	
  queue->type = type;
	
  if (queue->fd == -1) {
    /* First, open the queue with the flags provided by the user */
    int fd = open(queue->name, type == OSYNC_QUEUE_SENDER ? O_WRONLY : O_RDONLY);
    if (fd == -1) {
      osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open fifo");
      goto error;
    }
    queue->fd = fd;
  }

  int oldflags = fcntl(queue->fd, F_GETFD);
  if (oldflags == -1) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get fifo flags");
    goto error_close;
  }
  if (fcntl(queue->fd, F_SETFD, oldflags|FD_CLOEXEC) == -1) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to set fifo flags");
    goto error_close;
  }

  queue->connected = TRUE;
  signal(SIGPIPE, SIG_IGN);
	
  /* now we start a thread which handles reading/writing of the queue */
  queue->thread = osync_thread_new(queue->context, error);

  if (!queue->thread)
    goto error;
	
  queue->write_functions = g_malloc0(sizeof(GSourceFuncs));
  queue->write_functions->prepare = _queue_prepare;
  queue->write_functions->check = _queue_check;
  queue->write_functions->dispatch = _queue_dispatch;
  queue->write_functions->finalize = NULL;

  queue->write_source = g_source_new(queue->write_functions, sizeof(GSource) + sizeof(OSyncQueue *));
  queueptr = (OSyncQueue **)(queue->write_source + 1);
  *queueptr = queue;
  g_source_set_callback(queue->write_source, NULL, queue, NULL);
  g_source_attach(queue->write_source, queue->context);
  if (queue->context)
    g_main_context_ref(queue->context);

  queue->read_functions = g_malloc0(sizeof(GSourceFuncs));
  queue->read_functions->prepare = _source_prepare;
  queue->read_functions->check = _source_check;
  queue->read_functions->dispatch = _source_dispatch;
  queue->read_functions->finalize = NULL;

  queue->read_source = g_source_new(queue->read_functions, sizeof(GSource) + sizeof(OSyncQueue *));
  queueptr = (OSyncQueue **)(queue->read_source + 1);
  *queueptr = queue;
  g_source_set_callback(queue->read_source, NULL, queue, NULL);
  g_source_attach(queue->read_source, queue->context);
  if (queue->context)
    g_main_context_ref(queue->context);

  queue->timeout_functions = g_malloc0(sizeof(GSourceFuncs));
  queue->timeout_functions->prepare = _timeout_prepare;
  queue->timeout_functions->check = _timeout_check;
  queue->timeout_functions->dispatch = _timeout_dispatch;
  queue->timeout_functions->finalize = NULL;

  queue->timeout_source = g_source_new(queue->timeout_functions, sizeof(GSource) + sizeof(OSyncQueue *));
  queueptr = (OSyncQueue **)(queue->timeout_source + 1);
  *queueptr = queue;
  g_source_set_callback(queue->timeout_source, NULL, queue, NULL);
  g_source_attach(queue->timeout_source, queue->context);
  if (queue->context)
    g_main_context_ref(queue->context);
	
  osync_thread_start(queue->thread);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error_close:
  close(queue->fd);
 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
#endif //_WIN32
}
Example #23
0
void
event_activate(
    event_handle_t *handle)
{
    GIOCondition cond;
    assert(handle != NULL);

    g_static_mutex_lock(&event_mutex);

    /* add to the list of events */
    all_events = g_slist_prepend(all_events, (gpointer)handle);

    /* and set up the GSource for this event */
    switch (handle->type) {
	case EV_READFD:
	case EV_WRITEFD:
	    /* create a new source */
	    if (handle->type == EV_READFD) {
		cond = G_IO_IN | G_IO_HUP | G_IO_ERR;
	    } else {
		cond = G_IO_OUT | G_IO_ERR;
	    }

	    handle->source = new_fdsource(handle->data, cond);

	    /* attach it to the default GMainLoop */
	    g_source_attach(handle->source, NULL);
	    handle->source_id = g_source_get_id(handle->source);

	    /* And set its callbacks */
	    g_source_set_callback(handle->source, event_handle_callback,
				  (gpointer)handle, NULL);

	    /* drop our reference to it, so when it's detached, it will be
	     * destroyed. */
	    g_source_unref(handle->source);
	    break;

	case EV_TIME:
	    /* Glib provides a nice shortcut for timeouts.  The *1000 converts
	     * seconds to milliseconds. */
	    handle->source_id = g_timeout_add(handle->data * 1000, event_handle_callback,
					      (gpointer)handle);

	    /* But it doesn't give us the source directly.. */
	    handle->source = g_main_context_find_source_by_id(NULL, handle->source_id);
	    /* EV_TIME must always be handled after EV_READ */
	    g_source_set_priority(handle->source, 10);
	    break;

	case EV_WAIT:
	    /* nothing to do -- these are handled independently of GMainLoop */
	    break;

	default:
	    error(_("Unknown event type %s"), event_type2str(handle->type));
    }

    g_static_mutex_unlock(&event_mutex);
    return;
}
static void
swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
{
  GIOChannel *channel;
  Stream *stream;
  guint rate;
  int dsp_fd, ret, format, channels, fragsize;

  dsp_fd = open("/dev/dsp", O_WRONLY);
  if (dsp_fd == -1) {
    g_printerr ("Failed to open /dev/dsp\n");
    return;
  }

  format = AFMT_S16_LE;
  ret = ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &format);
  if (ret == -1) {
    g_printerr ("Failed to set sound format\n");
    close(dsp_fd);
    return;
  }

  channels = 2;
  ret = ioctl(dsp_fd, SNDCTL_DSP_CHANNELS, &channels);
  if (ret == -1) {
    g_printerr ("Failed to set stereo\n");
    close(dsp_fd);
    return;
  }

  rate = 44100;
  ret = ioctl(dsp_fd, SNDCTL_DSP_SPEED, &rate);
  if (ret == -1) {
    g_printerr ("Failed to set rate\n");
    close(dsp_fd);
    return;
  }

  ret = ioctl(dsp_fd, SNDCTL_DSP_GETBLKSIZE, &fragsize);
  if (ret == -1) {
    g_printerr ("Failed to get fragment size\n");
    close(dsp_fd);
    return;
  }

  stream = g_new0 (Stream, 1);
  stream->sound = sound;
  stream->audio = g_object_ref (audio);
  stream->dsp_fd = dsp_fd;
  stream->fragsize = fragsize;
  sound->streams = g_list_prepend (sound->streams, stream);

  channel = g_io_channel_unix_new (stream->dsp_fd);
  stream->source = g_io_create_watch (channel, G_IO_OUT);
  g_source_set_priority (stream->source, G_PRIORITY_HIGH);
  g_source_set_callback (stream->source, (GSourceFunc) handle_stream, stream,
			 NULL);
  g_io_channel_unref (channel);
  g_source_attach (stream->source, stream->sound->context);

  return;
}
Example #25
0
phStatus_t phOsal_GLib_Timer_Start( phOsal_GLib_DataParams_t  *pDataParams,
                                    uint32_t                   dwTimerId,
                                    uint32_t                   dwRegTimeCnt,
                                    uint16_t                   wOption,
                                    ppCallBck_t                pApplicationCallback,
                                    void                      *pContext
                                  )
{
   //g_debug("Starting timer %d...\r\n", dwTimerId);
   if( (dwTimerId > OSAL_GLIB_MAX_TIMERS) || (pDataParams->gTimers[dwTimerId].bTimerFree == TIMER_FREE) )
   {
	   /* Can't use a non existent timer */
	   /* Can't start a free timer, first create the timer */

	   return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_OSAL);
   }

   if( pDataParams->gTimers[dwTimerId].pGTimeoutSource != NULL )
   {
	   //Cannot start at timer which is already running
	   g_error("Timer %d already running\n", dwTimerId);
	   return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_OSAL);
   }

   //Convert usecs to millisecs if needed
   if( wOption ==  0 ) //
   {
	   //g_debug("%d us", dwRegTimeCnt);
	   //We're running in user-mode on a (probably) non realtime kernel, so even millisecs are very approximate
	   if( dwRegTimeCnt < 1000 )
	   {
		   pDataParams->gTimers[dwTimerId].dwMillisecs = 1;
	   }
	   else
	   {
		   pDataParams->gTimers[dwTimerId].dwMillisecs = dwRegTimeCnt / 1000;
	   }
   }
   else //These are already millisecs
   {
	   //g_debug("%d ms", dwRegTimeCnt);
	   pDataParams->gTimers[dwTimerId].dwMillisecs = dwRegTimeCnt;
   }

   //Remember callback
   pDataParams->gTimers[dwTimerId].pApplicationCallback = pApplicationCallback;
   pDataParams->gTimers[dwTimerId].pContext = pContext;

   //Create source
   pDataParams->gTimers[dwTimerId].pGTimeoutSource = g_timeout_source_new(pDataParams->gTimers[dwTimerId].dwMillisecs);
   if( pDataParams->gTimers[dwTimerId].pGTimeoutSource == NULL)
   {
	   return PH_ADD_COMPCODE(PH_ERR_INSUFFICIENT_RESOURCES, PH_COMP_OSAL);
   }

   //Set callback
   g_source_set_callback(pDataParams->gTimers[dwTimerId].pGTimeoutSource, phOsal_Int_Timer_Callback, &pDataParams->gTimers[dwTimerId], NULL);

   //Attach source to context
   g_source_attach(pDataParams->gTimers[dwTimerId].pGTimeoutSource, pDataParams->pgGLibMainContext);

   return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_OSAL);
}
Example #26
0
/*
 * Received a message
 */
static void
message_received_cb (G_GNUC_UNUSED GSSDPClient *client,
                     const char                *from_ip,
                     gushort                    from_port,
                     _GSSDPMessageType          type,
                     SoupMessageHeaders        *headers,
                     gpointer                   user_data)
{
        GSSDPResourceGroup *resource_group;
        GSSDPResourceGroupPrivate *priv;
        const char *target, *mx_str, *version_str, *man;
        gboolean want_all;
        int mx, version;
        GList *l;

        resource_group = GSSDP_RESOURCE_GROUP (user_data);
        priv = gssdp_resource_group_get_instance_private (resource_group);

        /* Only process if we are available */
        if (!priv->available)
                return;

        /* We only handle discovery requests */
        if (type != _GSSDP_DISCOVERY_REQUEST)
                return;

        /* Extract target */
        target = soup_message_headers_get_one (headers, "ST");
        if (target == NULL) {
                g_warning ("Discovery request did not have an ST header");

                return;
        }

        /* Is this the "ssdp:all" target? */
        want_all = (strcmp (target, GSSDP_ALL_RESOURCES) == 0);

        /* Extract MX */
        mx_str = soup_message_headers_get_one (headers, "MX");
        if (mx_str == NULL || atoi (mx_str) <= 0) {
                g_warning ("Discovery request did not have a valid MX header");

                return;
        }

        man = soup_message_headers_get_one (headers, "MAN");
        if (man == NULL || strcmp (man, DEFAULT_MAN_HEADER) != 0) {
                g_warning ("Discovery request did not have a valid MAN header");

                return;
        }

        mx = atoi (mx_str);

        /* Extract version */
        version_str = get_version_for_target ((char *) target);
        if (version_str != NULL)
                version = atoi (version_str);
        else
                version = 0;

        /* Find matching resource */
        for (l = priv->resources; l != NULL; l = l->next) {
                Resource *resource;

                resource = l->data;

                if (want_all ||
                    (g_regex_match (resource->target_regex,
                                    target,
                                    0,
                                    NULL) &&
                     (guint) version <= resource->version)) {
                        /* Match. */
                        guint timeout;
                        DiscoveryResponse *response;

                        /* Get a random timeout from the interval [0, mx] */
                        timeout = g_random_int_range (0, mx * 1000);

                        /* Prepare response */
                        response = g_slice_new (DiscoveryResponse);

                        response->dest_ip   = g_strdup (from_ip);
                        response->dest_port = from_port;
                        response->resource  = resource;

                        if (want_all)
                                response->target = g_strdup (resource->target);
                        else
                                response->target = g_strdup (target);

                        /* Add timeout */
                        response->timeout_src = g_timeout_source_new (timeout);
                        g_source_set_callback (response->timeout_src,
                                               discovery_response_timeout,
                                               response, NULL);

                        g_source_attach (response->timeout_src,
                                         g_main_context_get_thread_default ());

                        g_source_unref (response->timeout_src);

                        /* Add to resource */
                        resource->responses =
                                g_list_prepend (resource->responses, response);
                }
        }
}
Example #27
0
static void
ul_spawned_job_constructed (GObject *object)
{
  UlSpawnedJob *self = UL_SPAWNED_JOB (object);
  GError *error;
  gchar *cmd;

  G_OBJECT_CLASS (ul_spawned_job_parent_class)->constructed (object);

  cmd = g_strjoinv (" ", self->argv);
  g_debug ("spawned job: %s", cmd);

  self->main_context = g_main_context_get_thread_default ();
  if (self->main_context != NULL)
    g_main_context_ref (self->main_context);

  /* could already be cancelled */
  error = NULL;
  if (g_cancellable_set_error_if_cancelled (ul_job_get_cancellable (UL_JOB (self)), &error))
    {
      emit_completed_with_error_in_idle (self, error);
      g_error_free (error);
      goto out;
    }

  self->cancellable_handler_id = g_cancellable_connect (ul_job_get_cancellable (UL_JOB (self)),
                                                        G_CALLBACK (on_cancelled),
                                                        self,
                                                        NULL);

  error = NULL;
  if (!g_spawn_async_with_pipes (NULL, /* working directory */
                                 self->argv,
                                 NULL, /* envp */
                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                                 child_setup, /* child_setup */
                                 self, /* child_setup's user_data */
                                 &(self->child_pid),
                                 self->input_string != NULL ? &(self->child_stdin_fd) : NULL,
                                 &(self->child_stdout_fd),
                                 &(self->child_stderr_fd),
                                 &error))
    {
      g_prefix_error (&error, "Error spawning command-line `%s': ", cmd);
      emit_completed_with_error_in_idle (self, error);
      g_error_free (error);
      goto out;
    }

  self->child_watch_source = g_child_watch_source_new (self->child_pid);
  g_source_set_callback (self->child_watch_source, (GSourceFunc) child_watch_cb, self, NULL);
  g_source_attach (self->child_watch_source, self->main_context);
  g_source_unref (self->child_watch_source);

  if (self->child_stdin_fd != -1)
    {
      self->input_string_cursor = self->input_string;

      self->child_stdin_channel = g_io_channel_unix_new (self->child_stdin_fd);
      g_io_channel_set_flags (self->child_stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
      self->child_stdin_source = g_io_create_watch (self->child_stdin_channel, G_IO_OUT);
      g_source_set_callback (self->child_stdin_source, (GSourceFunc) write_child_stdin, self, NULL);
      g_source_attach (self->child_stdin_source, self->main_context);
      g_source_unref (self->child_stdin_source);
    }

  self->child_stdout_channel = g_io_channel_unix_new (self->child_stdout_fd);
  g_io_channel_set_flags (self->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL);
  self->child_stdout_source = g_io_create_watch (self->child_stdout_channel, G_IO_IN);
  g_source_set_callback (self->child_stdout_source, (GSourceFunc) read_child_stdout, self, NULL);
  g_source_attach (self->child_stdout_source, self->main_context);
  g_source_unref (self->child_stdout_source);

  self->child_stderr_channel = g_io_channel_unix_new (self->child_stderr_fd);
  g_io_channel_set_flags (self->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL);
  self->child_stderr_source = g_io_create_watch (self->child_stderr_channel, G_IO_IN);
  g_source_set_callback (self->child_stderr_source, (GSourceFunc) read_child_stderr, self, NULL);
  g_source_attach (self->child_stderr_source, self->main_context);
  g_source_unref (self->child_stderr_source);

out:
  g_free (cmd);
}
/**
 * gst_video_convert_sample_async:
 * @sample: a #GstSample
 * @to_caps: the #GstCaps to convert to
 * @timeout: the maximum amount of time allowed for the processing.
 * @callback: %GstVideoConvertSampleCallback that will be called after conversion.
 * @user_data: extra data that will be passed to the @callback
 * @destroy_notify: %GDestroyNotify to be called after @user_data is not needed anymore
 *
 * Converts a raw video buffer into the specified output caps.
 *
 * The output caps can be any raw video formats or any image formats (jpeg, png, ...).
 *
 * The width, height and pixel-aspect-ratio can also be specified in the output caps.
 *
 * @callback will be called after conversion, when an error occured or if conversion didn't
 * finish after @timeout. @callback will always be called from the thread default
 * %GMainContext, see g_main_context_get_thread_default(). If GLib before 2.22 is used,
 * this will always be the global default main context.
 *
 * @destroy_notify will be called after the callback was called and @user_data is not needed
 * anymore.
 */
void
gst_video_convert_sample_async (GstSample * sample,
    const GstCaps * to_caps, GstClockTime timeout,
    GstVideoConvertSampleCallback callback, gpointer user_data,
    GDestroyNotify destroy_notify)
{
  GMainContext *context = NULL;
  GError *error = NULL;
  GstBus *bus;
  GstBuffer *buf;
  GstCaps *from_caps, *to_caps_copy = NULL;
  GstElement *pipeline, *src, *sink;
  guint i, n;
  GSource *source;
  GstVideoConvertSampleContext *ctx;

  g_return_if_fail (sample != NULL);
  buf = gst_sample_get_buffer (sample);
  g_return_if_fail (buf != NULL);

  g_return_if_fail (to_caps != NULL);

  from_caps = gst_sample_get_caps (sample);
  g_return_if_fail (from_caps != NULL);
  g_return_if_fail (callback != NULL);

  context = g_main_context_get_thread_default ();

  if (!context)
    context = g_main_context_default ();

  to_caps_copy = gst_caps_new_empty ();
  n = gst_caps_get_size (to_caps);
  for (i = 0; i < n; i++) {
    GstStructure *s = gst_caps_get_structure (to_caps, i);

    s = gst_structure_copy (s);
    gst_structure_remove_field (s, "framerate");
    gst_caps_append_structure (to_caps_copy, s);
  }

  pipeline =
      build_convert_frame_pipeline (&src, &sink, from_caps,
      gst_buffer_get_video_crop_meta (buf), to_caps_copy, &error);
  if (!pipeline)
    goto no_pipeline;

  bus = gst_element_get_bus (pipeline);

  ctx = g_slice_new0 (GstVideoConvertSampleContext);
  g_mutex_init (&ctx->mutex);
  //ctx->buffer = gst_buffer_ref (buf);
  ctx->sample = gst_sample_ref (sample);
  ctx->callback = callback;
  ctx->user_data = user_data;
  ctx->destroy_notify = destroy_notify;
  ctx->context = g_main_context_ref (context);
  ctx->finished = FALSE;
  ctx->pipeline = pipeline;

  if (timeout != GST_CLOCK_TIME_NONE) {
    ctx->timeout_source = g_timeout_source_new (timeout / GST_MSECOND);
    g_source_set_callback (ctx->timeout_source,
        (GSourceFunc) convert_frame_timeout_callback, ctx, NULL);
    g_source_attach (ctx->timeout_source, context);
  }

  g_signal_connect (src, "need-data",
      G_CALLBACK (convert_frame_need_data_callback), ctx);
  g_signal_connect (sink, "new-preroll",
      G_CALLBACK (convert_frame_new_preroll_callback), ctx);

  source = gst_bus_create_watch (bus);
  g_source_set_callback (source, (GSourceFunc) convert_frame_bus_callback,
      ctx, NULL);
  g_source_attach (source, context);
  g_source_unref (source);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  gst_object_unref (bus);
  gst_caps_unref (to_caps_copy);

  return;
  /* ERRORS */
no_pipeline:
  {
    GstVideoConvertSampleCallbackContext *ctx;
    GSource *source;

    gst_caps_unref (to_caps_copy);

    ctx = g_slice_new0 (GstVideoConvertSampleCallbackContext);
    ctx->callback = callback;
    ctx->user_data = user_data;
    ctx->destroy_notify = destroy_notify;
    ctx->sample = NULL;
    ctx->error = error;

    source = g_timeout_source_new (0);
    g_source_set_callback (source,
        (GSourceFunc) convert_frame_dispatch_callback, ctx,
        (GDestroyNotify) gst_video_convert_frame_callback_context_free);
    g_source_attach (source, context);
    g_source_unref (source);
  }
}
/* Main method for the native code. This is executed on its own thread. */
static void *app_function (void *userdata) {
  JavaVMAttachArgs args;
  GstBus *bus;
  CustomData *data = (CustomData *)userdata;
  GSource *timeout_source;
  GSource *bus_source;
  GError *error = NULL;
  guint flags;

  GST_DEBUG ("Creating pipeline in CustomData at %p", data);

  /* Create our own GLib Main Context and make it the default one */
  data->context = g_main_context_new ();
  g_main_context_push_thread_default(data->context);

  /* Build pipeline */
  data->pipeline = gst_parse_launch("playbin2", &error);
  if (error) {
    gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
    g_clear_error (&error);
    set_ui_message(message, data);
    g_free (message);
    return NULL;
  }

  /* Disable subtitles */
  g_object_get (data->pipeline, "flags", &flags, NULL);
  flags &= ~GST_PLAY_FLAG_TEXT;
  g_object_set (data->pipeline, "flags", flags, NULL);

  /* Set the pipeline to READY, so it can already accept a window handle, if we have one */
  data->target_state = GST_STATE_READY;
  gst_element_set_state(data->pipeline, GST_STATE_READY);

  /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
  bus = gst_element_get_bus (data->pipeline);
  bus_source = gst_bus_create_watch (bus);
  g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
  g_source_attach (bus_source, data->context);
  g_source_unref (bus_source);
  g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, data);
  g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback)eos_cb, data);
  g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, data);
  g_signal_connect (G_OBJECT (bus), "message::duration", (GCallback)duration_cb, data);
  g_signal_connect (G_OBJECT (bus), "message::buffering", (GCallback)buffering_cb, data);
  g_signal_connect (G_OBJECT (bus), "message::clock-lost", (GCallback)clock_lost_cb, data);
  gst_object_unref (bus);

  /* Register a function that GLib will call 4 times per second */
  timeout_source = g_timeout_source_new (250);
  g_source_set_callback (timeout_source, (GSourceFunc)refresh_ui, data, NULL);
  g_source_attach (timeout_source, data->context);
  g_source_unref (timeout_source);

  /* Create a GLib Main Loop and set it to run */
  GST_DEBUG ("Entering main loop... (CustomData:%p)", data);
  data->main_loop = g_main_loop_new (data->context, FALSE);
  check_initialization_complete (data);
  g_main_loop_run (data->main_loop);
  GST_DEBUG ("Exited main loop");
  g_main_loop_unref (data->main_loop);
  data->main_loop = NULL;

  /* Free resources */
  g_main_context_pop_thread_default(data->context);
  g_main_context_unref (data->context);
  data->target_state = GST_STATE_NULL;
  gst_element_set_state (data->pipeline, GST_STATE_NULL);
  gst_object_unref (data->pipeline);

  return NULL;
}
static void
_channel_accepted (TpChannel *channel,
    const GValue *addressv,
    const GError *in_error,
    gpointer user_data,
    GObject *obj)
{
  TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj;
  GSocketAddress *remote_address;
  GError *error = NULL;

  if (in_error != NULL)
    {
      DEBUG ("Failed to Accept Stream Tube: %s", in_error->message);

      operation_failed (self, in_error);
      return;
    }

  tp_cli_channel_type_stream_tube_connect_to_new_local_connection (
      TP_CHANNEL (self), new_local_connection_cb, NULL, NULL,
      G_OBJECT (self), &error);

  if (error != NULL)
    {
      DEBUG ("Failed to connect to NewLocalConnection signal");
      operation_failed (self, error);

      g_error_free (error);
      return;
    }

  remote_address = tp_g_socket_address_from_variant (self->priv->socket_type,
      addressv, &error);
  if (error != NULL)
    {
      DEBUG ("Failed to convert address: %s", error->message);

      operation_failed (self, error);
      g_error_free (error);
      return;
    }

  /* Connect to CM */
  g_socket_set_blocking (self->priv->client_socket, FALSE);
  g_socket_connect (self->priv->client_socket, remote_address, NULL, &error);

  if (error == NULL)
    {
      /* Socket is connected */
      client_socket_connected (self);
      goto out;
    }
  else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
    {
      /* We have to wait that the socket is connected */
      GSource *source;

      source = g_socket_create_source (self->priv->client_socket,
          G_IO_OUT, NULL);

      g_source_attach (source, g_main_context_get_thread_default ());

      g_source_set_callback (source, (GSourceFunc) client_socket_cb,
          self, NULL);

      g_error_free (error);
      g_source_unref (source);
    }
  else
    {
      DEBUG ("Failed to connect to CM: %s", error->message);

      operation_failed (self, error);

      g_error_free (error);
    }

out:
  g_object_unref (remote_address);
}