示例#1
0
/* Callback handling data */
static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
{
    struct dev_context *devc = sdi->priv;
    struct sr_datafeed_packet packet;
    struct sr_datafeed_logic logic;
    struct sr_datafeed_dso dso;
    struct sr_datafeed_analog analog;
	static uint64_t samples_to_send, expected_samplenum, sending_now;
	int64_t time, elapsed;
    static uint16_t last_sample = 0;
    uint16_t cur_sample;
    int i;

	(void)fd;
	(void)revents;

	/* How many "virtual" samples should we have collected by now? */
	time = g_get_monotonic_time();
	elapsed = time - devc->starttime;
    devc->starttime = time;
    //expected_samplenum = ceil(elapsed / 1000000.0 * devc->cur_samplerate);
	/* Of those, how many do we still have to send? */
    //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN;
    //samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN;
    samples_to_send = ceil(elapsed / 1000000.0 * devc->cur_samplerate);

    if (devc->limit_samples) {
        if ((sdi->mode == DSO && !devc->instant) || sdi->mode == ANALOG)
            samples_to_send = MIN(samples_to_send,
                                  devc->limit_samples - devc->pre_index);
        else
            samples_to_send = MIN(samples_to_send,
                     devc->limit_samples - devc->samples_counter);
    }

    while (samples_to_send > 0) {
        sending_now = MIN(samples_to_send, BUFSIZE);
        samples_generator(devc->buf, sending_now, sdi, devc);

        if (devc->trigger_stage != 0) {
            for (i = 0; i < sending_now; i++) {
                if (devc->trigger_edge == 0) {
                    if ((*(devc->buf + i) | devc->trigger_mask) ==
                            (devc->trigger_value | devc->trigger_mask)) {
                        devc->trigger_stage = 0;
                        break;
                    }
                } else {
                    cur_sample = *(devc->buf + i);
                    if (((last_sample & devc->trigger_edge) ==
                         (~devc->trigger_value & devc->trigger_edge)) &&
                        ((cur_sample | devc->trigger_mask) ==
                         (devc->trigger_value | devc->trigger_mask)) &&
                        ((cur_sample & devc->trigger_edge) ==
                         (devc->trigger_value & devc->trigger_edge))) {
                        devc->trigger_stage = 0;
                        break;
                    }
                    last_sample = cur_sample;
                }
            }
            if (devc->trigger_stage == 0) {
                struct ds_trigger_pos demo_trigger_pos;
                demo_trigger_pos.real_pos = i;
                packet.type = SR_DF_TRIGGER;
                packet.payload = &demo_trigger_pos;
                sr_session_send(sdi, &packet);
            }
        }

        if (sdi->mode == ANALOG)
            devc->samples_counter += sending_now/g_slist_length(sdi->channels);
        else
            devc->samples_counter += sending_now;
        if (sdi->mode == DSO && !devc->instant &&
            devc->samples_counter > devc->limit_samples)
            devc->samples_counter = devc->limit_samples;

        if (devc->trigger_stage == 0){
            samples_to_send -= sending_now;
            if (sdi->mode == LOGIC) {
                packet.type = SR_DF_LOGIC;
                packet.payload = &logic;
                logic.length = sending_now * (NUM_PROBES >> 3);
                logic.unitsize = (NUM_PROBES >> 3);
                logic.data = devc->buf;
            } else if (sdi->mode == DSO) {
示例#2
0
static int
auto_scroll_timeout_callback (gpointer data)
{
	NemoIconContainer *container;
	GtkWidget *widget;
	float x_scroll_delta, y_scroll_delta;
	GdkRectangle exposed_area;
	GtkAllocation allocation;

	g_assert (NEMO_IS_ICON_CONTAINER (data));
	widget = GTK_WIDGET (data);
	container = NEMO_ICON_CONTAINER (widget);

	if (container->details->dnd_info->drag_info.waiting_to_autoscroll
	    && container->details->dnd_info->drag_info.start_auto_scroll_in > g_get_monotonic_time ()) {
		/* not yet */
		return TRUE;
	}

	container->details->dnd_info->drag_info.waiting_to_autoscroll = FALSE;

	nemo_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta);
	if (x_scroll_delta == 0 && y_scroll_delta == 0) {
		/* no work */
		return TRUE;
	}

	/* Clear the old dnd highlight frame */
	dnd_highlight_queue_redraw (widget);
	
	if (!nemo_icon_container_scroll (container, (int)x_scroll_delta, (int)y_scroll_delta)) {
		/* the scroll value got pinned to a min or max adjustment value,
		 * we ended up not scrolling
		 */
		return TRUE;
	}

	/* Make sure the dnd highlight frame is redrawn */
	dnd_highlight_queue_redraw (widget);
	
	/* update cached drag start offsets */
	container->details->dnd_info->drag_info.start_x -= x_scroll_delta;
	container->details->dnd_info->drag_info.start_y -= y_scroll_delta;

	/* Due to a glitch in GtkLayout, whe need to do an explicit draw of the exposed
	 * area. 
	 * Calculate the size of the area we need to draw
	 */
	gtk_widget_get_allocation (widget, &allocation);
	exposed_area.x = allocation.x;
	exposed_area.y = allocation.y;
	exposed_area.width = allocation.width;
	exposed_area.height = allocation.height;

	if (x_scroll_delta > 0) {
		exposed_area.x = exposed_area.width - x_scroll_delta;
	} else if (x_scroll_delta < 0) {
		exposed_area.width = -x_scroll_delta;
	}

	if (y_scroll_delta > 0) {
		exposed_area.y = exposed_area.height - y_scroll_delta;
	} else if (y_scroll_delta < 0) {
		exposed_area.height = -y_scroll_delta;
	}

	/* offset it to 0, 0 */
	exposed_area.x -= allocation.x;
	exposed_area.y -= allocation.y;

	gtk_widget_queue_draw_area (widget,
				    exposed_area.x,
				    exposed_area.y,
				    exposed_area.width,
				    exposed_area.height);

	return TRUE;
}
示例#3
0
int
main (int argc, char *argv[])
{
	int t_secs = 30;
	gboolean exit_no_nm = FALSE;
	gboolean wait_startup = FALSE;
	Timeout timeout;
	GOptionContext *opt_ctx = NULL;
	gboolean success;
	NMClient *client;
	NMState state = NM_STATE_UNKNOWN;
	GMainLoop *loop;
	gint64 remaining_ms;
	GError *error = NULL;

	GOptionEntry options[] = {
		{"timeout", 't', 0, G_OPTION_ARG_INT, &t_secs, N_("Time to wait for a connection, in seconds (without the option, default value is 30)"), "<timeout>"},
		{"exit", 'x', 0, G_OPTION_ARG_NONE, &exit_no_nm, N_("Exit immediately if NetworkManager is not running or connecting"), NULL},
		{"quiet", 'q', 0, G_OPTION_ARG_NONE, &timeout.quiet, N_("Don't print anything"), NULL},
		{"wait-for-startup", 's', 0, G_OPTION_ARG_NONE, &wait_startup, N_("Wait for NetworkManager startup instead of a connection"), NULL},
		{NULL}
	};

	timeout.start_timestamp_ms = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
	timeout.quiet = FALSE;

	/* Set locale to be able to use environment variables */
	setlocale (LC_ALL, "");

	bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	opt_ctx = g_option_context_new (NULL);
	g_option_context_set_translation_domain (opt_ctx, GETTEXT_PACKAGE);
	g_option_context_set_ignore_unknown_options (opt_ctx, FALSE);
	g_option_context_set_help_enabled (opt_ctx, TRUE);
	g_option_context_add_main_entries (opt_ctx, options, NULL);

	g_option_context_set_summary (opt_ctx,
	                              _("Waits for NetworkManager to finish activating startup network connections."));

	success = g_option_context_parse (opt_ctx, &argc, &argv, NULL);
	g_option_context_free (opt_ctx);

	if (!success) {
		g_printerr ("%s: %s\n", argv[0],
		            _("Invalid option.  Please use --help to see a list of valid options."));
		return 2;
	}

	if (t_secs < 0 || t_secs > 3600)  {
		g_printerr ("%s: %s\n", argv[0],
		            _("Invalid option.  Please use --help to see a list of valid options."));
		return 2;
	}
	remaining_ms = t_secs * 1000;

	nm_g_type_init ();

	client = nm_client_new (NULL, &error);
	if (!client) {
		g_printerr (_("Error: Could not create NMClient object: %s."), error->message);
		g_error_free (error);
		return 2;
	}

	loop = g_main_loop_new (NULL, FALSE);

	g_object_set_data (G_OBJECT (client), WAIT_STARTUP_TAG, GUINT_TO_POINTER (wait_startup));
	state = nm_client_get_state (client);
	if (!nm_client_get_nm_running (client)) {
		if (exit_no_nm) {
			g_object_unref (client);
			return 1;
		}
	} else if (wait_startup) {
		if (!nm_client_get_startup (client)) {
			g_object_unref (client);
			return 0;
		}
	} else {
		if (   state == NM_STATE_CONNECTED_LOCAL
		    || state == NM_STATE_CONNECTED_SITE
		    || state == NM_STATE_CONNECTED_GLOBAL) {
			g_object_unref (client);
			return 0;
		}
	}
	if (exit_no_nm && (state != NM_STATE_CONNECTING)) {
		g_object_unref (client);
		return 1;
	}

	if (remaining_ms == 0) {
		g_object_unref (client);
		return 1;
	}

	g_signal_connect (client, "notify",
	                  G_CALLBACK (client_properties_changed), loop);

	timeout.end_timestamp_ms = timeout.start_timestamp_ms + remaining_ms;
	timeout.progress_step_duration = (timeout.end_timestamp_ms - timeout.start_timestamp_ms + PROGRESS_STEPS/2) / PROGRESS_STEPS;

	g_timeout_add (timeout.quiet ? remaining_ms : 0,
	               handle_timeout, &timeout);

	g_main_loop_run (loop);
	g_main_loop_unref (loop);

	g_object_unref (client);

	return 0;
}
示例#4
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_usb_dev_inst *usb;
	struct sr_config *src;
	const struct hantek_6xxx_profile *prof;
	GSList *l, *devices, *conn_devices;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	int i, j;
	const char *conn;
	char connection_id[64];

	drvc = di->context;

	devices = 0;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN) {
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (conn)
		conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
	else
		conn_devices = NULL;

	/* Find all Hantek 60xx devices and upload firmware to all of them. */
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if (conn) {
			usb = NULL;
			for (l = conn_devices; l; l = l->next) {
				usb = l->data;
				if (usb->bus == libusb_get_bus_number(devlist[i])
					&& usb->address == libusb_get_device_address(devlist[i]))
					break;
			}
			if (!l)
				/* This device matched none of the ones that
				 * matched the conn specification. */
				continue;
		}

		libusb_get_device_descriptor(devlist[i], &des);

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		prof = NULL;
		for (j = 0; dev_profiles[j].orig_vid; j++) {
			if (des.idVendor == dev_profiles[j].orig_vid
				&& des.idProduct == dev_profiles[j].orig_pid) {
				/* Device matches the pre-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = hantek_6xxx_dev_new(prof);
				sdi->connection_id = g_strdup(connection_id);
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
						USB_CONFIGURATION, prof->firmware) == SR_OK)
					/* Remember when the firmware on this device was updated. */
					devc->fw_updated = g_get_monotonic_time();
				else
					sr_err("Firmware upload failed.");
				/* Dummy USB address of 0xff will get overwritten later. */
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]), 0xff, NULL);
				break;
			} else if (des.idVendor == dev_profiles[j].fw_vid
				&& des.idProduct == dev_profiles[j].fw_pid
				&& des.bcdDevice == dev_profiles[j].fw_prod_ver) {
				/* Device matches the post-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = hantek_6xxx_dev_new(prof);
				sdi->connection_id = g_strdup(connection_id);
				sdi->status = SR_ST_INACTIVE;
				devices = g_slist_append(devices, sdi);
				sdi->inst_type = SR_INST_USB;
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]),
						libusb_get_device_address(devlist[i]), NULL);
				break;
			}
		}
		if (!prof)
			/* Not a supported VID/PID. */
			continue;
	}
	libusb_free_device_list(devlist, 1);

	return std_scan_complete(di, devices);
}
示例#5
0
文件: serial.c 项目: poljar/libsigrok
/**
 * Try to find a valid packet in a serial data stream.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer containing the bytes to write.
 * @param count Size of the buffer.
 * @param packet_size Size, in bytes, of a valid packet.
 * @param is_valid Callback that assesses whether the packet is valid or not.
 * @param timeout_ms The timeout after which, if no packet is detected, to
 *                   abort scanning.
 * @param baudrate The baudrate of the serial port. This parameter is not
 *                 critical, but it helps fine tune the serial port polling
 *                 delay.
 *
 * @return SR_OK if a valid packet is found within the given timeout,
 *         SR_ERR upon failure.
 */
SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
				 uint8_t *buf, size_t *buflen,
				 size_t packet_size, packet_valid_t is_valid,
				 uint64_t timeout_ms, int baudrate)
{
	uint64_t start, time, byte_delay_us;
	size_t ibuf, i, maxlen;
	int len;

	maxlen = *buflen;

	sr_dbg("Detecting packets on FD %d (timeout = %" PRIu64
	       "ms, baudrate = %d).", serial->fd, timeout_ms, baudrate);

	if (maxlen < (packet_size / 2) ) {
		sr_err("Buffer size must be at least twice the packet size.");
		return SR_ERR;
	}

	/* Assume 8n1 transmission. That is 10 bits for every byte. */
	byte_delay_us = 10 * (1000000 / baudrate);
	start = g_get_monotonic_time();

	i = ibuf = len = 0;
	while (ibuf < maxlen) {
		len = serial_read(serial, &buf[ibuf], 1);
		if (len > 0) {
			ibuf += len;
		} else if (len == 0) {
			/* No logging, already done in serial_read(). */
		} else {
			/* Error reading byte, but continuing anyway. */
		}

		time = g_get_monotonic_time() - start;
		time /= 1000;

		if ((ibuf - i) >= packet_size) {
			/* We have at least a packet's worth of data. */
			if (is_valid(&buf[i])) {
				sr_spew("Found valid %d-byte packet after "
					"%" PRIu64 "ms.", (ibuf - i), time);
				*buflen = ibuf;
				return SR_OK;
			} else {
				sr_spew("Got %d bytes, but not a valid "
					"packet.", (ibuf - i));
			}
			/* Not a valid packet. Continue searching. */
			i++;
		}
		if (time >= timeout_ms) {
			/* Timeout */
			sr_dbg("Detection timed out after %dms.", time);
			break;
		}
		if (len < 1)
			g_usleep(byte_delay_us);
	}

	*buflen = ibuf;

	sr_err("Didn't find a valid packet (read %d bytes).", *buflen);

	return SR_ERR;
}
示例#6
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_usb_dev_inst *usb;
	struct sr_channel *ch;
	struct sr_channel_group *cg;
	struct sr_config *src;
	const struct fx2lafw_profile *prof;
	GSList *l, *devices, *conn_devices;
	gboolean has_firmware;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	struct libusb_device_handle *hdl;
	int ret, i, j;
	int num_logic_channels = 0, num_analog_channels = 0;
	const char *conn;
	char manufacturer[64], product[64], serial_num[64], connection_id[64];
	char channel_name[16];

	drvc = di->context;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (conn)
		conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
	else
		conn_devices = NULL;

	/* Find all fx2lafw compatible devices and upload firmware to them. */
	devices = NULL;
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if (conn) {
			usb = NULL;
			for (l = conn_devices; l; l = l->next) {
				usb = l->data;
				if (usb->bus == libusb_get_bus_number(devlist[i])
					&& usb->address == libusb_get_device_address(devlist[i]))
					break;
			}
			if (!l)
				/* This device matched none of the ones that
				 * matched the conn specification. */
				continue;
		}

		libusb_get_device_descriptor( devlist[i], &des);

		if (!is_plausible(&des))
			continue;

		if ((ret = libusb_open(devlist[i], &hdl)) < 0) {
			sr_warn("Failed to open potential device with "
				"VID:PID %04x:%04x: %s.", des.idVendor,
				des.idProduct, libusb_error_name(ret));
			continue;
		}

		if (des.iManufacturer == 0) {
			manufacturer[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iManufacturer, (unsigned char *) manufacturer,
				sizeof(manufacturer))) < 0) {
			sr_warn("Failed to get manufacturer string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		if (des.iProduct == 0) {
			product[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iProduct, (unsigned char *) product,
				sizeof(product))) < 0) {
			sr_warn("Failed to get product string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		if (des.iSerialNumber == 0) {
			serial_num[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iSerialNumber, (unsigned char *) serial_num,
				sizeof(serial_num))) < 0) {
			sr_warn("Failed to get serial number string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		libusb_close(hdl);

		if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0)
			continue;

		prof = NULL;
		for (j = 0; supported_fx2[j].vid; j++) {
			if (des.idVendor == supported_fx2[j].vid &&
					des.idProduct == supported_fx2[j].pid &&
					(!supported_fx2[j].usb_manufacturer ||
					 !strcmp(manufacturer, supported_fx2[j].usb_manufacturer)) &&
					(!supported_fx2[j].usb_product ||
					 !strcmp(product, supported_fx2[j].usb_product))) {
				prof = &supported_fx2[j];
				break;
			}
		}

		if (!prof)
			continue;

		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INITIALIZING;
		sdi->vendor = g_strdup(prof->vendor);
		sdi->model = g_strdup(prof->model);
		sdi->version = g_strdup(prof->model_version);
		sdi->serial_num = g_strdup(serial_num);
		sdi->connection_id = g_strdup(connection_id);

		/* Fill in channellist according to this device's profile. */
		num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8;
		num_analog_channels = prof->dev_caps & DEV_CAPS_AX_ANALOG ? 1 : 0;

		/* Logic channels, all in one channel group. */
		cg = g_malloc0(sizeof(struct sr_channel_group));
		cg->name = g_strdup("Logic");
		for (j = 0; j < num_logic_channels; j++) {
			sprintf(channel_name, "D%d", j);
			ch = sr_channel_new(sdi, j, SR_CHANNEL_LOGIC,
						TRUE, channel_name);
			cg->channels = g_slist_append(cg->channels, ch);
		}
		sdi->channel_groups = g_slist_append(NULL, cg);

		for (j = 0; j < num_analog_channels; j++) {
			snprintf(channel_name, 16, "A%d", j);
			ch = sr_channel_new(sdi, j + num_logic_channels,
					SR_CHANNEL_ANALOG, TRUE, channel_name);

			/* Every analog channel gets its own channel group. */
			cg = g_malloc0(sizeof(struct sr_channel_group));
			cg->name = g_strdup(channel_name);
			cg->channels = g_slist_append(NULL, ch);
			sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
		}

		devc = fx2lafw_dev_new();
		devc->profile = prof;
		sdi->priv = devc;
		devices = g_slist_append(devices, sdi);

		devc->samplerates = samplerates;
		devc->num_samplerates = ARRAY_SIZE(samplerates);
		has_firmware = usb_match_manuf_prod(devlist[i],
				"sigrok", "fx2lafw");

		if (has_firmware) {
			/* Already has the firmware, so fix the new address. */
			sr_dbg("Found an fx2lafw device.");
			sdi->status = SR_ST_INACTIVE;
			sdi->inst_type = SR_INST_USB;
			sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
					libusb_get_device_address(devlist[i]), NULL);
		} else {
			if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
					USB_CONFIGURATION, prof->firmware) == SR_OK) {
				/* Store when this device's FW was updated. */
				devc->fw_updated = g_get_monotonic_time();
			} else {
				sr_err("Firmware upload failed for "
				       "device %d.%d (logical), name %s.",
				       libusb_get_bus_number(devlist[i]),
				       libusb_get_device_address(devlist[i]),
				       prof->firmware);
			}
			sdi->inst_type = SR_INST_USB;
			sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
					0xff, NULL);
		}
	}
	libusb_free_device_list(devlist, 1);
	g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);

	return std_scan_complete(di, devices);
}
示例#7
0
/**
 * Scan for Metrahit 2x in a bidirectional mode using Gossen Metrawatt
 * 'BD 232' interface.
 */
static GSList *scan_2x_bd232(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	int cnt, byte;
	gint64 timeout_us;

	sdi = NULL;
	devc = NULL;
	conn = serialcomm = NULL;
	devices = NULL;

	sr_spew("scan_2x_bd232() called!");

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM_2X;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		goto exit_err;

	devc = g_malloc0(sizeof(struct dev_context));

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(VENDOR_GMC);
	sdi->priv = devc;

	/* Send message 03 "Query multimeter version and status" */
	sdi->conn = serial;
	if (req_stat14(sdi, TRUE) != SR_OK)
		goto exit_err;

	/* Wait for reply from device(s) for up to 2s. */
	timeout_us = g_get_monotonic_time() + (2 * 1000 * 1000);

	while (timeout_us > g_get_monotonic_time()) {
		/* Receive reply (14 bytes) */
		devc->buflen = 0;
		for (cnt = 0; cnt < GMC_REPLY_SIZE; cnt++) {
			byte = read_byte(serial, timeout_us);
			if (byte != -1)
				devc->buf[devc->buflen++] = (byte & MASK_6BITS);
		}

		if (devc->buflen != GMC_REPLY_SIZE)
			continue;

		devc->addr = devc->buf[0];
		process_msg14(sdi);
		devc->buflen = 0;

		if (devc->model != METRAHIT_NONE) {
			sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(devc->model));
			sr_sw_limits_init(&devc->limits);
			sdi->model = g_strdup(gmc_model_str(devc->model));
			sdi->version = g_strdup_printf("Firmware %d.%d", devc->fw_ver_maj, devc->fw_ver_min);
			sdi->conn = serial;
			sdi->priv = devc;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");
			devices = g_slist_append(devices, sdi);
			devc = g_malloc0(sizeof(struct dev_context));
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup(VENDOR_GMC);
		}
	};

	/* Free last alloc if no device found */
	if (devc->model == METRAHIT_NONE) {
		g_free(devc);
		sr_dev_inst_free(sdi);
	}

	return std_scan_complete(di, devices);

exit_err:
	sr_info("scan_2x_bd232(): Error!");

	sr_serial_dev_inst_free(serial);
	g_free(devc);
	sr_dev_inst_free(sdi);

	return NULL;
}
示例#8
0
GError *
sqlx_cache_open_and_lock_base(sqlx_cache_t *cache, const hashstr_t *hname,
		gint *result)
{
	gint bd;
	GError *err = NULL;
	sqlx_base_t *base = NULL;

	EXTRA_ASSERT(cache != NULL);
	EXTRA_ASSERT(hname != NULL);
	EXTRA_ASSERT(result != NULL);

	gint64 start = oio_ext_monotonic_time();
	gint64 deadline = DEFAULT_CACHE_OPEN_TIMEOUT;
	if (cache->open_timeout > 0)
		deadline = cache->open_timeout;
	GRID_TRACE2("%s(%p,%s,%p) delay = %"G_GINT64_FORMAT, __FUNCTION__,
			(void*)cache, hname ? hashstr_str(hname) : "NULL",
			(void*)result, deadline);
	deadline += start;

	g_mutex_lock(&cache->lock);
	cache->used = TRUE;
retry:

	bd = sqlx_lookup_id(cache, hname);
	if (bd < 0) {
		if (!(err = sqlx_base_reserve(cache, hname, &base))) {
			bd = base->index;
			*result = base->index;
			sqlx_base_debug("OPEN", base);
		}
		else {
			GRID_DEBUG("No base available for [%s] (%d %s)",
					hashstr_str(hname), err->code, err->message);
			if (sqlx_expire_first_idle_base(cache, 0) >= 0) {
				g_clear_error(&err);
				goto retry;
			}
		}
	}
	else {
		base = GET(cache, bd);
		gint64 now = oio_ext_monotonic_time ();

		if (now > deadline) {
			err = NEWERROR (CODE_UNAVAILABLE,
					"DB busy (after %"G_GINT64_FORMAT" ms)",
					(now - start) / G_TIME_SPAN_MILLISECOND);
		} else switch (base->status) {

			case SQLX_BASE_FREE:
				EXTRA_ASSERT(base->count_open == 0);
				EXTRA_ASSERT(base->owner == NULL);
				GRID_ERROR("free base referenced");
				g_assert_not_reached();
				break;

			case SQLX_BASE_IDLE:
			case SQLX_BASE_IDLE_HOT:
				EXTRA_ASSERT(base->count_open == 0);
				EXTRA_ASSERT(base->owner == NULL);
				sqlx_base_move_to_list(cache, base, SQLX_BASE_USED);
				base->count_open ++;
				base->owner = g_thread_self();
				*result = base->index;
				break;

			case SQLX_BASE_USED:
				EXTRA_ASSERT(base->count_open > 0);
				EXTRA_ASSERT(base->owner != NULL);
				if (base->owner != g_thread_self()) {
					GRID_DEBUG("Base [%s] in use by another thread (%X), waiting...",
							hashstr_str(hname), oio_log_thread_id(base->owner));
					/* The lock is held by another thread/request.
					   XXX(jfs): do not use 'now' because it can be a fake clock */
					g_cond_wait_until(base->cond, &cache->lock,
							g_get_monotonic_time() + oio_cache_period_cond_wait);
					goto retry;
				}
				base->owner = g_thread_self();
				base->count_open ++;
				*result = base->index;
				break;

			case SQLX_BASE_CLOSING:
				EXTRA_ASSERT(base->owner != NULL);
				/* Just wait for a notification then retry
				   XXX(jfs): do not use 'now' because it can be a fake clock */
				g_cond_wait_until(base->cond, &cache->lock,
						g_get_monotonic_time() + oio_cache_period_cond_wait);
				goto retry;
		}
	}

	if (base) {
		if (!err) {
			sqlx_base_debug(__FUNCTION__, base);
			EXTRA_ASSERT(base->owner == g_thread_self());
			EXTRA_ASSERT(base->count_open > 0);
		}
		g_cond_signal(base->cond);
	}
	g_mutex_unlock(&cache->lock);
	return err;
}
示例#9
0
文件: api.c 项目: DeeJay/libsigrok
static int dev_acquisition_start(const struct sr_dev_inst *sdi,
		void *cb_data)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	struct sr_usb_dev_inst *usb;
	GVariant *gvar, *rational[2];
	const uint64_t *si;
	int stored_mqflags, req_len, buf_len, len, ret;
	unsigned char buf[9];

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	drvc = di->priv;
	devc = sdi->priv;
	usb = sdi->conn;

	devc->cb_data = cb_data;
	devc->num_samples = 0;

	/* Send header packet to the session bus. */
	std_session_send_df_header(cb_data, LOG_PREFIX);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		/* Force configuration. */
		kecheng_kc_330b_configure(sdi);

		if (kecheng_kc_330b_status_get(sdi, &ret) != SR_OK)
			return SR_ERR;
		if (ret != DEVICE_ACTIVE) {
			sr_err("Device is inactive");
			/* Still continue though, since the device will
			 * just return 30.0 until the user hits the button
			 * on the device -- and then start feeding good
			 * samples back. */
		}
	} else {
		if (kecheng_kc_330b_log_info_get(sdi, buf) != SR_OK)
			return SR_ERR;
		stored_mqflags = buf[4] ? SR_MQFLAG_SPL_TIME_WEIGHT_S : SR_MQFLAG_SPL_TIME_WEIGHT_F;
		stored_mqflags |= buf[5] ? SR_MQFLAG_SPL_FREQ_WEIGHT_C : SR_MQFLAG_SPL_FREQ_WEIGHT_A;
		devc->stored_samples = (buf[7] << 8) | buf[8];
		if (devc->stored_samples == 0) {
			/* Notify frontend of empty log by sending start/end packets. */
			packet.type = SR_DF_END;
			sr_session_send(cb_data, &packet);
			return SR_OK;
		}

		if (devc->limit_samples && devc->limit_samples < devc->stored_samples)
			devc->stored_samples = devc->limit_samples;

		si = kecheng_kc_330b_sample_intervals[buf[1]];
		rational[0] = g_variant_new_uint64(si[0]);
		rational[1] = g_variant_new_uint64(si[1]);
		gvar = g_variant_new_tuple(rational, 2);
		src = sr_config_new(SR_CONF_SAMPLE_INTERVAL, gvar);
		packet.type = SR_DF_META;
		packet.payload = &meta;
		meta.config = g_slist_append(NULL, src);
		sr_session_send(devc->cb_data, &packet);
		g_free(src);
	}

	if (!(devc->xfer = libusb_alloc_transfer(0)))
		return SR_ERR;

	usb_source_add(drvc->sr_ctx, 10,
		kecheng_kc_330b_handle_events, (void *)sdi);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		buf[0] = CMD_GET_LIVE_SPL;
		buf_len = 1;
		devc->state = LIVE_SPL_WAIT;
		devc->last_live_request = g_get_monotonic_time() / 1000;
		req_len = 3;
	} else {
		buf[0] = CMD_GET_LOG_DATA;
		buf[1] = 0;
		buf[2] = 0;
		buf_len = 4;
		devc->state = LOG_DATA_WAIT;
		if (devc->stored_samples < 63)
			buf[3] = devc->stored_samples;
		else
			buf[3] = 63;
		/* Command ack byte + 2 bytes per sample. */
		req_len = 1 + buf[3] * 2;
	}

	ret = libusb_bulk_transfer(usb->devhdl, EP_OUT, buf, buf_len, &len, 5);
	if (ret != 0 || len != 1) {
		sr_dbg("Failed to start acquisition: %s", libusb_error_name(ret));
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	libusb_fill_bulk_transfer(devc->xfer, usb->devhdl, EP_IN, devc->buf,
			req_len, kecheng_kc_330b_receive_transfer, (void *)sdi, 15);
	if (libusb_submit_transfer(devc->xfer) != 0) {
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	return SR_OK;
}
示例#10
0
char *janus_sdp_merge(janus_ice_handle *handle, const char *origsdp) {
	if(handle == NULL || origsdp == NULL)
		return NULL;
	//~ su_home_t home[1] = { SU_HOME_INIT(home) };
	sdp_session_t *anon = NULL;
	sdp_parser_t *parser = sdp_parse(home, origsdp, strlen(origsdp), 0);
	if(!(anon = sdp_session(parser))) {
		JANUS_DEBUG("[%"SCNu64"] Error parsing/merging SDP: %s\n", handle->handle_id, sdp_parsing_error(parser));
		return NULL;
	}
	/* Prepare SDP to merge */
	gchar buffer[200];
	memset(buffer, 0, 200);
	char *sdp = (char*)calloc(BUFSIZE, sizeof(char));
	if(sdp == NULL) {
		JANUS_DEBUG("Memory error!\n");
		return NULL;
	}
	sdp[0] = '\0';
	/* Version v= */
	g_strlcat(sdp,
		"v=0\r\n", BUFSIZE);
	/* Origin o= */
	if(anon->sdp_origin) {
		g_sprintf(buffer,
			"o=%s %"SCNu64" %"SCNu64" IN IP4 127.0.0.1\r\n",	/* FIXME Should we fix the address? */
				anon->sdp_origin->o_username ? anon->sdp_origin->o_username : "******",
				anon->sdp_origin->o_id, anon->sdp_origin->o_version);
		g_strlcat(sdp, buffer, BUFSIZE);
	} else {
		gint64 sessid = g_get_monotonic_time();
		gint64 version = sessid;	/* FIXME This needs to be increased when it changes, so time should be ok */
		g_sprintf(buffer,
			"o=%s %"SCNi64" %"SCNi64" IN IP4 127.0.0.1\r\n",	/* FIXME Should we fix the address? */
				"-", sessid, version);
		g_strlcat(sdp, buffer, BUFSIZE);
	}
	/* Session name s= */
	g_sprintf(buffer,
		"s=%s\r\n", anon->sdp_subject ? anon->sdp_subject : "Meetecho Janus");
	g_strlcat(sdp, buffer, BUFSIZE);
	/* Timing t= */
	g_sprintf(buffer,
		"t=%lu %lu\r\n", anon->sdp_time ? anon->sdp_time->t_start : 0, anon->sdp_time ? anon->sdp_time->t_stop : 0);
	g_strlcat(sdp, buffer, BUFSIZE);
	/* Any global bandwidth? */
	//~ if(anon->sdp_bandwidths) {
		//~ g_sprintf(buffer,
			//~ "b=%s:%"SCNu64"\r\n",
				//~ anon->sdp_bandwidths->b_modifier_name ? anon->sdp_bandwidths->b_modifier_name : "AS",
				//~ anon->sdp_bandwidths->b_value);
		//~ g_strlcat(sdp, buffer, BUFSIZE);
	//~ }
	/* msid-semantic: add new global attribute */
	g_strlcat(sdp,
		"a=msid-semantic: WMS janus\r\n",
		BUFSIZE);
	//~ /* Connection c= (global) */
	//~ if(anon->sdp_connection) {
		//~ g_sprintf(buffer,
			//~ "c=IN IP4 %s\r\n", janus_get_local_ip());
		//~ g_strlcat(sdp, buffer, BUFSIZE);
	//~ }
	/* DTLS fingerprint a= (global) */
	g_sprintf(buffer,
		"a=fingerprint:sha-256 %s\r\n", janus_dtls_get_local_fingerprint());
	g_strlcat(sdp, buffer, BUFSIZE);
	/* Copy other global attributes, if any */
	if(anon->sdp_attributes) {
		sdp_attribute_t *a = anon->sdp_attributes;
		while(a) {
			if(a->a_value == NULL) {
				g_sprintf(buffer,
					"a=%s\r\n", a->a_name);
				g_strlcat(sdp, buffer, BUFSIZE);
			} else {
				g_sprintf(buffer,
					"a=%s:%s\r\n", a->a_name, a->a_value);
				g_strlcat(sdp, buffer, BUFSIZE);
			}
			a = a->a_next;
		}
	}
	/* Media lines now */
	if(anon->sdp_media) {
		int audio = 0, video = 0;
		sdp_media_t *m = anon->sdp_media;
		janus_ice_stream *stream = NULL;
		while(m) {
			if(m->m_type == sdp_media_audio) {
				audio++;
				if(audio > 1 || !handle->audio_id) {
					JANUS_DEBUG("[%"SCNu64"] Skipping audio line (we have %d audio lines, and the id is %d)\n", handle->handle_id, audio, handle->audio_id);
					g_strlcat(sdp, "m=audio 0 RTP/SAVPF 0\r\n", BUFSIZE);
					m = m->m_next;
					continue;
				}
				/* Audio */
				stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->audio_id));
				if(stream == NULL) {
					JANUS_DEBUG("[%"SCNu64"] Skipping audio line (invalid stream %d)\n", handle->handle_id, handle->audio_id);
					g_strlcat(sdp, "m=audio 0 RTP/SAVPF 0\r\n", BUFSIZE);
					m = m->m_next;
					continue;
				}
				g_strlcat(sdp, "m=audio ARTPP RTP/SAVPF", BUFSIZE);
			} else if(m->m_type == sdp_media_video) {
				video++;
				if(video > 1 || !handle->video_id) {
					JANUS_DEBUG("[%"SCNu64"] Skipping video line (we have %d video lines, and the id is %d)\n", handle->handle_id, video, handle->video_id);
					g_strlcat(sdp, "m=video 0 RTP/SAVPF 0\r\n", BUFSIZE);
					m = m->m_next;
					continue;
				}
				/* Video */
				stream = g_hash_table_lookup(handle->streams, GUINT_TO_POINTER(handle->video_id));
				if(stream == NULL) {
					JANUS_DEBUG("[%"SCNu64"] Skipping video line (invalid stream %d)\n", handle->handle_id, handle->audio_id);
					g_strlcat(sdp, "m=video 0 RTP/SAVPF 0\r\n", BUFSIZE);
					m = m->m_next;
					continue;
				}
				g_strlcat(sdp, "m=video VRTPP RTP/SAVPF", BUFSIZE);
			} else {
				JANUS_DEBUG("[%"SCNu64"] Skipping unsupported media line...\n", handle->handle_id);
				g_sprintf(buffer,
					"m=%s 0 %s 0\r\n",
					m->m_type_name, m->m_proto_name);
				g_strlcat(sdp, buffer, BUFSIZE);
				m = m->m_next;
				continue;
			}
			/* Add formats now */
			if(!m->m_rtpmaps) {
				JANUS_PRINT("[%"SCNu64"] No RTP maps?? trying formats...\n", handle->handle_id);
				if(!m->m_format) {
					JANUS_DEBUG("[%"SCNu64"] No formats either?? this sucks!\n", handle->handle_id);
					g_strlcat(sdp, " 0", BUFSIZE);	/* FIXME Won't work apparently */
				} else {
					sdp_list_t *fmt = m->m_format;
					while(fmt) {
						g_sprintf(buffer, " %s", fmt->l_text);
						g_strlcat(sdp, buffer, BUFSIZE);
						fmt = fmt->l_next;
					}
				}
			} else {
				sdp_rtpmap_t *r = m->m_rtpmaps;
				while(r) {
					g_sprintf(buffer, " %d", r->rm_pt);
					g_strlcat(sdp, buffer, BUFSIZE);
					r = r->rm_next;
				}
			}
			g_strlcat(sdp, "\r\n", BUFSIZE);
			/* Any bandwidth? */
			if(m->m_bandwidths) {
				g_sprintf(buffer,
					"b=%s:%lu\r\n",	/* FIXME Are we doing this correctly? */
						m->m_bandwidths->b_modifier_name ? m->m_bandwidths->b_modifier_name : "AS",
						m->m_bandwidths->b_value);
				g_strlcat(sdp, buffer, BUFSIZE);
			}
			/* Media connection c= */
			//~ if(m->m_connections) {
				g_sprintf(buffer,
					"c=IN IP4 %s\r\n", janus_get_local_ip());
				g_strlcat(sdp, buffer, BUFSIZE);
			//~ }
			/* What is the direction? */
			switch(m->m_mode) {
				case sdp_inactive:
					g_strlcat(sdp, "a=inactive\r\n", BUFSIZE);
					break;
				case sdp_sendonly:
					g_strlcat(sdp, "a=sendonly\r\n", BUFSIZE);
					break;
				case sdp_recvonly:
					g_strlcat(sdp, "a=recvonly\r\n", BUFSIZE);
					break;
				case sdp_sendrecv:
				default:
					g_strlcat(sdp, "a=sendrecv\r\n", BUFSIZE);
					break;
			}
			/* RTCP */
			g_sprintf(buffer, "a=rtcp:%s IN IP4 %s\r\n",
				m->m_type == sdp_media_audio ? "ARTCP" : "VRTCP", janus_get_local_ip());
			g_strlcat(sdp, buffer, BUFSIZE);
			/* RTP maps */
			if(m->m_rtpmaps) {
				sdp_rtpmap_t *rm = NULL;
				for(rm = m->m_rtpmaps; rm; rm = rm->rm_next) {
					g_sprintf(buffer, "a=rtpmap:%u %s/%lu%s%s\r\n",
						rm->rm_pt, rm->rm_encoding, rm->rm_rate,
						rm->rm_params ? "/" : "", 
						rm->rm_params ? rm->rm_params : "");
					g_strlcat(sdp, buffer, BUFSIZE);
				}
				for(rm = m->m_rtpmaps; rm; rm = rm->rm_next) {
					if(rm->rm_fmtp) {
						g_sprintf(buffer, "a=fmtp:%u %s\r\n", rm->rm_pt, rm->rm_fmtp);
						g_strlcat(sdp, buffer, BUFSIZE);
					}
				}
			}
			/* ICE ufrag and pwd, DTLS setup and connection a= */
			gchar *ufrag = NULL;
			gchar *password = NULL;
			nice_agent_get_local_credentials(handle->agent, stream->stream_id, &ufrag, &password);
			memset(buffer, 0, 100);
			g_sprintf(buffer,
				"a=ice-ufrag:%s\r\n"
				"a=ice-pwd:%s\r\n"
				"a=setup:%s\r\n"
				"a=connection:new\r\n",
					ufrag, password,
					janus_get_dtls_srtp_role(stream->dtls_role));
			g_strlcat(sdp, buffer, BUFSIZE);
			/* Copy existing media attributes, if any */
			if(m->m_attributes) {
				sdp_attribute_t *a = m->m_attributes;
				while(a) {
					if(a->a_value == NULL) {
						g_sprintf(buffer,
							"a=%s\r\n", a->a_name);
						g_strlcat(sdp, buffer, BUFSIZE);
					} else {
						g_sprintf(buffer,
							"a=%s:%s\r\n", a->a_name, a->a_value);
						g_strlcat(sdp, buffer, BUFSIZE);
					}
					a = a->a_next;
				}
			}
			/* Add last attributes, rtcp and ssrc (msid) */
			if(m->m_type == sdp_media_audio) {
				g_sprintf(buffer,
					//~ "a=rtcp:ARTCP IN IP4 %s\r\n"
					"a=ssrc:%i cname:janusaudio\r\n"
					"a=ssrc:%i msid:janus janusa0\r\n"
					"a=ssrc:%i mslabel:janus\r\n"
					"a=ssrc:%i label:janusa0\r\n",
						//~ janus_get_local_ip(),
						stream->ssrc, stream->ssrc, stream->ssrc, stream->ssrc);
				g_strlcat(sdp, buffer, BUFSIZE);
			} else if(m->m_type == sdp_media_video) {
				g_sprintf(buffer,
					//~ "a=rtcp:VRTCP IN IP4 %s\r\n"
					"a=ssrc:%i cname:janusvideo\r\n"
					"a=ssrc:%i msid:janus janusv0\r\n"
					"a=ssrc:%i mslabel:janus\r\n"
					"a=ssrc:%i label:janusv0\r\n",
						//~ janus_get_local_ip(),
						stream->ssrc, stream->ssrc, stream->ssrc, stream->ssrc);
				g_strlcat(sdp, buffer, BUFSIZE);
			}
			/* And now the candidates */
			janus_ice_setup_candidate(handle, sdp, stream->stream_id, 1);
			janus_ice_setup_candidate(handle, sdp, stream->stream_id, 2);
			/* Next */
			m = m->m_next;
		}
	}
	JANUS_PRINT(" -------------------------------------------\n");
	JANUS_PRINT("  >> Merged (%zu --> %zu bytes)\n", strlen(origsdp), strlen(sdp));
	JANUS_PRINT(" -------------------------------------------\n");
	JANUS_PRINT("%s\n", sdp);
	return sdp;
}
示例#11
0
SR_PRIV int motech_lps_30x_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;

	if (revents == G_IO_IN) { /* Serial data arrived. */
		while (LINELEN_MAX - devc->buflen - 2 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;

			/* Eliminate whitespace at beginning of line. */
			if (g_ascii_isspace(devc->buf[0])) {
				devc->buf[0] = '\0';
				devc->buflen = 0;
				continue;
			}

			devc->buflen += len;
			devc->buf[devc->buflen] = '\0';

			/* If line complete, process msg. */
			if ((devc->buflen > 0) && ((devc->buf[devc->buflen-1] == '\r') || devc->buf[devc->buflen-1] == '\n')) {
				devc->buflen--;
				devc->buf[devc->buflen] = '\0';

				sr_spew("Line complete: \"%s\"", devc->buf);
				process_line(sdi);
			}
		}
	}

	if (sr_sw_limits_check(&devc->limits))
		sdi->driver->dev_acquisition_stop(sdi);

	/* Only request the next packet if required. */
	if (!((sdi->status == SR_ST_ACTIVE) && (devc->acq_running)))
		return TRUE;

	if (devc->acq_req_pending) {
		int64_t elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
		if (elapsed_us > (REQ_TIMEOUT_MS * 1000)) {
			sr_spew("Request timeout: req=%d t=%" PRIi64 "us",
				(int)devc->acq_req, elapsed_us);
			devc->acq_req_pending = 0;
		}
	}

	if (devc->acq_req_pending == 0) {
		switch (devc->acq_req) {
		case AQ_NONE: /* Fall through */
		case AQ_STATUS:
			devc->acq_req = AQ_U1;
			lps_send_req(serial, "VOUT1");
			break;
		case AQ_U1:
			devc->acq_req = AQ_I1;
			lps_send_req(serial, "IOUT1");
			break;
		case AQ_I1:
			if (devc->model->num_channels == 1) {
				devc->acq_req = AQ_STATUS;
				lps_send_req(serial, "STATUS");
			} else {
				devc->acq_req = AQ_U2;
				lps_send_req(serial, "VOUT2");
			}
			break;
		case AQ_U2:
			devc->acq_req = AQ_I2;
			lps_send_req(serial, "IOUT2");
			break;
		case AQ_I2:
			devc->acq_req = AQ_STATUS;
			lps_send_req(serial, "STATUS");
			break;
		default:
			sr_err("Illegal devc->acq_req=%d", devc->acq_req);
			return SR_ERR;
		}
		devc->req_sent_at = g_get_real_time();
		devc->acq_req_pending = 1;
	}

	return TRUE;
}
static void
on_sensor_value_notify(IsSensor *sensor,
                       GParamSpec *pspec,
                       gpointer user_data)
{
  IsDynamicPlugin *self;
  IsDynamicPluginPrivate *priv;
  RateData *data;
  gdouble value, dv, dt, rate;
  gint64 now;

  self = IS_DYNAMIC_PLUGIN(user_data);
  priv = self->priv;

  value = is_sensor_get_value(sensor);

  if (value - IS_SENSOR_VALUE_UNSET <= DBL_EPSILON)
  {
    is_debug("dynamic", "sensor value for sensor %s is unset - ignoring",
             is_sensor_get_label(sensor));
    goto exit;
  }

  now = g_get_monotonic_time();

  data = g_object_get_data(G_OBJECT(sensor), DYNAMIC_RATE_DATA_KEY);
  if (data == NULL)
  {
    is_debug("dynamic", "Creating new dynamic rate data for sensor: %s",
             is_sensor_get_label(sensor));

    // allocate data
    data = g_malloc0(sizeof(*data));
    data->rate = 0.0f;
    data->last_value = value;
    data->last_time = now;
    g_object_set_data_full(G_OBJECT(sensor), DYNAMIC_RATE_DATA_KEY,
                           data, g_free);
    goto exit;
  }

  is_debug("dynamic", "Got existing rate data for sensor: %s - rate: %f, last_value %f, last_time %"PRId64"",
           is_sensor_get_label(sensor),
           data->rate,
           data->last_value,
           data->last_time);
  dv = value - data->last_value;
  dt = ((double)(now - data->last_time) /
        (double)G_USEC_PER_SEC);

  // convert rate to units per second
  rate = fabs(dv / dt);
  is_debug("dynamic", "abs rate of change of sensor %s: %f (t0: %f, t-1: %f, dv: %f, dt: %f)",
           is_sensor_get_label(sensor), rate, value, data->last_value,
           dv, dt);

  // calculate exponentially weighted moving average of rate
  rate = (EWMA_ALPHA * rate) + ((1 - EWMA_ALPHA) * data->rate);
  data->rate = rate;
  data->last_value = value;
  data->last_time = now;
  is_debug("dynamic", "EWMA abs rate of change of sensor %s: %f",
           is_sensor_get_label(sensor), rate);

  if (rate > priv->max_rate && sensor != priv->max)
  {
    // let's see if we can get away without taking a reference on sensor
    priv->max = sensor;

    is_message("dynamic", "New highest EWMA rate sensor: %s (rate %f)",
               is_sensor_get_label(sensor), rate);
  }

  if (sensor == priv->max)
  {
    priv->max_rate = rate;

    update_sensor_from_max(self);
  }

exit:
  return;
}
示例#13
0
static gboolean
gdk_frame_clock_paint_idle (void *data)
{
  GdkFrameClock *clock = GDK_FRAME_CLOCK (data);
  GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
  GdkFrameClockIdlePrivate *priv = clock_idle->priv;
  gboolean skip_to_resume_events;
  GdkFrameTimings *timings = NULL;

  priv->paint_idle_id = 0;
  priv->in_paint_idle = TRUE;
  priv->min_next_frame_time = 0;

  skip_to_resume_events =
    (priv->requested & ~(GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS | GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS)) == 0 &&
    priv->updating_count == 0;

  if (priv->phase > GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT)
    {
      timings = gdk_frame_clock_get_current_timings (clock);
    }

  if (!skip_to_resume_events)
    {
      switch (priv->phase)
        {
        case GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS:
          break;
        case GDK_FRAME_CLOCK_PHASE_NONE:
        case GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT:
          if (priv->freeze_count == 0)
            {
              priv->frame_time = compute_frame_time (clock_idle);

              _gdk_frame_clock_begin_frame (clock);
              timings = gdk_frame_clock_get_current_timings (clock);

              timings->frame_time = priv->frame_time;
              timings->slept_before = priv->sleep_serial != get_sleep_serial ();

              priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT;

              /* We always emit ::before-paint and ::after-paint if
               * any of the intermediate phases are requested and
               * they don't get repeated if you freeze/thaw while
               * in them.
               */
              priv->requested &= ~GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT;
              g_signal_emit_by_name (G_OBJECT (clock), "before-paint");
              priv->phase = GDK_FRAME_CLOCK_PHASE_UPDATE;
            }
          /* fallthrough */
        case GDK_FRAME_CLOCK_PHASE_UPDATE:
          if (priv->freeze_count == 0)
            {
              if ((priv->requested & GDK_FRAME_CLOCK_PHASE_UPDATE) != 0 ||
                  priv->updating_count > 0)
                {
                  priv->requested &= ~GDK_FRAME_CLOCK_PHASE_UPDATE;
                  g_signal_emit_by_name (G_OBJECT (clock), "update");
                }
            }
          /* fallthrough */
        case GDK_FRAME_CLOCK_PHASE_LAYOUT:
          if (priv->freeze_count == 0)
            {
	      int iter;
#ifdef G_ENABLE_DEBUG
              if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
                {
                  if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
                      (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
                    timings->layout_start_time = g_get_monotonic_time ();
                }
#endif /* G_ENABLE_DEBUG */

              priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
	      /* We loop in the layout phase, because we don't want to progress
	       * into the paint phase with invalid size allocations. This may
	       * happen in some situation like races between user window
	       * resizes and natural size changes.
	       */
	      iter = 0;
              while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
		     priv->freeze_count == 0 && iter++ < 4)
                {
                  priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
                  g_signal_emit_by_name (G_OBJECT (clock), "layout");
                }
	      if (iter == 5)
		g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
            }
          /* fallthrough */
        case GDK_FRAME_CLOCK_PHASE_PAINT:
          if (priv->freeze_count == 0)
            {
#ifdef G_ENABLE_DEBUG
              if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
                {
                  if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
                      (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
                    timings->paint_start_time = g_get_monotonic_time ();
                }
#endif /* G_ENABLE_DEBUG */

              priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
              if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
                {
                  priv->requested &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
                  g_signal_emit_by_name (G_OBJECT (clock), "paint");
                }
            }
          /* fallthrough */
        case GDK_FRAME_CLOCK_PHASE_AFTER_PAINT:
          if (priv->freeze_count == 0)
            {
              priv->requested &= ~GDK_FRAME_CLOCK_PHASE_AFTER_PAINT;
              g_signal_emit_by_name (G_OBJECT (clock), "after-paint");
              /* the ::after-paint phase doesn't get repeated on freeze/thaw,
               */
              priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;

#ifdef G_ENABLE_DEBUG
              if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
                timings->frame_end_time = g_get_monotonic_time ();
#endif /* G_ENABLE_DEBUG */
            }
          /* fallthrough */
        case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:
          ;
        }
    }

#ifdef G_ENABLE_DEBUG
  if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
    {
      if (timings && timings->complete)
        _gdk_frame_clock_debug_print_timings (clock, timings);
    }
#endif /* G_ENABLE_DEBUG */

  if (priv->requested & GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS)
    {
      priv->requested &= ~GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS;
      g_signal_emit_by_name (G_OBJECT (clock), "resume-events");
    }

  if (priv->freeze_count == 0)
    priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;

  priv->in_paint_idle = FALSE;

  /* If there is throttling in the backend layer, then we'll do another
   * update as soon as the backend unthrottles (if there is work to do),
   * otherwise we need to figure when the next frame should be.
   */
  if (priv->freeze_count == 0)
    {
      priv->min_next_frame_time = compute_min_next_frame_time (clock_idle,
                                                               priv->frame_time);
      maybe_start_idle (clock_idle);
    }

  if (priv->freeze_count == 0)
    priv->sleep_serial = get_sleep_serial ();

  return FALSE;
}
示例#14
0
static void
gb_terminal_respawn (GbTerminalView *self,
                     VteTerminal    *terminal)
{
  g_autoptr(GPtrArray) args = NULL;
  g_autoptr(IdeSubprocess) subprocess = NULL;
  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
  g_autofree gchar *workpath = NULL;
  g_autofree gchar *shell = NULL;
  GtkWidget *toplevel;
  GError *error = NULL;
  IdeContext *context;
  IdeVcs *vcs;
  VtePty *pty = NULL;
  GFile *workdir;
  gint64 now;
  int tty_fd = -1;
  gint stdout_fd = -1;
  gint stderr_fd = -1;

  IDE_ENTRY;

  g_assert (GB_IS_TERMINAL_VIEW (self));

  vte_terminal_reset (terminal, TRUE, TRUE);

  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
  if (!IDE_IS_WORKBENCH (toplevel))
    IDE_EXIT;

  /* Prevent flapping */
  now = g_get_monotonic_time ();
  if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10))
    IDE_EXIT;
  self->last_respawn = now;

  context = ide_workbench_get_context (IDE_WORKBENCH (toplevel));
  vcs = ide_context_get_vcs (context);
  workdir = ide_vcs_get_working_directory (vcs);
  workpath = g_file_get_path (workdir);

  shell = gb_terminal_view_discover_shell (NULL, &error);

  if (shell == NULL)
    {
      g_warning ("Failed to discover user shell: %s", error->message);

      /* We prefer bash in flatpak over sh */
      if (ide_is_flatpak ())
        shell = g_strdup ("/bin/bash");
      else
        shell = vte_get_user_shell ();

      g_clear_error (&error);
    }

  args = g_ptr_array_new ();
  g_ptr_array_add (args, (gchar *)shell);
  g_ptr_array_add (args, NULL);

  pty = vte_terminal_pty_new_sync (terminal,
                                   VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP,
                                   NULL,
                                   &error);
  if (pty == NULL)
    IDE_GOTO (failure);

  vte_terminal_set_pty (terminal, pty);

  if (-1 == (tty_fd = gb_vte_pty_create_slave (pty)))
    IDE_GOTO (failure);

  /* dup() is safe as it will inherit O_CLOEXEC */
  if (-1 == (stdout_fd = dup (tty_fd)) || -1 == (stderr_fd = dup (tty_fd)))
    IDE_GOTO (failure);

  /* XXX: It would be nice to allow using the runtimes launcher */
  launcher = ide_subprocess_launcher_new (0);
  ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
  ide_subprocess_launcher_set_clear_env (launcher, FALSE);
  ide_subprocess_launcher_set_cwd (launcher, workpath);
  ide_subprocess_launcher_push_args (launcher, (const gchar * const *)args->pdata);
  ide_subprocess_launcher_take_stdin_fd (launcher, tty_fd);
  ide_subprocess_launcher_take_stdout_fd (launcher, stdout_fd);
  ide_subprocess_launcher_take_stderr_fd (launcher, stderr_fd);
  ide_subprocess_launcher_setenv (launcher, "TERM", "xterm-256color", TRUE);
  ide_subprocess_launcher_setenv (launcher, "INSIDE_GNOME_BUILDER", PACKAGE_VERSION, TRUE);
  ide_subprocess_launcher_setenv (launcher, "SHELL", shell, TRUE);

  tty_fd = -1;
  stdout_fd = -1;
  stderr_fd = -1;

  if (NULL == (subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error)))
    IDE_GOTO (failure);

  ide_subprocess_wait_async (subprocess,
                             NULL,
                             gb_terminal_view_wait_cb,
                             g_object_ref (terminal));

failure:
  if (tty_fd != -1)
    close (tty_fd);

  if (stdout_fd != -1)
    close (stdout_fd);

  g_clear_object (&pty);

  if (error != NULL)
    {
      g_warning ("%s", error->message);
      g_clear_error (&error);
    }

  IDE_EXIT;
}
示例#15
0
int
main(int argc, char *argv[])
{
  int ser_fd;
  GError *err = NULL;
  int werr;
  gchar *err_info;
  gint64 data_offset;
  wtap *w;
  GOptionContext *opt_ctxt;
  gint64 ts_start_us = 0;
  gint64 time_start_us = 0;
  opt_ctxt = g_option_context_new ("FILE");
  g_option_context_add_main_entries(opt_ctxt, app_options, NULL);
  if (!g_option_context_parse(opt_ctxt, &argc, &argv, &err)) {
    g_printerr("Failed to parse options: %s\n", err->message);
    return EXIT_FAILURE;
  }
  g_option_context_free(opt_ctxt);
  
  w = wtap_open_offline(argv[1], WTAP_TYPE_AUTO, &werr, &err_info, FALSE);
  if (!w) {
    g_printerr("Failed to open packet file: %d\n", werr);
    return EXIT_FAILURE;
  }

  if (pseudo) {
    ser_fd = open_pseudo_terminal(&err);
    if (ser_fd < 0) {
      g_printerr("Failed open pseudo terminal: %s\n", err->message);
      return EXIT_FAILURE;
    }
  } else {
    ser_fd = profibus_serial_open(device, speed, &err);
    if (ser_fd < 0) {
      g_printerr("Failed open serial port: %s\n", err->message);
      return EXIT_FAILURE;
    }
  }
  
  while(TRUE) {
    guint8 *data;
    struct wtap_pkthdr *hdr;
    if (!wtap_read(w, &werr, &err_info, &data_offset)) {
      if (err == 0) break;
      g_printerr("Failed to read packet file: %d\n", werr);
      return EXIT_FAILURE;
    }
    hdr = wtap_phdr(w);
    data = wtap_buf_ptr(w);
    if (timing) {
      if (time_start_us == 0) {
	ts_start_us = hdr->ts.secs * 1000000LL +  hdr->ts.nsecs / 1000;
	time_start_us = g_get_monotonic_time();
      } else {
	gint64 ts = hdr->ts.secs * 1000000LL +  hdr->ts.nsecs / 1000;
	gint64 next = time_start_us + (ts - ts_start_us);
	gint64 now = g_get_monotonic_time();
	gint64 delay = next - now;
	if (delay > 0) {
	  poll(NULL, 0, delay / 1000);
	}
      }
    }
    if (write(ser_fd, data, hdr->len) != hdr->len) {
      g_printerr("Failed to write to serial device: %s\n", strerror(errno));
      break;
    }
    /* g_debug("Write %d", hdr->len); */
  }
  wtap_close(w);
  g_message("EOF");
  close(ser_fd);
  return EXIT_SUCCESS;
}
示例#16
0
void test_suite_run(TestSuite* suite) {
    suite->start_time = g_get_monotonic_time();
    g_main_loop_run(suite->loop);
    suite->end_time  = g_get_monotonic_time();
}
示例#17
0
mt_throws Result updateTime ()
{
    LibMary_ThreadLocal * const tlocal = libMary_getThreadLocal();

#ifdef LIBMARY_PLATFORM_WIN32
    DWORD const win_time_dw = timeGetTime();
    if (tlocal->prv_win_time_dw >= win_time_dw) {
        tlocal->win_time_offs += 0x100000000;
    }
    tlocal->prv_win_time_dw = win_time_dw;
    DWORD const win_time = win_time_dw + tlocal->win_time_offs;

    Time const new_seconds = (Time) win_time / 1000;
    Time const new_microseconds = (Time) win_time * 1000;
#else
  #ifdef __MACH__
    mach_timespec_t mts;
    {
        #warning TODO call host_get_clock_service only once
        clock_serv_t clk;
        host_get_clock_service (mach_host_self(), SYSTEM_CLOCK, &clk);

        clock_get_time (clk, &mts);

        mach_port_deallocate (mach_task_self(), clk);
    }

    Time const new_seconds = mts.tv_sec;
    Time const new_microseconds = (Uint64) mts.tv_sec * 1000000 + (Uint64) mts.tv_nsec / 1000;

#if 0
// Deprecated
    gint64 const mono_time = g_get_monotonic_time ();
    Int64 const mono_time = 0;
    Time const new_seconds = mono_time / 1000000;
    Time const new_microseconds = mono_time;
#endif
  #else
    struct timespec ts;
    // Note that clock_gettime is well-optimized on Linux x86_64 and does not carry
    // full syscall overhead (depends on system configuration).
    int const res = clock_gettime (CLOCK_MONOTONIC, &ts);
    if (res == -1) {
	exc_throw (PosixException, errno);
	exc_push (InternalException, InternalException::BackendError);
	logE_ (_func, "clock_gettime() failed: ", errnoString (errno));
	return Result::Failure;
    } else
    if (res != 0) {
	exc_throw (InternalException, InternalException::BackendError);
	logE_ (_func, "clock_gettime(): unexpected return value: ", res);
	return Result::Failure;
    }

    logD (time, _func, "tv_sec: ", ts.tv_sec, ", tv_nsec: ", ts.tv_nsec);

    Time const new_seconds = ts.tv_sec;
    Time const new_microseconds = (Uint64) ts.tv_sec * 1000000 + (Uint64) ts.tv_nsec / 1000;
  #endif
#endif

    tlocal->time_log_frac = new_microseconds % 1000000 / 100;

    if (new_seconds >= tlocal->time_seconds)
	tlocal->time_seconds = new_seconds;
    else
	logW_ (_func, "seconds backwards: ", new_seconds, " (was ", tlocal->time_seconds, ")");

    if (new_microseconds >= tlocal->time_microseconds)
	tlocal->time_microseconds = new_microseconds;
    else
	logW_ (_func, "microseconds backwards: ", new_microseconds, " (was ", tlocal->time_microseconds, ")");

    logD (time, _func, fmt_hex, tlocal->time_seconds, ", ", tlocal->time_microseconds);

    if (tlocal->saved_monotime < tlocal->time_seconds
        || tlocal->saved_unixtime == 0)
    {
	// Updading saved unixtime once in a minute.
	if (tlocal->time_seconds - tlocal->saved_monotime >= 60
            || tlocal->saved_unixtime == 0)
        {
	    // Obtaining current unixtime. This is an extra syscall.
	    tlocal->saved_unixtime = time (NULL);
	    tlocal->saved_monotime = tlocal->time_seconds;
	}

      // Updating localtime (broken-down time).

	time_t const cur_unixtime = tlocal->saved_unixtime + (tlocal->time_seconds - tlocal->saved_monotime);
	tlocal->unixtime = cur_unixtime;
	// Note that we call tzset() in libMary_posixInit() for localtime_r() to work correctly.
#ifdef LIBMARY_PLATFORM_WIN32
  #ifdef LIBMARY_WIN32_SECURE_CRT
        if (localtime_s (&tlocal->localtime, &cur_unixtime) != 0)
            logF_ (_func, "localtime_s() failed");
  #else
        libraryLock ();
        struct tm * const tmp_localtime = localtime (&cur_unixtime);
        if (tmp_localtime) {
            tlocal->localtime = *tmp_localtime;
        }
        libraryUnlock ();
        if (!tmp_localtime)
            logF_ (_func, "localtime() failed");
  #endif
#else
        // TODO FIXME This lib function is dog-slow and has huge synchronization overhead.
	localtime_r (&cur_unixtime, &tlocal->localtime);
#endif
    }

//    long const timezone_abs = timezone >= 0 ? timezone : -timezone;
    long const timezone_abs = 0;
//    tlocal->timezone_str [0] = timezone >= 0 ? '+' : '-';
    tlocal->timezone_str [0] = '+';
    tlocal->timezone_str [1] = '0' + timezone_abs / 36000;
    tlocal->timezone_str [2] = '0' + timezone_abs /  3600 % 10;
    tlocal->timezone_str [3] = '0' + timezone_abs /   600 %  6;
    tlocal->timezone_str [4] = '0' + timezone_abs /    60 % 10;

    return Result::Success;
}
/**
 * EscalateSubprocessShutdown:
 * @self: Subprocess that won't have any more messages sent to it.
 * @timeout_ms: Maximum time in milliseconds to wait for its stdout to close
 * before sending SIGKILL to the process.
 * @error: (out)(allow-none): Error return location or #NULL.
 *
 * Returns: #TRUE if stdout closed and had no more messages, or #FALSE if @error
 * is set and SIGKILL was sent.
 */
gboolean EscalateSubprocessShutdown(EscalateSubprocess *self, guint timeout_ms,
                                    GError **error) {
  GIOChannel *child_stdout = self->child_stdout;
  g_assert(child_stdout);
  GIOStatus status = G_IO_STATUS_ERROR;
  gint64 start_time = g_get_monotonic_time();
  GPollFD poll_fd = {
    g_io_channel_unix_get_fd(child_stdout), G_IO_IN | G_IO_HUP | G_IO_ERR, 0 };
  gchar leftover = '\0';
  gsize leftover_length = 0;
  gboolean result = FALSE;

  g_assert(self->child_pid);

  if (self->child_stdin)
    g_io_channel_unref(self->child_stdin);

  self->child_stdin = NULL;
  self->child_stdout = NULL;

  do {
    status = g_io_channel_set_flags(child_stdout, G_IO_FLAG_NONBLOCK, NULL);
  } while (status == G_IO_STATUS_AGAIN);
  g_assert(status == G_IO_STATUS_NORMAL);

  do {
    // Wait for stdout to be readable.
    gint poll_timeout = timeout_ms - (g_get_monotonic_time() - start_time)/1000;
    gint poll_result = 0;
    if (poll_timeout > 0)
      poll_result = g_poll(&poll_fd, 1, poll_timeout);
    if (poll_result == 0) {
      g_set_error(error, ESCALATE_SUBPROCESS_ERROR,
                  ESCALATE_SUBPROCESS_ERROR_SHUTDOWN_TIMEOUT,
                  "Timed out waiting for subprocess to exit");
      goto done;
    }

    // Try to read one more character so we know if there are any messages
    // waiting to be read.
    status = g_io_channel_read_chars(child_stdout, &leftover, 1,
                                     &leftover_length, error);
  } while (status == G_IO_STATUS_AGAIN);

  switch (status) {
    case G_IO_STATUS_NORMAL:
      g_assert(leftover_length == 1);
      g_set_error(error, ESCALATE_SUBPROCESS_ERROR,
                  ESCALATE_SUBPROCESS_ERROR_LEFTOVER_STDOUT,
                  "Subprocess stdout had unread messages");
      break;
    case G_IO_STATUS_EOF:
      result = TRUE;
      break;
    default:
      g_assert(!error || *error);
  }

done:
  if (!result && self->child_pid > 0) {
    g_assert(kill(self->child_pid, SIGKILL) == 0);
    self->child_pid = 0;
  }
  g_io_channel_unref(child_stdout);
  return result;
}
示例#19
0
文件: api.c 项目: abraxa/libsigrok
static int dev_open(struct sr_dev_inst *sdi)
{
	struct sr_dev_driver *di = sdi->driver;
	struct sr_usb_dev_inst *usb;
	struct dev_context *devc;
	int ret;
	int64_t timediff_us, timediff_ms;

	devc = sdi->priv;
	usb = sdi->conn;

	/*
	 * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS
	 * milliseconds for the FX2 to renumerate.
	 */
	ret = SR_ERR;
	if (devc->fw_updated > 0) {
		sr_info("Waiting for device to reset.");
		/* Takes >= 300ms for the FX2 to be gone from the USB bus. */
		g_usleep(300 * 1000);
		timediff_ms = 0;
		while (timediff_ms < MAX_RENUM_DELAY_MS) {
			if ((ret = fx2lafw_dev_open(sdi, di)) == SR_OK)
				break;
			g_usleep(100 * 1000);

			timediff_us = g_get_monotonic_time() - devc->fw_updated;
			timediff_ms = timediff_us / 1000;
			sr_spew("Waited %" PRIi64 "ms.", timediff_ms);
		}
		if (ret != SR_OK) {
			sr_err("Device failed to renumerate.");
			return SR_ERR;
		}
		sr_info("Device came back after %" PRIi64 "ms.", timediff_ms);
	} else {
		sr_info("Firmware upload was not needed.");
		ret = fx2lafw_dev_open(sdi, di);
	}

	if (ret != SR_OK) {
		sr_err("Unable to open device.");
		return SR_ERR;
	}

	ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
	if (ret != 0) {
		switch (ret) {
		case LIBUSB_ERROR_BUSY:
			sr_err("Unable to claim USB interface. Another "
			       "program or driver has already claimed it.");
			break;
		case LIBUSB_ERROR_NO_DEVICE:
			sr_err("Device has been disconnected.");
			break;
		default:
			sr_err("Unable to claim interface: %s.",
			       libusb_error_name(ret));
			break;
		}

		return SR_ERR;
	}

	if (devc->cur_samplerate == 0) {
		/* Samplerate hasn't been set; default to the slowest one. */
		devc->cur_samplerate = devc->samplerates[0];
	}

	return SR_OK;
}
/*
 * 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;
}
示例#21
0
static void
caja_icon_info_init (CajaIconInfo *icon)
{
    icon->last_use_time = g_get_monotonic_time () * 1000;
    icon->sole_owner = TRUE;
}
示例#22
0
void
gimp_fonts_load (Gimp               *gimp,
                 GimpInitStatusFunc  status_callback)
{
  FcConfig *config;
  GFile    *fonts_conf;
  GList    *path;

  g_return_if_fail (GIMP_IS_FONT_LIST (gimp->fonts));

  gimp_set_busy (gimp);

  if (gimp->be_verbose)
    g_print ("Loading fonts\n");

  gimp_container_freeze (GIMP_CONTAINER (gimp->fonts));

  gimp_container_clear (GIMP_CONTAINER (gimp->fonts));

  config = FcInitLoadConfig ();

  if (! config)
    goto cleanup;

  fonts_conf = gimp_directory_file (CONF_FNAME, NULL);
  if (! gimp_fonts_load_fonts_conf (config, fonts_conf))
    goto cleanup;

  fonts_conf = gimp_sysconf_directory_file (CONF_FNAME, NULL);
  if (! gimp_fonts_load_fonts_conf (config, fonts_conf))
    goto cleanup;

  path = gimp_config_path_expand_to_files (gimp->config->font_path, FALSE);
  gimp_fonts_add_directories (config, path);
  g_list_free_full (path, (GDestroyNotify) g_object_unref);

  if (status_callback)
    {
      gint64                 end_time;
      GThread               *cache_thread;
      GimpFontsLoadFuncData  data;

      /* We perform font cache initialization in a separate thread, so
       * in the case a cache rebuild is to be done it will not block
       * the UI.
       */
      data.config = config;
      g_mutex_init (&data.mutex);
      g_cond_init (&data.cond);
      data.caching_complete = FALSE;

      cache_thread = g_thread_new ("font-cacher",
                                   (GThreadFunc) gimp_fonts_load_thread,
                                   &data);

      g_mutex_lock (&data.mutex);

      end_time = g_get_monotonic_time () + 0.1 * G_TIME_SPAN_SECOND;
      while (! data.caching_complete)
        if (! g_cond_wait_until (&data.cond, &data.mutex, end_time))
          {
            status_callback (NULL, NULL, 0.6);

            end_time += 0.1 * G_TIME_SPAN_SECOND;
            continue;
          }

      g_mutex_unlock (&data.mutex);
      g_thread_join (cache_thread);

      g_mutex_clear (&data.mutex);
      g_cond_clear (&data.cond);
    }
  else
    {
      gimp_fonts_load_func (config);
    }

  gimp_font_list_restore (GIMP_FONT_LIST (gimp->fonts));

 cleanup:
  gimp_container_thaw (GIMP_CONTAINER (gimp->fonts));
  gimp_unset_busy (gimp);
}
示例#23
0
/*
 * Called by libusb (as triggered by handle_event()) when a transfer comes in.
 * Only channel data comes in asynchronously, and all transfers for this are
 * queued up beforehand, so this just needs to chuck the incoming data onto
 * the libsigrok session bus.
 */
static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;

	sdi = transfer->user_data;
	devc = sdi->priv;

	if (devc->dev_state == FLUSH) {
		g_free(transfer->buffer);
		libusb_free_transfer(transfer);
		devc->dev_state = CAPTURE;
		devc->aq_started = g_get_monotonic_time();
		read_channel(sdi, data_amount(sdi));
		return;
	}

	if (devc->dev_state != CAPTURE)
		return;

	if (!devc->sample_buf) {
		devc->sample_buf_size = 10;
		devc->sample_buf = g_try_malloc(devc->sample_buf_size * sizeof(transfer));
		devc->sample_buf_write = 0;
	}

	if (devc->sample_buf_write >= devc->sample_buf_size) {
		devc->sample_buf_size += 10;
		devc->sample_buf = g_try_realloc(devc->sample_buf,
				devc->sample_buf_size * sizeof(transfer));
		if (!devc->sample_buf) {
			sr_err("Sample buffer malloc failed.");
			devc->dev_state = STOPPING;
			return;
		}
	}

	devc->sample_buf[devc->sample_buf_write++] = transfer;
	devc->samp_received += transfer->actual_length / NUM_CHANNELS;

	sr_spew("receive_transfer(): calculated samplerate == %" PRIu64 "ks/s",
		(uint64_t)(transfer->actual_length * 1000 /
		(g_get_monotonic_time() - devc->read_start_ts + 1) /
		NUM_CHANNELS));

	sr_spew("receive_transfer(): status %s received %d bytes.",
		libusb_error_name(transfer->status), transfer->actual_length);

	if (transfer->actual_length == 0)
		/* Nothing to send to the bus. */
		return;

	if (devc->limit_samples && devc->samp_received >= devc->limit_samples) {
		sr_info("Requested number of samples reached, stopping. %"
			PRIu64 " <= %" PRIu64, devc->limit_samples,
			devc->samp_received);
		send_data(sdi, devc->sample_buf, devc->limit_samples);
		sdi->driver->dev_acquisition_stop(sdi);
	} else if (devc->limit_msec && (g_get_monotonic_time() -
			devc->aq_started) / 1000 >= devc->limit_msec) {
		sr_info("Requested time limit reached, stopping. %d <= %d",
			(uint32_t)devc->limit_msec,
			(uint32_t)(g_get_monotonic_time() - devc->aq_started) / 1000);
		send_data(sdi, devc->sample_buf, devc->samp_received);
		g_free(devc->sample_buf);
		devc->sample_buf = NULL;
		sdi->driver->dev_acquisition_stop(sdi);
	} else {
		read_channel(sdi, data_amount(sdi));
	}
}
示例#24
0
文件: gpoll.c 项目: cosimoc/glib
static void
test_gpoll (void)
{
  SOCKET sockets[NUM_POLLEES];
  GPollFD fds[NUM_POLLFDS];
  SOCKET opp_sockets[NUM_POLLEES];
  gint i;
  gint activatable;
  gint64 times[REPEAT][2];
#define BUCKET_COUNT 25
  gint64 bucket_limits[BUCKET_COUNT] = {3, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 120, 150, 180, 220, 280, 350, 450, 600, 800, 1000};
  gint   buckets[BUCKET_COUNT];
  gint64 times_avg = 0, times_min = G_MAXINT64, times_max = 0;

  prepare_sockets (sockets, opp_sockets, fds, NUM_POLLEES);
  prepare_fds (sockets, fds, NUM_POLLEES);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  for (i = 0; i < REPEAT; i++)
    {
      gint r;
      gint64 diff;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 0);
      times[i][1] = g_get_monotonic_time ();
      g_assert (r == 0);
      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  activatable = 0;

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;
      MSG msg;
      gboolean found_app;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = send (opp_sockets[activatable], (const char *) &t, 1, 0);
      g_assert (PostMessage (NULL, WM_APP, 1, 2));
      /* This is to ensure that all sockets catch up, otherwise some might not poll active */
      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();

      check_fds (sockets, fds, NUM_POLLEES);
      v = recv (sockets[activatable], (char *) &t, 1, 0);
      found_app = FALSE;
      while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
          found_app = TRUE;
      g_assert (s == 1);
      g_assert (r == 2);
      g_assert (v == 1);
      g_assert (found_app);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);
      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      activatable = (activatable + 1) % NUM_POLLEES;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  activatable = 0;

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = send (opp_sockets[activatable], (const char *) &t, 1, 0);

      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();

      check_fds (sockets, fds, NUM_POLLEES);
      v = recv (sockets[activatable], (char *) &t, 1, 0);
      g_assert (s == 1);
      g_assert (r == 1);
      g_assert (v == 1);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);

      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      activatable = (activatable + 1) % NUM_POLLEES;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;
      gint j;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = v = 0;

      for (j = 0; j < NUM_POLLEES / 2; j++)
        s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;

      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();
      check_fds (sockets, fds, NUM_POLLEES);
      for (j = 0; j < NUM_POLLEES / 2; j++)
        v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
      g_assert (s == NUM_POLLEES / 2);
      g_assert (r == NUM_POLLEES / 2);
      g_assert (v == NUM_POLLEES / 2);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);

      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;
      gint j;
      MSG msg;
      gboolean found_app;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = v = 0;

      for (j = 0; j < NUM_POLLEES / 2; j++)
        s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
      g_assert (PostMessage (NULL, WM_APP, 1, 2));

      /* This is to ensure that all sockets catch up, otherwise some might not poll active */
      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();
      check_fds (sockets, fds, NUM_POLLEES);
      for (j = 0; j < NUM_POLLEES / 2; j++)
        v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
      found_app = FALSE;
      while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
          found_app = TRUE;
      g_assert (s == NUM_POLLEES / 2);
      g_assert (r == NUM_POLLEES / 2 + 1);
      g_assert (v == NUM_POLLEES / 2);
      g_assert (found_app);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);

      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;
      gint j;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = v = 0;

      for (j = 0; j < NUM_POLLEES; j++)
        s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;

      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();
      check_fds (sockets, fds, NUM_POLLEES);
      for (j = 0; j < NUM_POLLEES; j++)
        v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
      g_assert (s == NUM_POLLEES);
      g_assert (r == NUM_POLLEES);
      g_assert (v == NUM_POLLEES);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);

      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
    }

  times_avg /= NUM_POLLEES;
  g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  activatable = 0;
  times_avg = 0;
  times_min = G_MAXINT64;
  times_max = 0;
  memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);

  for (i = 0; i < REPEAT; i++)
    {
      gint r, s, v, t;
      gint64 diff;
      gint j;
      MSG msg;
      gboolean found_app;

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      s = v = 0;

      for (j = 0; j < activatable; j++)
        s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
      g_assert (PostMessage (NULL, WM_APP, 1, 2));

      g_usleep (G_USEC_PER_SEC / 1000);

      times[i][0] = g_get_monotonic_time ();
      r = g_poll (fds, NUM_POLLFDS, 1000);
      times[i][1] = g_get_monotonic_time ();
      check_fds (sockets, fds, NUM_POLLEES);
      for (j = 0; j < activatable; j++)
        v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
      found_app = FALSE;
      while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
          found_app = TRUE;
      g_assert (s == activatable);
      g_assert (r == activatable + 1);
      g_assert (v == activatable);
      g_assert (found_app);

      reset_fds (fds, NUM_POLLEES);
      reset_fds_msg (fds, NUM_POLLFDS);
      r = g_poll (fds, NUM_POLLFDS, 0);
      check_fds (sockets, fds, NUM_POLLEES);
      g_assert (r == 0);

      diff = times[i][1] - times[i][0];
      if (times_min > diff)
        times_min = diff;
      if (times_max < diff)
        times_max = diff;
      times_avg += diff;
      bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
      activatable = (activatable + 1) % NUM_POLLEES;
    }

  times_avg /= NUM_POLLEES;
  g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
  print_buckets (buckets, bucket_limits, BUCKET_COUNT);

  cleanup_sockets (sockets, opp_sockets, NUM_POLLEES);
}
示例#25
0
SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;
	gboolean terminating;
	gdouble elapsed_s;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/*
				 * TODO: According to specs, should be \r, but
				 * then we'd have to get rid of the \n.
				 */
				devc->last_req_pending = FALSE;
				nma_process_line(sdi);
				break;
			}
		}
	}

	/* If number of samples or time limit reached, stop acquisition. */
	terminating = FALSE;
	if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) {
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		terminating = TRUE;
	}

	if (devc->limit_msec) {
		elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
		if ((elapsed_s * 1000) >= devc->limit_msec) {
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			terminating = TRUE;
		}
	}

	/* Request next package. */
	if (!terminating) {
		if (devc->last_req_pending) {
			gint64 elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
			if (elapsed_us > NMADMM_TIMEOUT_MS * 1000) {/* Timeout! */
				sr_spew("Request timeout!");
				devc->last_req_pending = FALSE;
			}
		}
		if (!devc->last_req_pending) {
			if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK)
				return FALSE;
		}
	}

	return TRUE;
}
示例#26
0
SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data)
{
	uint32_t cur_time, elapsed_time;
	uint64_t nrexpiration;
	struct sr_datafeed_packet packet, framep;
	struct sr_datafeed_analog_old analog;
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	struct channel_priv *chp;
	struct dev_context *devc;
	GSList *chl, chonly;
	unsigned i;

	(void)fd;
	(void)revents;

	sdi = cb_data;
	if (!sdi)
		return TRUE;

	devc = sdi->priv;
	if (!devc)
		return TRUE;

	packet.type = SR_DF_ANALOG_OLD;
	packet.payload = &analog;
	memset(&analog, 0, sizeof(struct sr_datafeed_analog_old));

	if (read(devc->timer_fd, &nrexpiration, sizeof(nrexpiration)) < 0) {
		sr_warn("Failed to read timer information");
		return TRUE;
	}

	/*
	 * We were not able to process the previous timer expiration, we are
	 * overloaded.
	 */
	if (nrexpiration > 1)
		devc->samples_missed += nrexpiration - 1;

	/*
	 * XXX This is a nasty workaround...
	 *
	 * At high sampling rates and maximum channels we are not able to
	 * acquire samples fast enough, even though frontends still think
	 * that samples arrive on time. This causes shifts in frontend
	 * plots.
	 *
	 * To compensate for the delay we check if any clock events were
	 * missed and - if so - don't really read the next value, but send
	 * the same sample as fast as possible. We do it until we are back
	 * on schedule.
	 *
	 * At high sampling rate this doesn't seem to visibly reduce the
	 * accuracy.
	 */
	for (i = 0; i < nrexpiration; i++) {
		framep.type = SR_DF_FRAME_BEGIN;
		sr_session_send(cb_data, &framep);

		/*
		 * Due to different units used in each channel we're sending
		 * samples one-by-one.
		 */
		for (chl = sdi->channels; chl; chl = chl->next) {
			ch = chl->data;
			chp = ch->priv;

			if (!ch->enabled)
				continue;
			chonly.next = NULL;
			chonly.data = ch;
			analog.channels = &chonly;
			analog.num_samples = 1;
			analog.mq = channel_to_mq(chl->data);
			analog.unit = channel_to_unit(ch);

			if (i < 1)
				chp->val = read_sample(ch);

			analog.data = &chp->val;
			sr_session_send(cb_data, &packet);
		}

		framep.type = SR_DF_FRAME_END;
		sr_session_send(cb_data, &framep);
	}

	devc->samples_read++;
	if (devc->limit_samples > 0 &&
	    devc->samples_read >= devc->limit_samples) {
		sr_info("Requested number of samples reached.");
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		devc->last_sample_fin = g_get_monotonic_time();
		return TRUE;
	} else if (devc->limit_msec > 0) {
		cur_time = g_get_monotonic_time();
		elapsed_time = cur_time - devc->start_time;

		if (elapsed_time >= devc->limit_msec) {
			sr_info("Sampling time limit reached.");
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			devc->last_sample_fin = g_get_monotonic_time();
			return TRUE;
		}
	}

	devc->last_sample_fin = g_get_monotonic_time();
	return TRUE;
}
示例#27
0
文件: api.c 项目: tschutter/libsigrok
static GSList *hw_scan(GSList *options)
{
	struct sr_dev_inst *sdi;
	const struct dso_profile *prof;
	struct drv_context *drvc;
	struct dev_context *devc;
	GSList *devices;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	int devcnt, ret, i, j;

	(void)options;

	drvc = di->priv;
	drvc->instances = NULL;

	devcnt = 0;
	devices = 0;

	clear_instances();

	/* Find all Hantek DSO devices and upload firmware to all of them. */
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
			sr_err("Failed to get device descriptor: %s.",
			       libusb_error_name(ret));
			continue;
		}

		prof = NULL;
		for (j = 0; dev_profiles[j].orig_vid; j++) {
			if (des.idVendor == dev_profiles[j].orig_vid
				&& des.idProduct == dev_profiles[j].orig_pid) {
				/* Device matches the pre-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = dso_dev_new(devcnt, prof);
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION,
						prof->firmware) == SR_OK)
					/* Remember when the firmware on this device was updated */
					devc->fw_updated = g_get_monotonic_time();
				else
					sr_err("Firmware upload failed for "
					       "device %d.", devcnt);
				/* Dummy USB address of 0xff will get overwritten later. */
				devc->usb = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]), 0xff, NULL);
				devcnt++;
				break;
			} else if (des.idVendor == dev_profiles[j].fw_vid
				&& des.idProduct == dev_profiles[j].fw_pid) {
				/* Device matches the post-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = dso_dev_new(devcnt, prof);
				sdi->status = SR_ST_INACTIVE;
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				devc->usb = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]),
						libusb_get_device_address(devlist[i]), NULL);
				devcnt++;
				break;
			}
		}
		if (!prof)
			/* not a supported VID/PID */
			continue;
	}
	libusb_free_device_list(devlist, 1);

	return devices;
}
示例#28
0
文件: demo.c 项目: AkosLukacs/DSLogic
/* Callback handling data */
static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
{
    struct dev_context *devc = sdi->priv;
    struct sr_datafeed_packet packet;
    struct sr_datafeed_logic logic;
    struct sr_datafeed_dso dso;
    struct sr_datafeed_analog analog;
    //uint16_t buf[BUFSIZE];
    uint16_t *buf;
	static uint64_t samples_to_send, expected_samplenum, sending_now;
	int64_t time, elapsed;
    static uint16_t last_sample = 0;
    uint16_t cur_sample;
    int i;

	(void)fd;
	(void)revents;

    if (!(buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) {
        sr_err("buf for receive_data malloc failed.");
        return FALSE;
    }

	/* How many "virtual" samples should we have collected by now? */
	time = g_get_monotonic_time();
	elapsed = time - devc->starttime;
    devc->starttime = time;
	expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
	/* Of those, how many do we still have to send? */
    //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN;
    samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN;

    if (devc->limit_samples) {
        if (sdi->mode == LOGIC)
            samples_to_send = MIN(samples_to_send,
                     devc->limit_samples - devc->samples_counter);
        else
            samples_to_send = MIN(samples_to_send,
                     devc->limit_samples);
    }

    while (samples_to_send > 0) {
        sending_now = MIN(samples_to_send, BUFSIZE);
		samples_generator(buf, sending_now, devc);

        if (devc->trigger_stage != 0) {
            for (i = 0; i < sending_now; i++) {
                if (devc->trigger_edge == 0) {
                    if ((*(buf + i) | devc->trigger_mask) ==
                            (devc->trigger_value | devc->trigger_mask)) {
                        devc->trigger_stage = 0;
                        break;
                    }
                } else {
                    cur_sample = *(buf + i);
                    if (((last_sample & devc->trigger_edge) ==
                         (~devc->trigger_value & devc->trigger_edge)) &&
                        ((cur_sample | devc->trigger_mask) ==
                         (devc->trigger_value | devc->trigger_mask)) &&
                        ((cur_sample & devc->trigger_edge) ==
                         (devc->trigger_value & devc->trigger_edge))) {
                        devc->trigger_stage = 0;
                        break;
                    }
                    last_sample = cur_sample;
                }
            }
            if (devc->trigger_stage == 0) {
                struct ds_trigger_pos demo_trigger_pos;
                demo_trigger_pos.real_pos = i;
                packet.type = SR_DF_TRIGGER;
                packet.payload = &demo_trigger_pos;
                sr_session_send(sdi, &packet);
            }
        }

        if (devc->trigger_stage == 0){
            samples_to_send -= sending_now;
            if (sdi->mode == LOGIC) {
                packet.type = SR_DF_LOGIC;
                packet.payload = &logic;
                logic.length = sending_now * (NUM_PROBES >> 3);
                logic.unitsize = (NUM_PROBES >> 3);
                logic.data = buf;
            } else if (sdi->mode == DSO) {
static void
current_call_view_init(CurrentCallView *view)
{
    gtk_widget_init_template(GTK_WIDGET(view));

    CurrentCallViewPrivate *priv = CURRENT_CALL_VIEW_GET_PRIVATE(view);

    /* create video widget and overlay the call info and controls on it */
    priv->video_widget = video_widget_new();
    gtk_container_add(GTK_CONTAINER(priv->frame_video), priv->video_widget);
    gtk_widget_show_all(priv->frame_video);

    auto stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(priv->video_widget));
    auto actor_info = gtk_clutter_actor_new_with_contents(priv->hbox_call_info);
    auto actor_controls = gtk_clutter_actor_new_with_contents(priv->hbox_call_controls);

    clutter_actor_add_child(stage, actor_info);
    clutter_actor_set_x_align(actor_info, CLUTTER_ACTOR_ALIGN_FILL);
    clutter_actor_set_y_align(actor_info, CLUTTER_ACTOR_ALIGN_START);

    clutter_actor_add_child(stage, actor_controls);
    clutter_actor_set_x_align(actor_controls, CLUTTER_ACTOR_ALIGN_CENTER);
    clutter_actor_set_y_align(actor_controls, CLUTTER_ACTOR_ALIGN_END);

    /* add fade in and out states to the info and controls */
    priv->time_last_mouse_motion = g_get_monotonic_time();
    priv->fade_info = create_fade_out_transition();
    priv->fade_controls = create_fade_out_transition();
    clutter_actor_add_transition(actor_info, "fade_info", priv->fade_info);
    clutter_actor_add_transition(actor_controls, "fade_controls", priv->fade_controls);
    clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_info), CLUTTER_TIMELINE_BACKWARD);
    clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_controls), CLUTTER_TIMELINE_BACKWARD);
    clutter_timeline_stop(CLUTTER_TIMELINE(priv->fade_info));
    clutter_timeline_stop(CLUTTER_TIMELINE(priv->fade_controls));

    /* have a timer check every 1 second if the controls should fade out */
    priv->timer_fade = g_timeout_add(1000, (GSourceFunc)timeout_check_last_motion_event, view);

    /* connect to the mouse motion event to reset the last moved time */
    g_signal_connect_swapped(priv->video_widget, "motion-notify-event", G_CALLBACK(mouse_moved), view);
    g_signal_connect_swapped(priv->video_widget, "button-press-event", G_CALLBACK(mouse_moved), view);
    g_signal_connect_swapped(priv->video_widget, "button-release-event", G_CALLBACK(mouse_moved), view);

    /* manually handle the focus of the video widget to be able to focus on the call controls */
    g_signal_connect(priv->video_widget, "focus", G_CALLBACK(video_widget_focus), view);

    /* toggle whether or not the chat is displayed */
    g_signal_connect(priv->togglebutton_chat, "toggled", G_CALLBACK(chat_toggled), view);

    /* bind the chat orientation to the gsetting */
    priv->settings = g_settings_new_full(get_ring_schema(), NULL, NULL);
    g_settings_bind_with_mapping(priv->settings, "chat-pane-horizontal",
                                 priv->paned_call, "orientation",
                                 G_SETTINGS_BIND_GET,
                                 map_boolean_to_orientation,
                                 nullptr, nullptr, nullptr);

    g_signal_connect(priv->scalebutton_quality, "value-changed", G_CALLBACK(quality_changed), view);
    /* customize the quality button scale */
    if (auto scale_box = gtk_scale_button_get_box(GTK_SCALE_BUTTON(priv->scalebutton_quality))) {
        priv->checkbutton_autoquality = gtk_check_button_new_with_label(C_("Enable automatic video quality", "Auto"));
        gtk_widget_show(priv->checkbutton_autoquality);
        gtk_box_pack_start(GTK_BOX(scale_box), priv->checkbutton_autoquality, FALSE, TRUE, 0);
        g_signal_connect(priv->checkbutton_autoquality, "toggled", G_CALLBACK(autoquality_toggled), view);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->checkbutton_autoquality), TRUE);
    }
    if (auto scale = gtk_scale_button_get_scale(GTK_SCALE_BUTTON(priv->scalebutton_quality))) {
        g_signal_connect(scale, "button-press-event", G_CALLBACK(quality_button_pressed), view);
        g_signal_connect(scale, "button-release-event", G_CALLBACK(quality_button_released), view);
    }
}
示例#30
0
void gw_debug(int msgno, const ustring & message, const char *file, int lineno, const char *func)
{
  gint64 milliseconds = (g_get_monotonic_time() / 1000);
  gw_message("DEBUG:"+std::to_string(msgno)+":"+std::to_string(milliseconds)+"ms: " + message + " " + func + ":" + file + ":" + std::to_string(lineno));
  //fsync(1); // flush data to disk
}