1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /* This file is part of the GtkHTML library. |
---|
3 | |
---|
4 | Copyright 1999, 2000 Helix Code, Inc. |
---|
5 | |
---|
6 | This library is free software; you can redistribute it and/or |
---|
7 | modify it under the terms of the GNU Library General Public |
---|
8 | License as published by the Free Software Foundation; either |
---|
9 | version 2 of the License, or (at your option) any later version. |
---|
10 | |
---|
11 | This library is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
14 | Library General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU Library General Public License |
---|
17 | along with this library; see the file COPYING.LIB. If not, write to |
---|
18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
19 | Boston, MA 02111-1307, USA. |
---|
20 | */ |
---|
21 | |
---|
22 | #include <config.h> |
---|
23 | |
---|
24 | #include <gtk/gtk.h> |
---|
25 | #include "gtkhtml.h" |
---|
26 | #include "gtkhtml-im.h" |
---|
27 | #include "gtkhtml-private.h" |
---|
28 | |
---|
29 | #ifdef GTK_HTML_USE_XIM |
---|
30 | void |
---|
31 | gtk_html_im_focus_in (GtkHTML *html) |
---|
32 | { |
---|
33 | if (html->priv->ic) |
---|
34 | gdk_im_begin (html->priv->ic, GTK_WIDGET (html)->window); |
---|
35 | } |
---|
36 | |
---|
37 | void |
---|
38 | gtk_html_im_focus_out (GtkHTML *html) |
---|
39 | { |
---|
40 | gdk_im_end (); |
---|
41 | } |
---|
42 | |
---|
43 | void |
---|
44 | gtk_html_im_realize (GtkHTML *html) |
---|
45 | { |
---|
46 | GtkWidget *widget = GTK_WIDGET (html); |
---|
47 | GdkICAttr *attr; |
---|
48 | GdkColormap *colormap; |
---|
49 | |
---|
50 | gint width, height; |
---|
51 | GdkEventMask mask; |
---|
52 | |
---|
53 | GdkICAttributesType attrmask = GDK_IC_ALL_REQ; |
---|
54 | GdkIMStyle style; |
---|
55 | GdkIMStyle supported_style = |
---|
56 | GDK_IM_PREEDIT_NONE | |
---|
57 | GDK_IM_PREEDIT_NOTHING | |
---|
58 | GDK_IM_PREEDIT_POSITION | |
---|
59 | GDK_IM_STATUS_NONE | |
---|
60 | GDK_IM_STATUS_NOTHING; |
---|
61 | |
---|
62 | if (!gdk_im_ready () || (attr = gdk_ic_attr_new ()) == NULL) |
---|
63 | return; |
---|
64 | |
---|
65 | if (widget->style && |
---|
66 | widget->style->font->type != GDK_FONT_FONTSET) |
---|
67 | supported_style &= ~GDK_IM_PREEDIT_POSITION; |
---|
68 | |
---|
69 | attr->style = style = |
---|
70 | gdk_im_decide_style (supported_style); |
---|
71 | attr->client_window = widget->window; |
---|
72 | |
---|
73 | if ((colormap = gtk_widget_get_colormap (widget)) != |
---|
74 | gtk_widget_get_default_colormap ()) { |
---|
75 | attrmask |= GDK_IC_PREEDIT_COLORMAP; |
---|
76 | attr->preedit_colormap = colormap; |
---|
77 | } |
---|
78 | |
---|
79 | attrmask |= GDK_IC_PREEDIT_FOREGROUND; |
---|
80 | attrmask |= GDK_IC_PREEDIT_BACKGROUND; |
---|
81 | attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL]; |
---|
82 | attr->preedit_background = widget->style->base[GTK_STATE_NORMAL]; |
---|
83 | |
---|
84 | switch (style & GDK_IM_PREEDIT_MASK) { |
---|
85 | case GDK_IM_PREEDIT_POSITION: |
---|
86 | if (widget->style && widget->style->font->type |
---|
87 | != GDK_FONT_FONTSET) { |
---|
88 | g_warning ("over-the-spot style requires fontset"); |
---|
89 | break; |
---|
90 | } |
---|
91 | |
---|
92 | gdk_window_get_size (widget->window, |
---|
93 | &width, &height); |
---|
94 | |
---|
95 | height = widget->style->font->ascent + |
---|
96 | widget->style->font->descent; |
---|
97 | |
---|
98 | attrmask |= GDK_IC_PREEDIT_POSITION_REQ; |
---|
99 | attr->spot_location.x = 0; |
---|
100 | attr->spot_location.y = height; |
---|
101 | attr->preedit_area.x = 0; |
---|
102 | attr->preedit_area.y = 0; |
---|
103 | attr->preedit_area.width = width; |
---|
104 | attr->preedit_area.height = height; |
---|
105 | attr->preedit_fontset = widget->style->font; |
---|
106 | |
---|
107 | break; |
---|
108 | } |
---|
109 | html->priv->ic_attr = attr; |
---|
110 | html->priv->ic = gdk_ic_new (attr, attrmask); |
---|
111 | |
---|
112 | if (html->priv->ic == NULL) |
---|
113 | g_warning ("Can't create input context."); |
---|
114 | else { |
---|
115 | mask = gdk_window_get_events (widget->window); |
---|
116 | mask |= gdk_ic_get_events (html->priv->ic); |
---|
117 | gdk_window_set_events (widget->window, mask); |
---|
118 | |
---|
119 | if (GTK_WIDGET_HAS_FOCUS(widget)) |
---|
120 | gdk_im_begin (html->priv->ic, widget->window); |
---|
121 | } |
---|
122 | } |
---|
123 | |
---|
124 | void |
---|
125 | gtk_html_im_unrealize (GtkHTML *html) |
---|
126 | { |
---|
127 | if (html->priv->ic) { |
---|
128 | gdk_ic_destroy (html->priv->ic); |
---|
129 | html->priv->ic = NULL; |
---|
130 | } |
---|
131 | if (html->priv->ic_attr) { |
---|
132 | gdk_ic_attr_destroy (html->priv->ic_attr); |
---|
133 | html->priv->ic_attr = NULL; |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | void |
---|
138 | gtk_html_im_size_allocate (GtkHTML *html) |
---|
139 | { |
---|
140 | GtkWidget *widget = GTK_WIDGET (html); |
---|
141 | |
---|
142 | if (!GTK_WIDGET_REALIZED (widget)) |
---|
143 | return; |
---|
144 | |
---|
145 | if (html->priv->ic == NULL) |
---|
146 | return; |
---|
147 | |
---|
148 | if (gdk_ic_get_style (html->priv->ic) & GDK_IM_PREEDIT_POSITION) { |
---|
149 | gint width, height; |
---|
150 | |
---|
151 | gdk_window_get_size (widget->window, |
---|
152 | &width, &height); |
---|
153 | html->priv->ic_attr->preedit_area.width = width; |
---|
154 | html->priv->ic_attr->preedit_area.height = height; |
---|
155 | gdk_ic_set_attr (html->priv->ic, html->priv->ic_attr, |
---|
156 | GDK_IC_PREEDIT_AREA); |
---|
157 | } |
---|
158 | } |
---|
159 | |
---|
160 | void |
---|
161 | gtk_html_im_position_update (GtkHTML *html, gint x, gint y) |
---|
162 | { |
---|
163 | GtkWidget *widget = GTK_WIDGET (html); |
---|
164 | |
---|
165 | if (!GTK_WIDGET_REALIZED (widget)) |
---|
166 | return; |
---|
167 | |
---|
168 | if (html->priv->ic == NULL) |
---|
169 | return; |
---|
170 | |
---|
171 | if (gdk_ic_get_style (html->priv->ic) & GDK_IM_PREEDIT_POSITION) { |
---|
172 | gint width, height; |
---|
173 | |
---|
174 | html->priv->ic_attr->spot_location.x = x+1; |
---|
175 | html->priv->ic_attr->spot_location.y = y; |
---|
176 | |
---|
177 | gdk_window_get_size (widget->window, |
---|
178 | &width, &height); |
---|
179 | html->priv->ic_attr->preedit_area.width = width; |
---|
180 | html->priv->ic_attr->preedit_area.height = height; |
---|
181 | gdk_ic_set_attr (html->priv->ic, html->priv->ic_attr, |
---|
182 | GDK_IC_SPOT_LOCATION | GDK_IC_PREEDIT_AREA); |
---|
183 | } |
---|
184 | } |
---|
185 | |
---|
186 | |
---|
187 | void |
---|
188 | gtk_html_im_style_set (GtkHTML *html) |
---|
189 | { |
---|
190 | GtkWidget *widget = GTK_WIDGET (html); |
---|
191 | GdkICAttributesType mask = 0; |
---|
192 | |
---|
193 | if (!GTK_WIDGET_REALIZED (widget)) |
---|
194 | return; |
---|
195 | |
---|
196 | if (html->priv->ic == NULL) |
---|
197 | return; |
---|
198 | |
---|
199 | gdk_ic_get_attr (html->priv->ic, html->priv->ic_attr, |
---|
200 | GDK_IC_PREEDIT_FOREGROUND | |
---|
201 | GDK_IC_PREEDIT_BACKGROUND | |
---|
202 | GDK_IC_PREEDIT_FONTSET); |
---|
203 | |
---|
204 | if (html->priv->ic_attr->preedit_foreground.pixel != |
---|
205 | widget->style->fg[GTK_STATE_NORMAL].pixel) { |
---|
206 | mask |= GDK_IC_PREEDIT_FOREGROUND; |
---|
207 | html->priv->ic_attr->preedit_foreground |
---|
208 | = widget->style->fg[GTK_STATE_NORMAL]; |
---|
209 | } |
---|
210 | if (html->priv->ic_attr->preedit_background.pixel != |
---|
211 | widget->style->base[GTK_STATE_NORMAL].pixel) { |
---|
212 | mask |= GDK_IC_PREEDIT_BACKGROUND; |
---|
213 | html->priv->ic_attr->preedit_background |
---|
214 | = widget->style->base[GTK_STATE_NORMAL]; |
---|
215 | } |
---|
216 | if ((gdk_ic_get_style (html->priv->ic) & GDK_IM_PREEDIT_POSITION) && |
---|
217 | widget->style->font != NULL && |
---|
218 | widget->style->font->type == GDK_FONT_FONTSET && |
---|
219 | !gdk_font_equal (html->priv->ic_attr->preedit_fontset, |
---|
220 | widget->style->font)) { |
---|
221 | mask |= GDK_IC_PREEDIT_FONTSET; |
---|
222 | html->priv->ic_attr->preedit_fontset = widget->style->font; |
---|
223 | } |
---|
224 | |
---|
225 | if (mask) |
---|
226 | gdk_ic_set_attr (html->priv->ic, html->priv->ic_attr, mask); |
---|
227 | } |
---|
228 | |
---|
229 | |
---|
230 | #endif |
---|
231 | |
---|
232 | |
---|
233 | |
---|
234 | |
---|
235 | |
---|
236 | |
---|