diff options
| author | Gerd Moellmann | 2000-01-29 23:17:49 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-01-29 23:17:49 +0000 |
| commit | 5a7df7d75faa0f8921fd6a9591cdf6836d89941b (patch) | |
| tree | 563e18c377af6a2b683d0b2ef883c75380ec793c | |
| parent | 1c815a24655db3419cc1cb45f9279ea8d194acbd (diff) | |
| download | emacs-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.c | 360 |
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 | ||
| 3052 | static void | 3052 | #ifdef HAVE_X_I18N |
| 3053 | x_create_im (f) | 3053 | |
| 3054 | static XFontSet xic_create_xfontset P_ ((struct frame *, char *)); | ||
| 3055 | static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *)); | ||
| 3056 | |||
| 3057 | |||
| 3058 | /* Supported XIM styles, ordered by preferenc. */ | ||
| 3059 | |||
| 3060 | static 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 | |||
| 3078 | static XFontSet | ||
| 3079 | xic_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 | |||
| 3103 | static XIMStyle | ||
| 3104 | best_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 | |||
| 3121 | void | ||
| 3122 | create_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 | |||
| 3226 | void | ||
| 3227 | free_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 | |||
| 3245 | void | ||
| 3246 | xic_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 | |||
| 3264 | void | ||
| 3265 | xic_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 | |||
| 3307 | void | ||
| 3308 | xic_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; |