Пример #1
0
static VALUE
rg_surrounding(VALUE self)
{
    gchar* text;
    gint cursor_index;
    gboolean result = gtk_im_context_get_surrounding(_SELF(self),
                                                     &text, &cursor_index);
    return result ? rb_ary_new3(2, CSTR2RVAL(text), INT2NUM(cursor_index)) : Qnil;
}
boolean scim_bridge_client_imcontext_get_surrounding_text (ScimBridgeClientIMContext *imcontext, int before_max, int after_max, char **string, int *cursor_position)
{
    char *str;
    int cur_pos_in_utf8;

    if (gtk_im_context_get_surrounding (GTK_IM_CONTEXT (imcontext), &str, &cur_pos_in_utf8)) {
        const size_t fetch_wstr_length = g_utf8_strlen (str, -1);
        const size_t after_wstr_length = g_utf8_strlen (str + cur_pos_in_utf8, -1);
        const size_t before_wstr_length = fetch_wstr_length - after_wstr_length;

        size_t before_copy_wstr_length;
        size_t after_copy_wstr_length;
        if (after_wstr_length > after_max) {
            after_copy_wstr_length = after_max;
        } else {
            after_copy_wstr_length = after_wstr_length;
        }
        if (before_wstr_length > before_max) {
            before_copy_wstr_length = before_max;
        } else {
            before_copy_wstr_length = before_wstr_length;
        }

        const size_t begin_wstr_index = before_wstr_length - before_copy_wstr_length;
        const size_t end_wstr_index = fetch_wstr_length - (after_wstr_length - after_copy_wstr_length);

        char* begin_str_ptr = g_utf8_offset_to_pointer (str, begin_wstr_index);
        char* end_str_ptr = g_utf8_offset_to_pointer (str, end_wstr_index);
        size_t str_length = end_str_ptr - begin_str_ptr;

        *string = malloc (sizeof (char) * (str_length + 1));
        strncpy (*string, begin_str_ptr, str_length);
        (*string)[str_length] = '\0';
        *cursor_position = before_copy_wstr_length;

        g_free (str);
        return TRUE;
    } else {
        *string = NULL;

        return FALSE;
    }
}
Пример #3
0
int
im_uim_acquire_primary_text(IMUIMContext *uic, enum UTextOrigin origin,
			    int former_req_len, int latter_req_len,
			    char **former, char **latter)
{
  gchar *text, *former_start, *p;
  gint cursor_index, len, precedence_len, following_len;
  gboolean success;
  int offset, err = 0;

  /*
   * We may try a specific way for GtkTextView since
   * gtk_im_context_get_surrounding cannot get text with multiple lines.
   */
  if (GTK_IS_TEXT_VIEW(uic->widget))
    return acquire_text_in_gtk_text_view(GTK_TEXT_VIEW(uic->widget), origin,
					 former_req_len, latter_req_len,
					 former, latter);

  /* cursor_index is represented with byte index */
  success = gtk_im_context_get_surrounding(GTK_IM_CONTEXT(uic), &text,
					   &cursor_index);
  if (!success)
    return -1;

  len = strlen(text);
  precedence_len = g_utf8_strlen(text, cursor_index);
  following_len = g_utf8_strlen(text + cursor_index, strlen(text) -
				cursor_index);
  switch (origin) {
  case UTextOrigin_Cursor:
    offset = 0;
    if (former_req_len >= 0) {
      if (precedence_len > former_req_len)
        offset = precedence_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    *former = g_strndup(former_start, text - former_start + cursor_index);

    offset = 0;
    if (latter_req_len >= 0) {
      if (following_len > latter_req_len)
	offset = strlen(g_utf8_offset_to_pointer(text, precedence_len +
						 latter_req_len));
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	g_free(*former);
	return -1;
      }
    }
    *latter = g_strndup(text + cursor_index, len - cursor_index - offset);
    if (latter_req_len == UTextExtent_Line) {
      gchar *p = strchr(*latter, '\n');
      if (p)
	*p = '\0';
    }
    break;

  case UTextOrigin_Beginning:
    *former = NULL;

    offset = 0;
    if (latter_req_len >= 0) {
      if ((precedence_len + following_len) > latter_req_len)
	offset = text + len - g_utf8_offset_to_pointer(text, latter_req_len);
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    *latter = g_strndup(text, len - offset); 
    if (latter_req_len == UTextExtent_Line &&
	(p = strchr(*latter, '\n')))
      *p = '\0';
    break;

  case UTextOrigin_End:
    offset = 0;
    if (former_req_len >= 0) {
      if ((precedence_len + following_len) > former_req_len)
        offset = precedence_len + following_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    if (former_req_len == UTextExtent_Line &&
	(p = strrchr(former_start, '\n')))
      *former = g_strdup(p + 1);
    else
      *former = g_strndup(former_start, text + len - former_start);

    *latter = NULL;
    break;

  case UTextOrigin_Unspecified:
  default:
    err = -1;
    break;
  }
  g_free(text);

  return err;
}
Пример #4
0
static gboolean
sinhala_transliterated_filter_keypress(GtkIMContext *context,
                        GdkEventKey  *event)
{
	int c, c1, l1;
	guchar *u = NULL;
	gchar *text;
	gint cursor, has_surrounding;

	if (event->keyval == 0) return FALSE;

	if (event->type == GDK_KEY_RELEASE) {
		if (event->keyval == GDK_Shift_L) shift_l = 0;
		if (event->keyval == GDK_Shift_R) shift_r = 0;
		if (event->keyval == GDK_Control_L) ctrl_l = 0;
		if (event->keyval == GDK_Control_R) ctrl_r = 0;
		return FALSE;
	}

	if (event->keyval == GDK_Shift_L) {
		shift_l = 1;
		return FALSE;
	}
	if (event->keyval == GDK_Shift_R) {
		shift_r = 1;
		return FALSE;
	}
	if (event->keyval == GDK_Control_L) {
		ctrl_l = 1;
		return FALSE;
	}
	if (event->keyval == GDK_Control_R) {
		ctrl_r = 1;
		return FALSE;
	}

	if ((event->keyval == GDK_space) && (shift_l || shift_r)) {
		/* FIXME: add non breaking space */
		return TRUE;
	}

	if ((event->keyval == GDK_space) && (ctrl_l || ctrl_r)) {
		sinhala_input = !sinhala_input;
		return TRUE;
	}

	if (event->state & (gtk_accelerator_get_default_mod_mask() & ~GDK_SHIFT_MASK))
		return FALSE;

	if (!sinhala_input && (event->keyval < 128)) {
		u = malloc(2);
		u[0] = event->keyval;
		u[1] = 0;

		g_signal_emit_by_name (context, "commit", u);

		free(u);
		return TRUE;
	}

	has_surrounding = gtk_im_context_get_surrounding(context, &text, &cursor);
	c = find_consonent_by_key(event->keyval);

	if (c >= 0) { /* a consonent is pressed. */

		/* do modifiers first. */
		if (has_surrounding && (cursor >= 3)) {
			c1 = get_known_lsb_character(text + cursor - 3);
			l1 = find_consonent(c1);
			/* do modifiers only if there is a valid character before */
			if (l1 >= 0) {
				if (event->keyval == GDK_w) {
					u = create_unicode_character_from_lsb(0xca);
					g_signal_emit_by_name (context, "commit", u);
					free(u);
					free(text);
					return TRUE;
				}
				if (event->keyval == GDK_W) {
					/* bandi hal kireema */
					u = malloc(7);
					u[0] = 0xe0; u[1] = 0xb7; u[2] = 0x8a;
					u[3] = 0xe2; u[4] = 0x80; u[5] = 0x8d;
					u[6] = 0;

					g_signal_emit_by_name (context, "commit", u);

					free(u);
					free(text);
					return TRUE;
				}
				if ((event->keyval == GDK_H) && (consonents[l1].mahaprana)) {
					gtk_im_context_delete_surrounding(context, -1, 1);
					u = create_unicode_character_from_lsb(consonents[l1].mahaprana);
					g_signal_emit_by_name (context, "commit", u);
					free(u);
					free(text);
					return TRUE;
				}
				if ((event->keyval == GDK_G) && (consonents[l1].sagngnaka)) {
					gtk_im_context_delete_surrounding(context, -1, 1);
					u = create_unicode_character_from_lsb(consonents[l1].sagngnaka);
					g_signal_emit_by_name (context, "commit", u);
					free(u);
					free(text);
					return TRUE;
				}
				if (event->keyval == GDK_R) {
					/* rakaraanshaya */
					u = malloc(10);
					u[0] = 0xe0; u[1] = 0xb7; u[2] = 0x8a;
					u[3] = 0xe2; u[4] = 0x80; u[5] = 0x8d;
					u[6] = 0xe0; u[7] = 0xb6; u[8] = 0xbb;
					u[9] = 0;

					g_signal_emit_by_name (context, "commit", u);

					free(u);
					free(text);
					return TRUE;
				}
				if (event->keyval == GDK_Y) {
					/* yansaya */
					u = malloc(10);
					u[0] = 0xe0; u[1] = 0xb7; u[2] = 0x8a;
					u[3] = 0xe2; u[4] = 0x80; u[5] = 0x8d;
					u[6] = 0xe0; u[7] = 0xb6; u[8] = 0xba;
					u[9] = 0;

					g_signal_emit_by_name (context, "commit", u);

					free(u);
					free(text);
					return TRUE;
				}
			}
		}

		u = create_unicode_character_from_lsb(consonents[c].character);
         	g_signal_emit_by_name (context, "commit", u);
		free(u);
		if (has_surrounding) free(text);
		return TRUE;
		/* end of consonent handling. */
	}

	c = find_vowel_by_key(event->keyval);
	if (c >= 0) {
		/* a vowel is pressed. */

		/* look for a previous character first. */
		u = NULL;
		if (has_surrounding && (cursor >= 3)) {
			c1 = get_known_lsb_character(text + cursor - 3);
			if (is_consonent(c1)) {
				u = create_unicode_character_from_lsb(vowels[c].single1);
			}
			else if (c1 == vowels[c].single0) {
				gtk_im_context_delete_surrounding(context, -1, 1);
				u = create_unicode_character_from_lsb(vowels[c].double0);
			}
			else if (c1 == vowels[c].single1) {
				gtk_im_context_delete_surrounding(context, -1, 1);
				u = create_unicode_character_from_lsb(vowels[c].double1);
			}
		}

		if (u == NULL)
			u = create_unicode_character_from_lsb(vowels[c].single0);

		g_signal_emit_by_name (context, "commit", u);

		free(u);
		if (has_surrounding) free(text);
		return TRUE;
		/* end of vowel handling. */
	}
	if (event->keyval < 128) {
		u = malloc(2);
		u[0] = event->keyval;
		u[1] = 0;
		g_signal_emit_by_name (context, "commit", u);
		free(u);
		if (has_surrounding) free(text);
		return TRUE;
	}
	if (event->keyval == GDK_BackSpace) {
	    gtk_im_context_delete_surrounding(context, -1, 1);
	    if (has_surrounding) free(text);
	    return TRUE;
	}
	if (has_surrounding) free(text);

	return FALSE;
}