aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Moellmann2000-01-29 23:17:49 +0000
committerGerd Moellmann2000-01-29 23:17:49 +0000
commit5a7df7d75faa0f8921fd6a9591cdf6836d89941b (patch)
tree563e18c377af6a2b683d0b2ef883c75380ec793c
parent1c815a24655db3419cc1cb45f9279ea8d194acbd (diff)
downloademacs-5a7df7d75faa0f8921fd6a9591cdf6836d89941b.tar.gz
emacs-5a7df7d75faa0f8921fd6a9591cdf6836d89941b.zip
(xic_set_preeditarea): Take window parameter and
window-relative pixel-positions. (x_create_im): Removed. (DEFAULT_STYLE, DEFAULT_FONT): Removed. (supported_xim_styles): Renamed from supported_styles. (best_xim_style): Renamed from best_style. (create_frame_xic): Renamed from xic_create_frame. (free_frame_xic): Renamed from xic_destroy_frame. (supported_styles): New variable. (DEFAULT_STYLE, DEFAULT_FONT): New macros (xic_create_xfontset, best_style, xic_create_frame) (xic_destroy_frame, xic_set_preeditarea, xic_set_statusarea) (xic_set_xfontset): New functions.
-rw-r--r--src/xfns.c360
1 files changed, 304 insertions, 56 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 143b870485b..a36b3a9986c 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3046,70 +3046,289 @@ hack_wm_protocols (f, widget)
3046#endif 3046#endif
3047 3047
3048 3048
3049/* Create input method and input context for frame F. Set FRAME_XIM 3049
3050 (F) and FRAME_XIC (F). */ 3050/* Support routines for XIC (X Input Context). */
3051 3051
3052static void 3052#ifdef HAVE_X_I18N
3053x_create_im (f) 3053
3054static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
3055static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
3056
3057
3058/* Supported XIM styles, ordered by preferenc. */
3059
3060static XIMStyle supported_xim_styles[] =
3061{
3062 XIMPreeditPosition | XIMStatusArea,
3063 XIMPreeditPosition | XIMStatusNothing,
3064 XIMPreeditPosition | XIMStatusNone,
3065 XIMPreeditNothing | XIMStatusArea,
3066 XIMPreeditNothing | XIMStatusNothing,
3067 XIMPreeditNothing | XIMStatusNone,
3068 XIMPreeditNone | XIMStatusArea,
3069 XIMPreeditNone | XIMStatusNothing,
3070 XIMPreeditNone | XIMStatusNone,
3071 0,
3072};
3073
3074
3075/* Create an X fontset on frame F with base font name
3076 BASE_FONTNAME.. */
3077
3078static XFontSet
3079xic_create_xfontset (f, base_fontname)
3054 struct frame *f; 3080 struct frame *f;
3081 char *base_fontname;
3055{ 3082{
3056 FRAME_XIM (f) = 0; 3083 XFontSet xfs;
3057 FRAME_XIC (f) = 0; 3084 char **missing_list;
3085 int missing_count;
3086 char *def_string;
3058 3087
3059#ifdef HAVE_X_I18N 3088 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
3089 base_fontname, &missing_list,
3090 &missing_count, &def_string);
3091 if (missing_list)
3092 XFreeStringList (missing_list);
3093
3094 /* No need to free def_string. */
3095 return xfs;
3096}
3097
3098
3099/* Value is the best input style, given user preferences USER (already
3100 checked to be supported by Emacs), and styles supported by the
3101 input method XIM. */
3102
3103static XIMStyle
3104best_xim_style (user, xim)
3105 XIMStyles *user;
3106 XIMStyles *xim;
3107{
3108 int i, j;
3109
3110 for (i = 0; i < user->count_styles; ++i)
3111 for (j = 0; j < xim->count_styles; ++j)
3112 if (user->supported_styles[i] == xim->supported_styles[j])
3113 return user->supported_styles[i];
3114
3115 /* Return the default style. */
3116 return XIMPreeditNothing | XIMStatusNothing;
3117}
3118
3119/* Create XIC for frame F. */
3120
3121void
3122create_frame_xic (f)
3123 struct frame *f;
3124{
3060#ifndef X_I18N_INHIBITED 3125#ifndef X_I18N_INHIBITED
3061 { 3126 XIM xim;
3062 XIM xim; 3127 XIC xic = NULL;
3063 XIC xic = NULL; 3128 XFontSet xfs = NULL;
3064 XIMStyles *styles; 3129 static XIMStyle xic_style;
3065 XIMStyle input_style = XIMPreeditNothing | XIMStatusNothing;
3066 int i, n;
3067
3068 xim = XOpenIM (FRAME_X_DISPLAY(f), NULL, NULL, NULL);
3069 if (!xim)
3070 return;
3071
3072 if (XGetIMValues (xim, XNQueryInputStyle, &styles, NULL)
3073 || !styles)
3074 {
3075 /* Input method doesn't support any input style. */
3076 XCloseIM (xim);
3077 return;
3078 }
3079 3130
3080 /* See if input_style is supported. Give up if it isn't. */ 3131 if (FRAME_XIC (f))
3081 n = styles->count_styles; 3132 return;
3082 for (i = 0; i < n; ++i) 3133
3083 if (styles->supported_styles[i] == input_style) 3134 xim = FRAME_X_XIM (f);
3084 break; 3135 if (xim)
3085 3136 {
3086 XFree (styles); 3137 XRectangle s_area = {0, 0, 1, 1};
3087 if (i == n) 3138 XPoint spot = {0, 1};
3088 { 3139 XVaNestedList preedit_attr;
3089 XCloseIM (xim); 3140 XVaNestedList status_attr;
3090 return; 3141 char *base_fontname;
3091 } 3142 int fontset;
3143
3144 /* Create X fontset. */
3145 fontset = FRAME_FONTSET (f);
3146 if (fontset < 0)
3147 base_fontname = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
3148 else
3149 {
3150 struct fontset_info *fontsetp;
3151 int len = 0;
3152 int i;
3153
3154 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
3155 for (i = 0; i <= MAX_CHARSET; i++)
3156 if (fontsetp->fontname[i])
3157 len += strlen (fontsetp->fontname[i]) + 1;
3158 base_fontname = alloca (len);
3159 strcpy (base_fontname, fontsetp->fontname[CHARSET_ASCII]);
3160 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
3161 if (fontsetp->fontname[i])
3162 {
3163 strcat (base_fontname, ",");
3164 strcat (base_fontname, fontsetp->fontname[i]);
3165 }
3166 }
3167 xfs = xic_create_xfontset (f, base_fontname);
3092 3168
3093 /* Create the input context. */ 3169 /* Determine XIC style. */
3094 xic = XCreateIC (xim, 3170 if (xic_style == 0)
3095 XNInputStyle, input_style, 3171 {
3096 XNClientWindow, FRAME_X_WINDOW(f), 3172 XIMStyles supported_list;
3097 XNFocusWindow, FRAME_X_WINDOW(f), 3173 supported_list.count_styles = (sizeof supported_xim_styles
3098 NULL); 3174 / sizeof supported_xim_styles[0]);
3099 3175 supported_list.supported_styles = supported_xim_styles;
3100 if (!xic) 3176 xic_style = best_xim_style (&supported_list,
3101 { 3177 FRAME_X_XIM_STYLES (f));
3102 XCloseIM (xim); 3178 }
3103 return;
3104 }
3105 3179
3106 FRAME_XIM (f) = xim; 3180 preedit_attr = XVaCreateNestedList (0,
3107 FRAME_XIC (f) = xic; 3181 XNFontSet, xfs,
3108 } 3182 XNForeground,
3183 FRAME_FOREGROUND_PIXEL (f),
3184 XNBackground,
3185 FRAME_BACKGROUND_PIXEL (f),
3186 (xic_style & XIMPreeditPosition
3187 ? XNSpotLocation
3188 : NULL),
3189 &spot,
3190 NULL);
3191 status_attr = XVaCreateNestedList (0,
3192 XNArea,
3193 &s_area,
3194 XNFontSet,
3195 xfs,
3196 XNForeground,
3197 FRAME_FOREGROUND_PIXEL (f),
3198 XNBackground,
3199 FRAME_BACKGROUND_PIXEL (f),
3200 NULL);
3201
3202 xic = XCreateIC (xim,
3203 XNInputStyle, xic_style,
3204 XNClientWindow, FRAME_X_WINDOW(f),
3205 XNFocusWindow, FRAME_X_WINDOW(f),
3206 XNStatusAttributes, status_attr,
3207 XNPreeditAttributes, preedit_attr,
3208 NULL);
3209 XFree (preedit_attr);
3210 XFree (status_attr);
3211 }
3212
3213 FRAME_XIC (f) = xic;
3214 FRAME_XIC_STYLE (f) = xic_style;
3215 FRAME_XIC_FONTSET (f) = xfs;
3216#else /* X_I18N_INHIBITED */
3217 FRAME_XIC (f) = NULL;
3218 FRAME_XIC_STYLE (f) = 0;
3219 FRAME_XIC_FONTSET (f) = NULL;
3109#endif /* X_I18N_INHIBITED */ 3220#endif /* X_I18N_INHIBITED */
3110#endif /* HAVE_X_I18N */
3111} 3221}
3112 3222
3223
3224/* Destroy XIC and free XIC fontset of frame F, if any. */
3225
3226void
3227free_frame_xic (f)
3228 struct frame *f;
3229{
3230 if (FRAME_XIC (f) == NULL)
3231 return;
3232
3233 XDestroyIC (FRAME_XIC (f));
3234 if (FRAME_XIC_FONTSET (f))
3235 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
3236
3237 FRAME_XIC (f) = NULL;
3238 FRAME_XIC_FONTSET (f) = NULL;
3239}
3240
3241
3242/* Place preedit area for XIC of window W's frame to specified
3243 pixel position X/Y. X and Y are relative to window W. */
3244
3245void
3246xic_set_preeditarea (w, x, y)
3247 struct window *w;
3248 int x, y;
3249{
3250 struct frame *f = XFRAME (w->frame);
3251 XVaNestedList attr;
3252 XPoint spot;
3253
3254 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x);
3255 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
3256 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
3257 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
3258 XFree (attr);
3259}
3260
3261
3262/* Place status area for XIC in bottom right corner of frame F.. */
3263
3264void
3265xic_set_statusarea (f)
3266 struct frame *f;
3267{
3268 XIC xic = FRAME_XIC (f);
3269 XVaNestedList attr;
3270 XRectangle area;
3271 XRectangle *needed;
3272
3273 /* Negotiate geometry of status area. If input method has existing
3274 status area, use its current size. */
3275 area.x = area.y = area.width = area.height = 0;
3276 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
3277 XSetICValues (xic, XNStatusAttributes, attr, NULL);
3278 XFree (attr);
3279
3280 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
3281 XGetICValues (xic, XNStatusAttributes, attr, NULL);
3282 XFree (attr);
3283
3284 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
3285 {
3286 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
3287 XGetICValues (xic, XNStatusAttributes, attr, NULL);
3288 XFree (attr);
3289 }
3290
3291 area.width = needed->width;
3292 area.height = needed->height;
3293 area.x = PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
3294 area.y = (PIXEL_HEIGHT (f) - area.height
3295 - FRAME_MENUBAR_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f));
3296 XFree (needed);
3297
3298 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
3299 XSetICValues(xic, XNStatusAttributes, attr, NULL);
3300 XFree (attr);
3301}
3302
3303
3304/* Set X fontset for XIC of frame F, using base font name
3305 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
3306
3307void
3308xic_set_xfontset (f, base_fontname)
3309 struct frame *f;
3310 char *base_fontname;
3311{
3312 XVaNestedList attr;
3313 XFontSet xfs;
3314
3315 xfs = xic_create_xfontset (f, base_fontname);
3316
3317 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
3318 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
3319 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
3320 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
3321 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
3322 XFree (attr);
3323
3324 if (FRAME_XIC_FONTSET (f))
3325 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
3326 FRAME_XIC_FONTSET (f) = xfs;
3327}
3328
3329#endif /* HAVE_X_I18N */
3330
3331
3113 3332
3114#ifdef USE_X_TOOLKIT 3333#ifdef USE_X_TOOLKIT
3115 3334
@@ -3266,7 +3485,11 @@ x_window (f, window_prompting, minibuffer_only)
3266 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data; 3485 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
3267 class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data; 3486 class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data;
3268 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); 3487 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
3269 x_create_im (f); 3488
3489#ifdef HAVE_X_I18N
3490 FRAME_XIC (f) = NULL;
3491 create_frame_xic (f);
3492#endif
3270 3493
3271 f->output_data.x->wm_hints.input = True; 3494 f->output_data.x->wm_hints.input = True;
3272 f->output_data.x->wm_hints.flags |= InputHint; 3495 f->output_data.x->wm_hints.flags |= InputHint;
@@ -3288,8 +3511,19 @@ x_window (f, window_prompting, minibuffer_only)
3288 XA_ATOM, 32, PropModeAppend, 3511 XA_ATOM, 32, PropModeAppend,
3289 (unsigned char*) NULL, 0); 3512 (unsigned char*) NULL, 0);
3290 3513
3291 /* Make all the standard events reach the Emacs frame. */ 3514 /* Make all the standard events reach the Emacs frame. */
3292 attributes.event_mask = STANDARD_EVENT_SET; 3515 attributes.event_mask = STANDARD_EVENT_SET;
3516
3517#ifdef HAVE_X_I18N
3518 if (FRAME_XIC (f))
3519 {
3520 /* XIM server might require some X events. */
3521 unsigned long fevent = NoEventMask;
3522 XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
3523 attributes.event_mask |= fevent;
3524 }
3525#endif /* HAVE_X_I18N */
3526
3293 attribute_mask = CWEventMask; 3527 attribute_mask = CWEventMask;
3294 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget), 3528 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
3295 attribute_mask, &attributes); 3529 attribute_mask, &attributes);
@@ -3357,7 +3591,21 @@ x_window (f)
3357 InputOutput, /* class */ 3591 InputOutput, /* class */
3358 FRAME_X_DISPLAY_INFO (f)->visual, 3592 FRAME_X_DISPLAY_INFO (f)->visual,
3359 attribute_mask, &attributes); 3593 attribute_mask, &attributes);
3360 x_create_im (f); 3594
3595#ifdef HAVE_X_I18N
3596 create_frame_xic (f);
3597 if (FRAME_XIC (f))
3598 {
3599 /* XIM server might require some X events. */
3600 unsigned long fevent = NoEventMask;
3601 XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
3602 attributes.event_mask |= fevent;
3603 attribute_mask = CWEventMask;
3604 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3605 attribute_mask, &attributes);
3606 }
3607#endif /* HAVE_X_I18N */
3608
3361 validate_x_resource_name (); 3609 validate_x_resource_name ();
3362 3610
3363 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data; 3611 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;