~ubuntu-branches/ubuntu/hardy/uim/hardy

« back to all changes in this revision

Viewing changes to helper/helper-candwin-gtk.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2005-12-04 13:10:42 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051204131042-ktzc8b17zi7a3cw8
Tags: 1:0.4.9.1-1
* New upstream release
* libuim0-nox, libuim-nox-dev, and libuim0-dbg-nox is now obsolete.
  Because libuim0 does not depends on X11. They now become dummy package,
  therefore you can safely remove them.
* Add --enable-debug in configure again.
* debian/patches/08_fix_privilage_escalation_CVE_2005_3149: disabled.
* Fix Error on purge because update-uim-config is not found.
  (closes: Bug#339345)
* uim-qt: New package for Qt utilities for uim. qt-immodule does not
  contained yet because of Debian's Qt3 does not support immodule and
  because uim does not recognize libqt4-dev's headers properly. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 
3
 
  Copyright (c) 2003,2004 uim Project http://uim.freedesktop.org/
 
3
  Copyright (c) 2003-2005 uim Project http://uim.freedesktop.org/
4
4
 
5
5
  All rights reserved.
6
6
 
17
17
     may be used to endorse or promote products derived from this software
18
18
     without specific prior written permission.
19
19
 
20
 
  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21
21
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
22
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 
  ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
23
  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24
24
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
25
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
26
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44
44
#include <sys/types.h>
45
45
#include <unistd.h>
46
46
 
 
47
#include "../gtk/caret-state-indicator.h"
 
48
 
47
49
#define UIM_TYPE_CANDIDATE_WINDOW       (candidate_window_get_type())
48
50
#define UIM_CANDIDATE_WINDOW(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj), candidate_window_get_type(), UIMCandidateWindow))
49
51
#define UIM_IS_CANDIDATE_WINDOW(obj)    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UIM_TYPE_CANDIDATE_WINDOW))
67
69
  gint candidate_index;
68
70
  gint page_index;
69
71
 
 
72
  gint pos_x;
 
73
  gint pos_y;
 
74
  gint width;
 
75
  gint height;
 
76
 
 
77
  GtkWidget *caret_state_indicator;
 
78
 
70
79
  gboolean is_active;
71
80
};
72
81
 
87
96
static void uim_cand_win_gtk_set_index(UIMCandidateWindow *cwin, gint index);
88
97
static void uim_cand_win_gtk_set_page(UIMCandidateWindow *cwin, gint page);
89
98
 
 
99
static void uim_cand_win_gtk_layout(void);
 
100
 
90
101
#define NR_CANDIDATES 10 /* FIXME! not used */
91
102
#define CANDWIN_DEFAULT_WIDTH   80
92
103
 
113
124
#if 0
114
125
static gboolean tree_view_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data);
115
126
#endif
 
127
static gboolean configure_event_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
116
128
 
117
129
static GType candidate_window_type = 0;
118
130
static GTypeInfo const object_info = {
129
141
 
130
142
static gint cand_win_gtk_signals[NR_SIGNALS] = {0};
131
143
 
132
 
static int read_tag;
 
144
static unsigned int read_tag;
133
145
 
134
146
static void init_candidate_win(void);
135
147
static void candwin_activate(gchar **str);
211
223
  idx = *indicies + cwin->display_limit * cwin->page_index;
212
224
 
213
225
  if (!path_currently_selected && cwin->candidate_index != idx) {
214
 
    cwin->candidate_index = idx;
215
 
    g_signal_emit(G_OBJECT(cwin),
216
 
                  cand_win_gtk_signals[INDEX_CHANGED_SIGNAL], 0);
217
 
 
 
226
    if (cwin->candidate_index >= 0) {
 
227
      cwin->candidate_index = idx;
 
228
      g_signal_emit(G_OBJECT(cwin),
 
229
                    cand_win_gtk_signals[INDEX_CHANGED_SIGNAL], 0);
 
230
    }
 
231
 
 
232
    update_label(cwin);
 
233
 
 
234
    if (cwin->candidate_index < 0)
 
235
      return FALSE;
 
236
    else
 
237
      return TRUE;
 
238
  } else {
 
239
    update_label(cwin);
 
240
 
 
241
    return TRUE;
218
242
  }
219
 
 
220
 
  update_label(cwin);
221
 
 
222
 
  return TRUE;
223
243
}
224
244
 
225
245
#if 0
276
296
  cwin = candidate_window_new();
277
297
  g_signal_connect(G_OBJECT(cwin), "index-changed",
278
298
                   G_CALLBACK(index_changed_cb), NULL);
 
299
  g_signal_connect(G_OBJECT(cwin), "configure_event",
 
300
                   G_CALLBACK(configure_event_cb), NULL);
279
301
}
280
302
 
281
303
static void
285
307
  GtkTreeViewColumn *column; 
286
308
  GtkWidget *vbox;
287
309
  GtkTreeSelection *selection;
 
310
  GdkRectangle cursor_location;
288
311
  
289
312
  vbox = gtk_vbox_new(FALSE, 0);
290
313
 
344
367
                   G_CALLBACK(tree_view_button_press), cwin);
345
368
#endif
346
369
 
 
370
  cwin->pos_x = 0;
 
371
  cwin->pos_y = 0;
347
372
  cwin->is_active = FALSE;
 
373
  cwin->caret_state_indicator = caret_state_indicator_new();
 
374
 
 
375
  cursor_location.x = 0;
 
376
  cursor_location.y = 0;
 
377
  cursor_location.height = 0;
 
378
  caret_state_indicator_set_cursor_location(cwin->caret_state_indicator, &cursor_location);
348
379
 
349
380
  gtk_widget_show(cwin->scrolled_window);
350
381
  gtk_widget_show(cwin->view);
359
390
  gint i, nr_stores = 1;
360
391
  guint j = 1;
361
392
  gchar *utf8_str;
362
 
  gint candwin_width, candwin_height;
363
393
  const gchar *charset;
364
394
  guint display_limit;
365
395
  GSList *candidates = NULL;
374
404
    g_object_unref(G_OBJECT(store));
375
405
  }
376
406
 
377
 
  gtk_window_get_size(GTK_WINDOW(cwin), &candwin_width, &candwin_height);
378
 
  if (candwin_width > CANDWIN_DEFAULT_WIDTH)
379
 
    gtk_window_resize(GTK_WINDOW(cwin),
380
 
                    CANDWIN_DEFAULT_WIDTH, candwin_height);
381
 
  
382
407
  if (!strncmp(str[1], "charset=", 8))
383
408
    charset = str[1] + 8;
384
409
  else
422
447
 
423
448
  /* create GtkListStores, and set candidates */
424
449
  for (i = 0; i < nr_stores; i++) {
425
 
    GtkListStore *store = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING);
 
450
    GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
426
451
    GSList *node;
427
452
 
428
453
    g_ptr_array_add(cwin->stores, store);
434
459
    {
435
460
      GtkTreeIter ti;
436
461
      if (node) {
437
 
        gchar *cand = node->data;
 
462
        gchar *str = node->data;
 
463
        gchar **column = g_strsplit(str, "\t", 2);
438
464
        gtk_list_store_append(store, &ti);
439
465
        gtk_list_store_set(store, &ti,
440
 
                           COLUMN_HEADING, j + 1,
441
 
                           COLUMN_CANDIDATE, cand,
 
466
                           COLUMN_HEADING, column[0],
 
467
                           COLUMN_CANDIDATE, column[1],
442
468
                           TERMINATOR);
443
 
        g_free(cand);
 
469
        g_strfreev(column);
 
470
        g_free(str);
444
471
      } else {
445
472
        /* No need to set any data for empty row. */
446
473
      }
448
475
  }
449
476
 
450
477
  uim_cand_win_gtk_set_page(cwin, 0);
 
478
  update_label(cwin);
 
479
 
451
480
  gtk_widget_show_all(GTK_WIDGET(cwin));
452
481
  cwin->is_active = TRUE;
453
482
}
464
493
static void
465
494
candwin_move(char **str)
466
495
{
467
 
  int x, y;
468
 
  int topwin_x, topwin_y;
469
 
  int cw_wi, cw_he, sc_wi, sc_he;
470
 
 
471
 
  sscanf(str[1], "%d", &topwin_x);
472
 
  sscanf(str[2], "%d", &topwin_y);
473
 
 
474
 
  gtk_window_get_size(GTK_WINDOW(cwin), &cw_wi, &cw_he);
475
 
 
476
 
  sc_wi = gdk_screen_get_width(gdk_screen_get_default());
477
 
  sc_he = gdk_screen_get_height(gdk_screen_get_default());
478
 
 
479
 
  if (sc_wi < topwin_x + cw_wi) {
480
 
    x = topwin_x - cw_wi;
481
 
  } else {
482
 
    x = topwin_x;
483
 
  }
484
 
 
485
 
  if (sc_he < topwin_y + cw_he) {
486
 
    /* FIXME : How can I determine the preedit height? */
487
 
    y = topwin_y - cw_he - 20;
488
 
  } else {
489
 
    y = topwin_y;
490
 
  }
491
 
 
492
 
  gtk_window_move(GTK_WINDOW(cwin), x, y);
 
496
  sscanf(str[1], "%d", &cwin->pos_x);
 
497
  sscanf(str[2], "%d", &cwin->pos_y);
 
498
 
 
499
  uim_cand_win_gtk_layout();
493
500
}
494
501
 
495
502
static void
506
513
  cwin->is_active = FALSE;
507
514
}
508
515
 
 
516
static void
 
517
caret_state_show(gchar **str)
 
518
{
 
519
  int timeout;
 
520
 
 
521
  sscanf(str[1], "%d", &timeout);
 
522
  caret_state_indicator_update(cwin->caret_state_indicator, cwin->pos_x, cwin->pos_y, str[2]);
 
523
  if (timeout != 0)
 
524
    caret_state_indicator_set_timeout(cwin->caret_state_indicator, timeout * 1000);
 
525
  gtk_widget_show_all(GTK_WIDGET(cwin->caret_state_indicator));
 
526
}
 
527
 
 
528
static void
 
529
caret_state_update()
 
530
{
 
531
  caret_state_indicator_update(cwin->caret_state_indicator, cwin->pos_x, cwin->pos_y, NULL);
 
532
}
 
533
 
 
534
static void
 
535
caret_state_hide()
 
536
{
 
537
  gtk_widget_hide(cwin->caret_state_indicator);
 
538
}
 
539
 
509
540
static void str_parse(gchar *str)
510
541
{
511
542
  gchar **tmp;
512
 
  int i = 0;
 
543
  gchar *command;
513
544
 
514
545
  tmp = g_strsplit(str, "\n", 0);
 
546
  command = tmp[0];
515
547
 
516
 
  while (tmp[i]) {
517
 
    if (strcmp("activate", tmp[i]) == 0) {
 
548
  if (command) {
 
549
    if (strcmp("activate", command) == 0) {
518
550
      candwin_activate(tmp);
519
 
    } else if (strcmp("select", tmp[i]) == 0) {
 
551
    } else if (strcmp("select", command) == 0) {
520
552
      candwin_update(tmp);
521
 
    } else if (strcmp("show", tmp[i]) == 0) {
 
553
    } else if (strcmp("show", command) == 0) {
522
554
      candwin_show();
523
 
    } else if (strcmp("hide", tmp[i]) == 0) {
 
555
    } else if (strcmp("hide", command) == 0) {
524
556
      gtk_widget_hide_all(GTK_WIDGET(cwin));
525
 
    } else if (strcmp("move", tmp[i]) == 0) {
 
557
    } else if (strcmp("move", command) == 0) {
526
558
      candwin_move(tmp);
527
 
    } else if (strcmp("deactivate", tmp[i]) == 0) {
 
559
    } else if (strcmp("deactivate", command) == 0) {
528
560
      candwin_deactivate();
 
561
    } else if (strcmp("show_caret_state", command) == 0) {
 
562
      caret_state_show(tmp);
 
563
    } else if (strcmp("update_caret_state", command) == 0) {
 
564
      caret_state_update();
 
565
    } else if (strcmp("hide_caret_state", command) == 0) {
 
566
      caret_state_hide();
529
567
    }
530
 
    i++;
531
568
  }
532
569
  g_strfreev(tmp);
533
570
}
534
571
 
535
 
static void
536
 
read_cb(gpointer p, int fd, GdkInputCondition c)
 
572
#define CANDIDATE_BUFFER_SIZE   4096
 
573
static gboolean
 
574
read_cb(GIOChannel *channel, GIOCondition c, gpointer p)
537
575
{
538
 
  char buf[1024];
 
576
  char buf[CANDIDATE_BUFFER_SIZE];
 
577
  char *read_buf = strdup("");
539
578
  int i = 0;
540
579
  int n;
541
580
  gchar **tmp;
 
581
  int fd = g_io_channel_unix_get_fd(channel);
542
582
 
543
 
  n = read(fd, buf, 1024 - 1);
544
 
  if (n == 0) {
545
 
    close(fd);
546
 
    exit(-1);
 
583
  while (uim_helper_fd_readable(fd) > 0) {
 
584
    n = read(fd, buf, CANDIDATE_BUFFER_SIZE - 1);
 
585
    if (n == 0) {
 
586
      close(fd);
 
587
      exit(-1);
 
588
    }
 
589
    if (n == -1)
 
590
      return TRUE;
 
591
    buf[n] = '\0';
 
592
    read_buf = realloc(read_buf, strlen(read_buf) + n + 1);
 
593
    strcat(read_buf, buf);
547
594
  }
548
 
  if (n == -1)
549
 
    return;
550
595
 
551
 
  buf[n] = '\0';
552
 
  tmp = g_strsplit(buf, "\n\n", 0);
 
596
  tmp = g_strsplit(read_buf, "\n\n", 0);
553
597
 
554
598
  while (tmp[i]) {
555
599
    str_parse(tmp[i]);
556
600
    i++;
557
601
  }
558
602
  g_strfreev(tmp);
559
 
  return;
 
603
  free(read_buf);
 
604
  return TRUE;
560
605
}
561
606
 
562
607
int
563
608
main(int argc, char *argv[])
564
609
{
 
610
  GIOChannel *channel;
 
611
 
565
612
  gtk_set_locale();
566
613
  gtk_init(&argc, &argv);
567
614
 
568
615
  init_candidate_win();
569
616
 
570
 
  read_tag = gdk_input_add(0, (GdkInputCondition)GDK_INPUT_READ,
571
 
                           read_cb, 0);
 
617
  channel = g_io_channel_unix_new(0);
 
618
  read_tag = g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR,
 
619
                            read_cb, 0);
 
620
  g_io_channel_unref(channel);
 
621
 
572
622
  gtk_main();
573
623
  return 0;
574
624
}
586
636
static void
587
637
uim_cand_win_gtk_set_index(UIMCandidateWindow *cwin, gint index)
588
638
{
589
 
  gint new_page = 0;
 
639
  gint new_page;
590
640
 
591
641
  g_return_if_fail(UIM_IS_CANDIDATE_WINDOW(cwin));
592
642
 
593
 
  if (index < 0)
594
 
    cwin->candidate_index = cwin->nr_candidates - 1;
595
 
  else if ((guint) index >= cwin->nr_candidates)
 
643
  if (index >= (gint) cwin->nr_candidates)
596
644
    cwin->candidate_index = 0;
597
645
  else
598
646
    cwin->candidate_index = index;
599
647
 
600
 
  if (cwin->display_limit)
 
648
  if (cwin->candidate_index >= 0 && cwin->display_limit)
601
649
    new_page = cwin->candidate_index / cwin->display_limit;
 
650
  else
 
651
    new_page = cwin->page_index;
602
652
 
603
653
  if (cwin->page_index != new_page)
604
654
    uim_cand_win_gtk_set_page(cwin, new_page);
628
678
uim_cand_win_gtk_set_page(UIMCandidateWindow *cwin, gint page)
629
679
{
630
680
  guint len, new_page;
631
 
  guint new_index;
 
681
  gint new_index;
632
682
 
633
683
  g_return_if_fail(UIM_IS_CANDIDATE_WINDOW(cwin));
634
684
  g_return_if_fail(cwin->stores);
658
708
      new_index
659
709
        = (new_page * cwin->display_limit) + (cwin->candidate_index % cwin->display_limit);
660
710
    else
661
 
      new_index = new_page * cwin->display_limit;
 
711
      new_index = -1;
662
712
  } else {
663
713
    new_index = cwin->candidate_index;
664
714
  }
665
715
 
666
 
  if (new_index >= cwin->nr_candidates)
 
716
  if (new_index >= (gint) cwin->nr_candidates)
667
717
    new_index = cwin->nr_candidates - 1;
668
718
 
 
719
 /* shrink the window */
 
720
  gtk_window_resize(GTK_WINDOW(cwin), CANDWIN_DEFAULT_WIDTH, 1);
 
721
 
669
722
  uim_cand_win_gtk_set_index(cwin, new_index);
670
723
}
 
724
 
 
725
static void
 
726
uim_cand_win_gtk_layout()
 
727
{
 
728
  int x, y;
 
729
  int screen_width, screen_height;
 
730
 
 
731
  screen_width = gdk_screen_get_width(gdk_screen_get_default());
 
732
  screen_height = gdk_screen_get_height(gdk_screen_get_default());
 
733
 
 
734
  if (screen_width < cwin->pos_x + cwin->width)
 
735
    x = cwin->pos_x - cwin->width;
 
736
  else
 
737
    x = cwin->pos_x;
 
738
 
 
739
  if (screen_height < cwin->pos_y + cwin->height)
 
740
    y = cwin->pos_y - cwin->height - 20; /* FIXME: Preedit height is needed to
 
741
                                            be sent by uim-xim */
 
742
  else
 
743
    y = cwin->pos_y;
 
744
 
 
745
  gtk_window_move(GTK_WINDOW(cwin), x, y);
 
746
}
 
747
 
 
748
static gboolean
 
749
configure_event_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
 
750
{
 
751
  cwin->width = event->width;
 
752
  cwin->height = event->height;
 
753
 
 
754
  uim_cand_win_gtk_layout();
 
755
 
 
756
  return FALSE;
 
757
}