Mercurial > vim
comparison src/mbyte.c @ 2275:e4d849f4df03 vim73
Remove the old and not well supported GTK 1 code. (James Vega)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Fri, 25 Jun 2010 05:37:59 +0200 |
parents | 1bac28a53fae |
children | f42e0b5ff9e9 |
comparison
equal
deleted
inserted
replaced
2274:7c31d761ffa9 | 2275:e4d849f4df03 |
---|---|
98 #endif | 98 #endif |
99 #ifdef X_LOCALE | 99 #ifdef X_LOCALE |
100 #include <X11/Xlocale.h> | 100 #include <X11/Xlocale.h> |
101 #endif | 101 #endif |
102 | 102 |
103 #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) && defined(HAVE_GTK2) | 103 #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) |
104 # include <gdk/gdkkeysyms.h> | 104 # include <gdk/gdkkeysyms.h> |
105 # ifdef WIN3264 | 105 # ifdef WIN3264 |
106 # include <gdk/gdkwin32.h> | 106 # include <gdk/gdkwin32.h> |
107 # else | 107 # else |
108 # include <gdk/gdkx.h> | 108 # include <gdk/gdkx.h> |
5066 #ifdef FEAT_GUI_X11 | 5066 #ifdef FEAT_GUI_X11 |
5067 static XIMStyle input_style; | 5067 static XIMStyle input_style; |
5068 static int status_area_enabled = TRUE; | 5068 static int status_area_enabled = TRUE; |
5069 #endif | 5069 #endif |
5070 | 5070 |
5071 #ifdef FEAT_GUI_GTK | |
5072 # ifdef WIN3264 | |
5073 # include <gdk/gdkwin32.h> | |
5074 # else | |
5075 # include <gdk/gdkx.h> | |
5076 # endif | |
5077 #else | |
5078 # ifdef PROTO | |
5079 /* Define a few things to be able to generate prototypes while not configured | |
5080 * for GTK. */ | |
5081 # define GSList int | |
5082 # define gboolean int | |
5083 typedef int GdkEvent; | |
5084 typedef int GdkEventKey; | |
5085 # define GdkIC int | |
5086 # endif | |
5087 #endif | |
5088 | |
5089 #if defined(FEAT_GUI_GTK) || defined(PROTO) | |
5090 static int preedit_buf_len = 0; | |
5091 static int xim_can_preediting INIT(= FALSE); /* XIM in showmode() */ | |
5092 static int xim_input_style; | |
5093 #ifndef FEAT_GUI_GTK | |
5094 # define gboolean int | |
5095 #endif | |
5096 static gboolean use_status_area = 0; | |
5097 | |
5098 static int im_xim_str2keycode __ARGS((unsigned int *code, unsigned int *state)); | |
5099 static void im_xim_send_event_imactivate __ARGS((void)); | |
5100 | |
5101 /* | |
5102 * Convert string to keycode and state for XKeyEvent. | |
5103 * When string is valid return OK, when invalid return FAIL. | |
5104 * | |
5105 * See 'imactivatekey' documentation for the format. | |
5106 */ | |
5107 static int | |
5108 im_xim_str2keycode(code, state) | |
5109 unsigned int *code; | |
5110 unsigned int *state; | |
5111 { | |
5112 int retval = OK; | |
5113 int len; | |
5114 unsigned keycode = 0, keystate = 0; | |
5115 Window window; | |
5116 Display *display; | |
5117 char_u *flag_end; | |
5118 char_u *str; | |
5119 | |
5120 if (*p_imak != NUL) | |
5121 { | |
5122 len = STRLEN(p_imak); | |
5123 for (flag_end = p_imak + len - 1; | |
5124 flag_end > p_imak && *flag_end != '-'; --flag_end) | |
5125 ; | |
5126 | |
5127 /* Parse modifier keys */ | |
5128 for (str = p_imak; str < flag_end; ++str) | |
5129 { | |
5130 switch (*str) | |
5131 { | |
5132 case 's': case 'S': | |
5133 keystate |= ShiftMask; | |
5134 break; | |
5135 case 'l': case 'L': | |
5136 keystate |= LockMask; | |
5137 break; | |
5138 case 'c': case 'C': | |
5139 keystate |= ControlMask; | |
5140 break; | |
5141 case '1': | |
5142 keystate |= Mod1Mask; | |
5143 break; | |
5144 case '2': | |
5145 keystate |= Mod2Mask; | |
5146 break; | |
5147 case '3': | |
5148 keystate |= Mod3Mask; | |
5149 break; | |
5150 case '4': | |
5151 keystate |= Mod4Mask; | |
5152 break; | |
5153 case '5': | |
5154 keystate |= Mod5Mask; | |
5155 break; | |
5156 case '-': | |
5157 break; | |
5158 default: | |
5159 retval = FAIL; | |
5160 } | |
5161 } | |
5162 if (*str == '-') | |
5163 ++str; | |
5164 | |
5165 /* Get keycode from string. */ | |
5166 gui_get_x11_windis(&window, &display); | |
5167 if (display) | |
5168 keycode = XKeysymToKeycode(display, XStringToKeysym((char *)str)); | |
5169 if (keycode == 0) | |
5170 retval = FAIL; | |
5171 | |
5172 if (code != NULL) | |
5173 *code = keycode; | |
5174 if (state != NULL) | |
5175 *state = keystate; | |
5176 } | |
5177 return retval; | |
5178 } | |
5179 | |
5180 static void | |
5181 im_xim_send_event_imactivate() | |
5182 { | |
5183 /* Force turn on preedit state by simulating keypress event. | |
5184 * Keycode and state is specified by 'imactivatekey'. | |
5185 */ | |
5186 XKeyEvent ev; | |
5187 | |
5188 gui_get_x11_windis(&ev.window, &ev.display); | |
5189 ev.root = RootWindow(ev.display, DefaultScreen(ev.display)); | |
5190 ev.subwindow = None; | |
5191 ev.time = CurrentTime; | |
5192 ev.x = 1; | |
5193 ev.y = 1; | |
5194 ev.x_root = 1; | |
5195 ev.y_root = 1; | |
5196 ev.same_screen = 1; | |
5197 ev.type = KeyPress; | |
5198 if (im_xim_str2keycode(&ev.keycode, &ev.state) == OK) | |
5199 XSendEvent(ev.display, ev.window, 1, KeyPressMask, (XEvent*)&ev); | |
5200 } | |
5201 | |
5202 /* | |
5203 * Return TRUE if 'imactivatekey' has a valid value. | |
5204 */ | |
5205 int | |
5206 im_xim_isvalid_imactivate() | |
5207 { | |
5208 return im_xim_str2keycode(NULL, NULL) == OK; | |
5209 } | |
5210 #endif /* FEAT_GUI_GTK */ | |
5211 | |
5212 /* | 5071 /* |
5213 * Switch using XIM on/off. This is used by the code that changes "State". | 5072 * Switch using XIM on/off. This is used by the code that changes "State". |
5214 */ | 5073 */ |
5215 void | 5074 void |
5216 im_set_active(active) | 5075 im_set_active(active) |
5230 active = TRUE; | 5089 active = TRUE; |
5231 #endif | 5090 #endif |
5232 | 5091 |
5233 /* Remember the active state, it is needed when Vim gets keyboard focus. */ | 5092 /* Remember the active state, it is needed when Vim gets keyboard focus. */ |
5234 xim_is_active = active; | 5093 xim_is_active = active; |
5235 | |
5236 #ifdef FEAT_GUI_GTK | |
5237 /* When 'imactivatekey' has valid key-string, try to control XIM preedit | |
5238 * state. When 'imactivatekey' has no or invalid string, try old XIM | |
5239 * focus control. | |
5240 */ | |
5241 if (*p_imak != NUL) | |
5242 { | |
5243 /* BASIC STRATEGY: | |
5244 * Destroy old Input Context (XIC), and create new one. New XIC | |
5245 * would have a state of preedit that is off. When argument:active | |
5246 * is false, that's all. Else argument:active is true, send a key | |
5247 * event specified by 'imactivatekey' to activate XIM preedit state. | |
5248 */ | |
5249 | |
5250 xim_is_active = TRUE; /* Disable old XIM focus control */ | |
5251 /* If we can monitor preedit state with preedit callback functions, | |
5252 * try least creation of new XIC. | |
5253 */ | |
5254 if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS) | |
5255 { | |
5256 if (xim_can_preediting && !active) | |
5257 { | |
5258 /* Force turn off preedit state. With some IM | |
5259 * implementations, we cannot turn off preedit state by | |
5260 * simulating keypress event. It is why using such a method | |
5261 * that destroy old IC (input context), and create new one. | |
5262 * When create new IC, its preedit state is usually off. | |
5263 */ | |
5264 xim_reset(); | |
5265 xim_set_focus(FALSE); | |
5266 gdk_ic_destroy(xic); | |
5267 xim_init(); | |
5268 xim_can_preediting = FALSE; | |
5269 } | |
5270 else if (!xim_can_preediting && active) | |
5271 im_xim_send_event_imactivate(); | |
5272 } | |
5273 else | |
5274 { | |
5275 /* First, force destroy old IC, and create new one. It | |
5276 * simulates "turning off preedit state". | |
5277 */ | |
5278 xim_set_focus(FALSE); | |
5279 gdk_ic_destroy(xic); | |
5280 xim_init(); | |
5281 xim_can_preediting = FALSE; | |
5282 | |
5283 /* 2nd, when requested to activate IM, simulate this by sending | |
5284 * the event. | |
5285 */ | |
5286 if (active) | |
5287 { | |
5288 im_xim_send_event_imactivate(); | |
5289 xim_can_preediting = TRUE; | |
5290 } | |
5291 } | |
5292 } | |
5293 else | |
5294 { | |
5295 # ifndef XIMPreeditUnKnown | |
5296 /* X11R5 doesn't have these, it looks safe enough to define here. */ | |
5297 typedef unsigned long XIMPreeditState; | |
5298 # define XIMPreeditUnKnown 0L | |
5299 # define XIMPreeditEnable 1L | |
5300 # define XIMPreeditDisable (1L<<1) | |
5301 # define XNPreeditState "preeditState" | |
5302 # endif | |
5303 XIMPreeditState preedit_state = XIMPreeditUnKnown; | |
5304 XVaNestedList preedit_attr; | |
5305 XIC pxic; | |
5306 | |
5307 preedit_attr = XVaCreateNestedList(0, | |
5308 XNPreeditState, &preedit_state, | |
5309 NULL); | |
5310 pxic = ((GdkICPrivate *)xic)->xic; | |
5311 | |
5312 if (!XGetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL)) | |
5313 { | |
5314 XFree(preedit_attr); | |
5315 preedit_attr = XVaCreateNestedList(0, | |
5316 XNPreeditState, | |
5317 active ? XIMPreeditEnable : XIMPreeditDisable, | |
5318 NULL); | |
5319 XSetICValues(pxic, XNPreeditAttributes, preedit_attr, NULL); | |
5320 xim_can_preediting = active; | |
5321 xim_is_active = active; | |
5322 } | |
5323 XFree(preedit_attr); | |
5324 } | |
5325 if (xim_input_style & XIMPreeditCallbacks) | |
5326 { | |
5327 preedit_buf_len = 0; | |
5328 init_preedit_start_col(); | |
5329 } | |
5330 #else | |
5331 # if 0 | |
5332 /* When had tested kinput2 + canna + Athena GUI version with | |
5333 * 'imactivatekey' is "s-space", im_xim_send_event_imactivate() did not | |
5334 * work correctly. It just inserted one space. I don't know why we | |
5335 * couldn't switch state of XIM preediting. This is reason why these | |
5336 * codes are commented out. | |
5337 */ | |
5338 /* First, force destroy old IC, and create new one. It simulates | |
5339 * "turning off preedit state". | |
5340 */ | |
5341 xim_set_focus(FALSE); | |
5342 XDestroyIC(xic); | |
5343 xic = NULL; | |
5344 xim_init(); | |
5345 | |
5346 /* 2nd, when requested to activate IM, simulate this by sending the | |
5347 * event. | |
5348 */ | |
5349 if (active) | |
5350 im_xim_send_event_imactivate(); | |
5351 # endif | |
5352 #endif | |
5353 xim_set_preedit(); | 5094 xim_set_preedit(); |
5354 } | 5095 } |
5355 | 5096 |
5356 /* | 5097 /* |
5357 * Adjust using XIM for gaining or losing keyboard focus. Also called when | 5098 * Adjust using XIM for gaining or losing keyboard focus. Also called when |
5371 if (focus && xim_is_active) | 5112 if (focus && xim_is_active) |
5372 { | 5113 { |
5373 if (!xim_has_focus) | 5114 if (!xim_has_focus) |
5374 { | 5115 { |
5375 xim_has_focus = TRUE; | 5116 xim_has_focus = TRUE; |
5376 #ifdef FEAT_GUI_GTK | |
5377 gdk_im_begin(xic, gui.drawarea->window); | |
5378 #else | |
5379 XSetICFocus(xic); | 5117 XSetICFocus(xic); |
5380 #endif | |
5381 } | 5118 } |
5382 } | 5119 } |
5383 else | 5120 else |
5384 { | 5121 { |
5385 if (xim_has_focus) | 5122 if (xim_has_focus) |
5386 { | 5123 { |
5387 xim_has_focus = FALSE; | 5124 xim_has_focus = FALSE; |
5388 #ifdef FEAT_GUI_GTK | |
5389 gdk_im_end(); | |
5390 #else | |
5391 XUnsetICFocus(xic); | 5125 XUnsetICFocus(xic); |
5392 #endif | |
5393 } | 5126 } |
5394 } | 5127 } |
5395 } | 5128 } |
5396 | 5129 |
5397 void | 5130 void |
5411 if (xic == NULL) | 5144 if (xic == NULL) |
5412 return; | 5145 return; |
5413 | 5146 |
5414 xim_set_focus(TRUE); | 5147 xim_set_focus(TRUE); |
5415 | 5148 |
5416 #ifdef FEAT_GUI_GTK | 5149 XVaNestedList attr_list; |
5417 if (gdk_im_ready()) | 5150 XRectangle spot_area; |
5418 { | 5151 XPoint over_spot; |
5419 int attrmask; | 5152 int line_space; |
5420 GdkICAttr *attr; | 5153 |
5421 | 5154 if (!xim_has_focus) |
5422 if (!xic_attr) | 5155 { |
5423 return; | 5156 /* hide XIM cursor */ |
5424 | 5157 over_spot.x = 0; |
5425 attr = xic_attr; | 5158 over_spot.y = -100; /* arbitrary invisible position */ |
5426 attrmask = 0; | 5159 attr_list = (XVaNestedList) XVaCreateNestedList(0, |
5427 | 5160 XNSpotLocation, |
5428 # ifdef FEAT_XFONTSET | 5161 &over_spot, |
5429 if ((xim_input_style & (int)GDK_IM_PREEDIT_POSITION) | 5162 NULL); |
5430 && gui.fontset != NOFONTSET | 5163 XSetICValues(xic, XNPreeditAttributes, attr_list, NULL); |
5431 && gui.fontset->type == GDK_FONT_FONTSET) | 5164 XFree(attr_list); |
5432 { | 5165 return; |
5433 if (!xim_has_focus) | 5166 } |
5434 { | 5167 |
5435 if (attr->spot_location.y >= 0) | 5168 if (input_style & XIMPreeditPosition) |
5436 { | 5169 { |
5437 attr->spot_location.x = 0; | |
5438 attr->spot_location.y = -100; | |
5439 attrmask |= (int)GDK_IC_SPOT_LOCATION; | |
5440 } | |
5441 } | |
5442 else | |
5443 { | |
5444 gint width, height; | |
5445 | |
5446 if (attr->spot_location.x != TEXT_X(gui.col) | |
5447 || attr->spot_location.y != TEXT_Y(gui.row)) | |
5448 { | |
5449 attr->spot_location.x = TEXT_X(gui.col); | |
5450 attr->spot_location.y = TEXT_Y(gui.row); | |
5451 attrmask |= (int)GDK_IC_SPOT_LOCATION; | |
5452 } | |
5453 | |
5454 gdk_window_get_size(gui.drawarea->window, &width, &height); | |
5455 width -= 2 * gui.border_offset; | |
5456 height -= 2 * gui.border_offset; | |
5457 if (xim_input_style & (int)GDK_IM_STATUS_AREA) | |
5458 height -= gui.char_height; | |
5459 if (attr->preedit_area.width != width | |
5460 || attr->preedit_area.height != height) | |
5461 { | |
5462 attr->preedit_area.x = gui.border_offset; | |
5463 attr->preedit_area.y = gui.border_offset; | |
5464 attr->preedit_area.width = width; | |
5465 attr->preedit_area.height = height; | |
5466 attrmask |= (int)GDK_IC_PREEDIT_AREA; | |
5467 } | |
5468 | |
5469 if (attr->preedit_fontset != gui.current_font) | |
5470 { | |
5471 attr->preedit_fontset = gui.current_font; | |
5472 attrmask |= (int)GDK_IC_PREEDIT_FONTSET; | |
5473 } | |
5474 } | |
5475 } | |
5476 # endif /* FEAT_XFONTSET */ | |
5477 | |
5478 if (xim_fg_color == INVALCOLOR) | 5170 if (xim_fg_color == INVALCOLOR) |
5479 { | 5171 { |
5480 xim_fg_color = gui.def_norm_pixel; | 5172 xim_fg_color = gui.def_norm_pixel; |
5481 xim_bg_color = gui.def_back_pixel; | 5173 xim_bg_color = gui.def_back_pixel; |
5482 } | 5174 } |
5483 if (attr->preedit_foreground.pixel != xim_fg_color) | 5175 over_spot.x = TEXT_X(gui.col); |
5484 { | 5176 over_spot.y = TEXT_Y(gui.row); |
5485 attr->preedit_foreground.pixel = xim_fg_color; | 5177 spot_area.x = 0; |
5486 attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND; | 5178 spot_area.y = 0; |
5487 } | 5179 spot_area.height = gui.char_height * Rows; |
5488 if (attr->preedit_background.pixel != xim_bg_color) | 5180 spot_area.width = gui.char_width * Columns; |
5489 { | 5181 line_space = gui.char_height; |
5490 attr->preedit_background.pixel = xim_bg_color; | 5182 attr_list = (XVaNestedList) XVaCreateNestedList(0, |
5491 attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND; | 5183 XNSpotLocation, &over_spot, |
5492 } | 5184 XNForeground, (Pixel) xim_fg_color, |
5493 | 5185 XNBackground, (Pixel) xim_bg_color, |
5494 if (attrmask != 0) | 5186 XNArea, &spot_area, |
5495 gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask); | 5187 XNLineSpace, line_space, |
5496 } | 5188 NULL); |
5497 #else /* FEAT_GUI_GTK */ | 5189 if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL)) |
5498 { | 5190 EMSG(_("E284: Cannot set IC values")); |
5499 XVaNestedList attr_list; | 5191 XFree(attr_list); |
5500 XRectangle spot_area; | 5192 } |
5501 XPoint over_spot; | |
5502 int line_space; | |
5503 | |
5504 if (!xim_has_focus) | |
5505 { | |
5506 /* hide XIM cursor */ | |
5507 over_spot.x = 0; | |
5508 over_spot.y = -100; /* arbitrary invisible position */ | |
5509 attr_list = (XVaNestedList) XVaCreateNestedList(0, | |
5510 XNSpotLocation, | |
5511 &over_spot, | |
5512 NULL); | |
5513 XSetICValues(xic, XNPreeditAttributes, attr_list, NULL); | |
5514 XFree(attr_list); | |
5515 return; | |
5516 } | |
5517 | |
5518 if (input_style & XIMPreeditPosition) | |
5519 { | |
5520 if (xim_fg_color == INVALCOLOR) | |
5521 { | |
5522 xim_fg_color = gui.def_norm_pixel; | |
5523 xim_bg_color = gui.def_back_pixel; | |
5524 } | |
5525 over_spot.x = TEXT_X(gui.col); | |
5526 over_spot.y = TEXT_Y(gui.row); | |
5527 spot_area.x = 0; | |
5528 spot_area.y = 0; | |
5529 spot_area.height = gui.char_height * Rows; | |
5530 spot_area.width = gui.char_width * Columns; | |
5531 line_space = gui.char_height; | |
5532 attr_list = (XVaNestedList) XVaCreateNestedList(0, | |
5533 XNSpotLocation, &over_spot, | |
5534 XNForeground, (Pixel) xim_fg_color, | |
5535 XNBackground, (Pixel) xim_bg_color, | |
5536 XNArea, &spot_area, | |
5537 XNLineSpace, line_space, | |
5538 NULL); | |
5539 if (XSetICValues(xic, XNPreeditAttributes, attr_list, NULL)) | |
5540 EMSG(_("E284: Cannot set IC values")); | |
5541 XFree(attr_list); | |
5542 } | |
5543 } | |
5544 #endif /* FEAT_GUI_GTK */ | |
5545 } | 5193 } |
5546 | 5194 |
5547 /* | 5195 /* |
5548 * Set up the status area. | 5196 * Set up the status area. |
5549 * | 5197 * |
5556 xim_set_status_area() | 5204 xim_set_status_area() |
5557 { | 5205 { |
5558 if (xic == NULL) | 5206 if (xic == NULL) |
5559 return; | 5207 return; |
5560 | 5208 |
5561 #ifdef FEAT_GUI_GTK | 5209 XVaNestedList preedit_list = 0, status_list = 0, list = 0; |
5562 # if defined(FEAT_XFONTSET) | 5210 XRectangle pre_area, status_area; |
5563 if (use_status_area) | 5211 |
5564 { | 5212 if (input_style & XIMStatusArea) |
5565 GdkICAttr *attr; | 5213 { |
5566 int style; | 5214 if (input_style & XIMPreeditArea) |
5567 gint width, height; | |
5568 GtkWidget *widget; | |
5569 int attrmask; | |
5570 | |
5571 if (!xic_attr) | |
5572 return; | |
5573 | |
5574 attr = xic_attr; | |
5575 attrmask = 0; | |
5576 style = (int)gdk_ic_get_style(xic); | |
5577 if ((style & (int)GDK_IM_STATUS_MASK) == (int)GDK_IM_STATUS_AREA) | |
5578 { | 5215 { |
5579 if (gui.fontset != NOFONTSET | 5216 XRectangle *needed_rect; |
5580 && gui.fontset->type == GDK_FONT_FONTSET) | 5217 |
5581 { | 5218 /* to get status_area width */ |
5582 widget = gui.mainwin; | 5219 status_list = XVaCreateNestedList(0, XNAreaNeeded, |
5583 gdk_window_get_size(widget->window, &width, &height); | 5220 &needed_rect, NULL); |
5584 | 5221 XGetICValues(xic, XNStatusAttributes, status_list, NULL); |
5585 attrmask |= (int)GDK_IC_STATUS_AREA; | 5222 XFree(status_list); |
5586 attr->status_area.x = 0; | 5223 |
5587 attr->status_area.y = height - gui.char_height - 1; | 5224 status_area.width = needed_rect->width; |
5588 attr->status_area.width = width; | |
5589 attr->status_area.height = gui.char_height; | |
5590 } | |
5591 } | |
5592 if (attrmask != 0) | |
5593 gdk_ic_set_attr(xic, attr, (GdkICAttributesType)attrmask); | |
5594 } | |
5595 # endif | |
5596 #else | |
5597 { | |
5598 XVaNestedList preedit_list = 0, status_list = 0, list = 0; | |
5599 XRectangle pre_area, status_area; | |
5600 | |
5601 if (input_style & XIMStatusArea) | |
5602 { | |
5603 if (input_style & XIMPreeditArea) | |
5604 { | |
5605 XRectangle *needed_rect; | |
5606 | |
5607 /* to get status_area width */ | |
5608 status_list = XVaCreateNestedList(0, XNAreaNeeded, | |
5609 &needed_rect, NULL); | |
5610 XGetICValues(xic, XNStatusAttributes, status_list, NULL); | |
5611 XFree(status_list); | |
5612 | |
5613 status_area.width = needed_rect->width; | |
5614 } | |
5615 else | |
5616 status_area.width = gui.char_width * Columns; | |
5617 | |
5618 status_area.x = 0; | |
5619 status_area.y = gui.char_height * Rows + gui.border_offset; | |
5620 if (gui.which_scrollbars[SBAR_BOTTOM]) | |
5621 status_area.y += gui.scrollbar_height; | |
5622 #ifdef FEAT_MENU | |
5623 if (gui.menu_is_active) | |
5624 status_area.y += gui.menu_height; | |
5625 #endif | |
5626 status_area.height = gui.char_height; | |
5627 status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL); | |
5628 } | 5225 } |
5629 else | 5226 else |
5630 { | 5227 status_area.width = gui.char_width * Columns; |
5631 status_area.x = 0; | 5228 |
5632 status_area.y = gui.char_height * Rows + gui.border_offset; | 5229 status_area.x = 0; |
5633 if (gui.which_scrollbars[SBAR_BOTTOM]) | 5230 status_area.y = gui.char_height * Rows + gui.border_offset; |
5634 status_area.y += gui.scrollbar_height; | 5231 if (gui.which_scrollbars[SBAR_BOTTOM]) |
5232 status_area.y += gui.scrollbar_height; | |
5635 #ifdef FEAT_MENU | 5233 #ifdef FEAT_MENU |
5636 if (gui.menu_is_active) | 5234 if (gui.menu_is_active) |
5637 status_area.y += gui.menu_height; | 5235 status_area.y += gui.menu_height; |
5638 #endif | 5236 #endif |
5639 status_area.width = 0; | 5237 status_area.height = gui.char_height; |
5640 status_area.height = gui.char_height; | 5238 status_list = XVaCreateNestedList(0, XNArea, &status_area, NULL); |
5641 } | 5239 } |
5642 | 5240 else |
5643 if (input_style & XIMPreeditArea) /* off-the-spot */ | 5241 { |
5644 { | 5242 status_area.x = 0; |
5645 pre_area.x = status_area.x + status_area.width; | 5243 status_area.y = gui.char_height * Rows + gui.border_offset; |
5646 pre_area.y = gui.char_height * Rows + gui.border_offset; | 5244 if (gui.which_scrollbars[SBAR_BOTTOM]) |
5647 pre_area.width = gui.char_width * Columns - pre_area.x; | 5245 status_area.y += gui.scrollbar_height; |
5648 if (gui.which_scrollbars[SBAR_BOTTOM]) | |
5649 pre_area.y += gui.scrollbar_height; | |
5650 #ifdef FEAT_MENU | 5246 #ifdef FEAT_MENU |
5651 if (gui.menu_is_active) | 5247 if (gui.menu_is_active) |
5652 pre_area.y += gui.menu_height; | 5248 status_area.y += gui.menu_height; |
5653 #endif | 5249 #endif |
5654 pre_area.height = gui.char_height; | 5250 status_area.width = 0; |
5655 preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL); | 5251 status_area.height = gui.char_height; |
5656 } | 5252 } |
5657 else if (input_style & XIMPreeditPosition) /* over-the-spot */ | 5253 |
5658 { | 5254 if (input_style & XIMPreeditArea) /* off-the-spot */ |
5659 pre_area.x = 0; | 5255 { |
5660 pre_area.y = 0; | 5256 pre_area.x = status_area.x + status_area.width; |
5661 pre_area.height = gui.char_height * Rows; | 5257 pre_area.y = gui.char_height * Rows + gui.border_offset; |
5662 pre_area.width = gui.char_width * Columns; | 5258 pre_area.width = gui.char_width * Columns - pre_area.x; |
5663 preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL); | 5259 if (gui.which_scrollbars[SBAR_BOTTOM]) |
5664 } | 5260 pre_area.y += gui.scrollbar_height; |
5665 | 5261 #ifdef FEAT_MENU |
5666 if (preedit_list && status_list) | 5262 if (gui.menu_is_active) |
5667 list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list, | 5263 pre_area.y += gui.menu_height; |
5668 XNStatusAttributes, status_list, NULL); | 5264 #endif |
5669 else if (preedit_list) | 5265 pre_area.height = gui.char_height; |
5670 list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list, | 5266 preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL); |
5671 NULL); | 5267 } |
5672 else if (status_list) | 5268 else if (input_style & XIMPreeditPosition) /* over-the-spot */ |
5673 list = XVaCreateNestedList(0, XNStatusAttributes, status_list, | 5269 { |
5674 NULL); | 5270 pre_area.x = 0; |
5675 else | 5271 pre_area.y = 0; |
5676 list = NULL; | 5272 pre_area.height = gui.char_height * Rows; |
5677 | 5273 pre_area.width = gui.char_width * Columns; |
5678 if (list) | 5274 preedit_list = XVaCreateNestedList(0, XNArea, &pre_area, NULL); |
5679 { | 5275 } |
5680 XSetICValues(xic, XNVaNestedList, list, NULL); | 5276 |
5681 XFree(list); | 5277 if (preedit_list && status_list) |
5682 } | 5278 list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list, |
5683 if (status_list) | 5279 XNStatusAttributes, status_list, NULL); |
5684 XFree(status_list); | 5280 else if (preedit_list) |
5685 if (preedit_list) | 5281 list = XVaCreateNestedList(0, XNPreeditAttributes, preedit_list, |
5686 XFree(preedit_list); | 5282 NULL); |
5687 } | 5283 else if (status_list) |
5688 #endif | 5284 list = XVaCreateNestedList(0, XNStatusAttributes, status_list, |
5689 } | 5285 NULL); |
5690 | 5286 else |
5691 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) | 5287 list = NULL; |
5288 | |
5289 if (list) | |
5290 { | |
5291 XSetICValues(xic, XNVaNestedList, list, NULL); | |
5292 XFree(list); | |
5293 } | |
5294 if (status_list) | |
5295 XFree(status_list); | |
5296 if (preedit_list) | |
5297 XFree(preedit_list); | |
5298 } | |
5299 | |
5300 #if defined(FEAT_GUI_X11) | |
5692 static char e_xim[] = N_("E285: Failed to create input context"); | 5301 static char e_xim[] = N_("E285: Failed to create input context"); |
5693 #endif | 5302 #endif |
5694 | 5303 |
5695 #if defined(FEAT_GUI_X11) || defined(PROTO) | 5304 #if defined(FEAT_GUI_X11) || defined(PROTO) |
5696 # if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(sun) | 5305 # if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(sun) |
5996 return TRUE; | 5605 return TRUE; |
5997 } | 5606 } |
5998 | 5607 |
5999 #endif /* FEAT_GUI_X11 */ | 5608 #endif /* FEAT_GUI_X11 */ |
6000 | 5609 |
6001 #if defined(FEAT_GUI_GTK) || defined(PROTO) | |
6002 | |
6003 # ifdef FEAT_XFONTSET | |
6004 static char e_overthespot[] = N_("E290: over-the-spot style requires fontset"); | |
6005 # endif | |
6006 | |
6007 # ifdef PROTO | |
6008 typedef int GdkIC; | |
6009 # endif | |
6010 | |
6011 void | |
6012 xim_decide_input_style() | |
6013 { | |
6014 /* GDK_IM_STATUS_CALLBACKS was disabled, enabled it to allow Japanese | |
6015 * OverTheSpot. */ | |
6016 int supported_style = (int)GDK_IM_PREEDIT_NONE | | |
6017 (int)GDK_IM_PREEDIT_NOTHING | | |
6018 (int)GDK_IM_PREEDIT_POSITION | | |
6019 (int)GDK_IM_PREEDIT_CALLBACKS | | |
6020 (int)GDK_IM_STATUS_CALLBACKS | | |
6021 (int)GDK_IM_STATUS_AREA | | |
6022 (int)GDK_IM_STATUS_NONE | | |
6023 (int)GDK_IM_STATUS_NOTHING; | |
6024 | |
6025 #ifdef XIM_DEBUG | |
6026 xim_log("xim_decide_input_style()\n"); | |
6027 #endif | |
6028 | |
6029 if (!gdk_im_ready()) | |
6030 xim_input_style = 0; | |
6031 else | |
6032 { | |
6033 if (gtk_major_version > 1 | |
6034 || (gtk_major_version == 1 | |
6035 && (gtk_minor_version > 2 | |
6036 || (gtk_minor_version == 2 && gtk_micro_version >= 3)))) | |
6037 use_status_area = TRUE; | |
6038 else | |
6039 { | |
6040 EMSG(_("E291: Your GTK+ is older than 1.2.3. Status area disabled")); | |
6041 use_status_area = FALSE; | |
6042 } | |
6043 #ifdef FEAT_XFONTSET | |
6044 if (gui.fontset == NOFONTSET || gui.fontset->type != GDK_FONT_FONTSET) | |
6045 #endif | |
6046 supported_style &= ~((int)GDK_IM_PREEDIT_POSITION | |
6047 | (int)GDK_IM_STATUS_AREA); | |
6048 if (!use_status_area) | |
6049 supported_style &= ~(int)GDK_IM_STATUS_AREA; | |
6050 xim_input_style = (int)gdk_im_decide_style((GdkIMStyle)supported_style); | |
6051 } | |
6052 } | |
6053 | |
6054 static void | |
6055 preedit_start_cbproc(XIC thexic UNUSED, | |
6056 XPointer client_data UNUSED, | |
6057 XPointer call_data UNUSED) | |
6058 { | |
6059 #ifdef XIM_DEBUG | |
6060 xim_log("xim_decide_input_style()\n"); | |
6061 #endif | |
6062 | |
6063 draw_feedback = NULL; | |
6064 xim_can_preediting = TRUE; | |
6065 xim_has_preediting = TRUE; | |
6066 gui_update_cursor(TRUE, FALSE); | |
6067 if (showmode() > 0) | |
6068 { | |
6069 setcursor(); | |
6070 out_flush(); | |
6071 } | |
6072 } | |
6073 | |
6074 static void | |
6075 xim_back_delete(int n) | |
6076 { | |
6077 char_u str[3]; | |
6078 | |
6079 str[0] = CSI; | |
6080 str[1] = 'k'; | |
6081 str[2] = 'b'; | |
6082 while (n-- > 0) | |
6083 add_to_input_buf(str, 3); | |
6084 } | |
6085 | |
6086 static GSList *key_press_event_queue = NULL; | |
6087 static gboolean processing_queued_event = FALSE; | |
6088 | |
6089 static void | |
6090 preedit_draw_cbproc(XIC thexic UNUSED, | |
6091 XPointer client_data UNUSED, | |
6092 XPointer call_data) | |
6093 { | |
6094 XIMPreeditDrawCallbackStruct *draw_data; | |
6095 XIMText *text; | |
6096 char *src; | |
6097 GSList *event_queue; | |
6098 | |
6099 #ifdef XIM_DEBUG | |
6100 xim_log("preedit_draw_cbproc()\n"); | |
6101 #endif | |
6102 | |
6103 draw_data = (XIMPreeditDrawCallbackStruct *) call_data; | |
6104 text = (XIMText *) draw_data->text; | |
6105 | |
6106 if ((text == NULL && draw_data->chg_length == preedit_buf_len) | |
6107 || preedit_buf_len == 0) | |
6108 { | |
6109 init_preedit_start_col(); | |
6110 vim_free(draw_feedback); | |
6111 draw_feedback = NULL; | |
6112 } | |
6113 if (draw_data->chg_length > 0) | |
6114 { | |
6115 int bs_cnt; | |
6116 | |
6117 if (draw_data->chg_length > preedit_buf_len) | |
6118 bs_cnt = preedit_buf_len; | |
6119 else | |
6120 bs_cnt = draw_data->chg_length; | |
6121 xim_back_delete(bs_cnt); | |
6122 preedit_buf_len -= bs_cnt; | |
6123 } | |
6124 if (text != NULL) | |
6125 { | |
6126 int len; | |
6127 #ifdef FEAT_MBYTE | |
6128 char_u *buf = NULL; | |
6129 unsigned int nfeedback = 0; | |
6130 #endif | |
6131 char_u *ptr; | |
6132 | |
6133 src = text->string.multi_byte; | |
6134 if (src != NULL && !text->encoding_is_wchar) | |
6135 { | |
6136 len = strlen(src); | |
6137 ptr = (char_u *)src; | |
6138 /* Avoid the enter for decision */ | |
6139 if (*ptr == '\n') | |
6140 return; | |
6141 | |
6142 #ifdef FEAT_MBYTE | |
6143 if (input_conv.vc_type != CONV_NONE | |
6144 && (buf = string_convert(&input_conv, | |
6145 (char_u *)src, &len)) != NULL) | |
6146 { | |
6147 /* Converted from 'termencoding' to 'encoding'. */ | |
6148 add_to_input_buf_csi(buf, len); | |
6149 ptr = buf; | |
6150 } | |
6151 else | |
6152 #endif | |
6153 add_to_input_buf_csi((char_u *)src, len); | |
6154 /* Add count of character to preedit_buf_len */ | |
6155 while (*ptr != NUL) | |
6156 { | |
6157 #ifdef FEAT_MBYTE | |
6158 if (draw_data->text->feedback != NULL) | |
6159 { | |
6160 if (draw_feedback == NULL) | |
6161 draw_feedback = (char *)alloc(draw_data->chg_first | |
6162 + text->length); | |
6163 else | |
6164 draw_feedback = vim_realloc(draw_feedback, | |
6165 draw_data->chg_first + text->length); | |
6166 if (draw_feedback != NULL) | |
6167 { | |
6168 draw_feedback[nfeedback + draw_data->chg_first] | |
6169 = draw_data->text->feedback[nfeedback]; | |
6170 nfeedback++; | |
6171 } | |
6172 } | |
6173 if (has_mbyte) | |
6174 ptr += (*mb_ptr2len)(ptr); | |
6175 else | |
6176 #endif | |
6177 ptr++; | |
6178 preedit_buf_len++; | |
6179 } | |
6180 #ifdef FEAT_MBYTE | |
6181 vim_free(buf); | |
6182 #endif | |
6183 preedit_end_col = MAXCOL; | |
6184 } | |
6185 } | |
6186 if (text != NULL || draw_data->chg_length > 0) | |
6187 { | |
6188 event_queue = key_press_event_queue; | |
6189 processing_queued_event = TRUE; | |
6190 while (event_queue != NULL && processing_queued_event) | |
6191 { | |
6192 GdkEvent *ev = event_queue->data; | |
6193 | |
6194 gboolean *ret; | |
6195 gtk_signal_emit_by_name((GtkObject*)gui.mainwin, "key_press_event", | |
6196 ev, &ret); | |
6197 gdk_event_free(ev); | |
6198 event_queue = event_queue->next; | |
6199 } | |
6200 processing_queued_event = FALSE; | |
6201 if (key_press_event_queue) | |
6202 { | |
6203 g_slist_free(key_press_event_queue); | |
6204 key_press_event_queue = NULL; | |
6205 } | |
6206 } | |
6207 if (gtk_main_level() > 0) | |
6208 gtk_main_quit(); | |
6209 } | |
6210 | |
6211 /* | |
6212 * Retrieve the highlighting attributes at column col in the preedit string. | |
6213 * Return -1 if not in preediting mode or if col is out of range. | |
6214 */ | |
6215 int | |
6216 im_get_feedback_attr(int col) | |
6217 { | |
6218 if (draw_feedback != NULL && col < preedit_buf_len) | |
6219 { | |
6220 if (draw_feedback[col] & XIMReverse) | |
6221 return HL_INVERSE; | |
6222 else if (draw_feedback[col] & XIMUnderline) | |
6223 return HL_UNDERLINE; | |
6224 else | |
6225 return hl_attr(HLF_V); | |
6226 } | |
6227 | |
6228 return -1; | |
6229 } | |
6230 | |
6231 static void | |
6232 preedit_caret_cbproc(XIC thexic UNUSED, | |
6233 XPointer client_data UNUSED, | |
6234 XPointer call_data UNUSED) | |
6235 { | |
6236 #ifdef XIM_DEBUG | |
6237 xim_log("preedit_caret_cbproc()\n"); | |
6238 #endif | |
6239 } | |
6240 | |
6241 static void | |
6242 preedit_done_cbproc(XIC thexic UNUSED, | |
6243 XPointer client_data UNUSED, | |
6244 XPointer call_data UNUSED) | |
6245 { | |
6246 #ifdef XIM_DEBUG | |
6247 xim_log("preedit_done_cbproc()\n"); | |
6248 #endif | |
6249 | |
6250 vim_free(draw_feedback); | |
6251 draw_feedback = NULL; | |
6252 xim_can_preediting = FALSE; | |
6253 xim_has_preediting = FALSE; | |
6254 gui_update_cursor(TRUE, FALSE); | |
6255 if (showmode() > 0) | |
6256 { | |
6257 setcursor(); | |
6258 out_flush(); | |
6259 } | |
6260 } | |
6261 | |
6262 void | |
6263 xim_reset(void) | |
6264 { | |
6265 char *text; | |
6266 | |
6267 #ifdef XIM_DEBUG | |
6268 xim_log("xim_reset()\n"); | |
6269 #endif | |
6270 | |
6271 if (xic != NULL) | |
6272 { | |
6273 text = XmbResetIC(((GdkICPrivate *)xic)->xic); | |
6274 if (text != NULL && !(xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)) | |
6275 add_to_input_buf_csi((char_u *)text, strlen(text)); | |
6276 else | |
6277 preedit_buf_len = 0; | |
6278 if (text != NULL) | |
6279 XFree(text); | |
6280 } | |
6281 } | |
6282 | |
6283 int | |
6284 xim_queue_key_press_event(GdkEventKey *event, int down UNUSED) | |
6285 { | |
6286 #ifdef XIM_DEBUG | |
6287 xim_log("xim_queue_key_press_event()\n"); | |
6288 #endif | |
6289 | |
6290 if (preedit_buf_len <= 0) | |
6291 return FALSE; | |
6292 if (processing_queued_event) | |
6293 processing_queued_event = FALSE; | |
6294 | |
6295 key_press_event_queue = g_slist_append(key_press_event_queue, | |
6296 gdk_event_copy((GdkEvent *)event)); | |
6297 return TRUE; | |
6298 } | |
6299 | |
6300 static void | |
6301 preedit_callback_setup(GdkIC *ic UNUSED) | |
6302 { | |
6303 XIC xxic; | |
6304 XVaNestedList preedit_attr; | |
6305 XIMCallback preedit_start_cb; | |
6306 XIMCallback preedit_draw_cb; | |
6307 XIMCallback preedit_caret_cb; | |
6308 XIMCallback preedit_done_cb; | |
6309 | |
6310 xxic = ((GdkICPrivate*)xic)->xic; | |
6311 preedit_start_cb.callback = (XIMProc)preedit_start_cbproc; | |
6312 preedit_draw_cb.callback = (XIMProc)preedit_draw_cbproc; | |
6313 preedit_caret_cb.callback = (XIMProc)preedit_caret_cbproc; | |
6314 preedit_done_cb.callback = (XIMProc)preedit_done_cbproc; | |
6315 preedit_attr | |
6316 = XVaCreateNestedList(0, | |
6317 XNPreeditStartCallback, &preedit_start_cb, | |
6318 XNPreeditDrawCallback, &preedit_draw_cb, | |
6319 XNPreeditCaretCallback, &preedit_caret_cb, | |
6320 XNPreeditDoneCallback, &preedit_done_cb, | |
6321 NULL); | |
6322 XSetICValues(xxic, XNPreeditAttributes, preedit_attr, NULL); | |
6323 XFree(preedit_attr); | |
6324 } | |
6325 | |
6326 static void | |
6327 reset_state_setup(GdkIC *ic UNUSED) | |
6328 { | |
6329 #ifdef USE_X11R6_XIM | |
6330 /* don't change the input context when we call reset */ | |
6331 XSetICValues(((GdkICPrivate *)ic)->xic, XNResetState, XIMPreserveState, | |
6332 NULL); | |
6333 #endif | |
6334 } | |
6335 | |
6336 void | |
6337 xim_init(void) | |
6338 { | |
6339 #ifdef XIM_DEBUG | |
6340 xim_log("xim_init()\n"); | |
6341 #endif | |
6342 | |
6343 xic = NULL; | |
6344 xic_attr = NULL; | |
6345 | |
6346 if (!gdk_im_ready()) | |
6347 { | |
6348 if (p_verbose > 0) | |
6349 { | |
6350 verbose_enter(); | |
6351 EMSG(_("E292: Input Method Server is not running")); | |
6352 verbose_leave(); | |
6353 } | |
6354 return; | |
6355 } | |
6356 if ((xic_attr = gdk_ic_attr_new()) != NULL) | |
6357 { | |
6358 #ifdef FEAT_XFONTSET | |
6359 gint width, height; | |
6360 #endif | |
6361 int mask; | |
6362 GdkColormap *colormap; | |
6363 GdkICAttr *attr = xic_attr; | |
6364 int attrmask = (int)GDK_IC_ALL_REQ; | |
6365 GtkWidget *widget = gui.drawarea; | |
6366 | |
6367 attr->style = (GdkIMStyle)xim_input_style; | |
6368 attr->client_window = gui.mainwin->window; | |
6369 | |
6370 if ((colormap = gtk_widget_get_colormap(widget)) != | |
6371 gtk_widget_get_default_colormap()) | |
6372 { | |
6373 attrmask |= (int)GDK_IC_PREEDIT_COLORMAP; | |
6374 attr->preedit_colormap = colormap; | |
6375 } | |
6376 attrmask |= (int)GDK_IC_PREEDIT_FOREGROUND; | |
6377 attrmask |= (int)GDK_IC_PREEDIT_BACKGROUND; | |
6378 attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL]; | |
6379 attr->preedit_background = widget->style->base[GTK_STATE_NORMAL]; | |
6380 | |
6381 #ifdef FEAT_XFONTSET | |
6382 if ((xim_input_style & (int)GDK_IM_PREEDIT_MASK) | |
6383 == (int)GDK_IM_PREEDIT_POSITION) | |
6384 { | |
6385 if (gui.fontset == NOFONTSET | |
6386 || gui.fontset->type != GDK_FONT_FONTSET) | |
6387 { | |
6388 EMSG(_(e_overthespot)); | |
6389 } | |
6390 else | |
6391 { | |
6392 gdk_window_get_size(widget->window, &width, &height); | |
6393 | |
6394 attrmask |= (int)GDK_IC_PREEDIT_POSITION_REQ; | |
6395 attr->spot_location.x = TEXT_X(0); | |
6396 attr->spot_location.y = TEXT_Y(0); | |
6397 attr->preedit_area.x = gui.border_offset; | |
6398 attr->preedit_area.y = gui.border_offset; | |
6399 attr->preedit_area.width = width - 2*gui.border_offset; | |
6400 attr->preedit_area.height = height - 2*gui.border_offset; | |
6401 attr->preedit_fontset = gui.fontset; | |
6402 } | |
6403 } | |
6404 | |
6405 if ((xim_input_style & (int)GDK_IM_STATUS_MASK) | |
6406 == (int)GDK_IM_STATUS_AREA) | |
6407 { | |
6408 if (gui.fontset == NOFONTSET | |
6409 || gui.fontset->type != GDK_FONT_FONTSET) | |
6410 { | |
6411 EMSG(_(e_overthespot)); | |
6412 } | |
6413 else | |
6414 { | |
6415 gdk_window_get_size(gui.mainwin->window, &width, &height); | |
6416 attrmask |= (int)GDK_IC_STATUS_AREA_REQ; | |
6417 attr->status_area.x = 0; | |
6418 attr->status_area.y = height - gui.char_height - 1; | |
6419 attr->status_area.width = width; | |
6420 attr->status_area.height = gui.char_height; | |
6421 attr->status_fontset = gui.fontset; | |
6422 } | |
6423 } | |
6424 else if ((xim_input_style & (int)GDK_IM_STATUS_MASK) | |
6425 == (int)GDK_IM_STATUS_CALLBACKS) | |
6426 { | |
6427 /* FIXME */ | |
6428 } | |
6429 #endif | |
6430 | |
6431 xic = gdk_ic_new(attr, (GdkICAttributesType)attrmask); | |
6432 | |
6433 if (xic == NULL) | |
6434 EMSG(_(e_xim)); | |
6435 else | |
6436 { | |
6437 mask = (int)gdk_window_get_events(widget->window); | |
6438 mask |= (int)gdk_ic_get_events(xic); | |
6439 gdk_window_set_events(widget->window, (GdkEventMask)mask); | |
6440 if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS) | |
6441 preedit_callback_setup(xic); | |
6442 reset_state_setup(xic); | |
6443 } | |
6444 } | |
6445 } | |
6446 | |
6447 void | |
6448 im_shutdown(void) | |
6449 { | |
6450 #ifdef XIM_DEBUG | |
6451 xim_log("im_shutdown()\n"); | |
6452 #endif | |
6453 | |
6454 if (xic != NULL) | |
6455 { | |
6456 gdk_im_end(); | |
6457 gdk_ic_destroy(xic); | |
6458 xic = NULL; | |
6459 } | |
6460 xim_is_active = FALSE; | |
6461 xim_can_preediting = FALSE; | |
6462 preedit_start_col = MAXCOL; | |
6463 xim_has_preediting = FALSE; | |
6464 } | |
6465 | |
6466 #endif /* FEAT_GUI_GTK */ | |
6467 | |
6468 int | 5610 int |
6469 xim_get_status_area_height() | 5611 xim_get_status_area_height() |
6470 { | 5612 { |
6471 #ifdef FEAT_GUI_GTK | |
6472 if (xim_input_style & (int)GDK_IM_STATUS_AREA) | |
6473 return gui.char_height; | |
6474 #else | |
6475 if (status_area_enabled) | 5613 if (status_area_enabled) |
6476 return gui.char_height; | 5614 return gui.char_height; |
6477 #endif | |
6478 return 0; | 5615 return 0; |
6479 } | 5616 } |
6480 | 5617 |
6481 /* | 5618 /* |
6482 * Get IM status. When IM is on, return TRUE. Else return FALSE. | 5619 * Get IM status. When IM is on, return TRUE. Else return FALSE. |
6485 * tear-off menu item). | 5622 * tear-off menu item). |
6486 */ | 5623 */ |
6487 int | 5624 int |
6488 im_get_status() | 5625 im_get_status() |
6489 { | 5626 { |
6490 # ifdef FEAT_GUI_GTK | |
6491 if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS) | |
6492 return xim_can_preediting; | |
6493 # endif | |
6494 return xim_has_focus; | 5627 return xim_has_focus; |
6495 } | 5628 } |
6496 | 5629 |
6497 # endif /* !HAVE_GTK2 */ | 5630 # endif /* !HAVE_GTK2 */ |
6498 | 5631 |