--- scim-bridge-0.4.5/agent/scim-bridge-agent-imcontext.cpp.1-underline 2006-09-10 16:02:01.000000000 +1000 +++ scim-bridge-0.4.5/agent/scim-bridge-agent-imcontext.cpp 2006-10-19 13:15:08.000000000 +1000 @@ -646,8 +646,8 @@ ScimBridgeAgentIMContext *focused_imcontext = static_cast<ScimBridgeAgentIMContext*> (get_imengine ()->get_frontend_data ()); get_imengine ()->set_frontend_data (static_cast<ScimBridgeAgentIMContext*> (this)); - hide_preedit (); + hide_preedit (); get_imengine ()->focus_out (); if (imengine_shared) shared_imengine->reset (); panel_listener->turn_off (); --- scim-bridge-0.4.5/client-gtk/scim-bridge-client-imcontext-gtk.c.1-underline 2006-10-19 13:15:07.000000000 +1000 +++ scim-bridge-0.4.5/client-gtk/scim-bridge-client-imcontext-gtk.c 2006-10-19 13:15:08.000000000 +1000 @@ -636,6 +636,7 @@ if (scim_bridge_client_is_messenger_opened () && imcontext != NULL && imcontext->preedit_shown) { const size_t preedit_string_length = strlen (imcontext->preedit_string); + const size_t preedit_wstring_length = g_utf8_strlen (imcontext->preedit_string, -1); if (str) { if (preedit_string_length > 0) { @@ -645,9 +646,8 @@ } } if (cursor_pos) { - const size_t preedit_length = g_utf8_strlen (imcontext->preedit_string, -1); - if (imcontext->preedit_cursor_position > preedit_length) { - *cursor_pos = preedit_length; + if (imcontext->preedit_cursor_position > preedit_wstring_length) { + *cursor_pos = preedit_wstring_length; } else { *cursor_pos = imcontext->preedit_cursor_position; } @@ -656,28 +656,36 @@ if (pango_attrs) { *pango_attrs = pango_attr_list_new (); - gboolean underline_exists = FALSE; - + boolean *has_attribute = alloca (sizeof (boolean) * preedit_string_length); int i; + for (i = 0; i < preedit_string_length; ++i) { + has_attribute[i] = FALSE; + } + for (i = 0; i < imcontext->preedit_attribute_count; ++i) { const ScimBridgeAttribute *attr = imcontext->preedit_attributes[i]; const int begin_pos = scim_bridge_attribute_get_begin (attr); const int end_pos = scim_bridge_attribute_get_end (attr); - const int start_index = g_utf8_offset_to_pointer (imcontext->preedit_string, begin_pos) - imcontext->preedit_string; - const int end_index = g_utf8_offset_to_pointer (imcontext->preedit_string, end_pos) - imcontext->preedit_string; + if (begin_pos <= end_pos && 0 <= begin_pos && end_pos <= preedit_wstring_length) { + const int start_index = g_utf8_offset_to_pointer (imcontext->preedit_string, begin_pos) - imcontext->preedit_string; + const int end_index = g_utf8_offset_to_pointer (imcontext->preedit_string, end_pos) - imcontext->preedit_string; - if (start_index <= end_index && 0 <= start_index && end_index <= preedit_string_length) { const scim_bridge_attribute_type_t attr_type = scim_bridge_attribute_get_type (attr); const scim_bridge_attribute_value_t attr_value = scim_bridge_attribute_get_value (attr); + + boolean valid_attribute = FALSE; if (attr_type == ATTRIBUTE_DECORATE) { if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_UNDERLINE) { + valid_attribute = TRUE; + PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); pango_attr->start_index = start_index; pango_attr->end_index = end_index; pango_attr_list_insert (*pango_attrs, pango_attr); - underline_exists = TRUE; } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_REVERSE) { + valid_attribute = TRUE; + PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_normal_background.red, preedit_normal_background.green, preedit_normal_background.blue); pango_attr0->start_index = start_index; pango_attr0->end_index = end_index; @@ -688,6 +696,8 @@ pango_attr1->end_index = end_index; pango_attr_list_insert (*pango_attrs, pango_attr1); } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_HIGHLIGHT) { + valid_attribute = TRUE; + PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_active_foreground.red, preedit_active_foreground.green, preedit_active_foreground.blue); pango_attr0->start_index = start_index; pango_attr0->end_index = end_index; @@ -701,6 +711,8 @@ scim_bridge_perrorln ("Unknown preedit decoration!"); } } else if (attr_type == ATTRIBUTE_FOREGROUND) { + valid_attribute = TRUE; + const unsigned int red = scim_bridge_attribute_get_red (attr) * 256; const unsigned int green = scim_bridge_attribute_get_green (attr) * 256; const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256; @@ -710,6 +722,8 @@ pango_attr->end_index = end_index; pango_attr_list_insert (*pango_attrs, pango_attr); } else if (attr_type == ATTRIBUTE_BACKGROUND) { + valid_attribute = TRUE; + const unsigned int red = scim_bridge_attribute_get_red (attr) * 256; const unsigned int green = scim_bridge_attribute_get_green (attr) * 256; const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256; @@ -719,15 +733,26 @@ pango_attr->end_index = end_index; pango_attr_list_insert (*pango_attrs, pango_attr); } + + if (valid_attribute) { + int j; + for (j = start_index; j < end_index; ++j) { + has_attribute[j] = TRUE; + } + } } } - /* If there is no underline at all, then draw underline under the whole preedit string.*/ - if (!underline_exists) { - PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); - pango_attr->start_index = 0; - pango_attr->end_index = preedit_string_length; - pango_attr_list_insert (*pango_attrs, pango_attr); + + // Add underlines for the all characters without attributes. + for (i = 0; i < preedit_string_length; ++i) { + if (has_attribute[i] == FALSE) { + PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); + pango_attr->start_index = i; + for (; i < preedit_string_length && has_attribute[i] == FALSE; ++i); + pango_attr->end_index = i; + pango_attr_list_insert (*pango_attrs, pango_attr); + } } } } else { --- scim-bridge-0.4.5/client-common/scim-bridge-client.c.1-underline 2006-10-19 13:15:07.000000000 +1000 +++ scim-bridge-0.4.5/client-common/scim-bridge-client.c 2006-10-19 13:38:38.000000000 +1000 @@ -196,6 +196,14 @@ static retval_t received_message_focus_changed (const ScimBridgeMessage *message) { + const char *header = scim_bridge_message_get_header (message); + + if (pending_response.status == RESPONSE_PENDING && strcmp (pending_response.header, header) == 0) { + pending_response.status = RESPONSE_SUCCEEDED; + } else { + scim_bridge_perrorln ("The message is recieved in a wrong context: %s", header); + } + return RETVAL_SUCCEEDED; } @@ -1636,6 +1644,11 @@ return RETVAL_FAILED; } + if (pending_response.status != RESPONSE_DONE) { + scim_bridge_perrorln ("Another command is pending..."); + return RETVAL_FAILED; + } + scim_bridge_pdebugln (5, "Sending 'change_focus' message: ic_id = %d, focus_in = %s", id, focus_in ? "true":"false"); ScimBridgeMessage *message = scim_bridge_alloc_message (SCIM_BRIDGE_MESSAGE_CHANGE_FOCUS, 2); @@ -1651,6 +1664,10 @@ free (ic_id_str); free (focus_in_str); + pending_response.header = SCIM_BRIDGE_MESSAGE_FOCUS_CHANGED; + pending_response.consumed = FALSE; + pending_response.status = RESPONSE_PENDING; + scim_bridge_messenger_push_message (messenger, message); scim_bridge_free_message (message); @@ -1662,10 +1679,26 @@ } } - scim_bridge_pdebugln (6, "the focus changed: id = %d", id); - pending_response.header = NULL; - pending_response.status = RESPONSE_DONE; - return RETVAL_SUCCEEDED; + while (pending_response.status == RESPONSE_PENDING) { + if (scim_bridge_client_read_and_dispatch ()) { + scim_bridge_perrorln ("An IOException at scim_bridge_client_change_focus ()"); + pending_response.header = NULL; + pending_response.status = RESPONSE_DONE; + return RETVAL_FAILED; + } + } + + if (pending_response.status == RESPONSE_SUCCEEDED) { + scim_bridge_pdebugln (6, "The focus changed: id = %d", id); + pending_response.header = NULL; + pending_response.status = RESPONSE_DONE; + return RETVAL_SUCCEEDED; + } else { + scim_bridge_perrorln ("An unknown error occurred at scim_bridge_client_change_focus ()"); + pending_response.header = NULL; + pending_response.status = RESPONSE_DONE; + return RETVAL_FAILED; + } }