Back to index

im-sdk  12.3.91
palette_aux.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include "palette_pixmap.h"
00003 #include "palette_messages.h"
00004 #include "palette_aux.h"
00005 
00006 enum {
00007     BUTTON_STATE_NORMAL = 0,
00008     BUTTON_STATE_FOCUSED,
00009     BUTTON_STATE_PRESSED,
00010 };
00011 
00012 char **pixmaps[PIXMAPS_NUM] = {
00013     default_ime_xpm,
00014     dragarea_vertical_xpm,
00015     dragarea_horizontal_xpm,
00016     halfwidth_xpm,
00017     fullwidth_xpm,
00018     en_punct_xpm,
00019     ch_punct_xpm,
00020     keyboard_xpm,
00021     options_xpm
00022 };
00023 
00024 char *palette_tooltips[BUTTONS_NUM] = {
00025     TOOLTIPS_STR_FOR_GRAG_BUTTON,
00026     TOOLTIPS_STR_FOR_IME_BUTTON,
00027     TOOLTIPS_STR_FOR_QJBJ_BUTTON,
00028     TOOLTIPS_STR_FOR_PUNCT_BUTTON,
00029     TOOLTIPS_STR_FOR_VKB_BUTTON,
00030     TOOLTIPS_STR_FOR_UTILITY_BUTTON
00031 };
00032 
00033 #define TIMEOUT_SAVE_PROPERTIES  10000
00034 
00035 void palette_window_sync_to_property_data(palette_window_t *palette_window);
00036 void palette_window_sync_from_property_data(palette_window_t *palette_window);
00037 void palette_window_update_layout(palette_window_t *palette_window);
00038 void palette_window_hide_vkb_window(palette_window_t *palette_window);
00039 static void palette_window_init_attributes(palette_window_t *palette_window);
00040 void palette_window_draw_layout(palette_window_t *palette_window);
00041 GdkPixbuf *palette_window_new_pixbuf_from_xpm(char *xpm_file,
00042                                    const char **xpm,
00043                                         int width,
00044                                         int height,
00045                                         gboolean force_create);
00046 void palette_window_set_position(palette_window_t *palette_window,
00047                              gint pos_x, gint pos_y);
00048 static void palette_window_destroy_event_handler(GtkWidget *widget,
00049                                    palette_window_t *palette_window);
00050 static gboolean palette_window_expose_event_handler(GtkWidget *widget,
00051                                    GdkEventExpose *event,
00052                                    palette_window_t *palette_window);
00053 static gboolean palette_window_configure_event_handler(GtkWidget *widget,
00054                                    GdkEventConfigure *event,
00055                                    palette_window_t *palette_window);
00056 static gboolean palette_window_leave_event_handler(GtkWidget *widget,
00057                                    GdkEventCrossing *event,
00058                                    palette_window_t *palette_window);
00059 static gboolean palette_window_pointer_motion_event_handler(GtkWidget *widget,
00060                                    GdkEventMotion *event,
00061                                    palette_window_t *palette_window);
00062 static gboolean palette_window_pointer_press_event_handler(GtkWidget *widget,
00063                                    GdkEventButton *event,
00064                                    palette_window_t *palette_window);
00065 static gboolean palette_window_pointer_release_event_handler(GtkWidget *widget,
00066                                    GdkEventButton *event,
00067                                    palette_window_t *palette_window);
00068 
00069 palette_window_t *palette_window_new()
00070 {
00071     palette_window_t *palette_window = NULL;
00072 
00073     palette_window = (palette_window_t *)calloc(1, sizeof (palette_window_t));
00074     if (palette_window == NULL)
00075         return NULL;
00076 
00077     palette_window->window = gtk_window_new(GTK_WINDOW_POPUP);
00078     gtk_window_set_resizable(GTK_WINDOW(palette_window->window), FALSE);
00079     gtk_container_set_border_width(GTK_CONTAINER(palette_window->window), 0);
00080 
00081     palette_window->drawing_area = gtk_drawing_area_new();
00082 
00083     gtk_widget_set_events(palette_window->drawing_area,
00084                        GDK_EXPOSURE_MASK |
00085                        GDK_LEAVE_NOTIFY_MASK |
00086                        GDK_BUTTON_PRESS_MASK |
00087                        GDK_BUTTON_RELEASE_MASK |
00088                        GDK_POINTER_MOTION_MASK);
00089 
00090     g_signal_connect(G_OBJECT(palette_window->window),
00091                    "destroy",
00092                    G_CALLBACK(palette_window_destroy_event_handler),
00093                    (gpointer)palette_window);
00094 
00095     g_signal_connect(G_OBJECT(palette_window->drawing_area),
00096                    "expose_event",
00097                    G_CALLBACK(palette_window_expose_event_handler),
00098                    (gpointer)palette_window);
00099 
00100     g_signal_connect(G_OBJECT(palette_window->drawing_area),
00101                    "configure_event",
00102                    G_CALLBACK(palette_window_configure_event_handler),
00103                    (gpointer)palette_window);
00104 
00105     g_signal_connect(G_OBJECT(palette_window->drawing_area),
00106                    "leave_notify_event",
00107                    G_CALLBACK(palette_window_leave_event_handler),
00108                    (gpointer)palette_window);
00109 
00110     g_signal_connect(G_OBJECT(palette_window->drawing_area),
00111                    "button_press_event",
00112                    G_CALLBACK (palette_window_pointer_press_event_handler),
00113                    (gpointer)palette_window);
00114 
00115     g_signal_connect(G_OBJECT(palette_window->drawing_area),
00116                    "button_release_event",
00117                    G_CALLBACK (palette_window_pointer_release_event_handler),
00118                    (gpointer)palette_window);
00119 
00120     g_signal_connect(G_OBJECT (palette_window->drawing_area),
00121                    "motion-notify-event",
00122                    G_CALLBACK (palette_window_pointer_motion_event_handler),
00123                    (gpointer)palette_window);
00124 
00125     gtk_container_add(GTK_CONTAINER(palette_window->window),
00126                                 palette_window->drawing_area);
00127 
00128     palette_window_init_attributes(palette_window);
00129 
00130 #ifndef STANDALONE_DEBUG
00131     gtk_widget_realize(GTK_WIDGET(palette_window->window));
00132 #else
00133     gtk_widget_show_all(GTK_WIDGET(palette_window->window));
00134 #endif
00135 
00136     gtk_window_move(GTK_WINDOW(palette_window->window),
00137                   palette_window->pos_x,
00138                   palette_window->pos_y);
00139 
00140     return palette_window;
00141 }
00142 
00143 void
00144 palette_window_destroy(palette_window_t *palette_window)
00145 {
00146     int i;
00147 
00148     if (!palette_window)
00149        return;
00150 
00151     if (palette_window->font_desc)
00152        pango_font_description_free(palette_window->font_desc);
00153 
00154     if (palette_window->pango_layout)
00155        g_object_unref(palette_window->pango_layout);
00156 
00157     if (palette_window->pixmap)
00158         gdk_pixmap_unref(palette_window->pixmap);
00159 
00160     if (palette_window->moving_cursor)
00161         gdk_cursor_unref (palette_window->moving_cursor);
00162 
00163     if (palette_window->moving_cursor)
00164         gdk_cursor_unref (palette_window->normal_cursor);
00165 
00166     if (palette_window->ime_list_menu)
00167        gtk_widget_destroy(palette_window->ime_list_menu);
00168 
00169     if (palette_window->vkb_list_menu)
00170        gtk_widget_destroy(palette_window->vkb_list_menu);
00171 
00172     if (palette_window->vkb_layout_pc_keyboard)
00173        vkb_layout_destroy(palette_window->vkb_layout_pc_keyboard);
00174 
00175     if (palette_window->vkb_layout_list)
00176        vkb_layout_list_destroy(palette_window->vkb_layout_list);
00177 
00178     if (palette_window->vkb_window)
00179        vkb_window_destroy(palette_window->vkb_window);
00180 
00181     if (palette_window->property_data)
00182        property_data_destroy(palette_window->property_data);
00183 
00184     if (palette_window->property_window)
00185        property_window_destroy(palette_window->property_window);
00186 
00187     if (palette_window->utility_list_menu)
00188        gtk_widget_destroy(palette_window->utility_list_menu);
00189 
00190     if (palette_window->about_dialog)
00191        gtk_widget_destroy(palette_window->about_dialog);
00192 
00193     if (palette_window->window)
00194        gtk_widget_destroy(palette_window->window);
00195 
00196     /* destroy the pixmaps for buttons. */
00197     for (i = 0; i < PIXMAPS_NUM; i++) {
00198        if (palette_window->pixbufs[i])
00199            gdk_pixbuf_unref(palette_window->pixbufs[i]);
00200     }
00201 
00202     free ((char *)palette_window);
00203 }
00204 
00205 static void
00206 palette_window_init_attributes(palette_window_t *palette_window)
00207 {
00208     int i;
00209     int screen_width, screen_height;
00210     palette_button_t *buttons;
00211 
00212     palette_window->context = gtk_widget_get_pango_context(palette_window->drawing_area);
00213 
00214     palette_window->font_desc = pango_font_description_from_string("sans 10");
00215 
00216     palette_window->pango_layout = pango_layout_new(palette_window->context);
00217     pango_layout_set_font_description(palette_window->pango_layout, palette_window->font_desc);
00218 
00219     palette_window->pixmap = NULL;
00220 
00221     palette_window->tooltips = gtk_tooltips_new();
00222 
00223     palette_window->moving_cursor = gdk_cursor_new (GDK_FLEUR);
00224     palette_window->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR);
00225 
00226     /* initialize the pixmaps for buttons. */
00227     for (i = 0; i < PIXMAPS_NUM; i++) {
00228         palette_window->pixbufs[i] = palette_window_new_pixbuf_from_xpm(NULL,
00229                                                         (const char **)pixmaps[i],
00230                                                         -1, -1, FALSE);
00231     }
00232 
00233     buttons = palette_window->buttons;
00234     for (i = 0; i < BUTTONS_NUM; i++) {
00235        buttons[i].button_id = i;
00236        buttons[i].enabled = TRUE;
00237        buttons[i].activated = TRUE;
00238     }
00239 
00240     palette_window->pressed_button = NULL;
00241     palette_window->focused_button = NULL;
00242 
00243     palette_window->ime_list_menu = NULL;
00244     palette_window->current_ime = NULL;
00245     palette_window->ime_draw_style = IME_DRAW_ICON_ONLY,
00246 
00247     palette_window->vkb_list_menu = NULL;
00248     palette_window->vkb_layout_list_inited = 0;
00249     palette_window->vkb_layout_list = NULL;
00250     palette_window->current_vkb_layout = NULL;
00251     palette_window->vkb_window = NULL;
00252     palette_window->vkb_show_status = 0;
00253     palette_window->vkb_layout_pc_keyboard = (vkb_layout_t *)vkb_layout_new_for_pc_keyboard();
00254 
00255     palette_window->utility_list_menu = NULL;
00256 
00257     palette_window->property_data = (property_data_t *)property_data_new();
00258     palette_window->property_window = NULL;
00259 
00260     palette_window->about_dialog = NULL;
00261 
00262     palette_window->qjbj_status = 0;
00263     palette_window->punct_status = 0;
00264 
00265     palette_window->menu_popuped = 0;
00266 
00267     palette_window->draging = FALSE;
00268     palette_window->draw_draging_frame = TRUE;
00269 
00270     palette_window->pos_x = -1;
00271     palette_window->pos_y = -1;
00272     palette_window->show_style = SHOW_STYLE_HORIZONTAL;
00273 
00274     property_data_read_from_profile(palette_window->property_data, PROPERTY_DATA_FOR_LOCAL_PROFILE);
00275     palette_window_sync_from_property_data(palette_window);
00276 
00277     palette_window_update_layout(palette_window);
00278 
00279     screen_width = gdk_screen_width();
00280     screen_height = gdk_screen_height();
00281 
00282     if (palette_window->pos_x < 0 || 
00283         palette_window->pos_x >= screen_width)
00284         palette_window->pos_x = screen_width - palette_window->width - 110;
00285     if (palette_window->pos_y < 0 ||
00286         palette_window->pos_y >= screen_height)
00287         palette_window->pos_y = screen_height - palette_window->height - 40;
00288     if (palette_window->show_style)
00289         palette_window->show_style = SHOW_STYLE_VERTICAL;
00290 
00291     palette_window_sync_to_property_data(palette_window);
00292 
00293     return;
00294 }
00295 
00296 /********************************************************************/
00297 /*       palette window utility functions                           */
00298 /********************************************************************/
00299 GdkPixbuf *palette_window_new_pixbuf_from_xpm(char *xpm_file,
00300                                          const char **xpm,
00301                                               int width,
00302                                               int height,
00303                                               gboolean force_create)
00304 {
00305     GdkPixbuf *pixbuf = NULL;
00306     int width_pixbuf;
00307     int height_pixbuf;
00308 
00309     if (xpm_file && *xpm_file) {
00310        pixbuf = gdk_pixbuf_new_from_file(xpm_file, 0);
00311     }
00312 
00313     if (!pixbuf && xpm) {
00314        pixbuf = gdk_pixbuf_new_from_xpm_data(xpm);
00315     }
00316 
00317     if (!pixbuf && !force_create)
00318         return 0;
00319 
00320     if (!pixbuf) {
00321         if (width <= 0 || height <= 0)
00322             return 0;
00323 
00324         pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
00325         if (!pixbuf)
00326             return 0;
00327 
00328         gdk_pixbuf_fill(pixbuf, 0);
00329     }
00330 
00331     width_pixbuf = gdk_pixbuf_get_width(pixbuf);
00332     height_pixbuf = gdk_pixbuf_get_height(pixbuf);
00333 
00334     if (width <= 0) width = width_pixbuf;
00335     if (height <= 0) height = height_pixbuf;
00336 
00337     if (width != width_pixbuf || height != height_pixbuf) {
00338         GdkPixbuf *dest;
00339        dest = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR);
00340         gdk_pixbuf_unref(pixbuf);
00341         pixbuf = dest;
00342     }
00343 
00344     return pixbuf;
00345 }
00346 
00347 static void
00348 palette_window_draw_button_image(palette_window_t *palette_window,
00349                              palette_button_t *button,
00350                              GdkPixbuf *pixbuf,
00351                              int alignment)
00352 {
00353     int x, y;
00354     int width_pixbuf;
00355     int height_pixbuf;
00356 
00357     if (!palette_window->pixmap || !pixbuf)
00358        return;
00359 
00360     width_pixbuf = gdk_pixbuf_get_width(pixbuf);
00361     height_pixbuf = gdk_pixbuf_get_height(pixbuf);
00362 
00363     if (alignment == GTK_JUSTIFY_CENTER) {
00364         x = button->x + (button->width - width_pixbuf)/2;
00365     } else if (alignment == GTK_JUSTIFY_LEFT) {
00366         x = button->x;
00367     } else if (alignment == GTK_JUSTIFY_RIGHT) {
00368         x = button->x + button->width - width_pixbuf;
00369     }
00370 
00371     y = button->y + (button->height - height_pixbuf)/2;
00372 
00373     gdk_draw_pixbuf (palette_window->pixmap,
00374                     palette_window->drawing_area->style->fg_gc[GTK_STATE_NORMAL],
00375                    pixbuf,
00376                    0, 0,
00377                    x, y,
00378                      width_pixbuf, height_pixbuf,
00379                    GDK_RGB_DITHER_NORMAL,
00380                    0, 0); 
00381 
00382     return;
00383 }
00384 
00385 static void
00386 palette_window_draw_button(palette_window_t *palette_window,
00387                         palette_button_t *button,
00388                         int button_state)
00389 {
00390     GdkPixbuf *pixbuf;
00391 
00392     if (!palette_window->pixmap)
00393        return;
00394 
00395     if (button == NULL || button->activated == FALSE)
00396        return;
00397 
00398     if (button->button_id != BUTTON_ID_DRAG && button_state != BUTTON_STATE_NORMAL) {
00399        GtkShadowType shadow_type = GTK_SHADOW_OUT;
00400        GtkStateType  state_type = GTK_STATE_NORMAL;
00401 
00402        if (button_state == BUTTON_STATE_PRESSED) {
00403            state_type = GTK_STATE_ACTIVE;
00404            shadow_type = GTK_SHADOW_IN;
00405        } else if (button_state == BUTTON_STATE_FOCUSED) {
00406            state_type = GTK_STATE_PRELIGHT;
00407            shadow_type = GTK_SHADOW_OUT;
00408        }
00409 
00410        /* draw button frame */
00411         gtk_paint_box(palette_window->drawing_area->style, palette_window->pixmap,
00412                     state_type, shadow_type,
00413                     NULL, palette_window->drawing_area, "button",
00414                     button->x, button->y,
00415                     button->width, button->height);
00416     }
00417 
00418     if (button->button_id == BUTTON_ID_DRAG) {
00419 
00420         if (palette_window->show_style == SHOW_STYLE_HORIZONTAL) {
00421             pixbuf = palette_window->pixbufs[PIXMAP_ID_DRAGAREA_VERTICAL];
00422         } else {
00423             pixbuf = palette_window->pixbufs[PIXMAP_ID_DRAGAREA_HORIZONTAL];
00424         }
00425         palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00426 
00427     } else if (button->button_id == BUTTON_ID_IME) {
00428        int ime_draw_style;
00429         GdkGC *label_gc;
00430         char *str;
00431 
00432        ime_draw_style = palette_window->ime_draw_style;
00433 
00434        pixbuf = NULL;
00435        if (palette_window->current_ime != NULL)
00436            pixbuf = palette_window->current_ime->icon_pixbuf;
00437 
00438        if (pixbuf == NULL)
00439             pixbuf = palette_window->pixbufs[PIXMAP_ID_DEFAULT_IME];
00440 
00441        if (ime_draw_style == IME_DRAW_ICON_ONLY) {
00442             palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00443        } else {
00444            int x = button->x;
00445            int y = button->y + 2;
00446 
00447            if (ime_draw_style == IME_DRAW_BOTH_ICON_TEXT) {
00448                 palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_LEFT);
00449               x  += gdk_pixbuf_get_width(pixbuf) + 1;
00450             }
00451 
00452             label_gc = palette_window->drawing_area->style->text_gc[GTK_STATE_NORMAL];
00453 
00454            if (palette_window->current_ime && palette_window->current_ime->name)
00455                 str = palette_window->current_ime->name;
00456            else
00457               str = "NoIME";
00458             if (str && *str) {
00459                 pango_layout_set_text(palette_window->pango_layout, str, strlen(str));
00460                 gdk_draw_layout(palette_window->pixmap, label_gc,
00461                              x, y,
00462                               palette_window->pango_layout);
00463             }
00464        }
00465 
00466     } else if (button->button_id == BUTTON_ID_QJBJ) {
00467 
00468         if (palette_window->qjbj_status)
00469            pixbuf = palette_window->pixbufs[PIXMAP_ID_FULLWIDTH];
00470         else
00471            pixbuf = palette_window->pixbufs[PIXMAP_ID_HALFWIDTH];
00472 
00473         palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00474 
00475     } else if (button->button_id == BUTTON_ID_PUNCT) {
00476 
00477         if (palette_window->punct_status)
00478            pixbuf = palette_window->pixbufs[PIXMAP_ID_CNPUNCT];
00479         else
00480            pixbuf = palette_window->pixbufs[PIXMAP_ID_ENPUNCT];
00481 
00482         palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00483 
00484     } else if (button->button_id == BUTTON_ID_VKB) {
00485 
00486         pixbuf = palette_window->pixbufs[PIXMAP_ID_VKB];
00487         palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00488 
00489     } else if (button->button_id == BUTTON_ID_UTILITY) {
00490 
00491         pixbuf = palette_window->pixbufs[PIXMAP_ID_UTILITY];
00492         palette_window_draw_button_image(palette_window, button, pixbuf, GTK_JUSTIFY_CENTER);
00493 
00494     }
00495 
00496     return;
00497 }
00498 
00499 void palette_window_update_layout(palette_window_t *palette_window)
00500 {
00501     palette_button_t *buttons;
00502 
00503     int pos_x, pos_y;
00504     int margin_x, margin_y;
00505     int delta_x, delta_y;
00506     int width, height;
00507     int i;
00508 
00509     PangoRectangle logical_rect;
00510 
00511     margin_x = 2;
00512     margin_y = 2;
00513 
00514     if (palette_window->show_style == SHOW_STYLE_HORIZONTAL) {
00515         /* show the toolbar with horizontal style */
00516 
00517         int width_buttons[BUTTONS_NUM] = {
00518             10, 20, 20, 20, 20, 20
00519         };
00520 
00521         int button_height = 20;
00522         int delta_x = 0;
00523 
00524         if (palette_window->ime_draw_style == IME_DRAW_ICON_ONLY) {
00525            width_buttons[BUTTON_ID_IME] = 18;
00526         } else {
00527            width_buttons[BUTTON_ID_IME] = 0;
00528            if (palette_window->ime_draw_style == IME_DRAW_BOTH_ICON_TEXT) {
00529                width_buttons[BUTTON_ID_IME] += 18;
00530            }
00531 
00532            pango_layout_get_extents(palette_window->pango_layout, NULL, &logical_rect);
00533            width_buttons[BUTTON_ID_IME] += PANGO_PIXELS(logical_rect.width);
00534         }
00535 
00536         pos_x = margin_x;
00537         pos_y = margin_y;
00538 
00539         buttons = palette_window->buttons;
00540         for (i = 0; i < BUTTONS_NUM; i++) {
00541            if (buttons[i].activated == FALSE)
00542                continue;
00543 
00544            width = width_buttons[i];
00545 
00546            buttons[i].x = pos_x;
00547            buttons[i].y = pos_y;
00548            buttons[i].width = width;
00549            buttons[i].height = button_height;
00550 
00551            pos_x += width + delta_x;
00552         }
00553 
00554         width = pos_x + margin_x;
00555         height = button_height + 2 * margin_y;
00556     } else {
00557         /* show the toolbar with vertical style */
00558         int height_buttons[BUTTONS_NUM] = {
00559             10, 18, 18, 18, 18, 18
00560         };
00561 
00562         int button_width = 20;
00563         int delta_y = 0;
00564 
00565         pos_x = margin_x;
00566         pos_y = margin_y;
00567 
00568         buttons = palette_window->buttons;
00569         for (i = 0; i < BUTTONS_NUM; i++) {
00570            if (buttons[i].activated == FALSE)
00571                continue;
00572 
00573            height = height_buttons[i];
00574 
00575            buttons[i].x = pos_x;
00576            buttons[i].y = pos_y;
00577            buttons[i].width = button_width;
00578            buttons[i].height = height;
00579 
00580            pos_y += height + delta_y;
00581         }
00582 
00583         width = button_width + 2 * margin_x;
00584         height = pos_y + margin_y;
00585     }
00586 
00587     palette_window->width = width;
00588     palette_window->height = height;
00589 
00590     gtk_widget_set_size_request(GTK_WIDGET(palette_window->drawing_area),
00591                             palette_window->width,
00592                             palette_window->height);
00593 
00594     gtk_widget_set_size_request(GTK_WIDGET(palette_window->window),
00595                             palette_window->width,
00596                             palette_window->height);
00597 
00598     palette_window_draw_layout(palette_window);
00599 
00600     return;
00601 }
00602 
00603 void palette_window_draw_layout(palette_window_t *palette_window)
00604 {
00605     GtkShadowType shadow_type = GTK_SHADOW_NONE;
00606     GtkStateType  state_type = GTK_STATE_NORMAL;
00607     palette_button_t *button;
00608     int i;
00609 
00610     if (!palette_window || !palette_window->pixmap)
00611        return;
00612 
00613     gtk_paint_box(palette_window->drawing_area->style, palette_window->pixmap,
00614                 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
00615                 NULL, palette_window->drawing_area, "button",
00616                 0, 0,
00617                 palette_window->width,
00618                 palette_window->height);
00619 
00620     for (i = 0; i < BUTTONS_NUM; i ++) {
00621        int button_state = BUTTON_STATE_NORMAL;
00622 
00623        button = &palette_window->buttons[i];
00624 
00625        if (button == palette_window->focused_button)
00626            button_state = BUTTON_STATE_FOCUSED;
00627 
00628         palette_window_draw_button(palette_window, button, button_state);
00629     }
00630     gtk_widget_queue_draw(palette_window->drawing_area);
00631 }
00632 
00633 static gboolean
00634 palette_window_check_pos_in_button(palette_button_t *button, int x, int y)
00635 {
00636     return ((button->x <= x) && (button->x + button->width >= x) &&
00637            (button->y <= y) && (button->y + button->height >= y));
00638 }
00639 
00640 palette_button_t *palette_window_get_button_from_pos(palette_window_t *palette_window, int x, int y)
00641 {
00642     palette_button_t *button;
00643     gint i;
00644 
00645     for (i = 0; i < BUTTONS_NUM; i++) {
00646        button = &palette_window->buttons[i];
00647        if (button->activated && palette_window_check_pos_in_button(button, x, y))
00648            return button;
00649     }
00650     return NULL;
00651 }
00652 
00653 void
00654 palette_window_set_position(palette_window_t *palette_window,
00655                          gint pos_x, gint pos_y)
00656 {
00657     GtkRequisition ws;
00658     gint screen_width;
00659     gint screen_height;
00660 
00661     gtk_widget_size_request(palette_window->window, &ws);
00662 
00663     screen_width = gdk_screen_width();
00664     screen_height = gdk_screen_height();
00665 
00666     if (pos_x < 0) {
00667         pos_x = 0;
00668     } else if (pos_x + ws.width > screen_width) {
00669         pos_x = screen_width - ws.width;
00670     }
00671 
00672     if (pos_y < 0) {
00673         pos_y = 0;
00674     } else if (pos_y + ws.height > screen_height) {
00675         pos_y = screen_height - ws.height;
00676     }
00677 
00678     if (palette_window->pos_x != pos_x || palette_window->pos_y != pos_y) {
00679         gtk_window_move(GTK_WINDOW(palette_window->window), pos_x, pos_y);
00680         palette_window->pos_x = pos_x;
00681         palette_window->pos_y = pos_y;
00682     }
00683 }
00684 
00685 static void palette_window_set_tooltips(palette_window_t *palette_window,
00686                                    palette_button_t *button)
00687 {
00688     if (palette_window == NULL)
00689        return;
00690 
00691     if (button == NULL ||
00692        button->activated == FALSE) {
00693        return;
00694     }
00695 
00696     gtk_tooltips_set_tip(palette_window->tooltips, palette_window->window,
00697                       palette_tooltips[button->button_id], NULL);
00698     return;
00699 }
00700 
00701 void palette_window_enable_tooltips(palette_window_t *palette_window)
00702 {
00703     if (palette_window == NULL)
00704        return;
00705 
00706     gtk_tooltips_enable(palette_window->tooltips);
00707     return;
00708 }
00709 
00710 void palette_window_disable_tooltips(palette_window_t *palette_window)
00711 {
00712     if (palette_window == NULL)
00713        return;
00714 
00715     gtk_tooltips_disable(palette_window->tooltips);
00716     return;
00717 }
00718 
00719 static void
00720 palette_window_get_menu_popup_pos(GtkMenu * menu,
00721                                   gint * x, gint * y, 
00722                                   gboolean * push_in,
00723                                   gpointer func_data)
00724 {
00725     palette_button_t *button = (palette_button_t *) func_data;
00726     GtkRequisition size_menu, size_widget;
00727     gint menu_pos_x, menu_pos_y;
00728 
00729     palette_window_t *palette_window = NULL;
00730 
00731     palette_window = (palette_window_t *)g_object_get_data(G_OBJECT(menu),
00732                                                            DATA_PALETTE_AUX_WINDOW_INFO);
00733     if (palette_window == NULL)
00734         return;
00735 
00736     gtk_widget_size_request((GtkWidget *) menu, &size_menu);
00737 
00738     menu_pos_x = 0;
00739     menu_pos_y = 0;
00740     if (palette_window->show_style == SHOW_STYLE_HORIZONTAL) {
00741         if (palette_window->pos_y - size_menu.height > 0) {
00742             menu_pos_y = palette_window->pos_y - size_menu.height;
00743         } else {
00744             gtk_widget_size_request((GtkWidget *) palette_window->window,
00745                                      &size_widget);
00746             menu_pos_y = palette_window->pos_y + size_widget.height;
00747         }
00748 
00749         menu_pos_x = palette_window->pos_x + button->x;
00750     } else {
00751         int screen_height = gdk_screen_height();
00752         int screen_width  = gdk_screen_width();
00753 
00754         menu_pos_x = palette_window->pos_x + palette_window->width;
00755         if (menu_pos_x + size_menu.width > screen_width)
00756             menu_pos_x = palette_window->pos_x - size_menu.width;
00757 
00758         menu_pos_y = palette_window->pos_y + button->y;
00759         if (menu_pos_y + size_menu.height > screen_height)
00760             menu_pos_y = screen_height - size_menu.height;
00761     }
00762 
00763     *x = menu_pos_x;
00764     *y = menu_pos_y;
00765 }
00766 
00767 void
00768 palette_window_set_show_style(palette_window_t *palette_window,
00769                            int show_style)
00770 {
00771     if (palette_window == NULL)
00772        return;
00773 
00774     palette_window->show_style = show_style;
00775     palette_window_update_layout(palette_window);
00776 
00777     palette_window_set_position(palette_window, palette_window->pos_x, palette_window->pos_y);
00778     palette_window_sync_to_property_data(palette_window);
00779     property_data_save_to_profile(palette_window->property_data, PROPERTY_DATA_FOR_LOCAL_PROFILE);
00780 }
00781 
00782 void
00783 palette_window_set_qjbj_status(palette_window_t *palette_window,
00784                             int qjbj_status)
00785 {
00786     DEBUG_printf("qjbj_status: %d\n", qjbj_status);
00787     if (palette_window->qjbj_status == qjbj_status)
00788         return;
00789 
00790     palette_window->qjbj_status = qjbj_status;
00791 
00792     palette_window_update_layout(palette_window);
00793 }
00794 
00795 void
00796 palette_window_set_punct_status(palette_window_t *palette_window,
00797                              int punct_status)
00798 {
00799     if (palette_window->punct_status == punct_status)
00800         return;
00801 
00802     palette_window->punct_status = punct_status;
00803 
00804     palette_window_update_layout(palette_window);
00805 }
00806 
00807 static void
00808 palette_window_set_focused_button(palette_window_t *palette_window,
00809                               palette_button_t *button)
00810 {
00811     palette_button_t *focused_button_old = NULL;
00812 
00813     focused_button_old = palette_window->focused_button;
00814 
00815     if (focused_button_old == button)
00816        return;
00817 
00818     if (button && button->button_id == BUTTON_ID_DRAG) {
00819        gdk_window_set_cursor(palette_window->drawing_area->window,
00820                            palette_window->moving_cursor);
00821     } else {
00822        gdk_window_set_cursor(palette_window->drawing_area->window,
00823                            palette_window->normal_cursor);
00824     }
00825 
00826     palette_window->focused_button = button;
00827     palette_window_draw_layout(palette_window);
00828 }
00829 
00830 static void
00831 palette_window_set_pressed_button(palette_window_t *palette_window,
00832                               palette_button_t *button)
00833 {
00834     palette_button_t *pressed_button_old = NULL;
00835 
00836     pressed_button_old = palette_window->pressed_button;
00837 
00838     palette_window->pressed_button = button;
00839     palette_window_draw_layout(palette_window);
00840     palette_window_draw_button(palette_window, button, BUTTON_STATE_PRESSED);
00841     gtk_widget_queue_draw(palette_window->drawing_area);
00842 }
00843 
00844 void
00845 palette_window_sync_to_property_data(palette_window_t *palette_window)
00846 {
00847     property_data_t *property_data;
00848 
00849     if (!palette_window || !palette_window->property_data)
00850         return;
00851 
00852     property_data = palette_window->property_data;
00853 
00854     property_data->pos_x_palette = palette_window->pos_x;
00855     property_data->pos_y_palette = palette_window->pos_y;
00856 
00857     property_data->show_with_vertical = FALSE;
00858     if (palette_window->show_style == SHOW_STYLE_VERTICAL)
00859         property_data->show_with_vertical = TRUE;
00860 
00861     return;
00862 }
00863 
00864 void
00865 palette_window_sync_from_property_data(palette_window_t *palette_window)
00866 {
00867     property_data_t *property_data;
00868 
00869     if (!palette_window || !palette_window->property_data)
00870         return;
00871 
00872     property_data = palette_window->property_data;
00873 
00874     palette_window->pos_x = property_data->pos_x_palette;
00875     palette_window->pos_y = property_data->pos_y_palette;
00876 
00877     palette_window->buttons[BUTTON_ID_IME].activated = TRUE;
00878     if (property_data->show_ime_button == FALSE)
00879        palette_window->buttons[BUTTON_ID_IME].activated = FALSE;
00880 
00881     palette_window->buttons[BUTTON_ID_QJBJ].activated = TRUE;
00882     if (property_data->show_qjbj_button == FALSE)
00883        palette_window->buttons[BUTTON_ID_QJBJ].activated = FALSE;
00884 
00885     palette_window->buttons[BUTTON_ID_PUNCT].activated = TRUE;
00886     if (property_data->show_punct_button == FALSE)
00887        palette_window->buttons[BUTTON_ID_PUNCT].activated = FALSE;
00888 
00889     palette_window->buttons[BUTTON_ID_VKB].activated = TRUE;
00890     if (property_data->show_vkb_button == FALSE)
00891        palette_window->buttons[BUTTON_ID_VKB].activated = FALSE;
00892 
00893     palette_window->buttons[BUTTON_ID_UTILITY].activated = TRUE;
00894     if (property_data->show_utility_button == FALSE)
00895        palette_window->buttons[BUTTON_ID_UTILITY].activated = FALSE;
00896 
00897     palette_window->show_style = SHOW_STYLE_HORIZONTAL;
00898     if (property_data->show_with_vertical)
00899        palette_window->show_style = SHOW_STYLE_VERTICAL;
00900 
00901     return;
00902 }
00903 
00904 void palette_window_hide(palette_window_t *palette_window)
00905 {
00906     if (palette_window == NULL)
00907         return;
00908 
00909     gtk_widget_hide(palette_window->window);
00910     palette_window_hide_vkb_window(palette_window);
00911 
00912     return;
00913 }
00914 
00915 /********************************************************************/
00916 /*       draging functions                                          */
00917 /********************************************************************/
00918 static void
00919 palette_window_draw_draging_frame(palette_window_t *palette_window,
00920                               int pos_x, int pos_y)
00921 {
00922     GdkGC *xor_gc;
00923     GdkGCValues values;
00924     GdkWindow *root_window;
00925 
00926     values.foreground = (palette_window->drawing_area->style->white.pixel==0 ?
00927                          palette_window->drawing_area->style->black:
00928                       palette_window->drawing_area->style->white);
00929     values.function = GDK_XOR;
00930     values.subwindow_mode = GDK_INCLUDE_INFERIORS; 
00931 
00932     root_window = gtk_widget_get_root_window (palette_window->drawing_area);
00933     xor_gc = gdk_gc_new_with_values (root_window,
00934                                      &values,
00935                                      GDK_GC_FOREGROUND |
00936                                      GDK_GC_FUNCTION |
00937                                      GDK_GC_SUBWINDOW);
00938 
00939     gdk_draw_rectangle (root_window, xor_gc, FALSE,
00940                         pos_x, pos_y,
00941                         palette_window->width - 1,
00942                         palette_window->height - 1);
00943 }
00944 
00945 static void
00946 palette_window_begin_draging(palette_window_t *palette_window,
00947                           GdkEventButton *event)
00948 {
00949     /* begin draging */
00950     palette_window->drag_x_start = (gint) event->x_root;
00951     palette_window->drag_y_start = (gint) event->y_root;
00952     palette_window->drag_x_save = (gint) event->x_root;
00953     palette_window->drag_y_save = (gint) event->y_root;
00954 
00955     /* Grab the cursor to prevent losing events. */
00956     gdk_pointer_grab (palette_window->drawing_area->window, FALSE,
00957                     GDK_BUTTON_RELEASE_MASK |
00958                     GDK_POINTER_MOTION_MASK,
00959                     NULL, palette_window->moving_cursor, event->time);
00960 
00961     palette_window_draw_draging_frame(palette_window,
00962                                   palette_window->pos_x,
00963                                   palette_window->pos_y);
00964 
00965     return;
00966 }
00967 
00968 static void
00969 palette_window_end_draging(palette_window_t *palette_window,
00970                         GdkEventButton *event)
00971 {
00972     gint pos_x, pos_y;
00973 
00974     if (palette_window->draw_draging_frame) {
00975         pos_x = palette_window->pos_x;
00976         pos_y = palette_window->pos_y;
00977 
00978         pos_x += ((gint) event->x_root - palette_window->drag_x_start);
00979         pos_y += ((gint) event->y_root - palette_window->drag_y_start);
00980 
00981         palette_window_set_position(palette_window, pos_x, pos_y);
00982         gtk_widget_queue_draw(palette_window->drawing_area);
00983 
00984         palette_window_sync_to_property_data(palette_window);
00985         property_data_save_to_profile(palette_window->property_data, PROPERTY_DATA_FOR_LOCAL_PROFILE);
00986     }
00987 
00988     gdk_pointer_ungrab(event->time);
00989 
00990     return;
00991 }
00992 
00993 static void
00994 palette_window_do_draging(palette_window_t *palette_window,
00995                        GdkEventMotion *event)
00996 {
00997     gint pos_x, pos_y;
00998 
00999     pos_x = palette_window->pos_x;
01000     pos_y = palette_window->pos_y;
01001 
01002     if (palette_window->draw_draging_frame) {
01003        /* remove the old draging frame */
01004         pos_x += (palette_window->drag_x_save - palette_window->drag_x_start);
01005         pos_y += (palette_window->drag_y_save - palette_window->drag_y_start);
01006         palette_window_draw_draging_frame(palette_window,
01007                                       pos_x, pos_y);
01008 
01009        /* draw the new draging frame */
01010         pos_x += (event->x_root - palette_window->drag_x_save);
01011         pos_y += (event->y_root - palette_window->drag_y_save);
01012         palette_window_draw_draging_frame(palette_window,
01013                                       pos_x, pos_y);
01014     } else {
01015         pos_x += ((gint) event->x_root - palette_window->drag_x_start);
01016         pos_y += ((gint) event->y_root - palette_window->drag_y_start);
01017 
01018        palette_window->drag_x_start = event->x_root;
01019        palette_window->drag_y_start = event->y_root;
01020 
01021        /* directly move the palette window */
01022         palette_window_set_position(palette_window, pos_x, pos_y);
01023     }
01024 
01025     /* save the curent draging pointer position */
01026     palette_window->drag_x_save = event->x_root;
01027     palette_window->drag_y_save = event->y_root;
01028 }
01029 
01030 /********************************************************************/
01031 /*       vkb_layout functions                                       */
01032 /********************************************************************/
01033 void palette_window_init_vkb_window(palette_window_t *palette_window)
01034 {
01035     if (palette_window->vkb_window == NULL)
01036         palette_window->vkb_window = (vkb_window_t *)vkb_window_new();
01037 
01038     return;
01039 }
01040 
01041 vkb_layout_t **palette_window_get_vkb_layout_list(palette_window_t *palette_window)
01042 {
01043     char file_name[256];
01044 
01045     if (palette_window == NULL)
01046         return NULL;
01047 
01048     if (palette_window->vkb_layout_list_inited == 0) {
01049         snprintf(file_name, 256, "%s/gtk2/%s", LE_AUX_MODULES_DIR, PALETTE_AUX_VKB_LAYOUT_FILE);
01050 
01051         palette_window->vkb_layout_list = (vkb_layout_t **)
01052             vkb_layout_list_read_from_layout_file(file_name);
01053 
01054 #ifdef DEBUG
01055         vkb_layout_list_print(palette_window->vkb_layout_list);
01056 #endif
01057 
01058         palette_window->vkb_layout_list_inited = 1;
01059     }
01060 
01061     return (palette_window->vkb_layout_list);
01062 }
01063 
01064 vkb_layout_t *palette_window_get_current_ime_vkb_layout(palette_window_t *palette_window)
01065 {
01066     int i;
01067     ime_module_t *current_ime;
01068     ImePropertyListRec *ime_property_list;
01069 
01070     if (palette_window == NULL)
01071        return NULL;
01072 
01073     current_ime = palette_window->current_ime;
01074     if (current_ime == NULL)
01075        return NULL;
01076 
01077     if (current_ime->num_vkbs <= 0 || current_ime->vkbs == NULL)
01078        return NULL;
01079 
01080     ime_property_list = current_ime->property_list;
01081     if (current_ime->num_vkbs == 1 ||
01082         ime_property_list == NULL ||
01083         ime_property_list->count <= 0 ||
01084         ime_property_list->properties == NULL)
01085         return (current_ime->vkbs[0]);
01086 
01087     for (i = 0; i < ime_property_list->count; i++) {
01088         int vkb_id = 0;
01089        ImePropertyRec *p = &(ime_property_list->properties[i]);
01090         if (!strcasecmp(p->key, "/keymapping")) {
01091             vkb_id = p->value.int_value;
01092             if (vkb_id < 0 || vkb_id >= current_ime->num_vkbs)
01093                 vkb_id = 0;
01094             return (current_ime->vkbs[vkb_id]);
01095         }
01096     }
01097 
01098     return NULL;
01099 }
01100 
01101 void palette_window_hide_vkb_window(palette_window_t *palette_window)
01102 {
01103     if (palette_window == NULL)
01104         return;
01105 
01106     palette_window->vkb_show_status = 0;
01107     vkb_window_hide(palette_window->vkb_window);
01108     return;
01109 }
01110 
01111 void palette_window_show_vkb_window_with_layout(palette_window_t *palette_window,
01112                                           vkb_layout_t *vkb_layout)
01113 {
01114     if (vkb_layout == NULL)
01115         return;
01116 
01117     palette_window_init_vkb_window(palette_window);
01118 
01119     if (palette_window->vkb_window == NULL)
01120         return;
01121 
01122     palette_window->vkb_show_status = 1;
01123     vkb_window_update_layout(palette_window->vkb_window, vkb_layout);
01124 
01125     return;
01126 }
01127 
01128 void palette_window_toggle_vkb_window(palette_window_t *palette_window)
01129 {
01130     vkb_layout_t **vkb_layout_list;
01131     vkb_layout_t *vkb_layout = NULL;
01132 
01133     if (palette_window == NULL)
01134         return;
01135 
01136     if (palette_window->vkb_show_status == 1) {
01137         palette_window_hide_vkb_window(palette_window);
01138         return;
01139     }
01140 
01141     /* need draw the current vkb layout */
01142     vkb_layout = palette_window->current_vkb_layout;
01143     if (vkb_layout == NULL) {
01144         /* get current IME vkb */
01145         vkb_layout = (vkb_layout_t *)palette_window_get_current_ime_vkb_layout(palette_window);
01146         if (vkb_layout == NULL)
01147             vkb_layout = palette_window->vkb_layout_pc_keyboard;
01148     }
01149 
01150     if (vkb_layout == NULL) {
01151         /* get the first vkb in vkb_layout_list */
01152         vkb_layout_list = (vkb_layout_t **) palette_window_get_vkb_layout_list(palette_window);
01153         if (vkb_layout_list != NULL)
01154             vkb_layout = vkb_layout_list[0];
01155     }
01156 
01157     palette_window_show_vkb_window_with_layout(palette_window, vkb_layout);
01158     return;
01159 }
01160 
01161 /********************************************************************/
01162 /*            event functions                                       */
01163 /********************************************************************/
01164 static void
01165 palette_window_destroy_event_handler(GtkWidget *widget,
01166                                  palette_window_t *palette_window)
01167 {
01168     palette_window_destroy(palette_window);
01169 }
01170 
01171 static gboolean
01172 palette_window_expose_event_handler(GtkWidget *widget,
01173                                 GdkEventExpose *event,
01174                                 palette_window_t *palette_window)
01175 {
01176     if (!palette_window->pixmap)
01177        return FALSE;
01178 
01179     gdk_draw_drawable(palette_window->drawing_area->window,
01180                     widget->style->base_gc[GTK_STATE_NORMAL],
01181                     palette_window->pixmap,
01182                     event->area.x, event->area.y,
01183                     event->area.x, event->area.y,
01184                     event->area.width, event->area.height);
01185     return FALSE;
01186 }
01187 
01188 static gboolean
01189 palette_window_configure_event_handler(GtkWidget *widget,
01190                                    GdkEventConfigure *event,
01191                                    palette_window_t *palette_window)
01192 {
01193     DEBUG_printf("palette_window_configure_event_handler =\n");
01194     if (palette_window->pixmap)
01195         gdk_pixmap_unref(palette_window->pixmap);
01196 
01197     palette_window->pixmap = gdk_pixmap_new(widget->window,
01198                             widget->allocation.width,
01199                             widget->allocation.height,
01200                             -1);
01201 
01202     palette_window_draw_layout(palette_window);
01203 
01204     return TRUE;
01205 }
01206 
01207 static gboolean
01208 palette_window_leave_event_handler(GtkWidget *widget,
01209                                GdkEventCrossing *event,
01210                                palette_window_t *palette_window)
01211 {
01212     DEBUG_printf("palette_window_leave_event_handler =\n");
01213 
01214     /* if any button already pressed then do nothing */
01215     if (palette_window->pressed_button != NULL)
01216         return TRUE;
01217 
01218     palette_window->focused_button = NULL;
01219     palette_window_draw_layout(palette_window);
01220 
01221     return TRUE;
01222 }
01223 
01224 static gboolean
01225 palette_window_pointer_press_event_handler(GtkWidget *widget,
01226                                       GdkEventButton *event,
01227                                       palette_window_t *palette_window)
01228 {
01229     GtkWidget *menu = NULL;
01230     palette_button_t *button;
01231 
01232     DEBUG_printf("palette_window_pointer_press_event_handler =\n");
01233     if (palette_window == NULL)
01234        return TRUE;
01235 
01236     if (palette_window->draging)
01237        return TRUE;
01238 
01239     button = palette_window_get_button_from_pos(palette_window, event->x, event->y);
01240     palette_window->pressed_button = button;
01241     if (button == NULL)
01242        return TRUE;
01243 
01244     if (event->button > 1) {
01245        if (button->button_id == BUTTON_ID_VKB) {
01246            if (palette_window->vkb_list_menu == NULL) {
01247               palette_window->vkb_list_menu = (GtkWidget *)palette_window_create_vkb_list_menu(palette_window);
01248             } else {
01249               palette_window->vkb_list_menu = (GtkWidget *)palette_window_update_vkb_list_menu(palette_window);
01250            }
01251            if (palette_window->vkb_list_menu != NULL) {
01252               palette_window->menu_popuped = 1;
01253               gtk_menu_popup(GTK_MENU(palette_window->vkb_list_menu), NULL, NULL,
01254                            NULL,
01255                            NULL,
01256                            event->button, event->time);
01257            }
01258        } else {
01259             if (palette_window->utility_list_menu == NULL) {
01260                 palette_window->utility_list_menu = (GtkWidget *)palette_window_create_utility_list_menu(palette_window);
01261             } else {
01262                 palette_window->utility_list_menu = (GtkWidget *)palette_window_update_utility_list_menu(palette_window);
01263            }
01264             if (palette_window->utility_list_menu != NULL) {
01265               palette_window->menu_popuped = 1;
01266                 gtk_menu_popup(GTK_MENU(palette_window->utility_list_menu), NULL, NULL,
01267                            NULL,
01268                            NULL,
01269                            event->button, event->time);
01270            } 
01271        }
01272        return TRUE;
01273     }
01274     
01275     if (button->button_id == BUTTON_ID_DRAG) {
01276         palette_window->draging = TRUE;
01277        palette_window_begin_draging(palette_window, event);
01278        return TRUE;
01279     } else if (button->button_id == BUTTON_ID_IME) {
01280         menu = palette_window->ime_list_menu;
01281         if (menu != NULL) {
01282            palette_window->menu_popuped = 1;
01283             gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
01284                            palette_window_get_menu_popup_pos,
01285                            button,
01286                            event->button, event->time);
01287         }
01288     } else if (button->button_id == BUTTON_ID_UTILITY) {
01289         if (palette_window->utility_list_menu == NULL) {
01290             palette_window->utility_list_menu = (GtkWidget *)palette_window_create_utility_list_menu(palette_window);
01291         } else {
01292             palette_window->utility_list_menu = (GtkWidget *)palette_window_update_utility_list_menu(palette_window);
01293        }
01294         if (palette_window->utility_list_menu != NULL) {
01295            palette_window->menu_popuped = 1;
01296             gtk_menu_popup(GTK_MENU(palette_window->utility_list_menu), NULL, NULL,
01297                            palette_window_get_menu_popup_pos,
01298                            button,
01299                            event->button, event->time);
01300         }
01301     }
01302     
01303     palette_window_draw_button(palette_window, button, BUTTON_STATE_PRESSED);
01304     gtk_widget_queue_draw(palette_window->drawing_area);
01305     return TRUE;
01306 }
01307 
01308 static gboolean
01309 palette_window_pointer_release_event_handler(GtkWidget *widget,
01310                                         GdkEventButton *event,
01311                                         palette_window_t *palette_window)
01312 {
01313     palette_button_t *pressed_button;
01314     palette_button_t *released_button;
01315 
01316     DEBUG_printf("palette_window_pointer_release_event_handler =\n");
01317     if (palette_window == NULL)
01318        return TRUE;
01319 
01320     if (event->button > 1)
01321        return TRUE;
01322     
01323     /* button released */
01324     if (palette_window->draging == TRUE) {
01325         palette_window->draging = FALSE;
01326        palette_window_end_draging(palette_window, event);
01327         palette_window->pressed_button = NULL;
01328         return TRUE;
01329     }
01330 
01331     pressed_button = palette_window->pressed_button;
01332     released_button = palette_window_get_button_from_pos(palette_window,
01333                                                   event->x, event->y);
01334 
01335     palette_window->draging = FALSE;
01336     palette_window->pressed_button = NULL;
01337 
01338     if (pressed_button != released_button) {
01339        /* do nothing and just redraw the focus button */
01340         palette_window->focused_button = released_button;
01341        palette_window_draw_layout(palette_window);
01342        return TRUE;
01343     }
01344 
01345     if (pressed_button == NULL)
01346        return TRUE;
01347 
01348     /* if pressed_button == released_button */
01349     if (pressed_button->button_id == BUTTON_ID_QJBJ) {
01350         palette_window_set_qjbj_status(palette_window, !palette_window->qjbj_status);
01351         palette_aux_Switch_LE_QjBj_Request(palette_window->qjbj_status);
01352     } else if (pressed_button->button_id == BUTTON_ID_PUNCT) {
01353         palette_window_set_punct_status(palette_window, !palette_window->punct_status);
01354         palette_aux_Switch_LE_Punct_Request(palette_window->punct_status);
01355     } else if (pressed_button->button_id == BUTTON_ID_VKB) {
01356        palette_window_toggle_vkb_window(palette_window);
01357 
01358        /* redraw the focused button */
01359        palette_window_draw_layout(palette_window);
01360     }
01361 
01362     return TRUE;
01363 }
01364 
01365 static gboolean
01366 palette_window_pointer_motion_event_handler(GtkWidget *widget,
01367                                        GdkEventMotion *event,
01368                                        palette_window_t *palette_window)
01369 {
01370     if (palette_window == NULL)
01371        return TRUE;
01372 
01373     DEBUG_printf("palette_window_pointer_motion_event_handler\n");
01374     if ((event->state & GDK_BUTTON1_MASK) != 0 &&
01375         palette_window->draging) {
01376        palette_window_do_draging(palette_window, event);
01377     } else {
01378         palette_button_t *button;
01379         DEBUG_printf("begin set focused button\n");
01380 
01381        /* if any button already pressed then do nothing */
01382        if (palette_window->pressed_button != NULL)
01383            return TRUE;
01384 
01385        button = palette_window_get_button_from_pos(palette_window, event->x, event->y);
01386        if (button == palette_window->focused_button)
01387            return TRUE;
01388 
01389        if (button && button->button_id == BUTTON_ID_DRAG) {
01390            gdk_window_set_cursor(palette_window->drawing_area->window,
01391                               palette_window->moving_cursor);
01392        } else {
01393            gdk_window_set_cursor(palette_window->drawing_area->window,
01394                               palette_window->normal_cursor);
01395        }
01396 
01397        palette_window_set_tooltips(palette_window, button);
01398        palette_window->focused_button = button;
01399        palette_window_draw_layout(palette_window);
01400     }
01401 
01402     return TRUE;
01403 }