Esempio n. 1
0
void
g_ptr_array_remove_range (GPtrArray* farray,
                          guint      index_,
                          guint      length)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;

  g_return_if_fail (array);
  g_return_if_fail (index_ < array->len);
  g_return_if_fail (index_ + length <= array->len);

  if (index_ + length != array->len)
    g_memmove (&array->pdata[index_],
               &array->pdata[index_ + length], 
               (array->len - (index_ + length)) * sizeof (gpointer));

  array->len -= length;
  if (G_UNLIKELY (g_mem_gc_friendly))
    {
      guint i;
      for (i = 0; i < length; i++)
        array->pdata[array->len + i] = NULL;
    }
}
Esempio n. 2
0
/**
 * g_array_remove_index:
 * @array: a #GArray.
 * @index_: the index of the element to remove.
 * @Returns: the #GArray.
 *
 * Removes the element at the given index from a #GArray. The following
 * elements are moved down one place.
 **/
GArray*
g_array_remove_index (GArray *farray,
		      guint   index_)
{
  GRealArray* array = (GRealArray*) farray;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index_ < array->len, NULL);

  if (index_ != array->len - 1)
    g_memmove (g_array_elt_pos (array, index_),
	       g_array_elt_pos (array, index_ + 1),
	       g_array_elt_len (array, array->len - index_ - 1));
  
  array->len -= 1;

  if (G_UNLIKELY (g_mem_gc_friendly))
    g_array_elt_zero (array, array->len, 1);
  else
    g_array_zero_terminate (array);

  return farray;
}
Esempio n. 3
0
/**
 * g_array_insert_val:
 * @a: a #GArray.
 * @i: the index to place the element at.
 * @v: the value to insert into the array.
 * @Returns: the #GArray.
 *
 * Inserts an element into an array at the given index.
 *
 * <note><para>g_array_insert_val() is a macro which uses a reference
 * to the value parameter @v. This means that you cannot use it with
 * literal values such as "27". You must use variables.</para></note>
 **/
GArray*
g_array_insert_vals (GArray        *farray,
		     guint          index_,
		     gconstpointer  data,
		     guint          len)
{
  GRealArray *array = (GRealArray*) farray;

  g_return_val_if_fail (array, NULL);

  g_array_maybe_expand (array, len);

  g_memmove (g_array_elt_pos (array, len + index_), 
	     g_array_elt_pos (array, index_), 
	     g_array_elt_len (array, array->len - index_));

  memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));

  array->len += len;

  g_array_zero_terminate (array);

  return farray;
}
Esempio n. 4
0
/**
 * g_array_remove_range:
 * @array: a @GArray.
 * @index_: the index of the first element to remove.
 * @length: the number of elements to remove.
 * @Returns: the #GArray.
 *
 * Removes the given number of elements starting at the given index
 * from a #GArray.  The following elements are moved to close the gap.
 *
 * Since: 2.4
 **/
GArray*
g_array_remove_range (GArray *farray,
                      guint   index_,
                      guint   length)
{
  GRealArray *array = (GRealArray*) farray;

  g_return_val_if_fail (array, NULL);
  g_return_val_if_fail (index_ < array->len, NULL);
  g_return_val_if_fail (index_ + length <= array->len, NULL);

  if (index_ + length != array->len)
    g_memmove (g_array_elt_pos (array, index_), 
               g_array_elt_pos (array, index_ + length), 
               (array->len - (index_ + length)) * array->elt_size);

  array->len -= length;
  if (G_UNLIKELY (g_mem_gc_friendly))
    g_array_elt_zero (array, array->len, length);
  else
    g_array_zero_terminate (array);

  return farray;
}
Esempio n. 5
0
gpointer
g_ptr_array_remove_index (GPtrArray* farray,
			  guint      index)
{
  GRealPtrArray* array = (GRealPtrArray*) farray;
  gpointer result;

  g_return_val_if_fail (array, NULL);

  g_return_val_if_fail (index < array->len, NULL);

  result = array->pdata[index];
  
  if (index != array->len - 1)
    g_memmove (array->pdata + index, array->pdata + index + 1, 
	       sizeof (gpointer) * (array->len - index - 1));
  
  array->len -= 1;

  if (G_UNLIKELY (g_mem_gc_friendly))
    array->pdata[array->len] = NULL;

  return result;
}
Esempio n. 6
0
static GdaRow *
new_row_from_mysql_stmt (GdaMysqlRecordset *imodel, G_GNUC_UNUSED gint rownum, GError **error)
{
	//g_print ("%s(): NCOLS=%d  ROWNUM=%d\n", __func__, ((GdaDataSelect *) imodel)->prep_stmt->ncols, rownum);
	int res;
	MYSQL_BIND *mysql_bind_result;
	g_return_val_if_fail (imodel->priv->mysql_stmt != NULL, NULL);

	mysql_bind_result = ((GdaMysqlPStmt *) ((GdaDataSelect *) imodel)->prep_stmt)->mysql_bind_result;
	g_assert (mysql_bind_result);

	res = mysql_stmt_fetch (imodel->priv->mysql_stmt);
	if (res == MYSQL_NO_DATA) {
		/* should not happen */
		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
			     "%s", "No more data, please report this bug to "
			     "http://bugzilla.gnome.org/ for the \"libgda\" product and the MySQL provider.");
	}
	else if (res == MYSQL_DATA_TRUNCATED) {
		GString *string;

		string = g_string_new ("Truncated data, please report this bug to "
				       "http://bugzilla.gnome.org/ for the \"libgda\" product and the MySQL provider.");

		gint col;
		for (col = 0; col < ((GdaDataSelect *) imodel)->prep_stmt->ncols; ++col) {
			my_bool truncated;
			mysql_bind_result[col].error = &truncated;
			mysql_stmt_fetch_column (imodel->priv->mysql_stmt, &(mysql_bind_result[col]),
						 (unsigned int)col, 0);
			if (truncated)
				g_string_append_printf (string, "\n  column %d is truncated\n", col);
			mysql_bind_result[col].error = NULL;
		}
		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", string->str);
		g_string_free (string, TRUE);

		return NULL;
	}
	else if (res) {
		_gda_mysql_make_error (imodel->priv->cnc, NULL, imodel->priv->mysql_stmt, error);
		return NULL;
	}

	/* g_print ("%s: SQL=%s\n", __func__, ((GdaDataSelect *) imodel)->prep_stmt->sql); */

	
	GdaRow *row = gda_row_new (((GdaDataSelect *) imodel)->prep_stmt->ncols);
	gint col;
	for (col = 0; col < ((GdaDataSelect *) imodel)->prep_stmt->ncols; ++col) {
		gint i = col;
		
		GValue *value = gda_row_get_value (row, i);
		GType type = ((GdaDataSelect *) imodel)->prep_stmt->types[i];
		
		/*g_print ("%s: #%d : TYPE=%d, GTYPE=%s\n", __func__, i, mysql_bind_result[i].buffer_type, g_type_name (type));*/

		my_bool is_null = FALSE;
		unsigned long length;
		
		g_memmove (&is_null, mysql_bind_result[i].is_null, sizeof (my_bool));
		if (is_null) {
			gda_value_set_null (value);
			continue;
		}
		else
			gda_value_reset_with_type (value, type);

		switch (mysql_bind_result[i].buffer_type) {
		case MYSQL_TYPE_SHORT: {
			short int bvalue = 0;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));
			g_value_set_int (value, bvalue);
			break;
		}
		case MYSQL_TYPE_TINY: {
			signed char bvalue = 0;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));
			g_value_set_int (value, bvalue);
			break;
		}
		case MYSQL_TYPE_INT24:
		case MYSQL_TYPE_LONG:
		case MYSQL_TYPE_YEAR: {
			int bvalue = 0;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));
			
			if (type == G_TYPE_INT)
				g_value_set_int (value, bvalue);
			else if (type == G_TYPE_LONG)
				g_value_set_long (value, (long) bvalue);
			else if (type == G_TYPE_BOOLEAN)
				g_value_set_boolean (value, bvalue ? TRUE : FALSE);
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %d"),
					     g_type_name (type), bvalue);
			}
			break;
		}
		case MYSQL_TYPE_LONGLONG: {
			long long bvalue = 0;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));

			if (type == G_TYPE_BOOLEAN)
				g_value_set_boolean (value, bvalue ? TRUE : FALSE);
			else if (type == G_TYPE_INT)
				g_value_set_int (value, bvalue);
			else if (type == G_TYPE_LONG)
				g_value_set_long (value, bvalue);
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %lld"),
					     g_type_name (type), bvalue);
			}
			break;
		}
		case MYSQL_TYPE_NULL:
			gda_value_set_null (value);
			break;
		case MYSQL_TYPE_TIME:
		case MYSQL_TYPE_DATE:
		case MYSQL_TYPE_DATETIME:
		case MYSQL_TYPE_TIMESTAMP: {
			MYSQL_TIME bvalue = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));

			if (type == GDA_TYPE_TIME) {
				GdaTime time = {
					.hour = bvalue.hour,
					.minute = bvalue.minute,
					.second = bvalue.second,
					.fraction = bvalue.second_part,
					.timezone = 0 /* GMT */
				};
				gda_value_set_time (value, &time);
			}
			else if (type == G_TYPE_DATE) {
				GDate *date = g_date_new_dmy
					((bvalue.day != 0) ? bvalue.day : 1,
					 (bvalue.month != 0) ? bvalue.month : 1,
					 (bvalue.year != 0) ? bvalue.year : 1970);
				g_value_take_boxed (value, date);
			}
			else if (type == GDA_TYPE_TIMESTAMP) {
				GdaTimestamp timestamp = {
					.year = bvalue.year,
					.month = bvalue.month,
					.day = bvalue.day,
					.hour = bvalue.hour,
					.minute = bvalue.minute,
					.second = bvalue.second,
					.fraction = bvalue.second_part,
					.timezone = 0 /* GMT */
				};
				gda_value_set_timestamp (value, &timestamp);
			}
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %d/%d/%d %d:%d:%d.%lu"),
					     g_type_name (type), bvalue.year, bvalue.month,
					     bvalue.day, bvalue.hour, bvalue.minute,
					     bvalue.second, bvalue.second_part);
			}
			break;
		}
		case MYSQL_TYPE_FLOAT: {
			float bvalue = 0.;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));
			
			if (type == G_TYPE_FLOAT)
				g_value_set_float (value, (float) bvalue);
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %f"),
					     g_type_name (type), bvalue);
			}			
			break;
		}
		case MYSQL_TYPE_DOUBLE: {
			double bvalue = 0.0;
			g_memmove (&bvalue, mysql_bind_result[i].buffer, sizeof (bvalue));
			
			if (type == G_TYPE_DOUBLE)
				g_value_set_double (value, bvalue);
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %f"),
					     g_type_name (type), bvalue);
			}
			break;
		}
		case MYSQL_TYPE_STRING:
		case MYSQL_TYPE_VAR_STRING:
		case MYSQL_TYPE_BLOB:
		case MYSQL_TYPE_TINY_BLOB:
		case MYSQL_TYPE_MEDIUM_BLOB:
		case MYSQL_TYPE_LONG_BLOB:
		case MYSQL_TYPE_NEWDECIMAL:
		case MYSQL_TYPE_DECIMAL:
		case MYSQL_TYPE_BIT: {
			char *bvalue = NULL;
			g_memmove (&length, mysql_bind_result[i].length, sizeof (unsigned long));
			if (length > 0) {
				bvalue = g_malloc (length + 1);
				memcpy (bvalue, mysql_bind_result[i].buffer, length);
				bvalue [length] = 0;
			}
			
			if (type == G_TYPE_STRING)
				g_value_set_string (value, bvalue);
			else if (type == GDA_TYPE_BINARY) {
				GdaBinary binary = {
					.data = (guchar*) bvalue,
					.binary_length = length
				};
				gda_value_set_binary (value, &binary);
			}
			else if (type == GDA_TYPE_BLOB) {
				/* we don't use GdaMysqlBlobOp because it looks like the MySQL
				 * API does not support BLOBs accessed in a random way,
				 * so we return the whole BLOB at once */
				GdaBlob blob = { {(guchar*) bvalue, length}, NULL };
				gda_value_set_blob (value, &blob);
			}
			else if (type == GDA_TYPE_NUMERIC) {
				if (length > 0) {
					GdaNumeric *numeric;
					numeric = gda_numeric_new ();
					gda_numeric_set_from_string (numeric, bvalue);
					gda_numeric_set_precision (numeric, 6);
					gda_numeric_set_width (numeric, length);
					gda_value_set_numeric (value, numeric);
					gda_numeric_free (numeric);
				}
			}
			else if (type == G_TYPE_DOUBLE) {
				if (length > 0)
					g_value_set_double (value, g_ascii_strtod (bvalue, NULL));
				else {
					/* error: wrong column type */
					gda_row_invalidate_value (row, value);
					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
						     GDA_SERVER_PROVIDER_DATA_ERROR,
						     _("Invalid column bind data type. %d\n"),
						     mysql_bind_result[i].buffer_type);
					break;
				}
			}
			else if (type == G_TYPE_INT) {
				if (length > 0)
					g_value_set_int (value, atoi (bvalue));
				else {
					/* error: wrong column type */
					gda_row_invalidate_value (row, value);
					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
						     GDA_SERVER_PROVIDER_DATA_ERROR,
						     _("Invalid column bind data type. %d\n"),
						     mysql_bind_result[i].buffer_type);
					break;
				}
			}
			else if (type == G_TYPE_BOOLEAN) {
				if (length > 0)
					g_value_set_boolean (value, atoi (bvalue));
				else {
					/* error: wrong column type */
					gda_row_invalidate_value (row, value);
					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
						     GDA_SERVER_PROVIDER_DATA_ERROR,
						     _("Invalid column bind data type. %d\n"),
						     mysql_bind_result[i].buffer_type);
					break;
				}
			}
			else {
				gda_row_invalidate_value (row, value);
				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
					     GDA_SERVER_PROVIDER_DATA_ERROR,
					     _("Type %s not mapped for value %s"),
					     g_type_name (type), bvalue);
			}
			g_free (bvalue);
			break;
		}
Esempio n. 7
0
/**
 * soup_headers_parse:
 * @str: the header string (including the Request-Line or Status-Line,
 *   but not the trailing blank line)
 * @len: length of @str
 * @dest: #SoupMessageHeaders to store the header values in
 *
 * Parses the headers of an HTTP request or response in @str and
 * stores the results in @dest. Beware that @dest may be modified even
 * on failure.
 *
 * This is a low-level method; normally you would use
 * soup_headers_parse_request() or soup_headers_parse_response().
 *
 * Return value: success or failure
 *
 * Since: 2.26
 **/
gboolean
soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
{
	const char *headers_start;
	char *headers_copy, *name, *name_end, *value, *value_end;
	char *eol, *sol, *p;
	gsize copy_len;
	gboolean success = FALSE;

	g_return_val_if_fail (str != NULL, FALSE);
	g_return_val_if_fail (dest != NULL, FALSE);

	/* As per RFC 2616 section 19.3, we treat '\n' as the
	 * line terminator, and '\r', if it appears, merely as
	 * ignorable trailing whitespace.
	 */

	/* Skip over the Request-Line / Status-Line */
	headers_start = memchr (str, '\n', len);
	if (!headers_start)
		return FALSE;
	/* No '\0's in the Request-Line / Status-Line */
	if (memchr (str, '\0', headers_start - str))
		return FALSE;

	/* We work on a copy of the headers, which we can write '\0's
	 * into, so that we don't have to individually g_strndup and
	 * then g_free each header name and value.
	 */
	copy_len = len - (headers_start - str);
	headers_copy = g_malloc (copy_len + 1);
	memcpy (headers_copy, headers_start, copy_len);
	headers_copy[copy_len] = '\0';
	value_end = headers_copy;

	/* There shouldn't be any '\0's in the headers already, but
	 * this is the web we're talking about.
	 */
	while ((p = memchr (headers_copy, '\0', copy_len))) {
		memmove (p, p + 1, copy_len - (p - headers_copy));
		copy_len--;
	}

	while (*(value_end + 1)) {
		name = value_end + 1;
		name_end = strchr (name, ':');

		/* Reject if there is no ':', or the header name is
		 * empty, or it contains whitespace.
		 */
		if (!name_end ||
		    name_end == name ||
		    name + strcspn (name, " \t\r\n") < name_end) {
			/* Ignore this line. Note that if it has
			 * continuation lines, we'll end up ignoring
			 * them too since they'll start with spaces.
			 */
			value_end = strchr (name, '\n');
			if (!value_end)
				goto done;
			continue;
		}

		/* Find the end of the value; ie, an end-of-line that
		 * isn't followed by a continuation line.
		 */
		value = name_end + 1;
		value_end = strchr (name, '\n');
		if (!value_end)
			goto done;
		while (*(value_end + 1) == ' ' || *(value_end + 1) == '\t') {
			value_end = strchr (value_end + 1, '\n');
			if (!value_end)
				goto done;
		}

		*name_end = '\0';
		*value_end = '\0';

		/* Skip leading whitespace */
		while (value < value_end &&
		       (*value == ' ' || *value == '\t' ||
			*value == '\r' || *value == '\n'))
			value++;

		/* Collapse continuation lines */
		while ((eol = strchr (value, '\n'))) {
			/* find start of next line */
			sol = eol + 1;
			while (*sol == ' ' || *sol == '\t')
				sol++;

			/* back up over trailing whitespace on current line */
			while (eol[-1] == ' ' || eol[-1] == '\t' || eol[-1] == '\r')
				eol--;

			/* Delete all but one SP */
			*eol = ' ';
			g_memmove (eol + 1, sol, strlen (sol) + 1);
		}

		/* clip trailing whitespace */
		eol = strchr (value, '\0');
		while (eol > value &&
		       (eol[-1] == ' ' || eol[-1] == '\t' || eol[-1] == '\r'))
			eol--;
		*eol = '\0';

		/* convert (illegal) '\r's to spaces */
		for (p = strchr (value, '\r'); p; p = strchr (p, '\r'))
			*p = ' ';

		soup_message_headers_append (dest, name, value);
        }
	success = TRUE;

done:
	g_free (headers_copy);
	return success;
}
Esempio n. 8
0
/**
 * g_string_insert_unichar:
 * @string: a #GString
 * @pos: the position at which to insert character, or -1 to
 *       append at the end of the string.
 * @wc: a Unicode character
 * 
 * Converts a Unicode character into UTF-8, and insert it
 * into the string at the given position.
 * 
 * Return value: @string
 **/
GString*
g_string_insert_unichar (GString *string,
			 gssize   pos,    
			 gunichar wc)
{
  gint charlen, first, i;
  gchar *dest;

  g_return_val_if_fail (string != NULL, NULL);

  /* Code copied from g_unichar_to_utf() */
  if (wc < 0x80)
    {
      first = 0;
      charlen = 1;
    }
  else if (wc < 0x800)
    {
      first = 0xc0;
      charlen = 2;
    }
  else if (wc < 0x10000)
    {
      first = 0xe0;
      charlen = 3;
    }
   else if (wc < 0x200000)
    {
      first = 0xf0;
      charlen = 4;
    }
  else if (wc < 0x4000000)
    {
      first = 0xf8;
      charlen = 5;
    }
  else
    {
      first = 0xfc;
      charlen = 6;
    }
  /* End of copied code */

  g_string_maybe_expand (string, charlen);

  if (pos < 0)
    pos = string->len;
  else
    g_return_val_if_fail (pos <= string->len, string);

  /* If not just an append, move the old stuff */
  if (pos < string->len)
    g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos);

  dest = string->str + pos;
  /* Code copied from g_unichar_to_utf() */
  for (i = charlen - 1; i > 0; --i)
    {
      dest[i] = (wc & 0x3f) | 0x80;
      wc >>= 6;
    }
  dest[0] = wc | first;
  /* End of copied code */
  
  string->len += charlen;

  string->str[string->len] = 0;

  return string;
}
static void hev_serial_port_read_async_handler(GObject *source_object,
			GAsyncResult *res, gpointer user_data)
{
	HevSerialPort *self = HEV_SERIAL_PORT(source_object);
	HevSerialPortPrivate *priv = HEV_SERIAL_PORT_GET_PRIVATE(self);
	GSimpleAsyncResult *simple = user_data;
	HevSerialPortQueueCommandData *data = NULL;
	gssize size = 0;
	GError *error = NULL;

	g_debug("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__);

	data = g_simple_async_result_get_op_res_gpointer(simple);
	size = hev_serial_port_read_finish(self, res, &error);
	if(-1 == size)
	{
		g_simple_async_result_take_error(simple, error);
		g_simple_async_result_set_op_res_gpointer(simple, NULL, NULL);
		g_simple_async_result_complete_in_idle(simple);
		g_object_unref(simple);

		if(data->read_buffer)
		  g_free(data->read_buffer);
		g_free(data);

		return;
	}

	/* Get read size */
	size = data->read_callback(data->read_buffer, data->read_size,
				data->user_data);
	if(0 < size)
	{
		gpointer old_buffer = data->read_buffer;
		gsize new_size = data->read_size+size;

		data->read_buffer = g_malloc0(new_size);
		if(data->read_buffer)
		{
			g_memmove(data->read_buffer, old_buffer, data->read_size);

			/* Read data */
			hev_serial_port_read_async(self, data->read_buffer+data->read_size, size,
						data->cancellable, hev_serial_port_read_async_handler,simple);

			data->read_size = new_size;
		}
		else
		{
			g_simple_async_result_set_error(simple, g_quark_from_static_string("Memory"),
						0, "Memory not enough!");
			g_simple_async_result_set_op_res_gpointer(simple, NULL, NULL);
			g_simple_async_result_complete_in_idle(simple);
			g_object_unref(simple);

			g_free(data);
		}

		g_free(old_buffer);
	}
	else
	{
		GByteArray *rdata = NULL;

		rdata = g_byte_array_new();
		g_byte_array_append(rdata, data->read_buffer, data->read_size);
		g_simple_async_result_set_op_res_gpointer(simple, rdata, NULL);
		g_simple_async_result_complete(simple);
		g_object_unref(simple);

		if(data->read_buffer)
		  g_free(data->read_buffer);
		g_free(data);
	}
}
Esempio n. 10
0
// paste xournal native data
void clipboard_paste_from_xournal(GtkSelectionData *sel_data)
{
  unsigned char *p;
  int nitems, npts, i, len;
  struct Item *item;
  double hoffset, voffset, cx, cy;
  double *pf;
  int sx, sy, wx, wy;
  
  reset_selection();
  
  ui.selection = g_new(struct Selection, 1);
  p = sel_data->data + sizeof(int);
  g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
  ui.selection->type = ITEM_SELECTRECT;
  ui.selection->layer = ui.cur_layer;
  g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
  ui.selection->items = NULL;
  
  // find by how much we translate the pasted selection
  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
  gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
  gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
  cx -= ui.cur_page->hoffset;
  cy -= ui.cur_page->voffset;
  if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
    cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
  if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
    cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
  if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
    cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
  if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
    cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
  hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
  voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
  ui.selection->bbox.left += hoffset;
  ui.selection->bbox.right += hoffset;
  ui.selection->bbox.top += voffset;
  ui.selection->bbox.bottom += voffset;

  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
      gnome_canvas_rect_get_type(), "width-pixels", 1,
      "outline-color-rgba", 0x000000ff,
      "fill-color-rgba", 0x80808040,
      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
  make_dashed(ui.selection->canvas_item);

  while (nitems-- > 0) {
    item = g_new(struct Item, 1);
    ui.selection->items = g_list_append(ui.selection->items, item);
    ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
    ui.cur_layer->nitems++;
    g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
    if (item->type == ITEM_STROKE) {
      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
      item->path = gnome_canvas_points_new(npts);
      pf = (double *)p;
      for (i=0; i<npts; i++) {
        item->path->coords[2*i] = pf[2*i] + hoffset;
        item->path->coords[2*i+1] = pf[2*i+1] + voffset;
      }
      p+= 2*item->path->num_points*sizeof(double);
      if (item->brush.variable_width) {
        item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
        p+= (item->path->num_points-1)*sizeof(double);
      }
      else item->widths = NULL;
      update_item_bbox(item);
      make_canvas_item_one(ui.cur_layer->group, item);
    }
    if (item->type == ITEM_TEXT) {
      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
      g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
      item->bbox.left += hoffset;
      item->bbox.top += voffset;
      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
      item->text = g_malloc(len+1);
      g_memmove(item->text, p, len+1); p+= len+1;
      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
      item->font_name = g_malloc(len+1);
      g_memmove(item->font_name, p, len+1); p+= len+1;
      g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
      make_canvas_item_one(ui.cur_layer->group, item);
    }
    if (item->type == ITEM_IMAGE) {
      item->canvas_item = NULL;
      item->image_png = NULL;
      item->image_png_len = 0;
      g_memmove(&item->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
      item->bbox.left += hoffset;
      item->bbox.right += hoffset;
      item->bbox.top += voffset;
      item->bbox.bottom += voffset;
      g_memmove(&item->image_png_len, p, sizeof(gsize)); p+= sizeof(gsize);
      if (item->image_png_len > 0) {
        item->image_png = g_memdup(p, item->image_png_len);
        item->image = pixbuf_from_buffer(item->image_png, item->image_png_len);
        p+= item->image_png_len;
      } else {
        item->image = NULL;
      }
      make_canvas_item_one(ui.cur_layer->group, item);
    }
  }

  prepare_new_undo();
  undo->type = ITEM_PASTE;
  undo->layer = ui.cur_layer;
  undo->itemlist = g_list_copy(ui.selection->items);  
  
  gtk_selection_data_free(sel_data);
  update_copy_paste_enabled();
  update_color_menu();
  update_thickness_buttons();
  update_color_buttons();
  update_font_button();  
  update_cursor(); // FIXME: can't know if pointer is within selection!
}
Esempio n. 11
0
static gboolean
xmms_faad_init (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;
	xmms_error_t error;

	NeAACDecConfigurationPtr config;
	gint bytes_read;
	gulong samplerate;
	guchar channels;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_faad_data_t, 1);
	data->outbuf = g_string_new (NULL);
	data->buffer_size = FAAD_BUFFER_SIZE;

	xmms_xform_private_data_set (xform, data);

	data->decoder = NeAACDecOpen ();
	config = NeAACDecGetCurrentConfiguration (data->decoder);
	config->defObjectType = LC;
	config->defSampleRate = 44100;
	config->outputFormat = FAAD_FMT_16BIT;
	config->downMatrix = 0;
	config->dontUpSampleImplicitSBR = 0;
	NeAACDecSetConfiguration (data->decoder, config);

	switch (config->outputFormat) {
	case FAAD_FMT_16BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S16;
		break;
	case FAAD_FMT_24BIT:
		/* we don't have 24-bit format to use in xmms2 */
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_32BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_FLOAT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_FLOAT;
		break;
	case FAAD_FMT_DOUBLE:
		data->sampleformat = XMMS_SAMPLE_FORMAT_DOUBLE;
		break;
	}

	while (data->buffer_length < 8) {
		xmms_error_reset (&error);
		bytes_read = xmms_xform_read (xform,
		                              (gchar *) data->buffer + data->buffer_length,
		                              data->buffer_size - data->buffer_length,
		                              &error);
		data->buffer_length += bytes_read;

		if (bytes_read < 0) {
			xmms_log_error ("Error while trying to read data on init");
			goto err;
		} else if (bytes_read == 0) {
			XMMS_DBG ("Not enough bytes to check the AAC header");
			goto err;
		}
	}

	/* which type of file are we dealing with? */
	data->filetype = FAAD_TYPE_UNKNOWN;
	if (xmms_xform_auxdata_has_val (xform, "decoder_config")) {
		data->filetype = FAAD_TYPE_MP4;
	} else if (!strncmp ((char *) data->buffer, "ADIF", 4)) {
		data->filetype = FAAD_TYPE_ADIF;
	} else {
		int i;

		/* ADTS mpeg file can be a stream and start in the middle of a
		 * frame so we need to have extra loop check here */
		for (i=0; i<data->buffer_length-1; i++) {
			if (data->buffer[i] == 0xff && (data->buffer[i+1]&0xf6) == 0xf0) {
				data->filetype = FAAD_TYPE_ADTS;
				g_memmove (data->buffer, data->buffer+i, data->buffer_length-i);
				data->buffer_length -= i;
				break;
			}
		}
	}

	if (data->filetype == FAAD_TYPE_ADTS || data->filetype == FAAD_TYPE_ADIF) {
		bytes_read = NeAACDecInit (data->decoder, data->buffer,
		                          data->buffer_length, &samplerate,
		                          &channels);
	} else if (data->filetype == FAAD_TYPE_MP4) {
		const guchar *tmpbuf;
		gsize tmpbuflen;
		guchar *copy;

		if (!xmms_xform_auxdata_get_bin (xform, "decoder_config", &tmpbuf,
		                                 &tmpbuflen)) {
			XMMS_DBG ("AAC decoder config data found but it's wrong type! (something broken?)");
			goto err;
		}

		copy = g_memdup (tmpbuf, tmpbuflen);
		bytes_read = NeAACDecInit2 (data->decoder, copy, tmpbuflen,
		                           &samplerate, &channels);
		g_free (copy);
	}

	if (bytes_read < 0) {
		XMMS_DBG ("Error initializing decoder library.");
		goto err;
	}

	/* Get mediainfo and skip the possible header */
	xmms_faad_get_mediainfo (xform);
	g_memmove (data->buffer, data->buffer + bytes_read,
	           data->buffer_length - bytes_read);
	data->buffer_length -= bytes_read;

	data->samplerate = samplerate;
	data->channels = channels;

	/* Because for HE AAC files some versions of libfaad return the wrong
	 * samplerate in init, we have to do one read and let it decide the
	 * real parameters. After changing sample parameters and format is
	 * supported, this hack should be removed and handled in read instead. */
	{
		gchar tmpbuf[1024];

		xmms_error_reset (&error);
		bytes_read = xmms_faad_read (xform, tmpbuf, 1024, &error);
		if (bytes_read <= 0) {
			XMMS_DBG ("First read from faad decoder failed!");
			return FALSE;
		}
		g_string_prepend_len (data->outbuf, tmpbuf, bytes_read);
	}

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             data->sampleformat,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->samplerate,
	                             XMMS_STREAM_TYPE_END);

	XMMS_DBG ("AAC decoder inited successfully!");

	return TRUE;

err:
	g_string_free (data->outbuf, TRUE);
	g_free (data);

	return FALSE;
}
Esempio n. 12
0
static PyObject *
_wrap_g_field_info_set_value (PyGIBaseInfo *self,
                              PyObject     *args)
{
    PyObject *instance;
    PyObject *py_value;
    GIBaseInfo *container_info;
    GIInfoType container_info_type;
    gpointer pointer;
    GITypeInfo *field_type_info;
    GIArgument value;
    PyObject *retval = NULL;

    if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) {
        return NULL;
    }

    container_info = g_base_info_get_container (self->info);
    g_assert (container_info != NULL);

    /* Check the instance. */
    if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
        _PyGI_ERROR_PREFIX ("argument 1: ");
        return NULL;
    }

    /* Get the pointer to the container. */
    container_info_type = g_base_info_get_type (container_info);
    switch (container_info_type) {
        case GI_INFO_TYPE_UNION:
        case GI_INFO_TYPE_STRUCT:
            pointer = pyg_boxed_get (instance, void);
            break;
        case GI_INFO_TYPE_OBJECT:
            pointer = pygobject_get (instance);
            break;
        default:
            /* Other types don't have fields. */
            g_assert_not_reached();
    }

    field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);

    /* Check the value. */
    {
        gboolean retval;

        retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE);
        if (retval < 0) {
            goto out;
        }

        if (!retval) {
            _PyGI_ERROR_PREFIX ("argument 2: ");
            goto out;
        }
    }

    /* Set the field's value. */
    /* A few types are not handled by g_field_info_set_field, so do it here. */
    if (!g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
        GIBaseInfo *info;
        GIInfoType info_type;

        if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_WRITABLE)) {
            PyErr_SetString (PyExc_RuntimeError, "field is not writable");
            goto out;
        }

        info = g_type_info_get_interface (field_type_info);

        info_type = g_base_info_get_type (info);

        switch (info_type) {
            case GI_INFO_TYPE_UNION:
                PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet");
                goto out;
            case GI_INFO_TYPE_STRUCT:
            {
                gboolean is_simple;
                gsize offset;
                gssize size;

                is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info);

                if (!is_simple) {
                    PyErr_SetString (PyExc_TypeError,
                                     "cannot set a structure which has no well-defined ownership transfer rules");
                    g_base_info_unref (info);
                    goto out;
                }

                value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
                if (PyErr_Occurred()) {
                    g_base_info_unref (info);
                    goto out;
                }

                offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);
                size = g_struct_info_get_size ( (GIStructInfo *) info);
                g_assert (size > 0);

                g_memmove ((char*) pointer + offset, value.v_pointer, size);

                g_base_info_unref (info);

                retval = Py_None;
                goto out;
            }
            default:
                /* Fallback. */
                break;
        }

        g_base_info_unref (info);
    } else if (g_type_info_is_pointer (field_type_info)
            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID) {
        int offset;

        if (py_value != Py_None && !PYGLIB_PyLong_Check(py_value)) {
            if (PyErr_WarnEx(PyExc_RuntimeWarning,
                         "Usage of gpointers to store objects is being deprecated. "
                         "Please use integer values only, see: https://bugzilla.gnome.org/show_bug.cgi?id=683599",
                         1))
                goto out;
        }

        offset = g_field_info_get_offset ((GIFieldInfo *) self->info);
        value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);

        /* Decrement the previous python object stashed on the void pointer.
         * This seems somewhat dangerous as the code is blindly assuming any
         * void pointer field stores a python object pointer and then decrefs it.
         * This is essentially the same as something like:
         *  Py_XDECREF(struct->void_ptr); */
        Py_XDECREF(G_STRUCT_MEMBER (gpointer, pointer, offset));

        /* Assign and increment the newly assigned object. At this point the value
         * arg will hold a pointer the python object "py_value" or NULL.
         * This is essentially:
         *  struct->void_ptr = value.v_pointer;
         *  Py_XINCREF(struct->void_ptr);
         */
        G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer;
        Py_XINCREF(G_STRUCT_MEMBER (gpointer, pointer, offset));

        retval = Py_None;
        goto out;
    }

    value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING);
    if (PyErr_Occurred()) {
        goto out;
    }

    if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) {
        _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
        PyErr_SetString (PyExc_RuntimeError, "unable to set value for field");
        goto out;
    }

    retval = Py_None;

out:
    g_base_info_unref ( (GIBaseInfo *) field_type_info);

    Py_XINCREF (retval);
    return retval;
}
Esempio n. 13
0
gint
xmms_xform_this_read (xmms_xform_t *xform, gpointer buf, gint siz,
                      xmms_error_t *err)
{
	gint read = 0;
	gint nexths;

	if (xform->error) {
		xmms_error_set (err, XMMS_ERROR_GENERIC, "Read on errored xform");
		return -1;
	}

	/* update hotspots */
	nexths = xmms_xform_hotspots_update (xform);
	if (nexths >= 0) {
		siz = MIN (siz, nexths);
	}

	if (xform->buffered) {
		read = MIN (siz, xform->buffered);
		memcpy (buf, xform->buffer, read);
		xform->buffered -= read;

		/* buffer edited, update hotspot positions */
		g_queue_foreach (xform->hotspots, &xmms_xform_hotspot_callback, &read);

		if (xform->buffered) {
			/* unless we are _peek:ing often
			   this should be fine */
			memmove (xform->buffer, &xform->buffer[read], xform->buffered);
		}
	}

	if (xform->eos) {
		return read;
	}

	while (read < siz) {
		gint res;

		res = xmms_xform_plugin_read (xform->plugin, xform, buf + read, siz - read, err);
		if (xform->metadata_collected && xform->metadata_changed)
			xmms_xform_metadata_update (xform);

		if (res < -1) {
			XMMS_DBG ("Read method of %s returned bad value (%d) - BUG IN PLUGIN", xmms_xform_shortname (xform), res);
			res = -1;
		}

		if (res == 0) {
			xform->eos = TRUE;
			break;
		} else if (res == -1) {
			xform->error = TRUE;
			return -1;
		} else {
			if (read == 0)
				xmms_xform_hotspots_update (xform);

			if (!g_queue_is_empty (xform->hotspots)) {
				if (xform->buffered + res > xform->buffersize) {
					xform->buffersize = MAX (xform->buffersize * 2,
					                         xform->buffersize + res);
					xform->buffer = g_realloc (xform->buffer,
					                           xform->buffersize);
				}

				g_memmove (xform->buffer + xform->buffered, buf + read, res);
				xform->buffered += res;
				break;
			}
			read += res;
		}
	}

	return read;
}
Esempio n. 14
0
/* DCC SERVER: text received */
static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg)
{
	g_return_if_fail(IS_DCC_SERVER(dcc));
	g_return_if_fail(msg != NULL);

	/* Check for CHAT protocol */
	if (g_strncasecmp(msg, "100 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting chat requests.*/
		if (dcc->accept_chat) {
			/* Connect and start DCC Chat */
			char *str;
			CHAT_DCC_REC *dccchat = dcc_chat_create(dcc->server, NULL, msg, "chat");

			dccchat->starttime = time(NULL);
			dccchat->handle = dcc->handle;
			dccchat->sendbuf = net_sendbuffer_create(dccchat->handle, 0);
			memcpy(&dccchat->addr, &dcc->addr, sizeof(IPADDR));
			net_ip2host(&dccchat->addr, dccchat->addrstr);
			dccchat->port = dcc->port;
			dccchat->tagread = g_input_add(dccchat->handle, G_INPUT_READ,
						       (GInputFunction) dcc_chat_input, dccchat);

			dcc->connection_established = 1;
			signal_emit("dcc connected", 1, dccchat);

			str = g_strdup_printf("101 %s\n",
					      (dccchat->server) ? dccchat->server->nick : "??");
			net_sendbuffer_send(dccchat->sendbuf, str, strlen(str));
			g_free(str);
		}
	}

	/* Check for FSERVE protocol */
	if (g_strncasecmp(msg, "110 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting fserve requests.*/
		if (dcc->accept_fserve) {
			/* TODO - Connect and start DCC Fserve */
		}
	}

	/* Check for SEND protocol */
	if (g_strncasecmp(msg, "120 ", 4) == 0) {
		msg += 4;
		/* Check if this server is accepting send requests.*/
		if (dcc->accept_send) {
			/* Connect and start DCC Send */
			GET_DCC_REC *dccget;
			char **params, *fname, *nick;
			int paramcount, len, quoted = FALSE;
			uoff_t size;

			/* 120 clientnickname filesize filename */
			params = g_strsplit(msg, " ", -1);
			paramcount = strarray_length(params);

			if (paramcount < 3) {
				g_strfreev(params);
				signal_stop();
				return;
			}

			nick = params[0];
			size = str_to_uofft(params[1]);
			fname = g_strjoinv(" ", &params[2]);

			len = strlen(fname);
			if (len > 1 && *fname == '"' && fname[len-1] == '"') {
				/* "file name" - MIRC sends filenames with spaces like this */
				fname[len-1] = '\0';
				g_memmove(fname, fname+1, len);
				quoted = TRUE;
			}

			dccget = dcc_get_create(dcc->server, NULL, nick, fname);
			dccget->handle = dcc->handle;
			dccget->target = g_strdup(dcc->server ? dcc->server->nick : "??");
			memcpy(&dccget->addr, &dcc->addr, sizeof(dcc->addr));
			if (dccget->addr.family == AF_INET) {
				net_ip2host(&dccget->addr, dccget->addrstr);
			} else {
				/* with IPv6, show it to us as it was sent */
				memcpy(dccget->addrstr, dcc->addrstr, sizeof(dccget->addrstr));
			}
			dccget->port = dcc->port;
			dccget->size = size;
			dccget->file_quoted = quoted;
			dccget->from_dccserver = 1;

			dcc->connection_established = 1;
			signal_emit("dcc request", 2, dccget, dccget->addrstr);

			g_strfreev(params);
			g_free(fname);
		}
	}

	signal_stop();
}
Esempio n. 15
0
static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleConnection *gc = (PurpleConnection *) data;
	qq_data *qd;
	qq_connection *conn;
	guint8 buf[1024];		/* set to 16 when test  tcp_rxqueue */
	gint buf_len;
	gint bytes;

	guint8 *pkt;
	guint16 pkt_len;

	gchar *error_msg;
	guint8 *jump;
	gint jump_len;

	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
	qd = (qq_data *) gc->proto_data;

	if(cond != PURPLE_INPUT_READ) {
		purple_connection_error_reason(gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				_("Socket error"));
		return;
	}

	conn = connection_find(qd, source);
	g_return_if_fail(conn != NULL);

	/* test code, not using tcp_rxqueue
	memset(pkt,0, sizeof(pkt));
	buf_len = read(qd->fd, pkt, sizeof(pkt));
	if (buf_len > 2) {
		packet_process(gc, pkt + 2, buf_len - 2);
	}
	return;
	*/

	buf_len = read(source, buf, sizeof(buf));
	if (buf_len < 0) {
		if (errno == EAGAIN)
			/* No worries */
			return;

		error_msg = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno));
		purple_connection_error_reason(gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				error_msg);
		g_free(error_msg);
		return;
	} else if (buf_len == 0) {
		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				_("Server closed the connection"));
		return;
	}

	/* keep alive will be sent in 30 seconds since last_receive
	 *  QQ need a keep alive packet in every 60 seconds
	 gc->last_received = time(NULL);
	*/
#if 1
	purple_debug_info("TCP_PENDING", "Read %d bytes, tcp_rxlen is %d\n", buf_len, conn->tcp_rxlen);
#endif
	conn->tcp_rxqueue = g_realloc(conn->tcp_rxqueue, buf_len + conn->tcp_rxlen);
	memcpy(conn->tcp_rxqueue + conn->tcp_rxlen, buf, buf_len);
	conn->tcp_rxlen += buf_len;

	pkt = g_newa(guint8, MAX_PACKET_SIZE);
	while (PURPLE_CONNECTION_IS_VALID(gc)) {
		if (qd->openconns == NULL) {
			break;
		}
		if (conn->tcp_rxqueue == NULL) {
			conn->tcp_rxlen = 0;
			break;
		}
		if (conn->tcp_rxlen < QQ_TCP_HEADER_LENGTH) {
			break;
		}

		bytes = 0;
		bytes += qq_get16(&pkt_len, conn->tcp_rxqueue + bytes);
		if (conn->tcp_rxlen < pkt_len) {
			break;
		}

#if 1
		qq_show_packet("tcp_pending", conn->tcp_rxqueue, pkt_len);
#endif
		/* purple_debug_info("TCP_PENDING", "Packet len=%d, rxlen=%d\n", pkt_len, conn->tcp_rxlen); */
		if ( pkt_len < QQ_TCP_HEADER_LENGTH
		    || *(conn->tcp_rxqueue + bytes) != QQ_PACKET_TAG
			|| *(conn->tcp_rxqueue + pkt_len - 1) != QQ_PACKET_TAIL) {
			/* HEY! This isn't even a QQ. What are you trying to pull? */
			purple_debug_warning("TCP_PENDING", "Packet error, no header or tail tag\n");

			jump = memchr(conn->tcp_rxqueue + 1, QQ_PACKET_TAIL, conn->tcp_rxlen - 1);
			if ( !jump ) {
				purple_debug_warning("TCP_PENDING", "Failed to find next tail, clear receive buffer\n");
				g_free(conn->tcp_rxqueue);
				conn->tcp_rxqueue = NULL;
				conn->tcp_rxlen = 0;
				return;
			}

			/* jump and over QQ_PACKET_TAIL */
			jump_len = (jump - conn->tcp_rxqueue) + 1;
			purple_debug_warning("TCP_PENDING", "Find next tail at %d, jump %d\n", jump_len, jump_len + 1);
			g_memmove(conn->tcp_rxqueue, jump, conn->tcp_rxlen - jump_len);
			conn->tcp_rxlen -= jump_len;
			continue;
		}

		/* get packet */
		memset(pkt, 0, MAX_PACKET_SIZE);
		g_memmove(pkt, conn->tcp_rxqueue + bytes, pkt_len - bytes);

		/* jump to next packet */
		conn->tcp_rxlen -= pkt_len;
		if (conn->tcp_rxlen) {
			/* purple_debug_info("TCP_PENDING", "shrink tcp_rxqueue to %d\n", conn->tcp_rxlen);	*/
			jump = g_memdup(conn->tcp_rxqueue + pkt_len, conn->tcp_rxlen);
			g_free(conn->tcp_rxqueue);
			conn->tcp_rxqueue = jump;
		} else {
			/* purple_debug_info("TCP_PENDING", "free tcp_rxqueue\n"); */
			g_free(conn->tcp_rxqueue);
			conn->tcp_rxqueue = NULL;
		}

		/* packet_process may call disconnect and destory data like conn
		 * do not call packet_process before jump,
		 * break if packet_process return FALSE */
		if (packet_process(gc, pkt, pkt_len - bytes) == FALSE) {
			purple_debug_info("TCP_PENDING", "Connection has been destory\n");
			break;
		}
	}
}
Esempio n. 16
0
File: output.c Progetto: worr/wsh
static void construct_out(struct collate* c, struct f_collate* f) {
	// If both are null, let's not bother with any of this
	if (*c->error == NULL && *c->output == NULL) return;

	gsize new_len = 0;
	gchar* host_list_str_stdout, * host_list_str_stderr, * host_list_str_base;
	host_list_str_base = host_list_str_stderr = host_list_str_stdout = NULL;

	// Calculate size of host list
	gsize host_list_len = 0;
	for (GSList* host_list = c->hosts; host_list != NULL;
	        host_list = host_list->next) {
		host_list_len += strlen(host_list->data) + 2;
	}

	// Build host list string
	host_list_str_base = g_slice_alloc0(host_list_len + WSHC_STDERR_TAIL_SIZE);
	for (GSList* host_list = c->hosts; host_list != NULL;
	        host_list = host_list->next) {
		g_strlcat(host_list_str_base, host_list->data, host_list_len);
		g_strlcat(host_list_str_base, " ", host_list_len);
	}

	// Copy the host list string
	if (*c->output && ! *c->error)
		host_list_str_stdout = host_list_str_base;
	else if (*c->error && ! *c->output)
		host_list_str_stderr = host_list_str_base;
	else {
		host_list_str_stdout = host_list_str_base;
		host_list_str_stderr = g_slice_copy(host_list_len + WSHC_STDOUT_TAIL_SIZE,
		                                    host_list_str_base);
	}

	// Add the tails of the host command to the host list
	if (host_list_str_stderr)
		strncat(host_list_str_stderr, WSHC_STDERR_TAIL, WSHC_STDERR_TAIL_SIZE);
	if(host_list_str_stdout)
		strncat(host_list_str_stdout, WSHC_STDOUT_TAIL, WSHC_STDOUT_TAIL_SIZE);

	// Calculate the size of the stderr and stdout
	gsize stderr_len = 0;
	for (gchar** p = c->error; *p != NULL; p++) stderr_len += (strlen(*p) + 1);

	gsize stdout_len = 0;
	for (gchar** p = c->output; *p != NULL; p++) stdout_len += (strlen(*p) + 1);

	// Allocate memory until requirement is satisfied
	new_len = 1 + stderr_len + stdout_len + host_list_len * 2 +
	          WSHC_STDOUT_TAIL_SIZE + WSHC_STDERR_TAIL_SIZE;
	while (*f->size == 0 || new_len + strlen(*f->out) > *f->size) {
		gchar* new_output = g_slice_alloc0(*f->size + WSHC_ALLOC_LEN);
		g_memmove(new_output, *f->out, *f->size);
		if (*f->size)
			g_slice_free1(*f->size, *f->out);
		*f->out = new_output;
		*f->size += WSHC_ALLOC_LEN;
	}

	// Start copying data into out
	if (*c->error && host_list_str_stderr) {
		strncat(*f->out, host_list_str_stderr, *f->size);

		for (gchar** p = c->error; *p != NULL; p++) {
			strncat(*f->out, *p, *f->size);
			strncat(*f->out, "\n", *f->size);
		}

		// Add separating newline
		if (*c->output != NULL)
			strncat(*f->out, "\n", *f->size);
	}

	if (*c->output && host_list_str_stdout) {
		strncat(*f->out, host_list_str_stdout, *f->size);

		for (gchar** p = c->output; *p != NULL; p++) {
			strncat(*f->out, *p, *f->size);
			strncat(*f->out, "\n", *f->size);
		}
	}

	strncat(*f->out, "\n", *f->size);

	if (host_list_str_stderr)
		g_slice_free1(host_list_len + WSHC_STDERR_TAIL_SIZE, host_list_str_stderr);
	if (host_list_str_stdout)
		g_slice_free1(host_list_len + WSHC_STDOUT_TAIL_SIZE, host_list_str_stdout);
}
Esempio n. 17
0
SaErrorT snmp_bc_bulk_selcache(	struct oh_handler_state *handle,
                                SaHpiResourceIdT id)
{
    struct snmp_bc_hnd *custom_handle;
    SaErrorT 	err;
    int 		isdst;
    sel_entry 	sel_entry;
    SaHpiEventT 	tmpevent;
    netsnmp_pdu	*pdu, *response;
    netsnmp_variable_list *vars;
    LogSource2ResourceT logsrc2res;
    int             count;
    int             running;
    int             status;
    char 		logstring[MAX_ASN_STR_LEN];
    char 		objoid[SNMP_BC_MAX_OID_LENGTH];
    oid             name[MAX_OID_LEN];
    oid             root[MAX_OID_LEN];
    size_t          rootlen;
    size_t          name_length;
    size_t 		str_len;
    int             reps;

    if (!handle) {
        err("Invalid parameter.");
        return(SA_ERR_HPI_INVALID_PARAMS);
    }

    str_len = MAX_ASN_STR_LEN;
    isdst=0;
    custom_handle = (struct snmp_bc_hnd *)handle->data;
    reps = custom_handle->count_per_getbulk;

    /* --------------------------------------------------- */
    /* Set initial Event Log Entry OID and root tree       */
    /* --------------------------------------------------- */

    if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) {
        snprintf(objoid, SNMP_BC_MAX_OID_LENGTH, "%s", SNMP_BC_SEL_ENTRY_OID_RSA);
    } else {
        snprintf(objoid, SNMP_BC_MAX_OID_LENGTH, "%s",SNMP_BC_SEL_ENTRY_OID);
    }
    rootlen = MAX_OID_LEN;
    read_objid(objoid, root, &rootlen);

    /* --------------------------------------------------- */
    /* Object ID for GETBULK request                       */
    /* --------------------------------------------------- */
    g_memmove(name, root, rootlen * sizeof(oid));
    name_length = rootlen;

    running = 1;

    while (running) {

        /* --------------------------------------------------- */
        /* Create PDU for GETBULK request                      */
        /* --------------------------------------------------- */
        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);

        status = snmp_getn_bulk(custom_handle->sessp,
                                name,
                                name_length,
                                pdu,
                                &response,
                                reps);

        if (pdu) snmp_free_pdu(pdu);

        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                for (vars = response->variables; vars;
                        vars = vars->next_variable) {

                    /* ------------------------------------------------- */
                    /* Check if this variable is of the same OID tree    */
                    /* ------------------------------------------------- */
                    if ((vars->name_length < rootlen)
                            || (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0))
                    {
                        /* Exit vars processing */
                        running = 0;
                        continue;
                    }

                    if ((vars->type != SNMP_ENDOFMIBVIEW) &&
                            (vars->type != SNMP_NOSUCHOBJECT) &&
                            (vars->type != SNMP_NOSUCHINSTANCE)) {

                        if (snmp_oid_compare(name, name_length,
                                             vars->name,
                                             vars->name_length) >= 0) {
                            fprintf(stderr, "Error: OID not increasing: ");
                            fprint_objid(stderr, name, name_length);
                            fprintf(stderr, " >= ");
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                            fprintf(stderr, "\n");
                            running = 0;
                        }
                        /* ---------------------------------- */
                        /* Check if last variable,            */
                        /* and if so, save for next request.  */
                        /* ---------------------------------- */
                        if (vars->next_variable == NULL) {
                            g_memmove(name, vars->name,
                                      vars->name_length * sizeof(oid));
                            name_length = vars->name_length;
                        }

                        /* ---------------------------------- */
                        /* ---------------------------------- */
                        /* ---------------------------------- */
                        if ((running == 1) && (vars->type == ASN_OCTET_STR)) {

                            if (vars->val_len < MAX_ASN_STR_LEN) str_len = vars->val_len;
                            else str_len = MAX_ASN_STR_LEN;

                            /* ---------------------------------- */
                            /* Guarantee NULL terminated string   */
                            /* ---------------------------------- */
                            // memcpy(logstring, vars->val.string, str_len);
                            g_memmove(logstring, vars->val.string, str_len);
                            logstring[str_len] = '\0';


                            err = snmp_bc_parse_sel_entry(handle,logstring, &sel_entry);
                            isdst = sel_entry.time.tm_isdst;
                            snmp_bc_log2event(handle, logstring, &tmpevent, isdst, &logsrc2res);
                            err = oh_el_prepend(handle->elcache, &tmpevent, NULL, NULL);
                            if (custom_handle->isFirstDiscovery == SAHPI_FALSE)
                                err = snmp_bc_add_to_eventq(handle, &tmpevent, SAHPI_TRUE);
                        }
                    } else {
                        /* Stop on an exception value */
                        running = 0;
                    }
                }  /* end for */
            } else {   /* if (response->errstat != SNMP_ERR_NOERROR) */

                /* --------------------------------------------- */
                /* Error condition is seen in response,          */
                /* for now, print the error then exit            */
                /* Not sure what to do for recovery              */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                } else {
                    fprintf(stderr, "Error in packet.\nReason: %s\n",
                            snmp_errstring(response->errstat));
                    if (response->errindex != 0) {
                        fprintf(stderr, "Failed object: ");
                        for (count = 1, vars = response->variables;
                                vars && count != response->errindex;
                                vars = vars->next_variable, count++)
                            if (vars)
                                fprint_objid(stderr, vars->name,
                                             vars->name_length);
                        fprintf(stderr, "\n");
                    }
                }
            }
        } else if (status == STAT_TIMEOUT) {
            fprintf(stderr, "Timeout: No Response\n");
            running = 0;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmp_bulk_sel",custom_handle->sessp );
            running = 0;
        }

        if (response)
            snmp_free_pdu(response);
    }
    return(SA_OK);
}
Esempio n. 18
0
static guint
gtk_entry_buffer_normal_insert_text (GtkEntryBuffer *buffer,
                                     guint           position,
                                     const gchar    *chars,
                                     guint           n_chars)
{
  GtkEntryBufferPrivate *pv = buffer->priv;
  gsize prev_size;
  gsize n_bytes;
  gsize at;

  n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars;

  /* Need more memory */
  if (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size)
    {
      gchar *et_new;

      prev_size = pv->normal_text_size;

      /* Calculate our new buffer size */
      while (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size)
        {
          if (pv->normal_text_size == 0)
            pv->normal_text_size = MIN_SIZE;
          else
            {
              if (2 * pv->normal_text_size < GTK_ENTRY_BUFFER_MAX_SIZE)
                pv->normal_text_size *= 2;
              else
                {
                  pv->normal_text_size = GTK_ENTRY_BUFFER_MAX_SIZE;
                  if (n_bytes > pv->normal_text_size - pv->normal_text_bytes - 1)
                    {
                      n_bytes = pv->normal_text_size - pv->normal_text_bytes - 1;
                      n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars;
                      n_chars = g_utf8_strlen (chars, n_bytes);
                    }
                  break;
                }
            }
        }

      /* Could be a password, so can't leave stuff in memory. */
      et_new = g_malloc (pv->normal_text_size);
      memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size));
      trash_area (pv->normal_text, prev_size);
      g_free (pv->normal_text);
      pv->normal_text = et_new;
    }

  /* Actual text insertion */
  at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
  g_memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at);
  memcpy (pv->normal_text + at, chars, n_bytes);

  /* Book keeping */
  pv->normal_text_bytes += n_bytes;
  pv->normal_text_chars += n_chars;
  pv->normal_text[pv->normal_text_bytes] = '\0';

  gtk_entry_buffer_emit_inserted_text (buffer, position, chars, n_chars);
  return n_chars;
}
Esempio n. 19
0
static gint
xmms_faad_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err)
{
	xmms_faad_data_t *data;
	xmms_error_t error;

	NeAACDecFrameInfo frameInfo;
	gpointer sample_buffer;
	guint size, bytes_read = 0;

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	size = MIN (data->outbuf->len, len);
	while (size == 0) {
		gboolean need_read;

		/* MP4 demuxer always gives full packets so we need different handling */
		if (data->filetype == FAAD_TYPE_MP4)
			need_read = (data->buffer_length == 0);
		else
			need_read = (data->buffer_length < data->buffer_size);

		if (need_read) {
			bytes_read = xmms_xform_read (xform,
			                              (gchar *) data->buffer + data->buffer_length,
			                              data->buffer_size - data->buffer_length,
			                              &error);

			if (bytes_read <= 0 && data->buffer_length == 0) {
				XMMS_DBG ("EOF");
				return 0;
			}

			data->buffer_length += bytes_read;
		}

		sample_buffer = NeAACDecDecode (data->decoder, &frameInfo, data->buffer,
		                               data->buffer_length);

		g_memmove (data->buffer, data->buffer + frameInfo.bytesconsumed,
		           data->buffer_length - frameInfo.bytesconsumed);
		data->buffer_length -= frameInfo.bytesconsumed;
		bytes_read = frameInfo.samples * xmms_sample_size_get (data->sampleformat);

		if (bytes_read > 0 && frameInfo.error == 0) {
			gint32 temp, toskip = 0;

			if (data->samplerate != frameInfo.samplerate ||
			    data->channels != frameInfo.channels) {
				/* We should inform output to change parameters somehow */
				XMMS_DBG ("Output format changed in the middle of a read!");
				data->samplerate = frameInfo.samplerate;
				data->channels = frameInfo.channels;
			}

			if (xmms_xform_auxdata_get_int (xform, "frame_offset", &temp)) {
				toskip = (temp * frameInfo.channels *
				          xmms_sample_size_get (data->sampleformat));
			}

			if (xmms_xform_auxdata_get_int (xform, "frame_duration", &temp)) {
				bytes_read = (temp * frameInfo.channels *
				              xmms_sample_size_get (data->sampleformat));
			}

			g_string_append_len (data->outbuf, sample_buffer + toskip,
			                     bytes_read - toskip);
		} else if (frameInfo.error > 0) {
			XMMS_DBG ("ERROR %d in faad decoding: %s", frameInfo.error,
			          NeAACDecGetErrorMessage (frameInfo.error));
			return -1;
		}

		size = MIN (data->outbuf->len, len);
	}

	memcpy (buf, data->outbuf->str, size);
	g_string_erase (data->outbuf, 0, size);
	return size;
}
Esempio n. 20
0
void finalize_selectregion(void)
{
  GList *itemlist;
  struct Item *item;
  ArtVpath *vpath;
  ArtSVP *lassosvp;
  int i, n;
  double *pt;
  
  ui.cur_item_type = ITEM_NONE;
  
  // build SVP for the lasso path
  n = ui.cur_path.num_points;
  vpath = g_malloc((n+2)*sizeof(ArtVpath));
  for (i=0; i<n; i++) { 
    vpath[i].x = ui.cur_path.coords[2*i];
    vpath[i].y = ui.cur_path.coords[2*i+1];
  }
  vpath[n].x = vpath[0].x; vpath[n].y = vpath[0].y;
  vpath[0].code = ART_MOVETO;
  for (i=1; i<=n; i++) vpath[i].code = ART_LINETO;
  vpath[n+1].code = ART_END;
  lassosvp = art_svp_from_vpath(vpath);
  g_free(vpath);

  // see which items we selected
  for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
    item = (struct Item *)itemlist->data;
    if (hittest_item(lassosvp, item)) {
      // update the selection bbox
      if (ui.selection->items==NULL || ui.selection->bbox.left>item->bbox.left)
        ui.selection->bbox.left = item->bbox.left;
      if (ui.selection->items==NULL || ui.selection->bbox.right<item->bbox.right)
        ui.selection->bbox.right = item->bbox.right;
      if (ui.selection->items==NULL || ui.selection->bbox.top>item->bbox.top)
        ui.selection->bbox.top = item->bbox.top;
      if (ui.selection->items==NULL || ui.selection->bbox.bottom<item->bbox.bottom)
        ui.selection->bbox.bottom = item->bbox.bottom;
      // add the item
      ui.selection->items = g_list_append(ui.selection->items, item); 
    }
  }
  art_svp_free(lassosvp);
  
  if (ui.selection->items == NULL) {
    // if we clicked inside a text zone or image?
    pt = ui.cur_path.coords; 
    item = click_is_in_text_or_image(ui.selection->layer, pt[0], pt[1]);
    if (item!=NULL) {
      for (i=0; i<n; i++, pt+=2) {
        if (pt[0]<item->bbox.left || pt[0]>item->bbox.right || pt[1]<item->bbox.top || pt[1]>item->bbox.bottom)
          { item = NULL; break; }
      }
    }
    if (item!=NULL) {
      ui.selection->items = g_list_append(ui.selection->items, item);
      g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
    }
  }

  if (ui.selection->items == NULL) reset_selection();
  else { // make a selection rectangle instead of the lasso shape
    gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item));
    ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
      gnome_canvas_rect_get_type(), "width-pixels", 1, 
      "outline-color-rgba", 0x000000ff,
      "fill-color-rgba", 0x80808040,
      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
    make_dashed(ui.selection->canvas_item);
    ui.selection->type = ITEM_SELECTRECT;
  }

  update_cursor();
  update_copy_paste_enabled();
  update_font_button();
}
Esempio n. 21
0
void selection_to_clip(void)
{
  struct XojSelectionData *sel;
  int bufsz, nitems, val;
  char *p;
  GList *list;
  struct Item *item;
  GtkTargetList *targetlist;
  GtkTargetEntry *targets;
  int n_targets;
  
  if (ui.selection == NULL) return;
  bufsz = 2*sizeof(int) // bufsz, nitems
        + sizeof(struct BBox); // bbox
  nitems = 0;
  for (list = ui.selection->items; list != NULL; list = list->next) {
    item = (struct Item *)list->data;
    nitems++;
    if (item->type == ITEM_STROKE) {
      bufsz+= sizeof(int) // type
            + sizeof(struct Brush) // brush
            + sizeof(int) // num_points
            + 2*item->path->num_points*sizeof(double); // the points
      if (item->brush.variable_width)
        bufsz += (item->path->num_points-1)*sizeof(double); // the widths
    }
    else if (item->type == ITEM_TEXT) {
      bufsz+= sizeof(int) // type
            + sizeof(struct Brush) // brush
            + 2*sizeof(double) // bbox upper-left
            + sizeof(int) // text len
            + strlen(item->text)+1 // text
            + sizeof(int) // font_name len
            + strlen(item->font_name)+1 // font_name
            + sizeof(double); // font_size
    }
    else if (item->type == ITEM_IMAGE) {
      if (item->image_png == NULL) {
        set_cursor_busy(TRUE);
        if (!gdk_pixbuf_save_to_buffer(item->image, &item->image_png, &item->image_png_len, "png", NULL, NULL))
          item->image_png_len = 0;       // failed for some reason, so forget it
        set_cursor_busy(FALSE);
      }
      bufsz+= sizeof(int) // type
        + sizeof(struct BBox)
        + sizeof(gsize) // png_buflen
        + item->image_png_len;
    }
    else bufsz+= sizeof(int); // type
  }

  // allocate selection data structure and buffer
  sel = g_malloc(sizeof(struct XojSelectionData));
  sel->xo_data_len = bufsz;
  sel->xo_data = g_malloc(bufsz);
  sel->image_data = NULL;
  sel->text_data = NULL;

  // fill in the data
  p = sel->xo_data;
  g_memmove(p, &bufsz, sizeof(int)); p+= sizeof(int);
  g_memmove(p, &nitems, sizeof(int)); p+= sizeof(int);
  g_memmove(p, &ui.selection->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
  for (list = ui.selection->items; list != NULL; list = list->next) {
    item = (struct Item *)list->data;
    g_memmove(p, &item->type, sizeof(int)); p+= sizeof(int);
    if (item->type == ITEM_STROKE) {
      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(p, &item->path->num_points, sizeof(int)); p+= sizeof(int);
      g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
      p+= 2*item->path->num_points*sizeof(double);
      if (item->brush.variable_width) {
        g_memmove(p, item->widths, (item->path->num_points-1)*sizeof(double));
        p+= (item->path->num_points-1)*sizeof(double);
      }
    }
    if (item->type == ITEM_TEXT) {
      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
      g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
      val = strlen(item->text);
      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
      g_memmove(p, item->text, val+1); p+= val+1;
      val = strlen(item->font_name);
      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
      g_memmove(p, item->font_name, val+1); p+= val+1;
      g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
      if (nitems==1) sel->text_data = g_strdup(item->text); // single text item
    }
    if (item->type == ITEM_IMAGE) {
      g_memmove(p, &item->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
      g_memmove(p, &item->image_png_len, sizeof(gsize)); p+= sizeof(gsize);
      if (item->image_png_len > 0) {
        g_memmove(p, item->image_png, item->image_png_len); p+= item->image_png_len;
      }
      if (nitems==1) sel->image_data = gdk_pixbuf_copy(item->image); // single image
    }
  }
  
  /* build list of valid targets */
  targetlist = gtk_target_list_new(NULL, 0);
  gtk_target_list_add(targetlist, 
    gdk_atom_intern(XOURNAL_TARGET_ATOM, FALSE), 0, TARGET_XOURNAL);
  if (sel->image_data!=NULL)
    gtk_target_list_add_image_targets(targetlist, TARGET_PIXBUF, TRUE);
  if (sel->text_data!=NULL) 
    gtk_target_list_add_text_targets(targetlist, TARGET_TEXT);
  targets = gtk_target_table_new_from_list(targetlist, &n_targets);
  gtk_target_list_unref(targetlist);
  
  gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), 
       targets, n_targets,
       callback_clipboard_get, callback_clipboard_clear, sel);
  gtk_target_table_free(targets, n_targets);
}
Esempio n. 22
0
// Copy addresses
void c_util::cpy_ipv4(struct in_addr* dst, struct in_addr* src)
{
    g_memmove(dst, src, sizeof(struct in_addr));
}
Esempio n. 23
0
GString*
g_string_insert_len (GString     *string,
		     gssize       pos,    
		     const gchar *val,
		     gssize       len)    
{
  g_return_val_if_fail (string != NULL, NULL);
  g_return_val_if_fail (val != NULL, string);

  if (len < 0)
    len = strlen (val);

  if (pos < 0)
    pos = string->len;
  else
    g_return_val_if_fail (pos <= string->len, string);

  /* Check whether val represents a substring of string.  This test
     probably violates chapter and verse of the C standards, since
     ">=" and "<=" are only valid when val really is a substring.
     In practice, it will work on modern archs.  */
  if (val >= string->str && val <= string->str + string->len)
    {
      gsize offset = val - string->str;
      gsize precount = 0;

      g_string_maybe_expand (string, len);
      val = string->str + offset;
      /* At this point, val is valid again.  */

      /* Open up space where we are going to insert.  */
      if (pos < string->len)
	g_memmove (string->str + pos + len, string->str + pos, string->len - pos);

      /* Move the source part before the gap, if any.  */
      if (offset < pos)
	{
	  precount = MIN (len, pos - offset);
	  memcpy (string->str + pos, val, precount);
	}

      /* Move the source part after the gap, if any.  */
      if (len > precount)
	memcpy (string->str + pos + precount,
		val + /* Already moved: */ precount + /* Space opened up: */ len,
		len - precount);
    }
  else
    {
      g_string_maybe_expand (string, len);

      /* If we aren't appending at the end, move a hunk
       * of the old string to the end, opening up space
       */
      if (pos < string->len)
	g_memmove (string->str + pos + len, string->str + pos, string->len - pos);

      /* insert the new string */
      if (len == 1)
        string->str[pos] = *val;
      else
        memcpy (string->str + pos, val, len);
    }

  string->len += len;

  string->str[string->len] = 0;

  return string;
}
Esempio n. 24
0
void c_util::cpy_ipv6(struct libnet_in6_addr* dst, struct libnet_in6_addr* src)
{
    g_memmove(dst, src, sizeof(struct libnet_in6_addr));
}
Esempio n. 25
0
static void
msn_dc_recv_cb(gpointer data, gint fd, PurpleInputCondition cond)
{
	MsnDirectConn *dc;
	int free_buf_space;
	int bytes_received;
	guint32 packet_length;

	g_return_if_fail(data != NULL);
	g_return_if_fail(fd != -1);

	dc = data;
	free_buf_space = dc->in_size - dc->in_pos;

	bytes_received = recv(fd, dc->in_buffer + dc->in_pos, free_buf_space, 0);
	if (bytes_received < 0) {
		if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
			return;

		purple_debug_warning("msn", "msn_dc_recv_cb: recv error\n");

		if(dc->state != DC_STATE_ESTABLISHED)
			msn_dc_fallback_to_sb(dc);
		else
			msn_dc_destroy(dc);
		return;

	} else if (bytes_received == 0) {
		/* EOF. Remote side closed connection. */
		purple_debug_info("msn", "msn_dc_recv_cb: recv EOF\n");

		if(dc->state != DC_STATE_ESTABLISHED)
			msn_dc_fallback_to_sb(dc);
		else
			msn_dc_destroy(dc);
		return;
	}

	dc->progress = TRUE;

	dc->in_pos += bytes_received;

	/* Wait for packet length */
	while (dc->in_pos >= 4) {
		packet_length = GUINT32_FROM_LE(*((guint32*)dc->in_buffer));

		if (packet_length > DC_MAX_PACKET_SIZE) {
			/* Oversized packet */
			purple_debug_warning("msn", "msn_dc_recv_cb: oversized packet received\n");
			return;
		}

		/* Wait for the whole packet to arrive */
		if (dc->in_pos < 4 + packet_length)
			return;

		switch (msn_dc_process_packet(dc, packet_length)) {
		case DC_PROCESS_CLOSE:
			return;

		case DC_PROCESS_FALLBACK:
			purple_debug_warning("msn", "msn_dc_recv_cb: packet processing error, fall back to SB\n");
			msn_dc_fallback_to_sb(dc);
			return;

		}

		if (dc->in_pos > packet_length + 4) {
			g_memmove(dc->in_buffer, dc->in_buffer + 4 + packet_length, dc->in_pos - packet_length - 4);
		}

		dc->in_pos -= packet_length + 4;
	}
}
Esempio n. 26
0
static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account, const gchar *from_addr)
{
    MimeInfo *msgcontent;
    gchar *textstr, *tmp;
    FILE *fp;
    gchar *sigcontent;
    gpgme_ctx_t ctx;
    gpgme_data_t gpgtext, gpgsig;
    size_t len;
    gpgme_error_t err;
    struct passphrase_cb_info_s info;
    gpgme_sign_result_t result = NULL;

    memset (&info, 0, sizeof info);

    /* get content node from message */
    msgcontent = (MimeInfo *) mimeinfo->node->children->data;
    if (msgcontent->type == MIMETYPE_MULTIPART) {
        if (!msgcontent->node->children) {
            debug_print("msgcontent->node->children NULL, bailing\n");
            privacy_set_error(_("Malformed message"));
            return FALSE;
        }
        msgcontent = (MimeInfo *) msgcontent->node->children->data;
    }
    /* get rid of quoted-printable or anything */
    procmime_decode_content(msgcontent);

    fp = my_tmpfile();
    if (fp == NULL) {
        perror("my_tmpfile");
        privacy_set_error(_("Couldn't create temporary file."));
        return FALSE;
    }
    procmime_write_mimeinfo(msgcontent, fp);
    rewind(fp);

    /* read temporary file into memory */
    textstr = fp_read_noconv(fp);

    fclose(fp);

    gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0);
    gpgme_data_new(&gpgsig);
    if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) {
        debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        return FALSE;
    }
    gpgme_set_textmode(ctx, 1);
    gpgme_set_armor(ctx, 1);

    if (!sgpgme_setup_signers(ctx, account, from_addr)) {
        gpgme_release(ctx);
        return FALSE;
    }

    prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent);
    if (!getenv("GPG_AGENT_INFO") || !prefs_gpg_get_config()->use_gpg_agent) {
        info.c = ctx;
        gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info);
    }

    err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR);
    if (err != GPG_ERR_NO_ERROR) {
        if (err == GPG_ERR_CANCELED) {
            /* ignore cancelled signing */
            privacy_reset_error();
            debug_print("gpgme_op_sign cancelled\n");
        } else {
            privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err));
            debug_print("gpgme_op_sign error : %x\n", err);
        }
        gpgme_release(ctx);
        return FALSE;
    }
    result = gpgme_op_sign_result(ctx);
    if (result && result->signatures) {
        gpgme_new_signature_t sig = result->signatures;
        while (sig) {
            debug_print("valid signature: %s\n", sig->fpr);
            sig = sig->next;
        }
    } else if (result && result->invalid_signers) {
        gpgme_invalid_key_t invalid = result->invalid_signers;
        while (invalid) {
            g_warning("invalid signer: %s (%s)", invalid->fpr,
                      gpgme_strerror(invalid->reason));
            privacy_set_error(_("Data signing failed due to invalid signer: %s"),
                              gpgme_strerror(invalid->reason));
            invalid = invalid->next;
        }
        gpgme_release(ctx);
        return FALSE;
    } else {
        /* can't get result (maybe no signing key?) */
        debug_print("gpgme_op_sign_result error\n");
        privacy_set_error(_("Data signing failed, no results."));
        gpgme_release(ctx);
        return FALSE;
    }


    sigcontent = sgpgme_data_release_and_get_mem(gpgsig, &len);

    if (sigcontent == NULL || len <= 0) {
        g_warning("sgpgme_data_release_and_get_mem failed");
        privacy_set_error(_("Data signing failed, no contents."));
        gpgme_data_release(gpgtext);
        g_free(textstr);
        g_free(sigcontent);
        gpgme_release(ctx);
        return FALSE;
    }

    tmp = g_malloc(len+1);
    g_memmove(tmp, sigcontent, len+1);
    tmp[len] = '\0';
    gpgme_data_release(gpgtext);
    g_free(textstr);
    g_free(sigcontent);

    if (msgcontent->content == MIMECONTENT_FILE &&
            msgcontent->data.filename != NULL) {
        if (msgcontent->tmp == TRUE)
            claws_unlink(msgcontent->data.filename);
        g_free(msgcontent->data.filename);
    }
    msgcontent->data.mem = g_strdup(tmp);
    msgcontent->content = MIMECONTENT_MEM;
    g_free(tmp);

    /* avoid all sorts of clear-signing problems with non ascii
     * chars
     */
    procmime_encode_content(msgcontent, ENC_BASE64);
    gpgme_release(ctx);

    return TRUE;
}
Esempio n. 27
0
static void process_server_msg(PurpleConnection *gc, guint8 *data, gint data_len, guint16 seq)
{
	qq_data *qd;
	guint8 *data_str, i = 0;
	gchar **segments, **seg;
	gchar *funct_str, *from, *to;
	gint bytes, funct;

	g_return_if_fail(data != NULL && data_len != 0);

	qd = (qq_data *) gc->proto_data;

	data_str = g_newa(guint8, data_len + 1);
	g_memmove(data_str, data, data_len);
	data_str[data_len] = 0x00;

	segments = g_strsplit((gchar *) data_str, "\x1f", 0);
	g_return_if_fail(segments != NULL);
	for (seg = segments; *seg != NULL; seg++)
		i++;
	if (i < 3) {
		purple_debug_warning("QQ", "Server message segments is less than 3\n");
		g_strfreev(segments);
		return;
	}

	bytes = 0;
	funct_str = segments[0];
	bytes += strlen(funct_str) + 1;
	from = segments[1];
	bytes += strlen(from) + 1;
	to = segments[2];
	bytes += strlen(to) + 1;

	/* qq_show_packet("Server MSG", data, data_len); */
	if (strtoul(to, NULL, 10) != qd->uid) {	/* not to me */
		purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to);
		g_strfreev(segments);
		return;
	}

	funct = strtol(funct_str, NULL, 10);
	switch (funct) {
		case QQ_SERVER_BUDDY_ADDED_DEPRECATED:
		case QQ_SERVER_BUDDY_ADDED_ME:
		case QQ_SERVER_BUDDY_ADD_REQUEST_DEPRECATED:
		case QQ_SERVER_BUDDY_REJECTED_ME:
		case QQ_SERVER_BUDDY_ADD_REQUEST:
		case QQ_SERVER_BUDDY_ADDING_EX:
		case QQ_SERVER_BUDDY_ADDED_ANSWER:
		case QQ_SERVER_BUDDY_ADDED:
			qq_process_buddy_from_server(gc,  funct, from, to, data + bytes, data_len - bytes);
			break;
		case QQ_SERVER_NOTICE:
			do_server_notice(gc, from, to, data + bytes, data_len - bytes);
			break;
		case QQ_SERVER_NEW_CLIENT:
			purple_debug_warning("QQ", "QQ Server has newer client version\n");
			break;
		default:
			qq_show_packet("Unknown sys msg", data, data_len);
			purple_debug_warning("QQ", "Recv unknown sys msg code: %s\n", funct_str);
			break;
	}
	g_strfreev(segments);
}
Esempio n. 28
0
static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
{
    MimeInfo *msgcontent;
    FILE *fp;
    gchar *enccontent;
    size_t len;
    gchar *textstr, *tmp;
    gpgme_data_t gpgtext, gpgenc;
    gpgme_ctx_t ctx;
    gpgme_key_t *kset = NULL;
    gchar **fprs = g_strsplit(encrypt_data, " ", -1);
    gpgme_error_t err;
    gint i = 0;

    while (fprs[i] && strlen(fprs[i])) {
        i++;
    }

    kset = g_malloc(sizeof(gpgme_key_t)*(i+1));
    memset(kset, 0, sizeof(gpgme_key_t)*(i+1));
    if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) {
        debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        g_free(kset);
        return FALSE;
    }
    i = 0;
    while (fprs[i] && strlen(fprs[i])) {
        gpgme_key_t key;
        err = gpgme_get_key(ctx, fprs[i], &key, 0);
        if (err) {
            debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err));
            privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err));
            g_free(kset);
            return FALSE;
        }
        debug_print("found %s at %d\n", fprs[i], i);
        kset[i] = key;
        i++;
    }


    debug_print("Encrypting message content\n");

    /* get content node from message */
    msgcontent = (MimeInfo *) mimeinfo->node->children->data;
    if (msgcontent->type == MIMETYPE_MULTIPART) {
        if (!msgcontent->node->children) {
            debug_print("msgcontent->node->children NULL, bailing\n");
            privacy_set_error(_("Malformed message"));
            g_free(kset);
            return FALSE;
        }
        msgcontent = (MimeInfo *) msgcontent->node->children->data;
    }
    /* get rid of quoted-printable or anything */
    procmime_decode_content(msgcontent);

    fp = my_tmpfile();
    if (fp == NULL) {
        privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno));
        perror("my_tmpfile");
        g_free(kset);
        return FALSE;
    }
    procmime_write_mimeinfo(msgcontent, fp);
    rewind(fp);

    /* read temporary file into memory */
    textstr = fp_read_noconv(fp);

    fclose(fp);

    /* encrypt data */
    gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0);
    gpgme_data_new(&gpgenc);
    if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) {
        debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        g_free(kset);
        return FALSE;
    }
    gpgme_set_armor(ctx, 1);

    err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);

    enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len);
    g_free(kset);

    if (enccontent == NULL || len <= 0) {
        g_warning("sgpgme_data_release_and_get_mem failed");
        privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err));
        gpgme_data_release(gpgtext);
        g_free(textstr);
        gpgme_release(ctx);
        g_free(enccontent);
        return FALSE;
    }

    tmp = g_malloc(len+1);
    g_memmove(tmp, enccontent, len+1);
    tmp[len] = '\0';
    g_free(enccontent);

    gpgme_data_release(gpgtext);
    g_free(textstr);

    if (msgcontent->content == MIMECONTENT_FILE &&
            msgcontent->data.filename != NULL) {
        if (msgcontent->tmp == TRUE)
            claws_unlink(msgcontent->data.filename);
        g_free(msgcontent->data.filename);
    }
    msgcontent->data.mem = g_strdup(tmp);
    msgcontent->content = MIMECONTENT_MEM;
    g_free(tmp);
    gpgme_release(ctx);

    return TRUE;
}
Esempio n. 29
0
static int
gst_wavpack_enc_push_block (void *id, void *data, int32_t count)
{
  GstWavpackEncWriteID *wid = (GstWavpackEncWriteID *) id;
  GstWavpackEnc *enc = GST_WAVPACK_ENC (wid->wavpack_enc);
  GstFlowReturn *flow;
  GstBuffer *buffer;
  GstPad *pad;
  guchar *block = (guchar *) data;

  pad = (wid->correction) ? enc->wvcsrcpad : enc->srcpad;
  flow =
      (wid->correction) ? &enc->wvcsrcpad_last_return : &enc->
      srcpad_last_return;

  *flow = gst_pad_alloc_buffer_and_set_caps (pad, GST_BUFFER_OFFSET_NONE,
      count, GST_PAD_CAPS (pad), &buffer);

  if (*flow != GST_FLOW_OK) {
    GST_WARNING_OBJECT (enc, "flow on %s:%s = %s",
        GST_DEBUG_PAD_NAME (pad), gst_flow_get_name (*flow));
    return FALSE;
  }

  g_memmove (GST_BUFFER_DATA (buffer), block, count);

  if (count > sizeof (WavpackHeader) && memcmp (block, "wvpk", 4) == 0) {
    /* if it's a Wavpack block set buffer timestamp and duration, etc */
    WavpackHeader wph;

    GST_LOG_OBJECT (enc, "got %d bytes of encoded wavpack %sdata",
        count, (wid->correction) ? "correction " : "");

    gst_wavpack_read_header (&wph, block);

    /* Only set when pushing the first buffer again, in that case
     * we don't want to delay the buffer or push newsegment events
     */
    if (!wid->passthrough) {
      /* Only push complete blocks */
      if (enc->pending_buffer == NULL) {
        enc->pending_buffer = buffer;
        enc->pending_offset = wph.block_index;
      } else if (enc->pending_offset == wph.block_index) {
        enc->pending_buffer = gst_buffer_join (enc->pending_buffer, buffer);
      } else {
        GST_ERROR ("Got incomplete block, dropping");
        gst_buffer_unref (enc->pending_buffer);
        enc->pending_buffer = buffer;
        enc->pending_offset = wph.block_index;
      }

      if (!(wph.flags & FINAL_BLOCK))
        return TRUE;

      buffer = enc->pending_buffer;
      enc->pending_buffer = NULL;
      enc->pending_offset = 0;

      /* if it's the first wavpack block, send a NEW_SEGMENT event */
      if (wph.block_index == 0) {
        gst_pad_push_event (pad,
            gst_event_new_new_segment (FALSE,
                1.0, GST_FORMAT_TIME, 0, GST_BUFFER_OFFSET_NONE, 0));

        /* save header for later reference, so we can re-send it later on
         * EOS with fixed up values for total sample count etc. */
        if (enc->first_block == NULL && !wid->correction) {
          enc->first_block =
              g_memdup (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
          enc->first_block_size = GST_BUFFER_SIZE (buffer);
        }
      }
    }

    /* set buffer timestamp, duration, offset, offset_end from
     * the wavpack header */
    GST_BUFFER_TIMESTAMP (buffer) = enc->timestamp_offset +
        gst_util_uint64_scale_int (GST_SECOND, wph.block_index,
        enc->samplerate);
    GST_BUFFER_DURATION (buffer) =
        gst_util_uint64_scale_int (GST_SECOND, wph.block_samples,
        enc->samplerate);
    GST_BUFFER_OFFSET (buffer) = wph.block_index;
    GST_BUFFER_OFFSET_END (buffer) = wph.block_index + wph.block_samples;
  } else {
    /* if it's something else set no timestamp and duration on the buffer */
    GST_DEBUG_OBJECT (enc, "got %d bytes of unknown data", count);

    GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
    GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
  }

  /* push the buffer and forward errors */
  GST_DEBUG_OBJECT (enc, "pushing buffer with %d bytes",
      GST_BUFFER_SIZE (buffer));
  *flow = gst_pad_push (pad, buffer);

  if (*flow != GST_FLOW_OK) {
    GST_WARNING_OBJECT (enc, "flow on %s:%s = %s",
        GST_DEBUG_PAD_NAME (pad), gst_flow_get_name (*flow));
    return FALSE;
  }

  return TRUE;
}
Esempio n. 30
0
/* the main pattern recognition function, called after finalize_stroke() */
void recognize_patterns(void)
{
  struct Item *it;
  struct Inertia s, ss[4];
  struct RecoSegment *rs;
  int n, i;
  int brk[5];
  double score;
  
  if (!undo || undo->type!=ITEM_STROKE) return;
  if (undo->next != last_item_checker) reset_recognizer(); // reset queue
  if (last_item_checker!=NULL && ui.cur_layer != last_item_checker->layer) reset_recognizer();

  it = undo->item;
  calc_inertia(it->path->coords, 0, it->path->num_points-1, &s);
#ifdef RECOGNIZER_DEBUG
  printf("DEBUG: Mass=%.0f, Center=(%.1f,%.1f), I=(%.0f,%.0f, %.0f), "
     "Rad=%.2f, Det=%.4f \n", 
     s.mass, center_x(s), center_y(s), I_xx(s), I_yy(s), I_xy(s), I_rad(s), I_det(s));
#endif

  // first see if it's a polygon
  n = find_polygonal(it->path->coords, 0, it->path->num_points-1, MAX_POLYGON_SIDES, brk, ss);
  if (n>0) {
    optimize_polygonal(it->path->coords, n, brk, ss);
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Polygon, %d edges: ", n);
    for (i=0; i<n; i++)
      printf("DEBUG: %d-%d (M=%.0f, det=%.4f) ", brk[i], brk[i+1], ss[i].mass, I_det(ss[i]));
    printf("\n");
#endif
    /* update recognizer segment queue (most recent at end) */
    while (n+recognizer_queue_length > MAX_POLYGON_SIDES) {
      // remove oldest polygonal stroke
      i=1;
      while (i<recognizer_queue_length && recognizer_queue[i].startpt!=0) i++;
      recognizer_queue_length-=i;
      g_memmove(recognizer_queue, recognizer_queue+i, 
              recognizer_queue_length * sizeof(struct RecoSegment));
    }
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Queue now has %d + %d edges\n", recognizer_queue_length, n);
#endif
    rs = recognizer_queue + recognizer_queue_length;
    recognizer_queue_length += n;
    for (i=0; i<n; i++) {
      rs[i].item = it;
      rs[i].startpt = brk[i];
      rs[i].endpt = brk[i+1];
      get_segment_geometry(it->path->coords, brk[i], brk[i+1], ss+i, rs+i);
    }  
    if (try_rectangle()) { reset_recognizer(); return; }
    if (try_arrow()) { reset_recognizer(); return; }
    if (try_closed_polygon(3)) { reset_recognizer(); return; }
    if (try_closed_polygon(4)) { reset_recognizer(); return; }
    if (n==1) { // current stroke is a line
      if (fabs(rs->angle)<SLANT_TOLERANCE) { // nearly horizontal
        rs->angle = 0.;
        rs->y1 = rs->y2 = rs->ycenter;
      }
      if (fabs(rs->angle)>M_PI/2-SLANT_TOLERANCE) { // nearly vertical
        rs->angle = (rs->angle>0)?(M_PI/2):(-M_PI/2);
        rs->x1 = rs->x2 = rs->xcenter;
      }
      realloc_cur_path(2);
      ui.cur_path.num_points = 2;
      ui.cur_path.coords[0] = rs->x1;
      ui.cur_path.coords[1] = rs->y1;
      ui.cur_path.coords[2] = rs->x2;
      ui.cur_path.coords[3] = rs->y2;
      remove_recognized_strokes(rs, 1);
      rs->item = insert_recognized_curpath();
    }
    last_item_checker = undo;
    return;
  }

  // not a polygon: maybe a circle ?
  reset_recognizer();
  if (I_det(s)>CIRCLE_MIN_DET) {
    score = score_circle(it->path->coords, 0, it->path->num_points-1, &s);
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Circle score: %.2f\n", score);
#endif
    if (score < CIRCLE_MAX_SCORE) {
      make_circle_shape(center_x(s), center_y(s), I_rad(s));
      recognizer_queue[0].item = it;
      remove_recognized_strokes(recognizer_queue, 1);
      insert_recognized_curpath();
    }
  }
}