Compare commits
13 Commits
path-point
...
gtk-new-im
Author | SHA1 | Date | |
---|---|---|---|
|
257e0f26ef | ||
|
f787ebb03f | ||
|
5d24f08d0a | ||
|
f3eb790c9e | ||
|
9624060bda | ||
|
d24b426b92 | ||
|
f109da8d74 | ||
|
e31ae4384b | ||
|
850653e8c7 | ||
|
cc7c62e0e2 | ||
|
0dcf14976d | ||
|
4ca0a710cd | ||
|
6ae1449a66 |
167
ChangeLog
167
ChangeLog
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1,3 +1,161 @@
|
||||
Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{gtkimcontextxim.[ch],imxim.c}: Rip
|
||||
out support for multiple locales; that simple doesn't
|
||||
work reliably with current Xlib
|
||||
|
||||
* gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch]
|
||||
gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c:
|
||||
Add support for positioning the cursor within the preedit string.
|
||||
|
||||
* modules/input/gtkimcontextxim.[ch]:
|
||||
|
||||
Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* modules/input/{imxim.c,gtkimcontextxim.[ch]}: Start
|
||||
at XIM input method module.
|
||||
|
||||
* gtk/gtktextview.c: Check for bindings after passing
|
||||
events to im context filter.
|
||||
|
||||
Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.c (add_preedit_attrs): Handle
|
||||
empty attribute lists properly.
|
||||
|
||||
Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/queryimmodules.c (main): Return non-zero exit
|
||||
status if errors were encountered querying any
|
||||
modules.
|
||||
|
||||
* modules/input/Makefile.am (moduledir): remove
|
||||
leftover bin program target.
|
||||
|
||||
* docs/make-todo: Fix typo in error message.
|
||||
|
||||
Sat Sep 16 14:04:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Add modules/input/Makefile
|
||||
|
||||
Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h: include gtkmodule.h gtkoldeditable.h,
|
||||
don't include gtkthemes.h.
|
||||
|
||||
* gtk/testgtk.c gtk/testtext.c: Set environment variables
|
||||
to point
|
||||
|
||||
* gtk/Makefile.am: Add new .c and .h files, build
|
||||
gtk-query-immodules and use it to create a gtk.immodules
|
||||
file for use of test programs.
|
||||
|
||||
* gtk/gtkpreview.c: remove extra blank line.
|
||||
|
||||
Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table):
|
||||
Add the ability to add extra tables beyond the default
|
||||
one, and also the ability to have compose sequences
|
||||
that are prefixes of other compose sequences.
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Export a preedit string which
|
||||
consists of possible candidates for keystrokes that have
|
||||
been entered but not yet committed.
|
||||
|
||||
* gtk/gtkimcontext.[ch] gtk/immulticontext.[ch]
|
||||
gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset()
|
||||
|
||||
* gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems):
|
||||
Add a function to add input-method switching menu items
|
||||
to a menu.
|
||||
|
||||
* gtk/gtkimmulticontext.[ch]: Properly handly set_client_window
|
||||
when switching input methods.
|
||||
|
||||
* gtk/gtkimcontextsimple.[ch]: Change the format of
|
||||
the compose table to allow compose tables of different
|
||||
lengths / sequence.
|
||||
|
||||
Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkimmodule.[ch]: Support routines for loading
|
||||
GtkIMContext implementations dynamically at runtime.
|
||||
|
||||
* modules/input/imcyrillic-translit.c: A sample input
|
||||
method (based on GtkIMContextSimple with an extra table),
|
||||
which demonstrates preedit strings and the module
|
||||
system for input modules
|
||||
|
||||
* gtk/queryimmodules.c: Program to query the available
|
||||
input modules and write the results into a file.
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the
|
||||
generic code from gtkthemes into a new abstraction
|
||||
GtkModule which has the logic for implementing
|
||||
a loadable module which implements a number of
|
||||
GObject types.
|
||||
|
||||
Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkeditable.[ch]: Convert GtkEditable from
|
||||
a class into an interface
|
||||
|
||||
* gtk/gtkoldeditable.[ch]: Move the old editable
|
||||
implementation into here, so legacy widgets can
|
||||
still rely on the implemenation. GtkOldEditable
|
||||
exports GtkEditable. Make selection handling
|
||||
code use new text conversion functions (and
|
||||
handle UTF-8 as a side-effect). Use GtkClipboard
|
||||
for CLIPBOARD.
|
||||
|
||||
* gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c:
|
||||
Adopt to match above changes.
|
||||
|
||||
* gtk/gtkentry.[ch]: Implement GtkEditable directly,
|
||||
avoid GtkOldEditable implementation. Restructure
|
||||
to reduce number of places that modify state directly.
|
||||
Move to GtkBindingSet. Display the preedit string.
|
||||
Queue recomputation of PangoLayout and scroll position
|
||||
to improve effiency of doing complex changes naively.
|
||||
Add a menu with cut/copy/paste and input method selection.
|
||||
|
||||
Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string()
|
||||
to set preedit string and attributes; display preedit string by
|
||||
inserting string and attributes at cursor when creating the
|
||||
GtkTextLineDisplay.
|
||||
|
||||
* gtk/gtktextlayout.c: Move all conversions between byte
|
||||
positions in PangoLayout and GtkTextIter into new functions
|
||||
line_display_iter_to_index/index_to_iter that properly
|
||||
handle the preedit string.
|
||||
|
||||
* gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify
|
||||
it to return const char * (eventually will end up
|
||||
as GCONST char *, most likely.)
|
||||
|
||||
* gtk/gtktextview.[ch]: Handle the preedit string, call
|
||||
gtk_im_context_reset() as necessary, add a menu to switch
|
||||
input methods.
|
||||
|
||||
* gtk/gtktextlayout.[ch]: Remove useless
|
||||
gtk_text_layout_get_log_attrs() function.
|
||||
|
||||
Thu Sep 14 12:43:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtk.h gtk/Makefile.am: Add gtkclipboard.[ch]
|
||||
|
||||
Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktexttypes.[ch]: Remove g_convert (moved to
|
||||
@@ -71,15 +229,6 @@ Thu Sep 14 12:21:12 2000 Owen Taylor <otaylor@redhat.com>
|
||||
* gtk/gtkselection.c (gtk_selection_data_copy/free): Copy
|
||||
and free selection_data->data properly
|
||||
|
||||
Sat Sep 9 17:15:45 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add
|
||||
extra config options "im_module_file" (cache file for
|
||||
input method modules), and "im_module_path" - path
|
||||
to look for modules when generating cache file.
|
||||
|
||||
This doesn't scale.
|
||||
|
||||
Sat Sep 9 10:23:53 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtkthemes.c: Remove some unecessary includes.
|
||||
|
@@ -1033,4 +1033,5 @@ gtk/makefile.mingw
|
||||
gtk/gtkcompat.h
|
||||
modules/Makefile
|
||||
modules/linux-fb/Makefile
|
||||
modules/input/Makefile
|
||||
], [chmod +x gtk-config-2.0])
|
||||
|
@@ -196,7 +196,7 @@ class TodoParser (xmllib.XMLParser):
|
||||
|
||||
def start_contact(self,attributes):
|
||||
if not self.entry:
|
||||
raise ParseError, "<contact> tag must be in <contact>"
|
||||
raise ParseError, "<contact> tag must be in <entry>"
|
||||
if self.in_data:
|
||||
raise ParseError, "Unexpected <contact> tag in content"
|
||||
self.in_data = 1
|
||||
|
129
gtk-config.in
129
gtk-config.in
@@ -1,129 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
glib_libs="@glib_libs@"
|
||||
glib_cflags="@glib_cflags@"
|
||||
glib_thread_libs="@glib_thread_libs@"
|
||||
glib_thread_cflags="@glib_thread_cflags@"
|
||||
|
||||
target=@gdktarget@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
exec_prefix_set=no
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: gtk-config [OPTIONS] [LIBRARIES]
|
||||
Options:
|
||||
[--prefix[=DIR]]
|
||||
[--exec-prefix[=DIR]]
|
||||
[--target=gdktarget]
|
||||
[--version]
|
||||
[--libs]
|
||||
[--cflags]
|
||||
Libraries:
|
||||
gtk
|
||||
gthread
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage 1 1>&2
|
||||
fi
|
||||
|
||||
lib_gtk=yes
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) optarg= ;;
|
||||
esac
|
||||
|
||||
case $1 in
|
||||
--prefix=*)
|
||||
prefix=$optarg
|
||||
if test $exec_prefix_set = no ; then
|
||||
exec_prefix=$optarg
|
||||
fi
|
||||
;;
|
||||
--prefix)
|
||||
echo_prefix=yes
|
||||
;;
|
||||
--exec-prefix=*)
|
||||
exec_prefix=$optarg
|
||||
exec_prefix_set=yes
|
||||
;;
|
||||
--target=*)
|
||||
target=$optarg
|
||||
;;
|
||||
--exec-prefix)
|
||||
echo_exec_prefix=yes
|
||||
;;
|
||||
--version)
|
||||
echo @GTK_MAJOR_VERSION@.@GTK_MINOR_VERSION@.@GTK_MICRO_VERSION@
|
||||
;;
|
||||
--cflags)
|
||||
echo_cflags=yes
|
||||
;;
|
||||
--libs)
|
||||
echo_libs=yes
|
||||
;;
|
||||
gtk)
|
||||
lib_gtk=yes
|
||||
;;
|
||||
gthread)
|
||||
lib_gthread=yes
|
||||
;;
|
||||
*)
|
||||
usage 1 1>&2
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test "$echo_prefix" = "yes"; then
|
||||
echo $prefix
|
||||
fi
|
||||
|
||||
if test "$echo_exec_prefix" = "yes"; then
|
||||
echo $exec_prefix
|
||||
fi
|
||||
|
||||
if test "$lib_gthread" = "yes"; then
|
||||
glib_cflags="$glib_thread_cflags"
|
||||
glib_libs="$glib_thread_libs"
|
||||
fi
|
||||
|
||||
if test "$echo_cflags" = "yes"; then
|
||||
if test @includedir@ != /usr/include ; then
|
||||
includes=-I@includedir@
|
||||
for i in $glib_cflags ; do
|
||||
if test $i = -I@includedir@ ; then
|
||||
includes=""
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo -I@libdir@/gtk+/include $includes $glib_cflags @PANGO_CFLAGS@ @more_cflags@
|
||||
fi
|
||||
|
||||
if test "$echo_libs" = "yes"; then
|
||||
my_glib_libs=
|
||||
libdirs=-L@libdir@
|
||||
for i in $glib_libs ; do
|
||||
if test $i != -L@libdir@ ; then
|
||||
if test -z "$my_glib_libs" ; then
|
||||
my_glib_libs="$i"
|
||||
else
|
||||
my_glib_libs="$my_glib_libs $i"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
<<<<<<< gtk-config.in
|
||||
echo $libdirs @x_ldflags@ -lgtk $my_glib_libs @INTLLIBS@ @x_libs@ @GDK_WLIBS@ @MATH_LIB@
|
||||
=======
|
||||
echo $libdirs @more_ldflags@ -lgtk-$target -lgdk_pixbuf -lgdk-$target $my_glib_libs @INTLLIBS@ @PANGO_LIBS@ @more_libs@ @GDK_WLIBS@ @MATH_LIB@
|
||||
>>>>>>> 1.21
|
||||
fi
|
||||
|
@@ -18,6 +18,7 @@ testtree
|
||||
gtkcompat.h
|
||||
testthreads
|
||||
libgtk.la
|
||||
gtkfeatures.h
|
||||
gtkmarshal.h
|
||||
gtktypebuiltins.h
|
||||
gtkmarshal.c
|
||||
@@ -29,3 +30,5 @@ testdnd
|
||||
stamp-gtktypebuiltins.h
|
||||
stamp-gtkmarshal.h
|
||||
stamp-gtk.defs
|
||||
gtk-query-immodules-2.0
|
||||
gtk.immodules
|
@@ -98,6 +98,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
|
||||
gtkhsv.h \
|
||||
gtkimage.h \
|
||||
gtkimcontext.h \
|
||||
gtkimmodule.h \
|
||||
gtkimmulticontext.h \
|
||||
gtkinputdialog.h \
|
||||
gtkinvisible.h \
|
||||
@@ -114,7 +115,9 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
|
||||
gtkmenuitem.h \
|
||||
gtkmenushell.h \
|
||||
gtkmisc.h \
|
||||
gtkmodule.h \
|
||||
gtknotebook.h \
|
||||
gtkoldeditable.h \
|
||||
gtkobject.h \
|
||||
gtkoptionmenu.h \
|
||||
gtkpacker.h \
|
||||
@@ -150,7 +153,6 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
|
||||
gtktexttagtable.h \
|
||||
gtktextview.h \
|
||||
gtktext.h \
|
||||
gtkthemes.h \
|
||||
gtktipsquery.h \
|
||||
gtktogglebutton.h \
|
||||
gtktoolbar.h \
|
||||
@@ -189,6 +191,7 @@ gtk_semipublic_h_sources = @STRIP_BEGIN@ \
|
||||
# GTK+ header files that don't get installed
|
||||
gtk_private_h_sources = @STRIP_BEGIN@ \
|
||||
gtktexttagprivate.h \
|
||||
gtkthemes.h \
|
||||
@STRIP_END@
|
||||
|
||||
# GTK+ C sources to build the library from
|
||||
@@ -242,6 +245,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
|
||||
gtkimcontext.c \
|
||||
gtkimcontextsimple.c \
|
||||
gtkimcontextsimple.h \
|
||||
gtkimmodule.c \
|
||||
gtkimmulticontext.c \
|
||||
gtkinputdialog.c \
|
||||
gtkintl.h \
|
||||
@@ -260,8 +264,10 @@ gtk_c_sources = @STRIP_BEGIN@ \
|
||||
gtkmenuitem.c \
|
||||
gtkmenushell.c \
|
||||
gtkmisc.c \
|
||||
gtkmodule.c \
|
||||
gtknotebook.c \
|
||||
gtkobject.c \
|
||||
gtkoldeditable.c \
|
||||
gtkoptionmenu.c \
|
||||
gtkpacker.c \
|
||||
gtkpaned.c \
|
||||
@@ -518,11 +524,11 @@ install-data-local:
|
||||
uninstall-local:
|
||||
rm -f $(DESTDIR)$(datadir)/themes/Default/gtk-2.0/gtkrc
|
||||
|
||||
#
|
||||
# test programs, not to be installed
|
||||
#
|
||||
noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple testtextbuffer # testthreads
|
||||
DEPS = @gtktargetlib@ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la $(top_builddir)/gdk/@gdktargetlib@
|
||||
############################################################################
|
||||
|
||||
DEPS = @gtktargetlib@ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la $(top_builddir)/gdk/@gdktargetlib@
|
||||
TEST_DEPS = $(DEPS) gtk.immodules
|
||||
|
||||
LDADDS = @STRIP_BEGIN@ \
|
||||
@gtktargetlib@ \
|
||||
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la \
|
||||
@@ -535,15 +541,34 @@ LDADDS = @STRIP_BEGIN@ \
|
||||
@GTK_LIBS_EXTRA@ \
|
||||
-lm \
|
||||
@STRIP_END@
|
||||
testgtk_DEPENDENCIES = $(DEPS)
|
||||
testcalendar_DEPENDENCIES = $(DEPS)
|
||||
testinput_DEPENDENCIES = $(DEPS)
|
||||
testselection_DEPENDENCIES = $(DEPS)
|
||||
testrgb_DEPENDENCIES = $(DEPS)
|
||||
testtext_DEPENDENCIES = $(DEPS)
|
||||
testdnd_DEPENDENCIES = $(DEPS)
|
||||
simple_DEPENDENCIES = $(DEPS)
|
||||
#testthreads_DEPENDENCIES = $(DEPS)
|
||||
|
||||
#
|
||||
# Installed tools
|
||||
#
|
||||
bin_PROGRAMS = gtk-query-immodules-2.0
|
||||
|
||||
gtk_query_immodules_2_0_DEPENDENCIES = $(DEPS)
|
||||
gtk_query_immodules_2_0_LDADD = $(LDADDS)
|
||||
|
||||
gtk_query_immodules_2_0_SOURCES = queryimmodules.c
|
||||
|
||||
gtk.immodules: gtk-query-immodules-2.0
|
||||
./gtk-query-immodules-2.0 ../modules/input/.libs/*.so > gtk.immodules
|
||||
|
||||
#
|
||||
# test programs, not to be installed
|
||||
#
|
||||
noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple testtextbuffer # testthreads
|
||||
testgtk_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcalendar_DEPENDENCIES = $(TEST_DEPS)
|
||||
testinput_DEPENDENCIES = $(TEST_DEPS)
|
||||
testselection_DEPENDENCIES = $(TEST_DEPS)
|
||||
testrgb_DEPENDENCIES = $(TEST_DEPS)
|
||||
testtext_DEPENDENCIES = $(TEST_DEPS)
|
||||
testdnd_DEPENDENCIES = $(TEST_DEPS)
|
||||
simple_DEPENDENCIES = $(TEST_DEPS)
|
||||
#testthreads_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
||||
testcalendar_LDADD = $(LDADDS)
|
||||
testgtk_LDADD = $(LDADDS)
|
||||
testinput_LDADD = $(LDADDS)
|
||||
|
@@ -93,8 +93,10 @@
|
||||
#include <gtk/gtkmenuitem.h>
|
||||
#include <gtk/gtkmenushell.h>
|
||||
#include <gtk/gtkmisc.h>
|
||||
#include <gtk/gtkmodule.h>
|
||||
#include <gtk/gtknotebook.h>
|
||||
#include <gtk/gtkobject.h>
|
||||
#include <gtk/gtkoldeditable.h>
|
||||
#include <gtk/gtkoptionmenu.h>
|
||||
#include <gtk/gtkpacker.h>
|
||||
#include <gtk/gtkpaned.h>
|
||||
@@ -123,7 +125,6 @@
|
||||
#include <gtk/gtktext.h>
|
||||
#include <gtk/gtktextbuffer.h>
|
||||
#include <gtk/gtktextview.h>
|
||||
#include <gtk/gtkthemes.h>
|
||||
#include <gtk/gtktipsquery.h>
|
||||
#include <gtk/gtktogglebutton.h>
|
||||
#include <gtk/gtktoolbar.h>
|
||||
|
@@ -132,6 +132,7 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com
|
||||
/* completion */
|
||||
if ((event->keyval == GDK_Tab) && (event->state & GDK_MOD1_MASK))
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (entry);
|
||||
GCompletion * cmpl;
|
||||
gchar* prefix;
|
||||
gchar* nprefix = NULL;
|
||||
@@ -145,16 +146,16 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com
|
||||
cmpl = g_completion_new ((GCompletionFunc)gtk_combo_func);
|
||||
g_completion_add_items (cmpl, GTK_LIST (combo->list)->children);
|
||||
|
||||
pos = GTK_EDITABLE (entry)->current_pos;
|
||||
prefix = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, pos);
|
||||
pos = gtk_editable_get_position (editable);
|
||||
prefix = gtk_editable_get_chars (editable, 0, pos);
|
||||
|
||||
g_completion_complete(cmpl, prefix, &nprefix);
|
||||
|
||||
if (nprefix && strlen (nprefix) > strlen (prefix))
|
||||
{
|
||||
gtk_editable_insert_text (GTK_EDITABLE (entry), nprefix + pos,
|
||||
strlen (nprefix) - strlen (prefix), &pos);
|
||||
GTK_EDITABLE (entry)->current_pos = pos;
|
||||
gtk_editable_insert_text (editable, nprefix + pos,
|
||||
strlen (nprefix) - strlen (prefix), &pos);
|
||||
gtk_editable_set_position (editable, pos);
|
||||
}
|
||||
|
||||
if (nprefix)
|
||||
|
@@ -24,91 +24,11 @@
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gdk/gdkkeysyms.h"
|
||||
#include "gdk/gdki18n.h"
|
||||
|
||||
#include "gtkeditable.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtksignal.h"
|
||||
|
||||
#define MIN_EDITABLE_WIDTH 150
|
||||
#define DRAW_TIMEOUT 20
|
||||
#define INNER_BORDER 2
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
INSERT_TEXT,
|
||||
DELETE_TEXT,
|
||||
/* Binding actions */
|
||||
ACTIVATE,
|
||||
SET_EDITABLE,
|
||||
MOVE_CURSOR,
|
||||
MOVE_WORD,
|
||||
MOVE_PAGE,
|
||||
MOVE_TO_ROW,
|
||||
MOVE_TO_COLUMN,
|
||||
KILL_CHAR,
|
||||
KILL_WORD,
|
||||
KILL_LINE,
|
||||
CUT_CLIPBOARD,
|
||||
COPY_CLIPBOARD,
|
||||
PASTE_CLIPBOARD,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_TEXT_POSITION,
|
||||
ARG_EDITABLE
|
||||
};
|
||||
|
||||
/* values for selection info */
|
||||
|
||||
enum {
|
||||
TARGET_STRING,
|
||||
TARGET_TEXT,
|
||||
TARGET_COMPOUND_TEXT
|
||||
};
|
||||
|
||||
static void gtk_editable_class_init (GtkEditableClass *klass);
|
||||
static void gtk_editable_init (GtkEditable *editable);
|
||||
static void gtk_editable_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void gtk_editable_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void *gtk_editable_get_public_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
static gint gtk_editable_selection_clear (GtkWidget *widget,
|
||||
GdkEventSelection *event);
|
||||
static void gtk_editable_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time);
|
||||
static void gtk_editable_selection_received (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint time);
|
||||
|
||||
static void gtk_editable_set_selection (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
static guint32 gtk_editable_get_event_time (GtkEditable *editable);
|
||||
|
||||
static void gtk_editable_real_cut_clipboard (GtkEditable *editable);
|
||||
static void gtk_editable_real_copy_clipboard (GtkEditable *editable);
|
||||
static void gtk_editable_real_paste_clipboard (GtkEditable *editable);
|
||||
static void gtk_editable_real_set_editable (GtkEditable *editable,
|
||||
gboolean is_editable);
|
||||
|
||||
static GtkWidgetClass *parent_class = NULL;
|
||||
static guint editable_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static GdkAtom clipboard_atom = GDK_NONE;
|
||||
|
||||
GtkType
|
||||
gtk_editable_get_type (void)
|
||||
{
|
||||
@@ -116,331 +36,32 @@ gtk_editable_get_type (void)
|
||||
|
||||
if (!editable_type)
|
||||
{
|
||||
static const GtkTypeInfo editable_info =
|
||||
static const GTypeInfo editable_info =
|
||||
{
|
||||
"GtkEditable",
|
||||
sizeof (GtkEditable),
|
||||
sizeof (GtkEditableClass),
|
||||
(GtkClassInitFunc) gtk_editable_class_init,
|
||||
(GtkObjectInitFunc) gtk_editable_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
sizeof (GtkEditableIface), /* class_size */
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
};
|
||||
|
||||
editable_type = gtk_type_unique (GTK_TYPE_WIDGET, &editable_info);
|
||||
editable_type = g_type_register_static (G_TYPE_INTERFACE, "GtkEditable", &editable_info);
|
||||
}
|
||||
|
||||
return editable_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_class_init (GtkEditableClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
object_class = (GtkObjectClass*) class;
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
|
||||
parent_class = gtk_type_class (GTK_TYPE_WIDGET);
|
||||
|
||||
editable_signals[CHANGED] =
|
||||
gtk_signal_new ("changed",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, changed),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[INSERT_TEXT] =
|
||||
gtk_signal_new ("insert_text",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, insert_text),
|
||||
gtk_marshal_NONE__POINTER_INT_POINTER,
|
||||
GTK_TYPE_NONE,
|
||||
3,
|
||||
GTK_TYPE_STRING,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_POINTER);
|
||||
|
||||
editable_signals[DELETE_TEXT] =
|
||||
gtk_signal_new ("delete_text",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, delete_text),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE,
|
||||
2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[ACTIVATE] =
|
||||
gtk_signal_new ("activate",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, activate),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
widget_class->activate_signal = editable_signals[ACTIVATE];
|
||||
|
||||
editable_signals[SET_EDITABLE] =
|
||||
gtk_signal_new ("set-editable",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, set_editable),
|
||||
gtk_marshal_NONE__BOOL,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_BOOL);
|
||||
|
||||
editable_signals[MOVE_CURSOR] =
|
||||
gtk_signal_new ("move_cursor",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, move_cursor),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_WORD] =
|
||||
gtk_signal_new ("move_word",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, move_word),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_PAGE] =
|
||||
gtk_signal_new ("move_page",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, move_page),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_TO_ROW] =
|
||||
gtk_signal_new ("move_to_row",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_row),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_TO_COLUMN] =
|
||||
gtk_signal_new ("move_to_column",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_column),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_CHAR] =
|
||||
gtk_signal_new ("kill_char",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, kill_char),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_WORD] =
|
||||
gtk_signal_new ("kill_word",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, kill_word),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_LINE] =
|
||||
gtk_signal_new ("kill_line",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, kill_line),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[CUT_CLIPBOARD] =
|
||||
gtk_signal_new ("cut_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, cut_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[COPY_CLIPBOARD] =
|
||||
gtk_signal_new ("copy_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, copy_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[PASTE_CLIPBOARD] =
|
||||
gtk_signal_new ("paste_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkEditableClass, paste_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL);
|
||||
|
||||
gtk_object_add_arg_type ("GtkEditable::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION);
|
||||
gtk_object_add_arg_type ("GtkEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
|
||||
|
||||
object_class->set_arg = gtk_editable_set_arg;
|
||||
object_class->get_arg = gtk_editable_get_arg;
|
||||
|
||||
widget_class->selection_clear_event = gtk_editable_selection_clear;
|
||||
widget_class->selection_received = gtk_editable_selection_received;
|
||||
widget_class->selection_get = gtk_editable_selection_get;
|
||||
|
||||
class->insert_text = NULL;
|
||||
class->delete_text = NULL;
|
||||
|
||||
class->activate = NULL;
|
||||
class->set_editable = gtk_editable_real_set_editable;
|
||||
|
||||
class->move_cursor = NULL;
|
||||
class->move_word = NULL;
|
||||
class->move_page = NULL;
|
||||
class->move_to_row = NULL;
|
||||
class->move_to_column = NULL;
|
||||
|
||||
class->kill_char = NULL;
|
||||
class->kill_word = NULL;
|
||||
class->kill_line = NULL;
|
||||
|
||||
class->cut_clipboard = gtk_editable_real_cut_clipboard;
|
||||
class->copy_clipboard = gtk_editable_real_copy_clipboard;
|
||||
class->paste_clipboard = gtk_editable_real_paste_clipboard;
|
||||
|
||||
class->update_text = NULL;
|
||||
class->get_chars = NULL;
|
||||
class->set_selection = NULL;
|
||||
class->set_position = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
|
||||
editable = GTK_EDITABLE (object);
|
||||
|
||||
switch (arg_id)
|
||||
{
|
||||
case ARG_TEXT_POSITION:
|
||||
gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
|
||||
break;
|
||||
case ARG_EDITABLE:
|
||||
gtk_editable_set_editable (editable, GTK_VALUE_BOOL (*arg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
|
||||
editable = GTK_EDITABLE (object);
|
||||
|
||||
switch (arg_id)
|
||||
{
|
||||
case ARG_TEXT_POSITION:
|
||||
GTK_VALUE_INT (*arg) = editable->current_pos;
|
||||
break;
|
||||
case ARG_EDITABLE:
|
||||
GTK_VALUE_BOOL (*arg) = editable->editable;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_init (GtkEditable *editable)
|
||||
{
|
||||
static const GtkTargetEntry targets[] = {
|
||||
{ "STRING", 0, TARGET_STRING },
|
||||
{ "TEXT", 0, TARGET_TEXT },
|
||||
{ "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }
|
||||
};
|
||||
static const gint n_targets = sizeof(targets) / sizeof(targets[0]);
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (editable, GTK_CAN_FOCUS);
|
||||
|
||||
editable->selection_start_pos = 0;
|
||||
editable->selection_end_pos = 0;
|
||||
editable->has_selection = FALSE;
|
||||
editable->editable = 1;
|
||||
editable->visible = 1;
|
||||
editable->clipboard_text = NULL;
|
||||
|
||||
#ifdef USE_XIM
|
||||
editable->ic = NULL;
|
||||
#endif
|
||||
|
||||
if (!clipboard_atom)
|
||||
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
|
||||
|
||||
gtk_selection_add_targets (GTK_WIDGET (editable), GDK_SELECTION_PRIMARY,
|
||||
targets, n_targets);
|
||||
gtk_selection_add_targets (GTK_WIDGET (editable), clipboard_atom,
|
||||
targets, n_targets);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
gchar buf[64];
|
||||
gchar *text;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_widget_ref (GTK_WIDGET (editable));
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
g_return_if_fail (position != NULL);
|
||||
|
||||
if (new_text_length < 0)
|
||||
new_text_length = strlen (new_text);
|
||||
|
||||
if (new_text_length <= 64)
|
||||
text = buf;
|
||||
else
|
||||
text = g_new (gchar, new_text_length);
|
||||
|
||||
strncpy (text, new_text, new_text_length);
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT], text, new_text_length, position);
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
|
||||
|
||||
if (new_text_length > 64)
|
||||
g_free (text);
|
||||
|
||||
gtk_widget_unref (GTK_WIDGET (editable));
|
||||
GTK_EDITABLE_GET_IFACE (editable)->insert_text (editable, new_text, new_text_length, position);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -448,360 +69,67 @@ gtk_editable_delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_widget_ref (GTK_WIDGET (editable));
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[DELETE_TEXT], start_pos, end_pos);
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
|
||||
|
||||
gtk_widget_unref (GTK_WIDGET (editable));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_update_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
klass->update_text (editable, start_pos, end_pos);
|
||||
GTK_EDITABLE_GET_IFACE (editable)->delete_text (editable, start_pos, end_pos);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
|
||||
|
||||
g_return_val_if_fail (editable != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
return klass->get_chars (editable, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like gtk_editable_get_chars, but if the editable is not
|
||||
* visible, return asterisks
|
||||
*/
|
||||
static void *
|
||||
gtk_editable_get_public_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
if (editable->visible)
|
||||
return gtk_editable_get_chars (editable, start, end);
|
||||
else
|
||||
{
|
||||
gint i;
|
||||
gint nchars = end - start;
|
||||
gchar *str;
|
||||
|
||||
if (nchars < 0)
|
||||
nchars = -nchars;
|
||||
|
||||
str = g_new (gchar, nchars + 1);
|
||||
for (i = 0; i<nchars; i++)
|
||||
str[i] = '*';
|
||||
str[i] = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_set_selection (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
klass->set_selection (editable, start_pos, end_pos);
|
||||
return GTK_EDITABLE_GET_IFACE (editable)->get_chars (editable, start, end);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_set_position (GtkEditable *editable,
|
||||
gint position)
|
||||
{
|
||||
GtkEditableClass *klass;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
klass = GTK_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
klass->set_position (editable, position);
|
||||
GTK_EDITABLE_GET_IFACE (editable)->set_position (editable, position);
|
||||
}
|
||||
|
||||
gint
|
||||
gtk_editable_get_position (GtkEditable *editable)
|
||||
{
|
||||
g_return_val_if_fail (editable != NULL, -1);
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), -1);
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), 0);
|
||||
|
||||
return editable->current_pos;
|
||||
return GTK_EDITABLE_GET_IFACE (editable)->get_position (editable);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_editable_selection_clear (GtkWidget *widget,
|
||||
GdkEventSelection *event)
|
||||
gboolean
|
||||
gtk_editable_get_selection_bounds (GtkEditable *editable,
|
||||
gint *start_pos,
|
||||
gint *end_pos)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
gint tmp_start, tmp_end;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (widget != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (widget), FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
/* Let the selection handling code know that the selection
|
||||
* has been changed, since we've overriden the default handler */
|
||||
if (!gtk_selection_clear (widget, event))
|
||||
return FALSE;
|
||||
|
||||
editable = GTK_EDITABLE (widget);
|
||||
|
||||
if (event->selection == GDK_SELECTION_PRIMARY)
|
||||
{
|
||||
if (editable->has_selection)
|
||||
{
|
||||
editable->has_selection = FALSE;
|
||||
gtk_editable_update_text (editable, editable->selection_start_pos,
|
||||
editable->selection_end_pos);
|
||||
}
|
||||
}
|
||||
else if (event->selection == clipboard_atom)
|
||||
{
|
||||
g_free (editable->clipboard_text);
|
||||
editable->clipboard_text = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
|
||||
|
||||
static void
|
||||
gtk_editable_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
gint selection_start_pos;
|
||||
gint selection_end_pos;
|
||||
result = GTK_EDITABLE_GET_IFACE (editable)->get_selection_bounds (editable, &tmp_start, &tmp_end);
|
||||
|
||||
gchar *str;
|
||||
gint length;
|
||||
if (start_pos)
|
||||
*start_pos = MIN (tmp_start, tmp_end);
|
||||
if (end_pos)
|
||||
*end_pos = MAX (tmp_start, tmp_end);
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (widget));
|
||||
|
||||
editable = GTK_EDITABLE (widget);
|
||||
|
||||
if (selection_data->selection == GDK_SELECTION_PRIMARY)
|
||||
{
|
||||
selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
|
||||
selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
|
||||
str = gtk_editable_get_public_chars(editable,
|
||||
selection_start_pos,
|
||||
selection_end_pos);
|
||||
if (!str)
|
||||
return; /* Refuse */
|
||||
length = strlen (str);
|
||||
}
|
||||
else /* CLIPBOARD */
|
||||
{
|
||||
if (!editable->clipboard_text)
|
||||
return; /* Refuse */
|
||||
|
||||
str = editable->clipboard_text;
|
||||
length = strlen (editable->clipboard_text);
|
||||
}
|
||||
|
||||
if (info == TARGET_STRING)
|
||||
{
|
||||
gtk_selection_data_set (selection_data,
|
||||
GDK_SELECTION_TYPE_STRING,
|
||||
8*sizeof(gchar), (guchar *)str, length);
|
||||
}
|
||||
else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT))
|
||||
{
|
||||
guchar *text;
|
||||
gchar c;
|
||||
GdkAtom encoding;
|
||||
gint format;
|
||||
gint new_length;
|
||||
|
||||
c = str[length];
|
||||
str[length] = '\0';
|
||||
gdk_string_to_compound_text (str, &encoding, &format, &text, &new_length);
|
||||
gtk_selection_data_set (selection_data, encoding, format, text, new_length);
|
||||
gdk_free_compound_text (text);
|
||||
str[length] = c;
|
||||
}
|
||||
|
||||
if (str != editable->clipboard_text)
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_selection_received (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint time)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
gint reselect;
|
||||
gint old_pos;
|
||||
gint tmp_pos;
|
||||
enum {INVALID, STRING, CTEXT} type;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (widget));
|
||||
|
||||
editable = GTK_EDITABLE (widget);
|
||||
|
||||
if (selection_data->type == GDK_TARGET_STRING)
|
||||
type = STRING;
|
||||
else if ((selection_data->type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)) ||
|
||||
(selection_data->type == gdk_atom_intern ("TEXT", FALSE)))
|
||||
type = CTEXT;
|
||||
else
|
||||
type = INVALID;
|
||||
|
||||
if (type == INVALID || selection_data->length < 0)
|
||||
{
|
||||
/* avoid infinite loop */
|
||||
if (selection_data->target != GDK_TARGET_STRING)
|
||||
gtk_selection_convert (widget, selection_data->selection,
|
||||
GDK_TARGET_STRING, time);
|
||||
return;
|
||||
}
|
||||
|
||||
reselect = FALSE;
|
||||
|
||||
if ((editable->selection_start_pos != editable->selection_end_pos) &&
|
||||
(!editable->has_selection ||
|
||||
(selection_data->selection == clipboard_atom)))
|
||||
{
|
||||
reselect = TRUE;
|
||||
|
||||
/* Don't want to call gtk_editable_delete_selection here if we are going
|
||||
* to reclaim the selection to avoid extra server traffic */
|
||||
if (editable->has_selection)
|
||||
{
|
||||
gtk_editable_delete_text (editable,
|
||||
MIN (editable->selection_start_pos, editable->selection_end_pos),
|
||||
MAX (editable->selection_start_pos, editable->selection_end_pos));
|
||||
}
|
||||
else
|
||||
gtk_editable_delete_selection (editable);
|
||||
}
|
||||
|
||||
tmp_pos = old_pos = editable->current_pos;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case STRING:
|
||||
selection_data->data[selection_data->length] = 0;
|
||||
gtk_editable_insert_text (editable, (gchar *)selection_data->data,
|
||||
strlen ((gchar *)selection_data->data),
|
||||
&tmp_pos);
|
||||
editable->current_pos = tmp_pos;
|
||||
break;
|
||||
case CTEXT:
|
||||
{
|
||||
gchar **list;
|
||||
gint count;
|
||||
gint i;
|
||||
|
||||
count = gdk_text_property_to_text_list (selection_data->type,
|
||||
selection_data->format,
|
||||
selection_data->data,
|
||||
selection_data->length,
|
||||
&list);
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
gtk_editable_insert_text (editable, list[i], strlen (list[i]), &tmp_pos);
|
||||
editable->current_pos = tmp_pos;
|
||||
}
|
||||
if (count > 0)
|
||||
gdk_free_text_list (list);
|
||||
}
|
||||
break;
|
||||
case INVALID: /* quiet compiler */
|
||||
break;
|
||||
}
|
||||
|
||||
if (reselect)
|
||||
gtk_editable_set_selection (editable, old_pos, editable->current_pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_delete_selection (GtkEditable *editable)
|
||||
{
|
||||
guint start;
|
||||
guint end;
|
||||
gint start, end;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
if (!editable->editable)
|
||||
return;
|
||||
|
||||
start = editable->selection_start_pos;
|
||||
end = editable->selection_end_pos;
|
||||
|
||||
editable->selection_start_pos = 0;
|
||||
editable->selection_end_pos = 0;
|
||||
|
||||
if (start != end)
|
||||
gtk_editable_delete_text (editable, MIN (start, end), MAX (start,end));
|
||||
|
||||
if (editable->has_selection)
|
||||
{
|
||||
editable->has_selection = FALSE;
|
||||
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (editable)->window)
|
||||
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_claim_selection (GtkEditable *editable,
|
||||
gboolean claim,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
g_return_if_fail (GTK_WIDGET_REALIZED (editable));
|
||||
|
||||
editable->has_selection = FALSE;
|
||||
|
||||
if (claim)
|
||||
{
|
||||
if (gtk_selection_owner_set (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY, time))
|
||||
editable->has_selection = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) ==
|
||||
GTK_WIDGET(editable)->window)
|
||||
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
|
||||
}
|
||||
if (gtk_editable_get_selection_bounds (editable, &start, &end))
|
||||
gtk_editable_delete_text (editable, start, end);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -809,57 +137,9 @@ gtk_editable_select_region (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
if (GTK_WIDGET_REALIZED (editable))
|
||||
gtk_editable_claim_selection (editable, start != end, GDK_CURRENT_TIME);
|
||||
|
||||
gtk_editable_set_selection (editable, start, end);
|
||||
}
|
||||
|
||||
/* Get the timestamp of the current event. Actually, the only thing
|
||||
* we really care about below is the key event
|
||||
*/
|
||||
static guint32
|
||||
gtk_editable_get_event_time (GtkEditable *editable)
|
||||
{
|
||||
GdkEvent *event;
|
||||
guint32 tm = GDK_CURRENT_TIME;
|
||||
|
||||
event = gtk_get_current_event();
|
||||
|
||||
if (event)
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
tm = event->motion.time; break;
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
tm = event->button.time; break;
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
tm = event->key.time; break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
tm = event->crossing.time; break;
|
||||
case GDK_PROPERTY_NOTIFY:
|
||||
tm = event->property.time; break;
|
||||
case GDK_SELECTION_CLEAR:
|
||||
case GDK_SELECTION_REQUEST:
|
||||
case GDK_SELECTION_NOTIFY:
|
||||
tm = event->selection.time; break;
|
||||
case GDK_PROXIMITY_IN:
|
||||
case GDK_PROXIMITY_OUT:
|
||||
tm = event->proximity.time; break;
|
||||
default: /* use current time */
|
||||
break;
|
||||
}
|
||||
gdk_event_free(event);
|
||||
|
||||
return tm;
|
||||
GTK_EDITABLE_GET_IFACE (editable)->set_selection_bounds (editable, start, end);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -868,7 +148,7 @@ gtk_editable_cut_clipboard (GtkEditable *editable)
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CUT_CLIPBOARD]);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (editable), "cut_clipboard");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -877,7 +157,7 @@ gtk_editable_copy_clipboard (GtkEditable *editable)
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[COPY_CLIPBOARD]);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (editable), "copy_clipboard");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -886,85 +166,16 @@ gtk_editable_paste_clipboard (GtkEditable *editable)
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[PASTE_CLIPBOARD]);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (editable), "paste_clipboard");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_set_editable (GtkEditable *editable,
|
||||
gboolean is_editable)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[SET_EDITABLE], is_editable != FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_real_set_editable (GtkEditable *editable,
|
||||
gboolean is_editable)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
editable->editable = is_editable != FALSE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (editable));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_real_cut_clipboard (GtkEditable *editable)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_editable_real_copy_clipboard (editable);
|
||||
gtk_editable_delete_selection (editable);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_real_copy_clipboard (GtkEditable *editable)
|
||||
{
|
||||
guint32 time;
|
||||
gint selection_start_pos;
|
||||
gint selection_end_pos;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
time = gtk_editable_get_event_time (editable);
|
||||
selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
|
||||
selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
|
||||
|
||||
if (selection_start_pos != selection_end_pos)
|
||||
{
|
||||
if (gtk_selection_owner_set (GTK_WIDGET (editable),
|
||||
clipboard_atom,
|
||||
time))
|
||||
editable->clipboard_text = gtk_editable_get_public_chars (editable,
|
||||
selection_start_pos,
|
||||
selection_end_pos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_real_paste_clipboard (GtkEditable *editable)
|
||||
{
|
||||
guint32 time;
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
time = gtk_editable_get_event_time (editable);
|
||||
if (editable->editable)
|
||||
gtk_selection_convert (GTK_WIDGET(editable),
|
||||
clipboard_atom,
|
||||
gdk_atom_intern ("COMPOUND_TEXT", FALSE), time);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_editable_changed (GtkEditable *editable)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
|
||||
gtk_object_set (GTK_OBJECT (editable),
|
||||
"editable", is_editable != FALSE,
|
||||
NULL);
|
||||
}
|
||||
|
@@ -31,132 +31,70 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
|
||||
#define GTK_EDITABLE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_EDITABLE, GtkEditable))
|
||||
#define GTK_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_EDITABLE, GtkEditableClass))
|
||||
#define GTK_IS_EDITABLE(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_EDITABLE))
|
||||
#define GTK_IS_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_EDITABLE))
|
||||
#define GTK_EDITABLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_EDITABLE, GtkEditableClass))
|
||||
#define GTK_EDITABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_EDITABLE, GtkEditable))
|
||||
#define GTK_IS_EDITABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_EDITABLE))
|
||||
#define GTK_EDITABLE_GET_IFACE(obj) ((GtkEditableIface *)g_type_interface_peek (((GTypeInstance *)GTK_EDITABLE (obj))->g_class, \
|
||||
GTK_TYPE_EDITABLE))
|
||||
|
||||
typedef struct _GtkEditable GtkEditable; /* Dummy typedef */
|
||||
typedef struct _GtkEditableIface GtkEditableIface;
|
||||
|
||||
typedef struct _GtkEditable GtkEditable;
|
||||
typedef struct _GtkEditableClass GtkEditableClass;
|
||||
|
||||
typedef void (*GtkTextFunction) (GtkEditable *editable, guint32 time);
|
||||
|
||||
struct _GtkEditable
|
||||
struct _GtkEditableIface
|
||||
{
|
||||
GtkWidget widget;
|
||||
|
||||
/*< public >*/
|
||||
guint current_pos;
|
||||
|
||||
guint selection_start_pos;
|
||||
guint selection_end_pos;
|
||||
guint has_selection : 1;
|
||||
|
||||
/*< private >*/
|
||||
guint editable : 1;
|
||||
guint visible : 1;
|
||||
GdkIC *ic;
|
||||
GdkICAttr *ic_attr;
|
||||
|
||||
gchar *clipboard_text;
|
||||
};
|
||||
|
||||
struct _GtkEditableClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/* Signals for notification/filtering of changes */
|
||||
void (* changed) (GtkEditable *editable);
|
||||
void (* insert_text) (GtkEditable *editable,
|
||||
const gchar *text,
|
||||
gint length,
|
||||
gint *position);
|
||||
void (* delete_text) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
|
||||
/* Bindings actions */
|
||||
void (* activate) (GtkEditable *editable);
|
||||
void (* set_editable) (GtkEditable *editable,
|
||||
gboolean is_editable);
|
||||
void (* move_cursor) (GtkEditable *editable,
|
||||
gint x,
|
||||
gint y);
|
||||
void (* move_word) (GtkEditable *editable,
|
||||
gint n);
|
||||
void (* move_page) (GtkEditable *editable,
|
||||
gint x,
|
||||
gint y);
|
||||
void (* move_to_row) (GtkEditable *editable,
|
||||
gint row);
|
||||
void (* move_to_column) (GtkEditable *editable,
|
||||
gint row);
|
||||
void (* kill_char) (GtkEditable *editable,
|
||||
gint direction);
|
||||
void (* kill_word) (GtkEditable *editable,
|
||||
gint direction);
|
||||
void (* kill_line) (GtkEditable *editable,
|
||||
gint direction);
|
||||
void (* cut_clipboard) (GtkEditable *editable);
|
||||
void (* copy_clipboard) (GtkEditable *editable);
|
||||
void (* paste_clipboard) (GtkEditable *editable);
|
||||
|
||||
/* Virtual functions. get_chars is in paricular not a signal because
|
||||
* it returns malloced memory. The others are not signals because
|
||||
* they would not be particularly useful as such. (All changes to
|
||||
* selection and position do not go through these functions)
|
||||
*/
|
||||
void (* update_text) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gchar* (* get_chars) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void (* set_selection)(GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void (* set_position) (GtkEditable *editable,
|
||||
gint position);
|
||||
void (* insert_text) (GtkEditable *editable,
|
||||
const gchar *text,
|
||||
gint length,
|
||||
gint *position);
|
||||
void (* delete_text) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gchar* (* get_chars) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void (* set_selection_bounds) (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gboolean (* get_selection_bounds) (GtkEditable *editable,
|
||||
gint *start_pos,
|
||||
gint *end_pos);
|
||||
void (* set_position) (GtkEditable *editable,
|
||||
gint position);
|
||||
gint (* get_position) (GtkEditable *editable);
|
||||
};
|
||||
|
||||
GtkType gtk_editable_get_type (void) G_GNUC_CONST;
|
||||
void gtk_editable_select_region (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
void gtk_editable_insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position);
|
||||
void gtk_editable_delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gchar* gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void gtk_editable_cut_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_copy_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_paste_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_claim_selection (GtkEditable *editable,
|
||||
gboolean claim,
|
||||
guint32 time);
|
||||
void gtk_editable_delete_selection (GtkEditable *editable);
|
||||
|
||||
void gtk_editable_changed (GtkEditable *editable);
|
||||
void gtk_editable_set_position (GtkEditable *editable,
|
||||
gint position);
|
||||
gint gtk_editable_get_position (GtkEditable *editable);
|
||||
void gtk_editable_set_editable (GtkEditable *editable,
|
||||
gboolean is_editable);
|
||||
|
||||
GtkType gtk_editable_get_type (void) G_GNUC_CONST;
|
||||
void gtk_editable_select_region (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
gboolean gtk_editable_get_selection_bounds (GtkEditable *editable,
|
||||
gint *start,
|
||||
gint *end);
|
||||
void gtk_editable_insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position);
|
||||
void gtk_editable_delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gchar* gtk_editable_get_chars (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void gtk_editable_cut_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_copy_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_paste_clipboard (GtkEditable *editable);
|
||||
void gtk_editable_delete_selection (GtkEditable *editable);
|
||||
void gtk_editable_set_position (GtkEditable *editable,
|
||||
gint position);
|
||||
gint gtk_editable_get_position (GtkEditable *editable);
|
||||
void gtk_editable_set_editable (GtkEditable *editable,
|
||||
gboolean is_editable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
2684
gtk/gtkentry.c
2684
gtk/gtkentry.c
File diff suppressed because it is too large
Load Diff
@@ -51,50 +51,79 @@ typedef struct _GtkEntryClass GtkEntryClass;
|
||||
|
||||
struct _GtkEntry
|
||||
{
|
||||
GtkEditable editable;
|
||||
GtkWidget widget;
|
||||
|
||||
GdkWindow *text_area;
|
||||
GdkPixmap *backing_pixmap;
|
||||
GdkCursor *cursor;
|
||||
gchar *text;
|
||||
|
||||
guint16 text_size; /* allocated size, in bytes */
|
||||
guint editable : 1;
|
||||
guint visible : 1;
|
||||
guint overwrite_mode : 1;
|
||||
|
||||
guint16 text_length; /* length in use, in chars */
|
||||
guint16 text_max_length;
|
||||
|
||||
/*< private >*/
|
||||
GdkWindow *text_area;
|
||||
GtkIMContext *im_context;
|
||||
GtkWidget *popup_menu;
|
||||
|
||||
gint current_pos;
|
||||
gint selection_bound;
|
||||
|
||||
PangoLayout *cached_layout;
|
||||
guint cache_includes_preedit : 1;
|
||||
|
||||
guint need_im_reset : 1;
|
||||
|
||||
guint button;
|
||||
guint32 timer;
|
||||
guint16 n_bytes; /* length in use, in bytes */
|
||||
PangoLayout *layout;
|
||||
guint timer;
|
||||
guint recompute_idle;
|
||||
gint scroll_offset;
|
||||
gint ascent; /* font ascent, in pango units */
|
||||
gint descent; /* font descent, in pango units */
|
||||
GtkIMContext *im_context;
|
||||
|
||||
guint16 text_size; /* allocated size, in bytes */
|
||||
guint16 n_bytes; /* length in use, in bytes */
|
||||
|
||||
guint16 preedit_length; /* length of preedit string, in bytes */
|
||||
guint16 preedit_cursor; /* offset of cursor within preedit string, in bytes */
|
||||
};
|
||||
|
||||
struct _GtkEntryClass
|
||||
{
|
||||
GtkEditableClass parent_class;
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/* Notification of changes
|
||||
*/
|
||||
void (* changed) (GtkEntry *entry);
|
||||
void (* insert_text) (GtkEntry *entry,
|
||||
const gchar *text,
|
||||
gint length,
|
||||
gint *position);
|
||||
void (* delete_text) (GtkEntry *entry,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
|
||||
/* Action signals
|
||||
*/
|
||||
void (* activate) (GtkEntry *entry);
|
||||
void (* move) (GtkEntry *entry,
|
||||
GtkMovementStep step,
|
||||
gint count,
|
||||
gboolean extend_selection);
|
||||
void (* insert) (GtkEntry *entry,
|
||||
const gchar *str);
|
||||
void (* delete) (GtkEntry *entry,
|
||||
GtkDeleteType type,
|
||||
gint count);
|
||||
void (* cut_clipboard) (GtkEntry *entry);
|
||||
void (* copy_clipboard) (GtkEntry *entry);
|
||||
void (* paste_clipboard) (GtkEntry *entry);
|
||||
void (* toggle_overwrite) (GtkEntry *entry);
|
||||
};
|
||||
|
||||
GtkType gtk_entry_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget* gtk_entry_new (void);
|
||||
GtkWidget* gtk_entry_new_with_max_length (guint16 max);
|
||||
void gtk_entry_set_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
void gtk_entry_append_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
void gtk_entry_prepend_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
void gtk_entry_set_position (GtkEntry *entry,
|
||||
gint position);
|
||||
/* returns a reference to the text */
|
||||
gchar* gtk_entry_get_text (GtkEntry *entry);
|
||||
void gtk_entry_select_region (GtkEntry *entry,
|
||||
gint start,
|
||||
gint end);
|
||||
void gtk_entry_set_visibility (GtkEntry *entry,
|
||||
gboolean visible);
|
||||
void gtk_entry_set_editable (GtkEntry *entry,
|
||||
@@ -103,6 +132,26 @@ void gtk_entry_set_editable (GtkEntry *entry,
|
||||
void gtk_entry_set_max_length (GtkEntry *entry,
|
||||
guint16 max);
|
||||
|
||||
/* Somewhat more convenient than the GtkEditable generic functions
|
||||
*/
|
||||
void gtk_entry_set_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
/* returns a reference to the text */
|
||||
gchar* gtk_entry_get_text (GtkEntry *entry);
|
||||
|
||||
/* Deprecated compatibility functions
|
||||
*/
|
||||
GtkWidget* gtk_entry_new_with_max_length (guint16 max);
|
||||
void gtk_entry_append_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
void gtk_entry_prepend_text (GtkEntry *entry,
|
||||
const gchar *text);
|
||||
void gtk_entry_set_position (GtkEntry *entry,
|
||||
gint position);
|
||||
void gtk_entry_select_region (GtkEntry *entry,
|
||||
gint start,
|
||||
gint end);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
@@ -35,7 +35,8 @@ static void gtk_im_context_init (GtkIMContext *im_context);
|
||||
|
||||
static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs);
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos);
|
||||
static gboolean gtk_im_context_real_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *event);
|
||||
|
||||
@@ -118,12 +119,15 @@ gtk_im_context_init (GtkIMContext *im_context)
|
||||
static void
|
||||
gtk_im_context_real_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs)
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos)
|
||||
{
|
||||
if (str)
|
||||
*str = g_strdup ("");
|
||||
if (attrs)
|
||||
*attrs = pango_attr_list_new ();
|
||||
if (cursor_pos)
|
||||
*cursor_pos = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -175,7 +179,8 @@ gtk_im_context_set_client_window (GtkIMContext *context,
|
||||
void
|
||||
gtk_im_context_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs)
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos)
|
||||
{
|
||||
GtkIMContextClass *klass;
|
||||
|
||||
@@ -183,7 +188,7 @@ gtk_im_context_get_preedit_string (GtkIMContext *context,
|
||||
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
|
||||
|
||||
klass = GTK_IM_CONTEXT_GET_CLASS (context);
|
||||
klass->get_preedit_string (context, str, attrs);
|
||||
klass->get_preedit_string (context, str, attrs, cursor_pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,7 +240,7 @@ gtk_im_context_focus_in (GtkIMContext *context)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_im_context_focus_in:
|
||||
* gtk_im_context_focus_out:
|
||||
* @context: a #GtkIMContext
|
||||
*
|
||||
* Notify the input method that the widget to which this
|
||||
@@ -256,4 +261,25 @@ gtk_im_context_focus_out (GtkIMContext *context)
|
||||
klass->focus_out (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_im_context_reset:
|
||||
* @context: a #GtkIMContext
|
||||
*
|
||||
* Notify the input method that a change such as a change in cursor
|
||||
* position has been made. This will typically cause the input
|
||||
* method to clear the preedit state.
|
||||
**/
|
||||
void
|
||||
gtk_im_context_reset (GtkIMContext *context)
|
||||
{
|
||||
GtkIMContextClass *klass;
|
||||
|
||||
g_return_if_fail (context != NULL);
|
||||
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
|
||||
|
||||
klass = GTK_IM_CONTEXT_GET_CLASS (context);
|
||||
if (klass->reset)
|
||||
klass->reset (context);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -60,11 +60,13 @@ struct _GtkIMContextClass
|
||||
GdkWindow *window);
|
||||
void (*get_preedit_string) (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs);
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos);
|
||||
gboolean (*filter_keypress) (GtkIMContext *context,
|
||||
GdkEventKey *event);
|
||||
void (*focus_in) (GtkIMContext *context);
|
||||
void (*focus_out) (GtkIMContext *context);
|
||||
void (*reset) (GtkIMContext *context);
|
||||
};
|
||||
|
||||
GtkType gtk_im_context_get_type (void) G_GNUC_CONST;
|
||||
@@ -72,12 +74,14 @@ GtkType gtk_im_context_get_type (void) G_GNUC_CONST;
|
||||
void gtk_im_context_set_client_window (GtkIMContext *context,
|
||||
GdkWindow *window);
|
||||
void gtk_im_context_get_preedit_string (GtkIMContext *context,
|
||||
char **str,
|
||||
PangoAttrList **attrs);
|
||||
gchar **str,
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos);
|
||||
gboolean gtk_im_context_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *event);
|
||||
void gtk_im_context_focus_in (GtkIMContext *context);
|
||||
void gtk_im_context_focus_out (GtkIMContext *context);
|
||||
void gtk_im_context_reset (GtkIMContext *context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -38,13 +38,17 @@ extern "C" {
|
||||
typedef struct _GtkIMContextSimple GtkIMContextSimple;
|
||||
typedef struct _GtkIMContextSimpleClass GtkIMContextSimpleClass;
|
||||
|
||||
#define GTK_MAX_COMPOSE_LEN 4
|
||||
#define GTK_MAX_COMPOSE_LEN 7
|
||||
|
||||
struct _GtkIMContextSimple
|
||||
{
|
||||
GtkIMContext object;
|
||||
|
||||
GSList *tables;
|
||||
|
||||
guint compose_buffer[GTK_MAX_COMPOSE_LEN + 1];
|
||||
gunichar tentative_match;
|
||||
gint tentative_match_len;
|
||||
};
|
||||
|
||||
struct _GtkIMContextSimpleClass
|
||||
@@ -53,8 +57,12 @@ struct _GtkIMContextSimpleClass
|
||||
};
|
||||
|
||||
GtkType gtk_im_context_simple_get_type (void) G_GNUC_CONST;
|
||||
GtkIMContext *gtk_im_context_simple_new (void);
|
||||
GtkIMContext *gtk_im_context_simple_new (void);
|
||||
|
||||
void gtk_im_context_simple_add_table (GtkIMContextSimple *context_simple,
|
||||
guint16 *data,
|
||||
gint max_seq_len,
|
||||
gint n_seqs);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
466
gtk/gtkimmodule.c
Normal file
466
gtk/gtkimmodule.c
Normal file
@@ -0,0 +1,466 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* Themes added by The Rasterman <raster@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <pango/pango-utils.h>
|
||||
#include "gtkimmodule.h"
|
||||
#include "gtkimcontextsimple.h"
|
||||
#include "gtkmodule.h"
|
||||
#include "gtkrc.h"
|
||||
#include "config.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
typedef struct _GtkIMModule GtkIMModule;
|
||||
|
||||
#define SIMPLE_ID "gtk-im-context-simple"
|
||||
|
||||
struct _GtkIMModule
|
||||
{
|
||||
GtkModule base_module;
|
||||
|
||||
GModule *library;
|
||||
|
||||
void (*list) (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
void (*init) (GtkModule *module);
|
||||
void (*exit) (void);
|
||||
GtkIMContext *(*create) (const gchar *context_id);
|
||||
|
||||
GtkIMContextInfo **contexts;
|
||||
guint n_contexts;
|
||||
|
||||
gchar *path;
|
||||
};
|
||||
|
||||
gint n_loaded_contexts = 0;
|
||||
static GHashTable *contexts_hash = NULL;
|
||||
static GSList *modules_list = NULL;
|
||||
|
||||
static gboolean
|
||||
gtk_im_module_load (GtkModule *module)
|
||||
{
|
||||
GtkIMModule *im_module = (GtkIMModule *)module;
|
||||
|
||||
im_module->library = g_module_open (im_module->path, 0);
|
||||
if (!im_module->library)
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* extract symbols from the lib */
|
||||
if (!g_module_symbol (im_module->library, "im_module_init",
|
||||
(gpointer *)&im_module->init) ||
|
||||
!g_module_symbol (im_module->library, "im_module_exit",
|
||||
(gpointer *)&im_module->exit) ||
|
||||
!g_module_symbol (im_module->library, "im_module_list",
|
||||
(gpointer *)&im_module->list) ||
|
||||
!g_module_symbol (im_module->library, "im_module_create",
|
||||
(gpointer *)&im_module->create))
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
g_module_close (im_module->library);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* call the theme's init (theme_init) function to let it */
|
||||
/* setup anything it needs to set up. */
|
||||
im_module->init (module);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_unload (GtkModule *module)
|
||||
{
|
||||
GtkIMModule *im_module = (GtkIMModule *)module;
|
||||
|
||||
im_module->exit();
|
||||
|
||||
g_module_close (im_module->library);
|
||||
im_module->library = NULL;
|
||||
|
||||
im_module->init = NULL;
|
||||
im_module->exit = NULL;
|
||||
im_module->list = NULL;
|
||||
im_module->create = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
free_info (GtkIMContextInfo *info)
|
||||
{
|
||||
g_free ((char *)info->context_id);
|
||||
g_free ((char *)info->context_name);
|
||||
g_free ((char *)info->domain);
|
||||
g_free ((char *)info->domain_dirname);
|
||||
g_free ((char *)info->default_locales);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
add_module (GtkIMModule *module, GSList *infos)
|
||||
{
|
||||
GSList *tmp_list = infos;
|
||||
gint i = 0;
|
||||
gint n = g_slist_length (infos);
|
||||
module->contexts = g_new (GtkIMContextInfo *, n);
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkIMContextInfo *info = tmp_list->data;
|
||||
|
||||
if (g_hash_table_lookup (contexts_hash, info->context_id))
|
||||
{
|
||||
free_info (info); /* Duplicate */
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (contexts_hash, (char *)info->context_id, module);
|
||||
module->contexts[i++] = tmp_list->data;
|
||||
n_loaded_contexts++;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
g_slist_free (infos);
|
||||
module->n_contexts = i;
|
||||
|
||||
gtk_module_init ((GtkModule *)module, module->path,
|
||||
gtk_im_module_load, gtk_im_module_unload);
|
||||
modules_list = g_slist_prepend (modules_list, module);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_module_init ()
|
||||
{
|
||||
GString *line_buf = g_string_new (NULL);
|
||||
GString *tmp_buf = g_string_new (NULL);
|
||||
const gchar *filename = gtk_rc_get_im_module_file();
|
||||
FILE *file;
|
||||
gboolean have_error = FALSE;
|
||||
|
||||
GtkIMModule *module = NULL;
|
||||
GSList *infos = NULL;
|
||||
|
||||
contexts_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
file = fopen (filename, "r");
|
||||
if (!file)
|
||||
{
|
||||
g_warning ("Can not open Input Method module file '%s': %s",
|
||||
filename, g_strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while (!have_error && pango_read_line (file, line_buf))
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = line_buf->str;
|
||||
|
||||
if (!pango_skip_space (&p))
|
||||
{
|
||||
/* Blank line marking the end of a module
|
||||
*/
|
||||
if (module && *p != '#')
|
||||
{
|
||||
add_module (module, infos);
|
||||
module = NULL;
|
||||
infos = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!module)
|
||||
{
|
||||
/* Read a module location
|
||||
*/
|
||||
module = g_new0 (GtkIMModule, 1);
|
||||
|
||||
if (!pango_scan_string (&p, tmp_buf) ||
|
||||
pango_skip_space (&p))
|
||||
{
|
||||
g_warning ("Error parsing context info in '%s'\n %s",
|
||||
filename, line_buf->str);
|
||||
have_error = TRUE;
|
||||
}
|
||||
|
||||
module->path = g_strdup (tmp_buf->str);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkIMContextInfo *info = g_new0 (GtkIMContextInfo, 1);
|
||||
|
||||
/* Read information about a context type
|
||||
*/
|
||||
if (!pango_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->context_id = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!pango_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->context_name = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!pango_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->domain = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!pango_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->domain_dirname = g_strdup (tmp_buf->str);
|
||||
|
||||
if (!pango_scan_string (&p, tmp_buf))
|
||||
goto context_error;
|
||||
info->default_locales = g_strdup (tmp_buf->str);
|
||||
|
||||
if (pango_skip_space (&p))
|
||||
goto context_error;
|
||||
|
||||
infos = g_slist_prepend (infos, info);
|
||||
continue;
|
||||
|
||||
context_error:
|
||||
g_warning ("Error parsing context info in '%s'\n %s",
|
||||
filename, line_buf->str);
|
||||
have_error = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_error)
|
||||
{
|
||||
GSList *tmp_list = infos;
|
||||
while (tmp_list)
|
||||
{
|
||||
free_info (tmp_list->data);
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
g_slist_free (infos);
|
||||
|
||||
if (module->path)
|
||||
g_free (module->path);
|
||||
|
||||
g_free (module);
|
||||
}
|
||||
else if (module)
|
||||
add_module (module, infos);
|
||||
|
||||
fclose (file);
|
||||
g_string_free (line_buf, TRUE);
|
||||
g_string_free (tmp_buf, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_im_module_list:
|
||||
* @contexts: location to store an array of pointers to #GtkIMContextInfo
|
||||
* this array should be freed with g_free() when you are finished.
|
||||
* The structures it points are statically allocated and should
|
||||
* not be modified or freed.
|
||||
* @n_contexts: the length of the array stored in @contexts
|
||||
*
|
||||
* List all available types of input method context
|
||||
**/
|
||||
void
|
||||
_gtk_im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
static const GtkIMContextInfo simple_context_info = {
|
||||
SIMPLE_ID,
|
||||
"Default",
|
||||
"gtk+",
|
||||
NULL,
|
||||
""
|
||||
};
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_init ();
|
||||
|
||||
if (n_contexts)
|
||||
*n_contexts = (n_loaded_contexts + 1);
|
||||
|
||||
if (contexts)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
int i;
|
||||
|
||||
*contexts = g_new (const GtkIMContextInfo *, n_loaded_contexts + 1);
|
||||
|
||||
(*contexts)[n++] = &simple_context_info;
|
||||
|
||||
tmp_list = modules_list;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkIMModule *module = tmp_list->data;
|
||||
|
||||
for (i=0; i<module->n_contexts; i++)
|
||||
(*contexts)[n++] = module->contexts[i];
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_im_module_create:
|
||||
* @context_id: the context ID for the context type to create
|
||||
*
|
||||
* Create an IM context of a type specified by the string
|
||||
* ID @context_id.
|
||||
*
|
||||
* Return value: a newly created input context of or @context_id, or
|
||||
* if that could not be created, a newly created GtkIMContextSimple.
|
||||
**/
|
||||
GtkIMContext *
|
||||
_gtk_im_module_create (const gchar *context_id)
|
||||
{
|
||||
GtkIMModule *im_module;
|
||||
GtkIMContext *context = NULL;
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_init ();
|
||||
|
||||
if (strcmp (context_id, SIMPLE_ID) != 0)
|
||||
{
|
||||
im_module = g_hash_table_lookup (contexts_hash, context_id);
|
||||
if (!im_module)
|
||||
{
|
||||
g_warning ("Attempt to load unknown IM context type '%s'", context_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_module_ref ((GtkModule *)im_module))
|
||||
{
|
||||
context = im_module->create (context_id);
|
||||
gtk_module_unref ((GtkModule *)im_module);
|
||||
}
|
||||
|
||||
if (!context)
|
||||
g_warning ("Loading IM context type '%s' failed", context_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return gtk_im_context_simple_new ();
|
||||
else
|
||||
return context;
|
||||
}
|
||||
|
||||
/* Match @locale against @against.
|
||||
*
|
||||
* 'en_US' against 'en_US' => 3
|
||||
* 'en_US' against 'en' => 2
|
||||
* 'en', 'en_UK' against 'en_US' => 1
|
||||
*/
|
||||
static gint
|
||||
match_locale (const gchar *locale,
|
||||
const gchar *against,
|
||||
gint against_len)
|
||||
{
|
||||
if (strcmp (locale, against) == 0)
|
||||
return 3;
|
||||
|
||||
if (strncmp (locale, against, 2) == 0)
|
||||
return (against_len == 2) ? 2 : 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_im_module_get_default_context_id:
|
||||
* @locale: a locale id in the form 'en_US'
|
||||
*
|
||||
* Return the context_id of the best IM context type
|
||||
* for the given locale ID.
|
||||
*
|
||||
* Return value: the context ID (will never be %NULL)
|
||||
* the value is newly allocated and must be freed
|
||||
* with g_free().
|
||||
**/
|
||||
const gchar *
|
||||
_gtk_im_module_get_default_context_id (const gchar *locale)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
const gchar *context_id = NULL;
|
||||
gint best_goodness = 0;
|
||||
gint i;
|
||||
gchar *tmp_locale, *tmp;
|
||||
gchar *envvar;
|
||||
|
||||
if (!contexts_hash)
|
||||
gtk_im_module_init ();
|
||||
|
||||
envvar = g_getenv ("GTK_IM_MODULE");
|
||||
if (envvar && g_hash_table_lookup (contexts_hash, envvar))
|
||||
return g_strdup (envvar);
|
||||
|
||||
/* Strip the locale code down to the essentials
|
||||
*/
|
||||
tmp_locale = g_strdup (locale);
|
||||
tmp = strchr (tmp_locale, '.');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
tmp = strchr (tmp_locale, '@');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp_list = modules_list;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkIMModule *module = tmp_list->data;
|
||||
|
||||
for (i=0; i<module->n_contexts; i++)
|
||||
{
|
||||
const gchar *p = module->contexts[i]->default_locales;
|
||||
while (p)
|
||||
{
|
||||
const gchar *q = strchr (p, ':');
|
||||
gint goodness = match_locale (tmp_locale, p, q ? q - p : strlen (p));
|
||||
|
||||
if (goodness > best_goodness)
|
||||
{
|
||||
context_id = module->contexts[i]->context_id;
|
||||
best_goodness = goodness;
|
||||
}
|
||||
|
||||
p = q ? q + 1 : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_free (tmp_locale);
|
||||
|
||||
return g_strdup (context_id ? context_id : SIMPLE_ID);
|
||||
}
|
63
gtk/gtkimmodule.h
Normal file
63
gtk/gtkimmodule.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat Software
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_IM_MODULE_H__
|
||||
#define __GTK_IM_MODULE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkmodule.h>
|
||||
|
||||
typedef struct _GtkIMContextInfo GtkIMContextInfo;
|
||||
|
||||
struct _GtkIMContextInfo
|
||||
{
|
||||
const gchar *context_id;
|
||||
const gchar *context_name;
|
||||
const gchar *domain;
|
||||
const gchar *domain_dirname;
|
||||
const gchar *default_locales;
|
||||
};
|
||||
|
||||
/* Functions for use within GTK+
|
||||
*/
|
||||
void _gtk_im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
GtkIMContext *_gtk_im_module_create (const gchar *context_id);
|
||||
const gchar * _gtk_im_module_get_default_context_id (const gchar *lang);
|
||||
|
||||
/* The following entry points are exported by each input method module
|
||||
*/
|
||||
|
||||
/*
|
||||
void im_module_list (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
void im_module_init (GtkModule *module);
|
||||
void im_module_exit (void);
|
||||
GtkIMContext *im_module_create (const gchar *context_id);
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif __GTK_IM_MODULE_H__
|
@@ -17,9 +17,18 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <X11/Xlocale.h> /* so we get the right setlocale */
|
||||
#else
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#include "gtksignal.h"
|
||||
#include "gtkimmulticontext.h"
|
||||
#include "gtkimcontextsimple.h"
|
||||
#include "gtkimmodule.h"
|
||||
#include "gtkmenuitem.h"
|
||||
|
||||
static void gtk_im_multicontext_class_init (GtkIMMulticontextClass *class);
|
||||
static void gtk_im_multicontext_init (GtkIMMulticontext *im_multicontext);
|
||||
@@ -32,11 +41,13 @@ static void gtk_im_multicontext_set_client_window (GtkIMContext
|
||||
GdkWindow *window);
|
||||
static void gtk_im_multicontext_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs);
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos);
|
||||
static gboolean gtk_im_multicontext_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *event);
|
||||
static void gtk_im_multicontext_focus_in (GtkIMContext *context);
|
||||
static void gtk_im_multicontext_focus_out (GtkIMContext *context);
|
||||
static void gtk_im_multicontext_reset (GtkIMContext *context);
|
||||
|
||||
void gtk_im_multicontext_preedit_start_cb (GtkIMContext *slave,
|
||||
GtkIMMulticontext *multicontext);
|
||||
@@ -50,6 +61,8 @@ void gtk_im_multicontext_commit_cb (GtkIMContext
|
||||
|
||||
static GtkIMContextClass *parent_class;
|
||||
|
||||
static const gchar *global_context_id = NULL;
|
||||
|
||||
GtkType
|
||||
gtk_im_multicontext_get_type (void)
|
||||
{
|
||||
@@ -88,6 +101,7 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
|
||||
im_context_class->filter_keypress = gtk_im_multicontext_filter_keypress;
|
||||
im_context_class->focus_in = gtk_im_multicontext_focus_in;
|
||||
im_context_class->focus_out = gtk_im_multicontext_focus_out;
|
||||
im_context_class->reset = gtk_im_multicontext_reset;
|
||||
|
||||
gobject_class->finalize = gtk_im_multicontext_finalize;
|
||||
}
|
||||
@@ -141,6 +155,9 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
|
||||
gtk_signal_connect (GTK_OBJECT (multicontext->slave), "commit",
|
||||
GTK_SIGNAL_FUNC (gtk_im_multicontext_commit_cb),
|
||||
multicontext);
|
||||
|
||||
if (multicontext->client_window)
|
||||
gtk_im_context_set_client_window (slave, multicontext->client_window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +165,22 @@ static GtkIMContext *
|
||||
gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
|
||||
{
|
||||
if (!multicontext->slave)
|
||||
gtk_im_multicontext_set_slave (multicontext, gtk_im_context_simple_new ());
|
||||
{
|
||||
if (!global_context_id)
|
||||
{
|
||||
const char *locale;
|
||||
|
||||
#ifdef HAVE_LC_MESSAGES
|
||||
locale = setlocale (LC_MESSAGES, NULL);
|
||||
#else
|
||||
locale = setlocale (LC_CTYPE, NULL);
|
||||
#endif
|
||||
global_context_id = _gtk_im_module_get_default_context_id (locale);
|
||||
}
|
||||
|
||||
gtk_im_multicontext_set_slave (multicontext, _gtk_im_module_create (global_context_id));
|
||||
multicontext->context_id = global_context_id;
|
||||
}
|
||||
|
||||
return multicontext->slave;
|
||||
}
|
||||
@@ -160,6 +192,8 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
|
||||
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
|
||||
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
|
||||
|
||||
multicontext->client_window = window;
|
||||
|
||||
if (slave)
|
||||
gtk_im_context_set_client_window (slave, window);
|
||||
}
|
||||
@@ -167,13 +201,14 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
|
||||
static void
|
||||
gtk_im_multicontext_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs)
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos)
|
||||
{
|
||||
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
|
||||
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
|
||||
|
||||
if (slave)
|
||||
gtk_im_context_get_preedit_string (slave, str, attrs);
|
||||
gtk_im_context_get_preedit_string (slave, str, attrs, cursor_pos);
|
||||
else
|
||||
{
|
||||
if (str)
|
||||
@@ -200,7 +235,17 @@ static void
|
||||
gtk_im_multicontext_focus_in (GtkIMContext *context)
|
||||
{
|
||||
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
|
||||
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
|
||||
GtkIMContext *slave;
|
||||
|
||||
/* If the global context type is different from the context we were
|
||||
* using before, get rid of the old slave and create a new one
|
||||
* for the new global context type.
|
||||
*/
|
||||
if (!multicontext->context_id ||
|
||||
strcmp (global_context_id, multicontext->context_id) != 0)
|
||||
gtk_im_multicontext_set_slave (multicontext, NULL);
|
||||
|
||||
slave = gtk_im_multicontext_get_slave (multicontext);
|
||||
|
||||
if (slave)
|
||||
gtk_im_context_focus_in (slave);
|
||||
@@ -216,6 +261,16 @@ gtk_im_multicontext_focus_out (GtkIMContext *context)
|
||||
gtk_im_context_focus_out (slave);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_multicontext_reset (GtkIMContext *context)
|
||||
{
|
||||
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
|
||||
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
|
||||
|
||||
if (slave)
|
||||
gtk_im_context_reset (slave);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_im_multicontext_preedit_start_cb (GtkIMContext *slave,
|
||||
GtkIMMulticontext *multicontext)
|
||||
@@ -245,3 +300,49 @@ gtk_im_multicontext_commit_cb (GtkIMContext *slave,
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (multicontext), "commit", str);;
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem,
|
||||
GtkIMMulticontext *context)
|
||||
{
|
||||
const gchar *id = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-context-id");
|
||||
|
||||
gtk_im_context_reset (GTK_IM_CONTEXT (context));
|
||||
|
||||
global_context_id = id;
|
||||
gtk_im_multicontext_set_slave (context, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_im_multicontext_append_menuitems:
|
||||
* @context: a #GtkIMMultiContext
|
||||
* @menushell: a #GtkMenuShell
|
||||
*
|
||||
* Add menuitems for various available input methods to a menu;
|
||||
* the menuitems, when selected, will switch the input method
|
||||
* for the context and the global default input method.
|
||||
**/
|
||||
void
|
||||
gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
|
||||
GtkMenuShell *menushell)
|
||||
{
|
||||
const GtkIMContextInfo **contexts;
|
||||
gint n_contexts, i;
|
||||
|
||||
_gtk_im_module_list (&contexts, &n_contexts);
|
||||
|
||||
for (i=0; i < n_contexts; i++)
|
||||
{
|
||||
GtkWidget *menuitem;
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label (contexts[i]->context_name);
|
||||
|
||||
gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-context-id",
|
||||
(char *)contexts[i]->context_id);
|
||||
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
|
||||
activate_cb, context);
|
||||
|
||||
gtk_widget_show (menuitem);
|
||||
gtk_menu_shell_append (menushell, menuitem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#define __GTK_IM_MULTICONTEXT_H__
|
||||
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkmenushell.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -43,6 +44,10 @@ struct _GtkIMMulticontext
|
||||
GtkIMContext object;
|
||||
|
||||
GtkIMContext *slave;
|
||||
|
||||
GdkWindow *client_window;
|
||||
|
||||
const gchar *context_id;
|
||||
};
|
||||
|
||||
struct _GtkIMMulticontextClass
|
||||
@@ -53,6 +58,9 @@ struct _GtkIMMulticontextClass
|
||||
GtkType gtk_im_multicontext_get_type (void) G_GNUC_CONST;
|
||||
GtkIMContext *gtk_im_multicontext_new (void);
|
||||
|
||||
void gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
|
||||
GtkMenuShell *menushell);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
261
gtk/gtkmodule.c
Normal file
261
gtk/gtkmodule.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gtkmodule.h"
|
||||
|
||||
typedef struct _GtkModuleTypeInfo GtkModuleTypeInfo;
|
||||
|
||||
struct _GtkModuleTypeInfo
|
||||
{
|
||||
gboolean loaded;
|
||||
GType type;
|
||||
GType parent_type;
|
||||
GTypeInfo info;
|
||||
};
|
||||
|
||||
static void gtk_module_plugin_ref (GTypePlugin *plugin);
|
||||
static void gtk_module_complete_type_info (GTypePlugin *plugin,
|
||||
GType g_type,
|
||||
GTypeInfo *info,
|
||||
GTypeValueTable *value_table);
|
||||
|
||||
static GTypePluginVTable gtk_module_plugin_vtable = {
|
||||
gtk_module_plugin_ref,
|
||||
(GTypePluginUnRef)gtk_module_unref,
|
||||
gtk_module_complete_type_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* gtk_module_init:
|
||||
* @module: a pointer to a #GtkModule structure. This will
|
||||
* typically be included as the first element in
|
||||
* a larger structure that is specific to the
|
||||
* type of module.
|
||||
* @name: a human-readable name to use in error messages.
|
||||
* @load_func: a function to call to load the module.
|
||||
* @unload_func: a function to call to unload the module.
|
||||
*
|
||||
* Initializes a structure as a GtkModule. The module is
|
||||
* created with a refcount of zero - that is, in the
|
||||
* unloaded state. In order to load the module initially,
|
||||
* you must call gtk_module_ref().
|
||||
**/
|
||||
void
|
||||
gtk_module_init (GtkModule *module,
|
||||
const gchar *name,
|
||||
GtkModuleLoadFunc load_func,
|
||||
GtkModuleUnloadFunc unload_func)
|
||||
{
|
||||
module->name = g_strdup (name);
|
||||
module->plugin.vtable = >k_module_plugin_vtable;
|
||||
module->load_func = load_func;
|
||||
module->unload_func = unload_func;
|
||||
module->ref_count = 0;
|
||||
module->type_infos = NULL;
|
||||
}
|
||||
|
||||
static GtkModuleTypeInfo *
|
||||
gtk_module_find_type_info (GtkModule *module,
|
||||
GType type)
|
||||
{
|
||||
GSList *tmp_list = module->type_infos;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkModuleTypeInfo *type_info = tmp_list->data;
|
||||
if (type_info->type == type)
|
||||
return type_info;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_module_ref:
|
||||
* @module: a #GtkModule
|
||||
*
|
||||
* Increases the reference count of a #GtkModule by one. If the
|
||||
* reference count was zero before, the module will be loaded.
|
||||
*
|
||||
* Return Value: %FALSE if the module needed to be loaded and
|
||||
* loading the module failed.
|
||||
**/
|
||||
gboolean
|
||||
gtk_module_ref (GtkModule *module)
|
||||
{
|
||||
g_return_val_if_fail (module != NULL, FALSE);
|
||||
|
||||
if (module->ref_count == 0)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
|
||||
if (!module->load_func (module))
|
||||
return FALSE;
|
||||
|
||||
tmp_list = module->type_infos;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkModuleTypeInfo *type_info = tmp_list->data;
|
||||
if (!type_info->loaded)
|
||||
{
|
||||
g_warning ("module '%s' failed to register type '%s'\n",
|
||||
module->name, g_type_name (type_info->type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
|
||||
module->ref_count++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_module_plugin_ref (GTypePlugin *plugin)
|
||||
{
|
||||
GtkModule *module = (GtkModule *)plugin;
|
||||
|
||||
if (!gtk_module_ref (module))
|
||||
{
|
||||
g_warning ("Fatal error - Could not reload previously loaded module '%s'\n",
|
||||
module->name);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_module_unref:
|
||||
* @module: a #GtkModule
|
||||
*
|
||||
* Decreases the reference count of a #GtkModule by one. If the
|
||||
* result is zero, the module will be unloaded. (However, the
|
||||
* #GtkModule will not be freed, and types associated with the
|
||||
* #GtkModule are not unregistered. Once a #GtkModule is
|
||||
* initialized, it must exist forever.)x
|
||||
**/
|
||||
void
|
||||
gtk_module_unref (GtkModule *module)
|
||||
{
|
||||
g_return_if_fail (module != NULL);
|
||||
g_return_if_fail (module->ref_count > 0);
|
||||
|
||||
module->ref_count--;
|
||||
|
||||
if (module->ref_count == 0)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
|
||||
module->unload_func (module);
|
||||
|
||||
tmp_list = module->type_infos;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkModuleTypeInfo *type_info = tmp_list->data;
|
||||
type_info->loaded = FALSE;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_module_complete_type_info (GTypePlugin *plugin,
|
||||
GType g_type,
|
||||
GTypeInfo *info,
|
||||
GTypeValueTable *value_table)
|
||||
{
|
||||
GtkModule *module = (GtkModule *)plugin;
|
||||
GtkModuleTypeInfo *module_type_info = gtk_module_find_type_info (module, g_type);
|
||||
|
||||
*info = module_type_info->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_module_register_type:
|
||||
* @engine: a #GtkModule
|
||||
* @parent_type: the type for the parent class
|
||||
* @type_name: name for the type
|
||||
* @type_info: type information structure
|
||||
*
|
||||
* Looks up or registers a type that is implemented with a particular
|
||||
* theme engine. If a type with name @type_name is already registered,
|
||||
* the #GType identifier for the type is returned, otherwise the type
|
||||
* is newly registered, and the resulting #GType identifier returned.
|
||||
*
|
||||
* As long as any instances of the type exist, the a reference will be
|
||||
* held to the theme engine and the theme engine will not be unloaded.
|
||||
*
|
||||
* Return value: the type identifier for the class.
|
||||
**/
|
||||
GType
|
||||
gtk_module_register_type (GtkModule *module,
|
||||
GType parent_type,
|
||||
const gchar *type_name,
|
||||
const GTypeInfo *type_info)
|
||||
{
|
||||
GtkModuleTypeInfo *module_type_info = NULL;
|
||||
GType type;
|
||||
|
||||
g_return_val_if_fail (module != NULL, 0);
|
||||
g_return_val_if_fail (type_name != NULL, 0);
|
||||
g_return_val_if_fail (type_info != NULL, 0);
|
||||
|
||||
type = g_type_from_name (type_name);
|
||||
if (type)
|
||||
{
|
||||
GtkModule *old_module = (GtkModule *)g_type_get_plugin (type);
|
||||
|
||||
if (old_module != module)
|
||||
{
|
||||
g_warning ("Two different modules tried to register '%s'.", type_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (type)
|
||||
{
|
||||
module_type_info = gtk_module_find_type_info (module, type);
|
||||
|
||||
if (module_type_info->parent_type != parent_type)
|
||||
{
|
||||
g_warning ("Type '%s' recreated with different parent type.\n"
|
||||
"(was '%s', now '%s')", type_name,
|
||||
g_type_name (module_type_info->parent_type),
|
||||
g_type_name (parent_type));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
module_type_info = g_new (GtkModuleTypeInfo, 1);
|
||||
|
||||
module_type_info->parent_type = parent_type;
|
||||
module_type_info->type = g_type_register_dynamic (parent_type, type_name, (GTypePlugin *)module);
|
||||
|
||||
module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
|
||||
}
|
||||
|
||||
module_type_info->loaded = TRUE;
|
||||
module_type_info->info = *type_info;
|
||||
|
||||
return module_type_info->type;
|
||||
}
|
64
gtk/gtkmodule.h
Normal file
64
gtk/gtkmodule.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_MODULE_H__
|
||||
#define __GTK_MODULE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef struct _GtkModule GtkModule;
|
||||
|
||||
typedef gboolean (*GtkModuleLoadFunc) (GtkModule *module);
|
||||
typedef void (*GtkModuleUnloadFunc) (GtkModule *module);
|
||||
|
||||
struct _GtkModule
|
||||
{
|
||||
/*< private >*/
|
||||
GTypePlugin plugin;
|
||||
|
||||
guint ref_count;
|
||||
|
||||
GtkModuleLoadFunc load_func;
|
||||
GtkModuleUnloadFunc unload_func;
|
||||
|
||||
GSList *type_infos;
|
||||
|
||||
gchar *name;
|
||||
};
|
||||
|
||||
gboolean gtk_module_ref (GtkModule *module);
|
||||
void gtk_module_unref (GtkModule *module);
|
||||
void gtk_module_init (GtkModule *module,
|
||||
const gchar *name,
|
||||
GtkModuleLoadFunc load_func,
|
||||
GtkModuleUnloadFunc unload_func);
|
||||
GType gtk_module_register_type (GtkModule *module,
|
||||
GType parent_type,
|
||||
const gchar *type_name,
|
||||
const GTypeInfo *type_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif __GTK_MODULE_H__
|
859
gtk/gtkoldeditable.c
Normal file
859
gtk/gtkoldeditable.c
Normal file
@@ -0,0 +1,859 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "gdk/gdkkeysyms.h"
|
||||
#include "gdk/gdki18n.h"
|
||||
#include "gtkclipboard.h"
|
||||
#include "gtkoldeditable.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtksignal.h"
|
||||
|
||||
#define MIN_EDITABLE_WIDTH 150
|
||||
#define DRAW_TIMEOUT 20
|
||||
#define INNER_BORDER 2
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
INSERT_TEXT,
|
||||
DELETE_TEXT,
|
||||
/* Binding actions */
|
||||
ACTIVATE,
|
||||
SET_EDITABLE,
|
||||
MOVE_CURSOR,
|
||||
MOVE_WORD,
|
||||
MOVE_PAGE,
|
||||
MOVE_TO_ROW,
|
||||
MOVE_TO_COLUMN,
|
||||
KILL_CHAR,
|
||||
KILL_WORD,
|
||||
KILL_LINE,
|
||||
CUT_CLIPBOARD,
|
||||
COPY_CLIPBOARD,
|
||||
PASTE_CLIPBOARD,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_TEXT_POSITION,
|
||||
ARG_EDITABLE
|
||||
};
|
||||
|
||||
/* values for selection info */
|
||||
|
||||
enum {
|
||||
TARGET_STRING,
|
||||
TARGET_TEXT,
|
||||
TARGET_COMPOUND_TEXT
|
||||
};
|
||||
|
||||
static void gtk_old_editable_class_init (GtkOldEditableClass *klass);
|
||||
static void gtk_old_editable_editable_init (GtkEditableIface *iface);
|
||||
static void gtk_old_editable_init (GtkOldEditable *editable);
|
||||
static void gtk_old_editable_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void gtk_old_editable_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void *gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
|
||||
gint start,
|
||||
gint end);
|
||||
|
||||
static gint gtk_old_editable_selection_clear (GtkWidget *widget,
|
||||
GdkEventSelection *event);
|
||||
static void gtk_old_editable_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time);
|
||||
static void gtk_old_editable_selection_received (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint time);
|
||||
|
||||
static void gtk_old_editable_set_selection (GtkOldEditable *old_editable,
|
||||
gint start,
|
||||
gint end);
|
||||
|
||||
static void gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
|
||||
gboolean is_editable);
|
||||
static void gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable);
|
||||
static void gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable);
|
||||
static void gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable);
|
||||
|
||||
static void gtk_old_editable_insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position);
|
||||
static void gtk_old_editable_delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
static gchar * gtk_old_editable_get_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
static void gtk_old_editable_set_selection_bounds (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end);
|
||||
static gboolean gtk_old_editable_get_selection_bounds (GtkEditable *editable,
|
||||
gint *start,
|
||||
gint *end);
|
||||
static void gtk_old_editable_set_position (GtkEditable *editable,
|
||||
gint position);
|
||||
static gint gtk_old_editable_get_position (GtkEditable *editable);
|
||||
|
||||
static GtkWidgetClass *parent_class = NULL;
|
||||
static guint editable_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
GtkType
|
||||
gtk_old_editable_get_type (void)
|
||||
{
|
||||
static GtkType old_editable_type = 0;
|
||||
|
||||
if (!old_editable_type)
|
||||
{
|
||||
static const GtkTypeInfo old_editable_info =
|
||||
{
|
||||
"GtkOldEditable",
|
||||
sizeof (GtkOldEditable),
|
||||
sizeof (GtkOldEditableClass),
|
||||
(GtkClassInitFunc) gtk_old_editable_class_init,
|
||||
(GtkObjectInitFunc) gtk_old_editable_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
static const GInterfaceInfo editable_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_old_editable_editable_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
|
||||
old_editable_type = gtk_type_unique (GTK_TYPE_WIDGET, &old_editable_info);
|
||||
g_type_add_interface_static (old_editable_type,
|
||||
GTK_TYPE_EDITABLE,
|
||||
&editable_info);
|
||||
}
|
||||
|
||||
return old_editable_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_class_init (GtkOldEditableClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
object_class = (GtkObjectClass*) class;
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
|
||||
parent_class = gtk_type_class (GTK_TYPE_WIDGET);
|
||||
|
||||
editable_signals[CHANGED] =
|
||||
gtk_signal_new ("changed",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, changed),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[INSERT_TEXT] =
|
||||
gtk_signal_new ("insert_text",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, insert_text),
|
||||
gtk_marshal_NONE__POINTER_INT_POINTER,
|
||||
GTK_TYPE_NONE,
|
||||
3,
|
||||
GTK_TYPE_STRING,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_POINTER);
|
||||
|
||||
editable_signals[DELETE_TEXT] =
|
||||
gtk_signal_new ("delete_text",
|
||||
GTK_RUN_LAST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, delete_text),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE,
|
||||
2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[ACTIVATE] =
|
||||
gtk_signal_new ("activate",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, activate),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
widget_class->activate_signal = editable_signals[ACTIVATE];
|
||||
|
||||
editable_signals[SET_EDITABLE] =
|
||||
gtk_signal_new ("set-editable",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, set_editable),
|
||||
gtk_marshal_NONE__BOOL,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_BOOL);
|
||||
|
||||
editable_signals[MOVE_CURSOR] =
|
||||
gtk_signal_new ("move_cursor",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_cursor),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_WORD] =
|
||||
gtk_signal_new ("move_word",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_word),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_PAGE] =
|
||||
gtk_signal_new ("move_page",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_page),
|
||||
gtk_marshal_NONE__INT_INT,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_INT,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_TO_ROW] =
|
||||
gtk_signal_new ("move_to_row",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_row),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[MOVE_TO_COLUMN] =
|
||||
gtk_signal_new ("move_to_column",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_column),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_CHAR] =
|
||||
gtk_signal_new ("kill_char",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_char),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_WORD] =
|
||||
gtk_signal_new ("kill_word",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_word),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[KILL_LINE] =
|
||||
gtk_signal_new ("kill_line",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_line),
|
||||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
editable_signals[CUT_CLIPBOARD] =
|
||||
gtk_signal_new ("cut_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, cut_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[COPY_CLIPBOARD] =
|
||||
gtk_signal_new ("copy_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, copy_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
editable_signals[PASTE_CLIPBOARD] =
|
||||
gtk_signal_new ("paste_clipboard",
|
||||
GTK_RUN_LAST | GTK_RUN_ACTION,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkOldEditableClass, paste_clipboard),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL);
|
||||
|
||||
gtk_object_add_arg_type ("GtkOldEditable::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION);
|
||||
gtk_object_add_arg_type ("GtkOldEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
|
||||
|
||||
object_class->set_arg = gtk_old_editable_set_arg;
|
||||
object_class->get_arg = gtk_old_editable_get_arg;
|
||||
|
||||
widget_class->selection_clear_event = gtk_old_editable_selection_clear;
|
||||
widget_class->selection_received = gtk_old_editable_selection_received;
|
||||
widget_class->selection_get = gtk_old_editable_selection_get;
|
||||
|
||||
class->insert_text = NULL;
|
||||
class->delete_text = NULL;
|
||||
|
||||
class->activate = NULL;
|
||||
class->set_editable = gtk_old_editable_real_set_editable;
|
||||
|
||||
class->move_cursor = NULL;
|
||||
class->move_word = NULL;
|
||||
class->move_page = NULL;
|
||||
class->move_to_row = NULL;
|
||||
class->move_to_column = NULL;
|
||||
|
||||
class->kill_char = NULL;
|
||||
class->kill_word = NULL;
|
||||
class->kill_line = NULL;
|
||||
|
||||
class->cut_clipboard = gtk_old_editable_real_cut_clipboard;
|
||||
class->copy_clipboard = gtk_old_editable_real_copy_clipboard;
|
||||
class->paste_clipboard = gtk_old_editable_real_paste_clipboard;
|
||||
|
||||
class->update_text = NULL;
|
||||
class->get_chars = NULL;
|
||||
class->set_selection = NULL;
|
||||
class->set_position = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_editable_init (GtkEditableIface *iface)
|
||||
{
|
||||
iface->insert_text = gtk_old_editable_insert_text;
|
||||
iface->delete_text = gtk_old_editable_delete_text;
|
||||
iface->get_chars = gtk_old_editable_get_chars;
|
||||
iface->set_selection_bounds = gtk_old_editable_set_selection_bounds;
|
||||
iface->get_selection_bounds = gtk_old_editable_get_selection_bounds;
|
||||
iface->set_position = gtk_old_editable_set_position;
|
||||
iface->get_position = gtk_old_editable_get_position;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (object);
|
||||
|
||||
switch (arg_id)
|
||||
{
|
||||
case ARG_TEXT_POSITION:
|
||||
gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
|
||||
break;
|
||||
case ARG_EDITABLE:
|
||||
gtk_signal_emit (object, editable_signals[SET_EDITABLE],
|
||||
GTK_VALUE_BOOL (*arg) != FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id)
|
||||
{
|
||||
GtkOldEditable *old_editable;
|
||||
|
||||
old_editable = GTK_OLD_EDITABLE (object);
|
||||
|
||||
switch (arg_id)
|
||||
{
|
||||
case ARG_TEXT_POSITION:
|
||||
GTK_VALUE_INT (*arg) = old_editable->current_pos;
|
||||
break;
|
||||
case ARG_EDITABLE:
|
||||
GTK_VALUE_BOOL (*arg) = old_editable->editable;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_init (GtkOldEditable *old_editable)
|
||||
{
|
||||
static const GtkTargetEntry targets[] = {
|
||||
{ "UTF8_STRING", 0, 0 },
|
||||
{ "STRING", 0, 0 },
|
||||
{ "TEXT", 0, 0 },
|
||||
{ "COMPOUND_TEXT", 0, 0 }
|
||||
};
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (old_editable, GTK_CAN_FOCUS);
|
||||
|
||||
old_editable->selection_start_pos = 0;
|
||||
old_editable->selection_end_pos = 0;
|
||||
old_editable->has_selection = FALSE;
|
||||
old_editable->editable = 1;
|
||||
old_editable->visible = 1;
|
||||
old_editable->clipboard_text = NULL;
|
||||
|
||||
#ifdef USE_XIM
|
||||
old_editable->ic = NULL;
|
||||
#endif
|
||||
|
||||
gtk_selection_add_targets (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY,
|
||||
targets, G_N_ELEMENTS (targets));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_insert_text (GtkEditable *editable,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position)
|
||||
{
|
||||
gchar buf[64];
|
||||
gchar *text;
|
||||
|
||||
gtk_widget_ref (GTK_WIDGET (editable));
|
||||
|
||||
if (new_text_length <= 63)
|
||||
text = buf;
|
||||
else
|
||||
text = g_new (gchar, new_text_length + 1);
|
||||
|
||||
text[new_text_length] = '\0';
|
||||
strncpy (text, new_text, new_text_length);
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT], text, new_text_length, position);
|
||||
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
|
||||
|
||||
if (new_text_length > 63)
|
||||
g_free (text);
|
||||
|
||||
gtk_widget_unref (GTK_WIDGET (editable));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_delete_text (GtkEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
|
||||
|
||||
gtk_widget_ref (GTK_WIDGET (old_editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[DELETE_TEXT], start_pos, end_pos);
|
||||
gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[CHANGED]);
|
||||
|
||||
if (old_editable->selection_start_pos == old_editable->selection_end_pos &&
|
||||
old_editable->has_selection)
|
||||
gtk_old_editable_claim_selection (old_editable, FALSE, GDK_CURRENT_TIME);
|
||||
|
||||
gtk_widget_unref (GTK_WIDGET (old_editable));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_update_text (GtkOldEditable *old_editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
|
||||
klass->update_text (GTK_OLD_EDITABLE (old_editable), start_pos, end_pos);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gtk_old_editable_get_chars (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
|
||||
return klass->get_chars (GTK_OLD_EDITABLE (editable), start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like gtk_editable_get_chars, but if the editable is not
|
||||
* visible, return asterisks; also convert result to UTF-8.
|
||||
*/
|
||||
static void *
|
||||
gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
gchar *str = NULL;
|
||||
gchar *charset;
|
||||
gboolean need_conversion = !g_get_charset (&charset);
|
||||
|
||||
if (old_editable->visible)
|
||||
{
|
||||
GError *error;
|
||||
gchar *tmp = gtk_editable_get_chars (GTK_EDITABLE (old_editable), start, end);
|
||||
|
||||
if (need_conversion)
|
||||
{
|
||||
str = g_convert (tmp, -1,
|
||||
"UTF-8", charset,
|
||||
NULL, NULL, &error);
|
||||
|
||||
if (!str)
|
||||
{
|
||||
g_warning ("Cannot convert text from charset to UTF-8 %s: %s", charset, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (tmp);
|
||||
}
|
||||
else
|
||||
str = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
gint i;
|
||||
gint nchars = end - start;
|
||||
|
||||
if (nchars < 0)
|
||||
nchars = -nchars;
|
||||
|
||||
str = g_new (gchar, nchars + 1);
|
||||
for (i = 0; i<nchars; i++)
|
||||
str[i] = '*';
|
||||
str[i] = '\0';
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_set_selection (GtkOldEditable *old_editable,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
|
||||
klass->set_selection (old_editable, start_pos, end_pos);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_set_position (GtkEditable *editable,
|
||||
gint position)
|
||||
{
|
||||
GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
|
||||
|
||||
klass->set_position (GTK_OLD_EDITABLE (editable), position);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_old_editable_get_position (GtkEditable *editable)
|
||||
{
|
||||
return GTK_OLD_EDITABLE (editable)->current_pos;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_old_editable_selection_clear (GtkWidget *widget,
|
||||
GdkEventSelection *event)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
|
||||
|
||||
/* Let the selection handling code know that the selection
|
||||
* has been changed, since we've overriden the default handler */
|
||||
if (!gtk_selection_clear (widget, event))
|
||||
return FALSE;
|
||||
|
||||
if (old_editable->has_selection)
|
||||
{
|
||||
old_editable->has_selection = FALSE;
|
||||
gtk_old_editable_update_text (old_editable, old_editable->selection_start_pos,
|
||||
old_editable->selection_end_pos);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
|
||||
gint selection_start_pos;
|
||||
gint selection_end_pos;
|
||||
|
||||
gchar *str;
|
||||
|
||||
selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
|
||||
selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
|
||||
|
||||
str = gtk_old_editable_get_public_chars (old_editable,
|
||||
selection_start_pos,
|
||||
selection_end_pos);
|
||||
|
||||
if (str)
|
||||
{
|
||||
gtk_selection_data_set_text (selection_data, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_paste_received (GtkOldEditable *old_editable,
|
||||
const gchar *text,
|
||||
gboolean is_clipboard)
|
||||
{
|
||||
const gchar *str = NULL;
|
||||
gchar *charset;
|
||||
gboolean need_conversion = FALSE;
|
||||
|
||||
if (text)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
need_conversion = !g_get_charset (&charset);
|
||||
|
||||
if (need_conversion)
|
||||
{
|
||||
str = g_convert_with_fallback (text, -1,
|
||||
charset, "UTF-8", NULL,
|
||||
NULL, NULL, &error);
|
||||
if (!str)
|
||||
{
|
||||
g_warning ("Cannot convert text from UTF-8 to %s: %s",
|
||||
charset, error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
str = text;
|
||||
}
|
||||
|
||||
if (str)
|
||||
{
|
||||
gboolean reselect;
|
||||
gint old_pos;
|
||||
gint tmp_pos;
|
||||
|
||||
reselect = FALSE;
|
||||
|
||||
if ((old_editable->selection_start_pos != old_editable->selection_end_pos) &&
|
||||
(!old_editable->has_selection || is_clipboard))
|
||||
{
|
||||
reselect = TRUE;
|
||||
|
||||
/* Don't want to call gtk_editable_delete_selection here if we are going
|
||||
* to reclaim the selection to avoid extra server traffic */
|
||||
if (old_editable->has_selection)
|
||||
{
|
||||
gtk_editable_delete_text (GTK_EDITABLE (old_editable),
|
||||
MIN (old_editable->selection_start_pos, old_editable->selection_end_pos),
|
||||
MAX (old_editable->selection_start_pos, old_editable->selection_end_pos));
|
||||
}
|
||||
else
|
||||
gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
|
||||
}
|
||||
|
||||
tmp_pos = old_pos = old_editable->current_pos;
|
||||
|
||||
gtk_editable_insert_text (GTK_EDITABLE (old_editable), str, -1, &tmp_pos);
|
||||
|
||||
if (reselect)
|
||||
gtk_old_editable_set_selection (old_editable, old_pos, old_editable->current_pos);
|
||||
|
||||
if (str && str != text)
|
||||
g_free ((gchar *) str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_selection_received (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint time)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
|
||||
|
||||
gchar *text = gtk_selection_data_get_text (selection_data);
|
||||
|
||||
if (!text)
|
||||
{
|
||||
/* If we asked for UTF8 and didn't get it, try text; if we asked
|
||||
* for text and didn't get it, try string. If we asked for
|
||||
* anything else and didn't get it, give up.
|
||||
*/
|
||||
if (selection_data->target == gdk_atom_intern ("UTF8_STRING", FALSE))
|
||||
{
|
||||
gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
|
||||
gdk_atom_intern ("TEXT", FALSE),
|
||||
time);
|
||||
return;
|
||||
}
|
||||
else if (selection_data->target == gdk_atom_intern ("TEXT", FALSE))
|
||||
{
|
||||
gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
|
||||
GDK_TARGET_STRING,
|
||||
time);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (text)
|
||||
{
|
||||
gtk_old_editable_paste_received (old_editable, text, FALSE);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
old_editable_text_received_cb (GtkClipboard *clipboard,
|
||||
const gchar *text,
|
||||
gpointer data)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (data);
|
||||
|
||||
gtk_old_editable_paste_received (old_editable, text, TRUE);
|
||||
g_object_unref (G_OBJECT (old_editable));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_old_editable_claim_selection (GtkOldEditable *old_editable,
|
||||
gboolean claim,
|
||||
guint32 time)
|
||||
{
|
||||
g_return_if_fail (old_editable != NULL);
|
||||
g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
|
||||
g_return_if_fail (GTK_WIDGET_REALIZED (old_editable));
|
||||
|
||||
old_editable->has_selection = FALSE;
|
||||
|
||||
if (claim)
|
||||
{
|
||||
if (gtk_selection_owner_set (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY, time))
|
||||
old_editable->has_selection = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (old_editable)->window)
|
||||
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_set_selection_bounds (GtkEditable *editable,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
|
||||
|
||||
if (GTK_WIDGET_REALIZED (editable))
|
||||
gtk_old_editable_claim_selection (old_editable, start != end, GDK_CURRENT_TIME);
|
||||
|
||||
gtk_old_editable_set_selection (old_editable, start, end);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_old_editable_get_selection_bounds (GtkEditable *editable,
|
||||
gint *start,
|
||||
gint *end)
|
||||
{
|
||||
GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
|
||||
|
||||
*start = old_editable->selection_start_pos;
|
||||
*end = old_editable->selection_end_pos;
|
||||
|
||||
return (old_editable->selection_start_pos != old_editable->selection_end_pos);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
|
||||
gboolean is_editable)
|
||||
{
|
||||
is_editable = is_editable != FALSE;
|
||||
|
||||
if (old_editable->editable != is_editable)
|
||||
{
|
||||
old_editable->editable = is_editable;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (old_editable));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable)
|
||||
{
|
||||
gtk_old_editable_real_copy_clipboard (old_editable);
|
||||
gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable)
|
||||
{
|
||||
gint selection_start_pos;
|
||||
gint selection_end_pos;
|
||||
|
||||
selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
|
||||
selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
|
||||
|
||||
if (selection_start_pos != selection_end_pos)
|
||||
{
|
||||
gchar *text = gtk_old_editable_get_public_chars (old_editable,
|
||||
selection_start_pos,
|
||||
selection_end_pos);
|
||||
|
||||
if (text)
|
||||
{
|
||||
gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), text, -1);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable)
|
||||
{
|
||||
g_object_ref (G_OBJECT (old_editable));
|
||||
gtk_clipboard_request_text (gtk_clipboard_get (GDK_NONE),
|
||||
old_editable_text_received_cb, old_editable);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_old_editable_changed (GtkOldEditable *old_editable)
|
||||
{
|
||||
g_return_if_fail (old_editable != NULL);
|
||||
g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[CHANGED]);
|
||||
}
|
142
gtk/gtkoldeditable.h
Normal file
142
gtk/gtkoldeditable.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_OLD_EDITABLE_H__
|
||||
#define __GTK_OLD_EDITABLE_H__
|
||||
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkeditable.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#define GTK_TYPE_OLD_EDITABLE (gtk_old_editable_get_type ())
|
||||
#define GTK_OLD_EDITABLE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_OLD_EDITABLE, GtkOldEditable))
|
||||
#define GTK_OLD_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_OLD_EDITABLE, GtkOldEditableClass))
|
||||
#define GTK_IS_OLD_EDITABLE(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_OLD_EDITABLE))
|
||||
#define GTK_IS_OLD_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OLD_EDITABLE))
|
||||
#define GTK_OLD_EDITABLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_OLD_EDITABLE, GtkOldEditableClass))
|
||||
|
||||
|
||||
typedef struct _GtkOldEditable GtkOldEditable;
|
||||
typedef struct _GtkOldEditableClass GtkOldEditableClass;
|
||||
|
||||
typedef void (*GtkTextFunction) (GtkOldEditable *editable, guint32 time);
|
||||
|
||||
struct _GtkOldEditable
|
||||
{
|
||||
GtkWidget widget;
|
||||
|
||||
/*< public >*/
|
||||
guint current_pos;
|
||||
|
||||
guint selection_start_pos;
|
||||
guint selection_end_pos;
|
||||
guint has_selection : 1;
|
||||
|
||||
/*< private >*/
|
||||
guint editable : 1;
|
||||
guint visible : 1;
|
||||
GdkIC *ic;
|
||||
GdkICAttr *ic_attr;
|
||||
|
||||
gchar *clipboard_text;
|
||||
};
|
||||
|
||||
struct _GtkOldEditableClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/* Signals for notification/filtering of changes */
|
||||
void (* changed) (GtkOldEditable *editable);
|
||||
void (* insert_text) (GtkOldEditable *editable,
|
||||
const gchar *text,
|
||||
gint length,
|
||||
gint *position);
|
||||
void (* delete_text) (GtkOldEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
|
||||
/* Bindings actions */
|
||||
void (* activate) (GtkOldEditable *editable);
|
||||
void (* set_editable) (GtkOldEditable *editable,
|
||||
gboolean is_editable);
|
||||
void (* move_cursor) (GtkOldEditable *editable,
|
||||
gint x,
|
||||
gint y);
|
||||
void (* move_word) (GtkOldEditable *editable,
|
||||
gint n);
|
||||
void (* move_page) (GtkOldEditable *editable,
|
||||
gint x,
|
||||
gint y);
|
||||
void (* move_to_row) (GtkOldEditable *editable,
|
||||
gint row);
|
||||
void (* move_to_column) (GtkOldEditable *editable,
|
||||
gint row);
|
||||
void (* kill_char) (GtkOldEditable *editable,
|
||||
gint direction);
|
||||
void (* kill_word) (GtkOldEditable *editable,
|
||||
gint direction);
|
||||
void (* kill_line) (GtkOldEditable *editable,
|
||||
gint direction);
|
||||
void (* cut_clipboard) (GtkOldEditable *editable);
|
||||
void (* copy_clipboard) (GtkOldEditable *editable);
|
||||
void (* paste_clipboard) (GtkOldEditable *editable);
|
||||
|
||||
/* Virtual functions. get_chars is in paricular not a signal because
|
||||
* it returns malloced memory. The others are not signals because
|
||||
* they would not be particularly useful as such. (All changes to
|
||||
* selection and position do not go through these functions)
|
||||
*/
|
||||
void (* update_text) (GtkOldEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
gchar* (* get_chars) (GtkOldEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void (* set_selection)(GtkOldEditable *editable,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void (* set_position) (GtkOldEditable *editable,
|
||||
gint position);
|
||||
};
|
||||
|
||||
GtkType gtk_old_editable_get_type (void) G_GNUC_CONST;
|
||||
void gtk_old_editable_claim_selection (GtkOldEditable *old_editable,
|
||||
gboolean claim,
|
||||
guint32 time);
|
||||
void gtk_old_editable_changed (GtkOldEditable *old_editable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __GTK_OLD_EDITABLE_H__ */
|
@@ -184,7 +184,6 @@ gtk_preview_init (GtkPreview *preview)
|
||||
void
|
||||
gtk_preview_uninit (void)
|
||||
{
|
||||
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
|
127
gtk/gtkrc.c
127
gtk/gtkrc.c
@@ -26,9 +26,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <X11/Xlocale.h> /* so we get the right setlocale */
|
||||
#else
|
||||
@@ -56,6 +53,9 @@
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include "gtkrc.h"
|
||||
#include "gtkbindings.h"
|
||||
#include "gtkthemes.h"
|
||||
@@ -126,6 +126,8 @@ static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
|
||||
static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
|
||||
static guint gtk_rc_parse_module_path (GScanner *scanner);
|
||||
static void gtk_rc_parse_module_path_string (gchar *mod_path);
|
||||
static guint gtk_rc_parse_im_module_path (GScanner *scanner);
|
||||
static guint gtk_rc_parse_im_module_file (GScanner *scanner);
|
||||
static guint gtk_rc_parse_path_pattern (GScanner *scanner);
|
||||
static void gtk_rc_clear_hash_node (gpointer key,
|
||||
gpointer data,
|
||||
@@ -220,10 +222,15 @@ static const struct
|
||||
{ "highest", GTK_RC_TOKEN_HIGHEST },
|
||||
{ "engine", GTK_RC_TOKEN_ENGINE },
|
||||
{ "module_path", GTK_RC_TOKEN_MODULE_PATH },
|
||||
{ "im_module_path", GTK_RC_TOKEN_IM_MODULE_PATH },
|
||||
{ "im_module_file", GTK_RC_TOKEN_IM_MODULE_FILE },
|
||||
};
|
||||
|
||||
static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
|
||||
|
||||
static gchar *im_module_path = NULL;
|
||||
static gchar *im_module_file = NULL;
|
||||
|
||||
static GHashTable *rc_style_ht = NULL;
|
||||
static GHashTable *realized_style_ht = NULL;
|
||||
static GSList *gtk_rc_sets_widget = NULL;
|
||||
@@ -297,6 +304,56 @@ get_themes_directory (void)
|
||||
|
||||
#endif
|
||||
|
||||
static gchar *
|
||||
gtk_rc_make_default_dir (const gchar *type)
|
||||
{
|
||||
gchar *var, *path;
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
var = getenv("GTK_EXE_PREFIX");
|
||||
if (var)
|
||||
path = g_strdup_printf("%s%s%s", var, "/lib/gtk-2.0/" GTK_VERSION "/", type);
|
||||
else
|
||||
path = g_strdup_printf("%s%s%s", GTK_EXE_PREFIX, "/lib/gtk-2.0/" GTK_VERSION "/", type);
|
||||
#else
|
||||
path = g_strdup_printf ("%s\\%s", get_themes_directory (), type);
|
||||
#endif
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gtk_rc_get_im_module_path (void)
|
||||
{
|
||||
gchar *result = g_getenv ("GTK_IM_MODULE_PATH");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
if (im_module_path)
|
||||
result = im_module_path;
|
||||
else
|
||||
return gtk_rc_make_default_dir ("immodules");
|
||||
}
|
||||
|
||||
return g_strdup (result);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gtk_rc_get_im_module_file (void)
|
||||
{
|
||||
gchar *result = g_getenv ("GTK_IM_MODULE_FILE");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
if (im_module_file)
|
||||
result = im_module_file;
|
||||
else
|
||||
result = GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk-2.0" G_DIR_SEPARATOR_S "gtk.immodules";
|
||||
}
|
||||
|
||||
return g_strdup (result);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gtk_rc_get_theme_dir(void)
|
||||
{
|
||||
@@ -318,19 +375,7 @@ gtk_rc_get_theme_dir(void)
|
||||
gchar *
|
||||
gtk_rc_get_module_dir(void)
|
||||
{
|
||||
gchar *var, *path;
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
var = getenv("GTK_EXE_PREFIX");
|
||||
if (var)
|
||||
path = g_strdup_printf("%s%s", var, "/lib/gtk-2.0/" GTK_VERSION "/engines");
|
||||
else
|
||||
path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk-2.0/" GTK_VERSION "/engines");
|
||||
#else
|
||||
path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
|
||||
#endif
|
||||
|
||||
return path;
|
||||
return gtk_rc_make_default_dir ("engines");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -887,7 +932,7 @@ gtk_rc_style_copy (GtkRcStyle *orig)
|
||||
{
|
||||
GtkRcStyle *style;
|
||||
|
||||
g_return_if_fail (GTK_IS_RC_STYLE (orig));
|
||||
g_return_val_if_fail (GTK_IS_RC_STYLE (orig), NULL);
|
||||
|
||||
style = GTK_RC_STYLE_GET_CLASS (orig)->clone (orig);
|
||||
GTK_RC_STYLE_GET_CLASS (style)->merge (style, orig);
|
||||
@@ -1494,6 +1539,12 @@ gtk_rc_parse_statement (GScanner *scanner)
|
||||
case GTK_RC_TOKEN_MODULE_PATH:
|
||||
return gtk_rc_parse_module_path (scanner);
|
||||
|
||||
case GTK_RC_TOKEN_IM_MODULE_PATH:
|
||||
return gtk_rc_parse_im_module_path (scanner);
|
||||
|
||||
case GTK_RC_TOKEN_IM_MODULE_FILE:
|
||||
return gtk_rc_parse_im_module_file (scanner);
|
||||
|
||||
default:
|
||||
g_scanner_get_next_token (scanner);
|
||||
return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
|
||||
@@ -2363,6 +2414,48 @@ gtk_rc_parse_module_path (GScanner *scanner)
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_rc_parse_im_module_path (GScanner *scanner)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
|
||||
return GTK_RC_TOKEN_IM_MODULE_FILE;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
if (token != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (im_module_path)
|
||||
g_free (im_module_path);
|
||||
|
||||
im_module_path = g_strdup (scanner->value.v_string);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_rc_parse_im_module_file (GScanner *scanner)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
|
||||
return GTK_RC_TOKEN_IM_MODULE_FILE;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
if (token != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (im_module_file)
|
||||
g_free (im_module_file);
|
||||
|
||||
im_module_file = g_strdup (scanner->value.v_string);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_rc_parse_module_path_string (gchar *mod_path)
|
||||
{
|
||||
|
@@ -143,6 +143,8 @@ gchar* gtk_rc_find_pixmap_in_path (GScanner *scanner,
|
||||
gchar* gtk_rc_find_module_in_path (const gchar *module_file);
|
||||
gchar* gtk_rc_get_theme_dir (void);
|
||||
gchar* gtk_rc_get_module_dir (void);
|
||||
gchar* gtk_rc_get_im_module_path (void);
|
||||
gchar* gtk_rc_get_im_module_file (void);
|
||||
|
||||
/* private functions/definitions */
|
||||
typedef enum {
|
||||
@@ -177,6 +179,8 @@ typedef enum {
|
||||
GTK_RC_TOKEN_HIGHEST,
|
||||
GTK_RC_TOKEN_ENGINE,
|
||||
GTK_RC_TOKEN_MODULE_PATH,
|
||||
GTK_RC_TOKEN_IM_MODULE_PATH,
|
||||
GTK_RC_TOKEN_IM_MODULE_FILE,
|
||||
GTK_RC_TOKEN_LAST
|
||||
} GtkRcTokenType;
|
||||
|
||||
|
@@ -113,10 +113,10 @@ static gint gtk_spin_button_key_release (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gint gtk_spin_button_scroll (GtkWidget *widget,
|
||||
GdkEventScroll *event);
|
||||
static void gtk_spin_button_activate (GtkEditable *editable);
|
||||
static void gtk_spin_button_activate (GtkEntry *entry);
|
||||
static void gtk_spin_button_snap (GtkSpinButton *spin_button,
|
||||
gfloat val);
|
||||
static void gtk_spin_button_insert_text (GtkEditable *editable,
|
||||
static void gtk_spin_button_insert_text (GtkEntry *entry,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position);
|
||||
@@ -161,11 +161,11 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkEditableClass *editable_class;
|
||||
GtkEntryClass *entry_class;
|
||||
|
||||
object_class = (GtkObjectClass*) class;
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
editable_class = (GtkEditableClass*) class;
|
||||
entry_class = (GtkEntryClass*) class;
|
||||
|
||||
parent_class = gtk_type_class (GTK_TYPE_ENTRY);
|
||||
|
||||
@@ -192,8 +192,8 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
|
||||
widget_class->leave_notify_event = gtk_spin_button_leave_notify;
|
||||
widget_class->focus_out_event = gtk_spin_button_focus_out;
|
||||
|
||||
editable_class->insert_text = gtk_spin_button_insert_text;
|
||||
editable_class->activate = gtk_spin_button_activate;
|
||||
entry_class->insert_text = gtk_spin_button_insert_text;
|
||||
entry_class->activate = gtk_spin_button_activate;
|
||||
|
||||
class->input = NULL;
|
||||
class->output = NULL;
|
||||
@@ -756,7 +756,7 @@ gtk_spin_button_focus_out (GtkWidget *widget,
|
||||
g_return_val_if_fail (GTK_IS_SPIN_BUTTON (widget), FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
if (GTK_EDITABLE (widget)->editable)
|
||||
if (GTK_ENTRY (widget)->editable)
|
||||
gtk_spin_button_update (GTK_SPIN_BUTTON (widget));
|
||||
|
||||
return GTK_WIDGET_CLASS (parent_class)->focus_out_event (widget, event);
|
||||
@@ -813,7 +813,7 @@ gtk_spin_button_button_press (GtkWidget *widget,
|
||||
gtk_grab_add (widget);
|
||||
spin->button = event->button;
|
||||
|
||||
if (GTK_EDITABLE (widget)->editable)
|
||||
if (GTK_ENTRY (widget)->editable)
|
||||
gtk_spin_button_update (spin);
|
||||
|
||||
if (event->y <= widget->requisition.height / 2)
|
||||
@@ -1066,7 +1066,7 @@ gtk_spin_button_key_press (GtkWidget *widget,
|
||||
|
||||
key_repeat = (event->time == spin->ev_time);
|
||||
|
||||
if (GTK_EDITABLE (widget)->editable &&
|
||||
if (GTK_ENTRY (widget)->editable &&
|
||||
(key == GDK_Up || key == GDK_Down ||
|
||||
key == GDK_Page_Up || key == GDK_Page_Down))
|
||||
gtk_spin_button_update (spin);
|
||||
@@ -1204,30 +1204,21 @@ gtk_spin_button_snap (GtkSpinButton *spin_button,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_activate (GtkEditable *editable)
|
||||
gtk_spin_button_activate (GtkEntry *entry)
|
||||
{
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
|
||||
|
||||
if (editable->editable)
|
||||
gtk_spin_button_update (GTK_SPIN_BUTTON (editable));
|
||||
if (entry->editable)
|
||||
gtk_spin_button_update (GTK_SPIN_BUTTON (entry));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_insert_text (GtkEditable *editable,
|
||||
gtk_spin_button_insert_text (GtkEntry *entry,
|
||||
const gchar *new_text,
|
||||
gint new_text_length,
|
||||
gint *position)
|
||||
{
|
||||
GtkEntry *entry;
|
||||
GtkSpinButton *spin;
|
||||
GtkEditable *editable = GTK_EDITABLE (entry);
|
||||
GtkSpinButton *spin = GTK_SPIN_BUTTON (editable);
|
||||
|
||||
g_return_if_fail (editable != NULL);
|
||||
g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
|
||||
|
||||
entry = GTK_ENTRY (editable);
|
||||
spin = GTK_SPIN_BUTTON (editable);
|
||||
|
||||
if (spin->numeric)
|
||||
{
|
||||
struct lconv *lc;
|
||||
@@ -1296,8 +1287,8 @@ gtk_spin_button_insert_text (GtkEditable *editable,
|
||||
}
|
||||
}
|
||||
|
||||
GTK_EDITABLE_CLASS (parent_class)->insert_text (editable, new_text,
|
||||
new_text_length, position);
|
||||
GTK_ENTRY_CLASS (parent_class)->insert_text (entry, new_text,
|
||||
new_text_length, position);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1565,7 +1556,7 @@ gtk_spin_button_set_snap_to_ticks (GtkSpinButton *spin_button,
|
||||
if (new_val != spin_button->snap_to_ticks)
|
||||
{
|
||||
spin_button->snap_to_ticks = new_val;
|
||||
if (new_val && GTK_EDITABLE (spin_button)->editable)
|
||||
if (new_val && GTK_ENTRY (spin_button)->editable)
|
||||
gtk_spin_button_update (spin_button);
|
||||
}
|
||||
}
|
||||
|
542
gtk/gtktext.c
542
gtk/gtktext.c
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkadjustment.h>
|
||||
#include <gtk/gtkeditable.h>
|
||||
#include <gtk/gtkoldeditable.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -64,7 +64,7 @@ struct _GtkPropertyMark
|
||||
|
||||
struct _GtkText
|
||||
{
|
||||
GtkEditable editable;
|
||||
GtkOldEditable old_editable;
|
||||
|
||||
GdkWindow *text_area;
|
||||
|
||||
@@ -169,7 +169,7 @@ struct _GtkText
|
||||
|
||||
struct _GtkTextClass
|
||||
{
|
||||
GtkEditableClass parent_class;
|
||||
GtkOldEditableClass parent_class;
|
||||
|
||||
void (*set_scroll_adjustments) (GtkText *text,
|
||||
GtkAdjustment *hadjustment,
|
||||
|
@@ -65,11 +65,6 @@ static GtkTextLineData *gtk_text_layout_real_wrap (GtkTextLayout *layout,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data);
|
||||
|
||||
static void gtk_text_layout_real_get_log_attrs (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
PangoLogAttr **attrs,
|
||||
gint *n_attrs);
|
||||
|
||||
static void gtk_text_layout_invalidated (GtkTextLayout *layout);
|
||||
|
||||
static void gtk_text_layout_real_invalidate (GtkTextLayout *layout,
|
||||
@@ -171,7 +166,6 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
|
||||
gobject_class->finalize = gtk_text_layout_finalize;
|
||||
|
||||
klass->wrap = gtk_text_layout_real_wrap;
|
||||
klass->get_log_attrs = gtk_text_layout_real_get_log_attrs;
|
||||
klass->invalidate = gtk_text_layout_real_invalidate;
|
||||
klass->free_line_data = gtk_text_layout_real_free_line_data;
|
||||
}
|
||||
@@ -221,6 +215,18 @@ gtk_text_layout_destroy (GtkObject *object)
|
||||
g_object_unref (G_OBJECT (layout->rtl_context));
|
||||
layout->rtl_context = NULL;
|
||||
}
|
||||
|
||||
if (layout->preedit_string)
|
||||
{
|
||||
g_free (layout->preedit_string);
|
||||
layout->preedit_string = NULL;
|
||||
}
|
||||
|
||||
if (layout->preedit_attrs)
|
||||
{
|
||||
pango_attr_list_unref (layout->preedit_attrs);
|
||||
layout->preedit_attrs = NULL;
|
||||
}
|
||||
|
||||
(* parent_class->destroy) (object);
|
||||
}
|
||||
@@ -332,6 +338,69 @@ gtk_text_layout_set_screen_width (GtkTextLayout *layout, gint width)
|
||||
gtk_text_layout_invalidate_all (layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_layout_set_preedit_string:
|
||||
* @layout: a #PangoLayout
|
||||
* @preedit_string: a string to display at the insertion point
|
||||
* @preedit_attrs: a #PangoAttrList of attributes that apply to @preedit_string
|
||||
* @cursor_pos: position of cursor within preedit string in chars
|
||||
*
|
||||
* Set the preedit string and attributes. The preedit string is a
|
||||
* string showing text that is currently being edited and not
|
||||
* yet committed into the buffer.
|
||||
**/
|
||||
void
|
||||
gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
|
||||
const gchar *preedit_string,
|
||||
PangoAttrList *preedit_attrs,
|
||||
gint cursor_pos)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextLine *line;
|
||||
GtkTextLineData *line_data;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (preedit_attrs != NULL || preedit_string == NULL);
|
||||
|
||||
if (layout->preedit_string)
|
||||
g_free (layout->preedit_string);
|
||||
|
||||
if (layout->preedit_attrs)
|
||||
pango_attr_list_unref (layout->preedit_attrs);
|
||||
|
||||
if (preedit_string)
|
||||
{
|
||||
layout->preedit_string = g_strdup (preedit_string);
|
||||
layout->preedit_len = strlen (layout->preedit_string);
|
||||
pango_attr_list_ref (preedit_attrs);
|
||||
layout->preedit_attrs = preedit_attrs;
|
||||
|
||||
cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (layout->preedit_string, -1));
|
||||
layout->preedit_cursor = g_utf8_offset_to_pointer (layout->preedit_string, cursor_pos) - layout->preedit_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
layout->preedit_string = NULL;
|
||||
layout->preedit_len = 0;
|
||||
layout->preedit_attrs = NULL;
|
||||
layout->preedit_cursor = 0;
|
||||
}
|
||||
|
||||
/* Now invalidate the paragraph containing the cursor
|
||||
*/
|
||||
gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter,
|
||||
gtk_text_buffer_get_mark (layout->buffer, "insert"));
|
||||
|
||||
line = gtk_text_iter_get_text_line (&iter);
|
||||
line_data = gtk_text_line_get_data (line, layout);
|
||||
if (line_data)
|
||||
{
|
||||
gtk_text_layout_invalidate_cache (layout, line);
|
||||
gtk_text_line_invalidate_wrap (line, line_data);
|
||||
gtk_text_layout_invalidated (layout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_layout_set_cursor_visible:
|
||||
* @layout: a #GtkTextLayout
|
||||
@@ -447,16 +516,6 @@ gtk_text_layout_wrap (GtkTextLayout *layout,
|
||||
return (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap) (layout, line, line_data);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_get_log_attrs (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
PangoLogAttr **attrs,
|
||||
gint *n_attrs)
|
||||
{
|
||||
(* GTK_TEXT_LAYOUT_GET_CLASS (layout)->get_log_attrs)
|
||||
(layout, line, attrs, n_attrs);
|
||||
}
|
||||
|
||||
GSList*
|
||||
gtk_text_layout_get_lines (GtkTextLayout *layout,
|
||||
/* [top_y, bottom_y) */
|
||||
@@ -820,21 +879,6 @@ gtk_text_layout_real_wrap (GtkTextLayout *layout,
|
||||
return line_data;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_layout_real_get_log_attrs (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
PangoLogAttr **attrs,
|
||||
gint *n_attrs)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, TRUE);
|
||||
pango_layout_get_log_attrs (display->layout, attrs, n_attrs);
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
}
|
||||
|
||||
/*
|
||||
* Layout utility functions
|
||||
*/
|
||||
@@ -1141,7 +1185,7 @@ gtk_text_attr_appearance_new (const GtkTextAppearance *appearance)
|
||||
|
||||
static void
|
||||
add_text_attrs (GtkTextLayout *layout,
|
||||
GtkTextAttributes *style,
|
||||
GtkTextAttributes *style,
|
||||
gint byte_count,
|
||||
PangoAttrList *attrs,
|
||||
gint start,
|
||||
@@ -1239,6 +1283,96 @@ add_cursor (GtkTextLayout *layout,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_color (GdkColor *result,
|
||||
PangoAttrColor *attr)
|
||||
{
|
||||
result->red = attr->red;
|
||||
result->blue = attr->blue;
|
||||
result->green = attr->green;
|
||||
}
|
||||
|
||||
/* This function is used to convert the preedit string attributes, which are
|
||||
* standard PangoAttributes, into the custom attributes used by the text
|
||||
* widget and insert them into a attr list with a given offset.
|
||||
*/
|
||||
static void
|
||||
add_preedit_attrs (GtkTextLayout *layout,
|
||||
GtkTextAttributes *style,
|
||||
PangoAttrList *attrs,
|
||||
gint offset,
|
||||
gboolean size_only)
|
||||
{
|
||||
PangoAttrIterator *iter = pango_attr_list_get_iterator (layout->preedit_attrs);
|
||||
|
||||
do
|
||||
{
|
||||
GtkTextAppearance appearance = style->appearance;
|
||||
PangoFontDescription font_desc;
|
||||
PangoAttribute *insert_attr;
|
||||
GSList *extra_attrs = NULL;
|
||||
GSList *tmp_list;
|
||||
gint start, end;
|
||||
|
||||
pango_attr_iterator_range (iter, &start, &end);
|
||||
|
||||
if (end == G_MAXINT)
|
||||
end = layout->preedit_len;
|
||||
|
||||
pango_attr_iterator_get_font (iter, style->font_desc,
|
||||
&font_desc, size_only ? NULL : &extra_attrs);
|
||||
|
||||
tmp_list = extra_attrs;
|
||||
while (tmp_list)
|
||||
{
|
||||
PangoAttribute *attr = tmp_list->data;
|
||||
|
||||
switch (attr->klass->type)
|
||||
{
|
||||
case PANGO_ATTR_FOREGROUND:
|
||||
convert_color (&appearance.fg_color, (PangoAttrColor *)attr);
|
||||
break;
|
||||
case PANGO_ATTR_BACKGROUND:
|
||||
convert_color (&appearance.bg_color, (PangoAttrColor *)attr);
|
||||
appearance.draw_bg = TRUE;
|
||||
break;
|
||||
case PANGO_ATTR_UNDERLINE:
|
||||
appearance.underline = ((PangoAttrInt *)attr)->value;
|
||||
break;
|
||||
case PANGO_ATTR_STRIKETHROUGH:
|
||||
appearance.strikethrough = ((PangoAttrInt *)attr)->value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pango_attribute_destroy (attr);
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_slist_free (extra_attrs);
|
||||
|
||||
insert_attr = pango_attr_font_desc_new (&font_desc);
|
||||
insert_attr->start_index = start + offset;
|
||||
insert_attr->end_index = end + offset;
|
||||
|
||||
pango_attr_list_insert (attrs, insert_attr);
|
||||
|
||||
if (!size_only)
|
||||
{
|
||||
insert_attr = gtk_text_attr_appearance_new (&appearance);
|
||||
|
||||
insert_attr->start_index = start + offset;
|
||||
insert_attr->end_index = end + offset;
|
||||
|
||||
pango_attr_list_insert (attrs, insert_attr);
|
||||
}
|
||||
}
|
||||
while (pango_attr_iterator_next (iter));
|
||||
|
||||
pango_attr_iterator_destroy (iter);
|
||||
}
|
||||
|
||||
GtkTextLineDisplay *
|
||||
gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
@@ -1277,6 +1411,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
|
||||
display->size_only = size_only;
|
||||
display->line = line;
|
||||
display->insert_index = -1;
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
&iter, line, 0);
|
||||
@@ -1336,8 +1471,9 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
*/
|
||||
|
||||
gint byte_count = 0;
|
||||
GtkTextLineSegment *prev_seg = NULL;
|
||||
|
||||
while (TRUE)
|
||||
while (seg)
|
||||
{
|
||||
if (seg->type == >k_text_char_type)
|
||||
{
|
||||
@@ -1345,21 +1481,31 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
byte_offset += seg->byte_count;
|
||||
byte_count += seg->byte_count;
|
||||
}
|
||||
else if (seg->body.mark.visible)
|
||||
else if (seg->type == >k_text_right_mark_type ||
|
||||
seg->type == >k_text_left_mark_type)
|
||||
{
|
||||
cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset));
|
||||
cursor_segs = g_slist_prepend (cursor_segs, seg);
|
||||
}
|
||||
/* If we have preedit string, break out of this loop - we'll almost
|
||||
* certainly have different attributes on the preedit string
|
||||
*/
|
||||
if (layout->preedit_len > 0 &&
|
||||
gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
(GtkTextMark*)seg))
|
||||
break;
|
||||
|
||||
if (!seg->next ||
|
||||
(seg->next->type != >k_text_right_mark_type &&
|
||||
seg->next->type != >k_text_left_mark_type &&
|
||||
seg->next->type != >k_text_char_type))
|
||||
if (seg->body.mark.visible)
|
||||
{
|
||||
cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset));
|
||||
cursor_segs = g_slist_prepend (cursor_segs, seg);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
prev_seg = seg;
|
||||
seg = seg->next;
|
||||
}
|
||||
|
||||
|
||||
seg = prev_seg; /* Back up one */
|
||||
add_text_attrs (layout, style, byte_count, attrs, byte_offset - byte_count, size_only);
|
||||
}
|
||||
else
|
||||
@@ -1386,11 +1532,36 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||
else if (seg->type == >k_text_right_mark_type ||
|
||||
seg->type == >k_text_left_mark_type)
|
||||
{
|
||||
gint cursor_offset = 0;
|
||||
|
||||
/* At the insertion point, add the preedit string, if any */
|
||||
|
||||
if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
(GtkTextMark*)seg))
|
||||
{
|
||||
display->insert_index = byte_offset;
|
||||
|
||||
if (layout->preedit_len > 0)
|
||||
{
|
||||
byte_count += layout->preedit_len;
|
||||
text = g_realloc (text, byte_count);
|
||||
|
||||
style = get_style (layout, &iter);
|
||||
add_preedit_attrs (layout, style, attrs, byte_offset, size_only);
|
||||
release_style (layout, style);
|
||||
|
||||
memcpy (text + byte_offset, layout->preedit_string, layout->preedit_len);
|
||||
byte_offset += layout->preedit_len;
|
||||
|
||||
cursor_offset = layout->preedit_cursor - layout->preedit_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display visible marks */
|
||||
|
||||
if (seg->body.mark.visible)
|
||||
{
|
||||
cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset));
|
||||
cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset + cursor_offset));
|
||||
cursor_segs = g_slist_prepend (cursor_segs, seg);
|
||||
}
|
||||
}
|
||||
@@ -1465,6 +1636,46 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
|
||||
}
|
||||
}
|
||||
|
||||
/* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
|
||||
* taking into account the preedit string, if necessary.
|
||||
*/
|
||||
gint
|
||||
line_display_iter_to_index (GtkTextLayout *layout,
|
||||
GtkTextLineDisplay *display,
|
||||
const GtkTextIter *iter)
|
||||
{
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (gtk_text_iter_get_text_line (iter) == display->line, 0);
|
||||
|
||||
index = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
if (index >= display->insert_index)
|
||||
index += layout->preedit_len;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
line_display_index_to_iter (GtkTextLayout *layout,
|
||||
GtkTextLineDisplay *display,
|
||||
GtkTextIter *iter,
|
||||
gint index,
|
||||
gint trailing)
|
||||
{
|
||||
if (index >= display->insert_index + layout->preedit_len)
|
||||
index -= layout->preedit_len;
|
||||
else if (index > display->insert_index)
|
||||
{
|
||||
index = display->insert_index;
|
||||
trailing = 0;
|
||||
}
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, display->line, index);
|
||||
gtk_text_iter_forward_chars (iter, trailing);
|
||||
}
|
||||
|
||||
/* FIXME: This really doesn't belong in this file ... */
|
||||
static GtkTextLineData*
|
||||
gtk_text_line_data_new (GtkTextLayout *layout,
|
||||
@@ -1574,12 +1785,7 @@ gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
|
||||
trailing = 0;
|
||||
}
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
target_iter,
|
||||
line, byte_index);
|
||||
|
||||
while (trailing--)
|
||||
gtk_text_iter_next_char (target_iter);
|
||||
line_display_index_to_iter (layout, display, target_iter, byte_index, trailing);
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
}
|
||||
@@ -1609,6 +1815,7 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
|
||||
GtkTextLine *line;
|
||||
GtkTextLineDisplay *display;
|
||||
gint line_top;
|
||||
gint index;
|
||||
|
||||
PangoRectangle pango_strong_pos;
|
||||
PangoRectangle pango_weak_pos;
|
||||
@@ -1617,12 +1824,13 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
index = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
line, layout);
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
|
||||
pango_layout_get_cursor_pos (display->layout, gtk_text_iter_get_line_index (iter),
|
||||
pango_layout_get_cursor_pos (display->layout, index,
|
||||
strong_pos ? &pango_strong_pos : NULL,
|
||||
weak_pos ? &pango_weak_pos : NULL);
|
||||
|
||||
@@ -1722,7 +1930,7 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
|
||||
}
|
||||
else
|
||||
{
|
||||
byte_index = gtk_text_iter_get_line_index (iter);
|
||||
byte_index = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
|
||||
|
||||
@@ -1735,6 +1943,8 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
}
|
||||
|
||||
/* FFIXX */
|
||||
|
||||
/* Find the iter for the logical beginning of the first display line whose
|
||||
* top y is >= y. If none exists, move the iter to the logical beginning
|
||||
* of the last line in the buffer.
|
||||
@@ -1941,9 +2151,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
line_byte = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
layout_line = tmp_list->data;
|
||||
@@ -1959,7 +2168,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, prev_line, FALSE);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
|
||||
while (tmp_list->next)
|
||||
{
|
||||
@@ -1969,12 +2178,10 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
byte_offset += layout_line->length;
|
||||
}
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, prev_line, byte_offset);
|
||||
line_display_index_to_iter (layout, display, iter, byte_offset, 0);
|
||||
}
|
||||
else
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, line, 0);
|
||||
line_display_index_to_iter (layout, display, iter, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1988,8 +2195,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
|
||||
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
{
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, line, prev_offset);
|
||||
line_display_index_to_iter (layout, display, iter, prev_offset, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2027,7 +2233,6 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
line_byte = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
while (line && !found_after)
|
||||
{
|
||||
@@ -2035,6 +2240,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
GSList *tmp_list;
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
while (tmp_list && !found_after)
|
||||
@@ -2043,9 +2249,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
|
||||
if (found)
|
||||
{
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, line,
|
||||
byte_offset);
|
||||
line_display_index_to_iter (layout, display, iter, byte_offset, 0);
|
||||
found_after = TRUE;
|
||||
}
|
||||
else if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
@@ -2085,9 +2289,8 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
line_byte = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
while (tmp_list)
|
||||
@@ -2096,9 +2299,9 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
|
||||
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
{
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, line,
|
||||
direction < 0 ? byte_offset : layout_line->length);
|
||||
line_display_index_to_iter (layout, display, iter,
|
||||
direction < 0 ? byte_offset : layout_line->length,
|
||||
0);
|
||||
|
||||
/* FIXME: Move back one position to avoid going to next line
|
||||
*/
|
||||
@@ -2141,9 +2344,9 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
line_byte = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
while (tmp_list)
|
||||
@@ -2179,12 +2382,7 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
x * PANGO_SCALE - x_offset,
|
||||
&byte_index, &trailing);
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter,
|
||||
line, byte_index);
|
||||
|
||||
while (trailing--)
|
||||
gtk_text_iter_next_char (iter);
|
||||
line_display_index_to_iter (layout, display, iter, byte_index, trailing);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2220,20 +2418,26 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint count)
|
||||
{
|
||||
GtkTextLineDisplay *display = NULL;
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
while (count != 0)
|
||||
{
|
||||
GtkTextLine *line = gtk_text_iter_get_text_line (iter);
|
||||
gint line_byte = gtk_text_iter_get_line_index (iter);
|
||||
GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
gint line_byte;
|
||||
gint extra_back = 0;
|
||||
|
||||
int byte_count = gtk_text_line_byte_count (line);
|
||||
|
||||
int new_index;
|
||||
int new_trailing;
|
||||
|
||||
|
||||
if (!display)
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
pango_layout_move_cursor_visually (display->layout, line_byte, 0, 1, &new_index, &new_trailing);
|
||||
@@ -2245,14 +2449,31 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
count++;
|
||||
}
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
||||
if (new_index < 0)
|
||||
/* We need to handle the preedit string specially. Well, we don't really need to
|
||||
* handle it specially, since hopefully calling gtk_im_context_reset() will
|
||||
* remove the preedit string; but if we start off in front of the preedit
|
||||
* string (logically) and end up in or on the back edge of the preedit string,
|
||||
* we should move the iter one place farther.
|
||||
*/
|
||||
if (layout->preedit_len > 0 && display->insert_index >= 0)
|
||||
{
|
||||
if (line_byte == display->insert_index + layout->preedit_len &&
|
||||
new_index < display->insert_index + layout->preedit_len)
|
||||
{
|
||||
line_byte = display->insert_index;
|
||||
extra_back = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_index < 0 || (new_index == 0 && extra_back))
|
||||
{
|
||||
line = gtk_text_line_previous (line);
|
||||
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
new_index = gtk_text_line_byte_count (line);
|
||||
|
||||
}
|
||||
@@ -2262,16 +2483,17 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
new_index = 0;
|
||||
}
|
||||
|
||||
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter,
|
||||
line, new_index);
|
||||
while (new_trailing--)
|
||||
gtk_text_iter_next_char (iter);
|
||||
line_display_index_to_iter (layout, display, iter, new_index, new_trailing);
|
||||
if (extra_back)
|
||||
gtk_text_iter_prev_char (iter);
|
||||
}
|
||||
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
}
|
||||
|
||||
typedef void (*GtkSignal_NONE__INT_INT_INT_INT) (GtkObject *object,
|
||||
@@ -2331,5 +2553,3 @@ gtk_text_layout_spew (GtkTextLayout *layout)
|
||||
layout->height, layout->screen_width);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@@ -70,6 +70,13 @@ struct _GtkTextLayout
|
||||
|
||||
/* Whether to show the insertion cursor */
|
||||
guint cursor_visible : 1;
|
||||
|
||||
/* The preedit string and attributes, if any */
|
||||
|
||||
gchar *preedit_string;
|
||||
PangoAttrList *preedit_attrs;
|
||||
gint preedit_len;
|
||||
gint preedit_cursor;
|
||||
};
|
||||
|
||||
struct _GtkTextLayoutClass
|
||||
@@ -136,6 +143,7 @@ struct _GtkTextLineDisplay
|
||||
gint right_margin;
|
||||
gint top_margin;
|
||||
gint bottom_margin;
|
||||
gint insert_index; /* Byte index of insert cursor within para or -1 */
|
||||
|
||||
gboolean size_only;
|
||||
GtkTextLine *line;
|
||||
@@ -156,6 +164,10 @@ void gtk_text_layout_set_contexts (GtkTextLayout *layout,
|
||||
void gtk_text_layout_default_style_changed (GtkTextLayout *layout);
|
||||
void gtk_text_layout_set_screen_width (GtkTextLayout *layout,
|
||||
gint width);
|
||||
void gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
|
||||
const gchar *preedit_string,
|
||||
PangoAttrList *preedit_attrs,
|
||||
gint cursor_pos);
|
||||
|
||||
void gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
|
||||
gboolean cursor_visible);
|
||||
@@ -221,10 +233,6 @@ GtkTextLineData *gtk_text_layout_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data);
|
||||
void gtk_text_layout_get_log_attrs (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
PangoLogAttr **attrs,
|
||||
gint *n_attrs);
|
||||
void gtk_text_layout_changed (GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
|
@@ -25,14 +25,14 @@ gtk_text_mark_is_visible(GtkTextMark *mark)
|
||||
return seg->body.mark.visible;
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
gtk_text_mark_get_name (GtkTextMark *mark)
|
||||
{
|
||||
GtkTextLineSegment *seg;
|
||||
|
||||
seg = (GtkTextLineSegment*)mark;
|
||||
|
||||
return g_strdup (seg->body.mark.name);
|
||||
return seg->body.mark.name;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -13,8 +13,7 @@ void gtk_text_mark_set_visible (GtkTextMark *mark,
|
||||
gboolean setting);
|
||||
|
||||
gboolean gtk_text_mark_is_visible (GtkTextMark *mark);
|
||||
/* Temporarily commented out until memory management behavior is figured out */
|
||||
/* char * gtk_text_mark_get_name (GtkTextMark *mark); */
|
||||
const char *gtk_text_mark_get_name (GtkTextMark *mark);
|
||||
|
||||
GtkTextMark *gtk_text_mark_ref (GtkTextMark *mark);
|
||||
void gtk_text_mark_unref (GtkTextMark *mark);
|
||||
|
@@ -52,7 +52,10 @@
|
||||
|
||||
#include "gtkbindings.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmenu.h"
|
||||
#include "gtkmenuitem.h"
|
||||
#include "gtksignal.h"
|
||||
#include "gtktext.h"
|
||||
#include "gtktextdisplay.h"
|
||||
@@ -194,6 +197,7 @@ static void gtk_text_view_set_values_from_style (GtkTextView *text_vi
|
||||
GtkStyle *style);
|
||||
static void gtk_text_view_ensure_layout (GtkTextView *text_view);
|
||||
static void gtk_text_view_destroy_layout (GtkTextView *text_view);
|
||||
static void gtk_text_view_reset_im_context (GtkTextView *text_view);
|
||||
static void gtk_text_view_start_selection_drag (GtkTextView *text_view,
|
||||
const GtkTextIter *iter,
|
||||
GdkEventButton *event);
|
||||
@@ -205,15 +209,17 @@ static void gtk_text_view_start_selection_dnd (GtkTextView *text_vi
|
||||
static void gtk_text_view_start_cursor_blink (GtkTextView *text_view);
|
||||
static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_value_changed (GtkAdjustment *adj,
|
||||
GtkTextView *view);
|
||||
static void gtk_text_view_commit_handler (GtkIMContext *context,
|
||||
const gchar *str,
|
||||
GtkTextView *text_view);
|
||||
static void gtk_text_view_value_changed (GtkAdjustment *adj,
|
||||
GtkTextView *view);
|
||||
static void gtk_text_view_commit_handler (GtkIMContext *context,
|
||||
const gchar *str,
|
||||
GtkTextView *text_view);
|
||||
static void gtk_text_view_preedit_changed_handler (GtkIMContext *context,
|
||||
GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *location,
|
||||
const char *mark_name,
|
||||
GtkTextMark *mark,
|
||||
gpointer data);
|
||||
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
|
||||
gint *x,
|
||||
@@ -225,6 +231,9 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
|
||||
static GtkAdjustment* get_hadjustment (GtkTextView *text_view);
|
||||
static GtkAdjustment* get_vadjustment (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_popup_menu (GtkTextView *text_view,
|
||||
GdkEventButton *event);
|
||||
|
||||
enum {
|
||||
TARGET_STRING,
|
||||
TARGET_TEXT,
|
||||
@@ -619,6 +628,8 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (text_view->im_context), "commit",
|
||||
GTK_SIGNAL_FUNC (gtk_text_view_commit_handler), text_view);
|
||||
gtk_signal_connect (GTK_OBJECT (text_view->im_context), "preedit_changed",
|
||||
GTK_SIGNAL_FUNC (gtk_text_view_preedit_changed_handler), text_view);
|
||||
|
||||
text_view->editable = TRUE;
|
||||
text_view->cursor_visible = TRUE;
|
||||
@@ -1411,7 +1422,10 @@ gtk_text_view_unrealize (GtkWidget *widget)
|
||||
g_source_remove (text_view->incremental_validate_idle);
|
||||
text_view->incremental_validate_idle = 0;
|
||||
}
|
||||
|
||||
|
||||
if (text_view->popup_menu)
|
||||
gtk_widget_destroy (text_view->popup_menu);
|
||||
|
||||
gtk_text_view_destroy_layout (text_view);
|
||||
|
||||
gtk_im_context_set_client_window (text_view->im_context, NULL);
|
||||
@@ -1570,7 +1584,6 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event)
|
||||
|
||||
insert = gtk_text_buffer_get_mark (text_view->buffer,
|
||||
"insert");
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter, insert);
|
||||
|
||||
return emit_event_on_tags (widget, event, &iter);
|
||||
@@ -1590,11 +1603,13 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
|
||||
text_view->buffer == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
|
||||
GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
|
||||
return TRUE;
|
||||
|
||||
if (gtk_im_context_filter_keypress (text_view->im_context, event))
|
||||
{
|
||||
text_view->need_im_reset = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
|
||||
GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
|
||||
return TRUE;
|
||||
else if (event->keyval == GDK_Return)
|
||||
{
|
||||
@@ -1625,14 +1640,18 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
|
||||
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
#if 0
|
||||
/* debug hack */
|
||||
if (event->button == 3 && (event->state & GDK_CONTROL_MASK) != 0)
|
||||
gtk_text_buffer_spew (GTK_TEXT_VIEW (widget)->buffer);
|
||||
else if (event->button == 3)
|
||||
gtk_text_layout_spew (GTK_TEXT_VIEW (widget)->layout);
|
||||
#endif
|
||||
|
||||
if (event->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
gtk_text_view_reset_im_context (text_view);
|
||||
|
||||
if (event->button == 1)
|
||||
{
|
||||
/* If we're in the selection, start a drag copy/move of the
|
||||
@@ -1674,10 +1693,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
|
||||
}
|
||||
else if (event->button == 3)
|
||||
{
|
||||
if (gtk_text_view_end_selection_drag (text_view, event))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
gtk_text_view_popup_menu (text_view, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1709,6 +1725,7 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
|
||||
gtk_text_view_start_cursor_blink (text_view);
|
||||
}
|
||||
|
||||
text_view->need_im_reset = TRUE;
|
||||
gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context);
|
||||
|
||||
return FALSE;
|
||||
@@ -1727,6 +1744,7 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
|
||||
gtk_text_view_stop_cursor_blink (text_view);
|
||||
}
|
||||
|
||||
text_view->need_im_reset = TRUE;
|
||||
gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context);
|
||||
|
||||
return FALSE;
|
||||
@@ -1851,12 +1869,14 @@ gtk_text_view_move (GtkTextView *text_view,
|
||||
|
||||
gint cursor_x_pos = 0;
|
||||
|
||||
gtk_text_view_reset_im_context (text_view);
|
||||
|
||||
if (step == GTK_MOVEMENT_PAGES)
|
||||
{
|
||||
gtk_text_view_scroll_pages (text_view, count);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
|
||||
gtk_text_buffer_get_mark (text_view->buffer,
|
||||
"insert"));
|
||||
@@ -2056,6 +2076,8 @@ gtk_text_view_delete (GtkTextView *text_view,
|
||||
GtkTextIter end;
|
||||
gboolean leave_one = FALSE;
|
||||
|
||||
gtk_text_view_reset_im_context (text_view);
|
||||
|
||||
if (type == GTK_DELETE_CHARS)
|
||||
{
|
||||
/* Char delete deletes the selection, if one exists */
|
||||
@@ -2540,6 +2562,14 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_reset_im_context (GtkTextView *text_view)
|
||||
{
|
||||
if (text_view->need_im_reset)
|
||||
text_view->need_im_reset = 0;
|
||||
|
||||
gtk_im_context_reset (text_view->im_context);
|
||||
}
|
||||
|
||||
/*
|
||||
* DND feature
|
||||
@@ -2910,19 +2940,46 @@ gtk_text_view_commit_handler (GtkIMContext *context,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_preedit_changed_handler (GtkIMContext *context,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
gchar *str;
|
||||
PangoAttrList *attrs;
|
||||
gint cursor_pos;
|
||||
|
||||
gtk_im_context_get_preedit_string (context, &str, &attrs, &cursor_pos);
|
||||
gtk_text_layout_set_preedit_string (text_view->layout, str, attrs, cursor_pos);
|
||||
|
||||
pango_attr_list_unref (attrs);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *location,
|
||||
const char *mark_name,
|
||||
GtkTextMark *mark,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (data);
|
||||
|
||||
if (!strcmp (mark_name, "insert"))
|
||||
gboolean need_reset = FALSE;
|
||||
|
||||
const gchar *mark_name = gtk_text_mark_get_name (mark);
|
||||
|
||||
if (mark_name && strcmp (mark_name, "insert") == 0)
|
||||
{
|
||||
text_view->virtual_cursor_x = -1;
|
||||
text_view->virtual_cursor_y = -1;
|
||||
need_reset = TRUE;
|
||||
}
|
||||
|
||||
if (mark_name && strcmp (mark_name, "selection_bound") == 0)
|
||||
{
|
||||
need_reset = TRUE;
|
||||
}
|
||||
|
||||
if (need_reset)
|
||||
gtk_text_view_reset_im_context (text_view);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2976,3 +3033,67 @@ gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
|
||||
text_view->virtual_cursor_x = (x == -1) ? strong_pos.x : x;
|
||||
text_view->virtual_cursor_y = (y == -1) ? strong_pos.y + strong_pos.height / 2 : y;
|
||||
}
|
||||
|
||||
/* Quick hack of a popup menu
|
||||
*/
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
const gchar *signal = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-signal");
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (text_view), signal);
|
||||
}
|
||||
|
||||
static void
|
||||
append_action_signal (GtkTextView *text_view,
|
||||
GtkWidget *menu,
|
||||
const gchar *label,
|
||||
const gchar *signal)
|
||||
{
|
||||
GtkWidget *menuitem = gtk_menu_item_new_with_label (label);
|
||||
|
||||
gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-signal", (char *)signal);
|
||||
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
|
||||
activate_cb, text_view);
|
||||
|
||||
gtk_widget_show (menuitem);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_menu_detach (GtkWidget *attach_widget,
|
||||
GtkMenu *menu)
|
||||
{
|
||||
GTK_TEXT_VIEW (attach_widget)->popup_menu = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_popup_menu (GtkTextView *text_view,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
if (!text_view->popup_menu)
|
||||
{
|
||||
GtkWidget *menuitem;
|
||||
|
||||
text_view->popup_menu = gtk_menu_new ();
|
||||
|
||||
gtk_menu_attach_to_widget (GTK_MENU (text_view->popup_menu),
|
||||
GTK_WIDGET (text_view),
|
||||
popup_menu_detach);
|
||||
|
||||
append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard");
|
||||
append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard");
|
||||
append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard");
|
||||
|
||||
menuitem = gtk_menu_item_new (); /* Separator */
|
||||
gtk_widget_show (menuitem);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
|
||||
|
||||
gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (text_view->im_context),
|
||||
GTK_MENU_SHELL (text_view->popup_menu));
|
||||
}
|
||||
|
||||
gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
|
||||
NULL, NULL,
|
||||
event->button, event->time);
|
||||
}
|
||||
|
@@ -29,13 +29,12 @@ struct _GtkTextView {
|
||||
guint selection_drag_scan_timeout;
|
||||
gint scrolling_accel_factor;
|
||||
|
||||
gboolean overwrite_mode;
|
||||
|
||||
GtkWrapMode wrap_mode; /* Default wrap mode */
|
||||
|
||||
gboolean editable; /* default editability */
|
||||
|
||||
gboolean cursor_visible;
|
||||
guint editable : 1; /* default editability */
|
||||
guint overwrite_mode : 1;
|
||||
guint cursor_visible : 1;
|
||||
gint need_im_reset : 1; /* If we have reset the IM since the last character entered */
|
||||
|
||||
GdkWindow *bin_window;
|
||||
GtkAdjustment *hadjustment;
|
||||
@@ -68,6 +67,7 @@ struct _GtkTextView {
|
||||
guint incremental_validate_idle; /* Idle to revalidate offscreen portions, runs after redraw */
|
||||
|
||||
GtkIMContext *im_context;
|
||||
GtkWidget *popup_menu;
|
||||
};
|
||||
|
||||
struct _GtkTextViewClass {
|
||||
|
338
gtk/gtkthemes.c
338
gtk/gtkthemes.c
@@ -28,55 +28,96 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include "gtkmodule.h"
|
||||
#include "gtkthemes.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkrc.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtksignal.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "config.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
typedef struct _GtkThemeEnginePlugin GtkThemeEnginePlugin;
|
||||
|
||||
struct _GtkThemeEngine
|
||||
{
|
||||
GtkModule base_module;
|
||||
|
||||
GModule *library;
|
||||
|
||||
void (*init) (GtkThemeEngine *);
|
||||
void (*init) (GtkModule *);
|
||||
void (*exit) (void);
|
||||
GtkRcStyle *(*create_rc_style) ();
|
||||
|
||||
gchar *name;
|
||||
|
||||
GSList *plugins; /* TypePlugins for this engine */
|
||||
|
||||
guint refcount;
|
||||
};
|
||||
|
||||
struct _GtkThemeEnginePlugin
|
||||
{
|
||||
GTypePlugin plugin;
|
||||
|
||||
GtkThemeEngine *engine;
|
||||
gchar *engine_name;
|
||||
GTypeInfo info;
|
||||
GType type;
|
||||
GType parent_type;
|
||||
};
|
||||
|
||||
static GHashTable *engine_hash = NULL;
|
||||
|
||||
#ifdef __EMX__
|
||||
static void gen_8_3_dll_name(gchar *name, gchar *fullname)
|
||||
static gboolean
|
||||
gtk_theme_engine_load (GtkModule *module)
|
||||
{
|
||||
/* 8.3 dll filename restriction */
|
||||
fullname[0] = '_';
|
||||
strncpy (fullname + 1, name, 7);
|
||||
fullname[8] = '\0';
|
||||
strcat (fullname, ".dll");
|
||||
}
|
||||
#endif
|
||||
GtkThemeEngine *engine = (GtkThemeEngine *)module;
|
||||
|
||||
gchar *fullname;
|
||||
gchar *engine_path;
|
||||
|
||||
fullname = g_module_build_path (NULL, engine->name);
|
||||
engine_path = gtk_rc_find_module_in_path (fullname);
|
||||
|
||||
if (!engine_path)
|
||||
{
|
||||
g_warning (_("Unable to locate loadable module in module_path: \"%s\","),
|
||||
fullname);
|
||||
|
||||
g_free (fullname);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (fullname);
|
||||
|
||||
/* load the lib */
|
||||
|
||||
GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
|
||||
|
||||
engine->library = g_module_open (engine_path, 0);
|
||||
g_free(engine_path);
|
||||
if (!engine->library)
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* extract symbols from the lib */
|
||||
if (!g_module_symbol (engine->library, "theme_init",
|
||||
(gpointer *)&engine->init) ||
|
||||
!g_module_symbol (engine->library, "theme_exit",
|
||||
(gpointer *)&engine->exit) ||
|
||||
!g_module_symbol (engine->library, "theme_create_rc_style",
|
||||
(gpointer *)&engine->create_rc_style))
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
g_module_close (engine->library);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* call the theme's init (theme_init) function to let it */
|
||||
/* setup anything it needs to set up. */
|
||||
engine->init (module);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_theme_engine_unload (GtkModule *module)
|
||||
{
|
||||
GtkThemeEngine *engine = (GtkThemeEngine *)module;
|
||||
|
||||
engine->exit();
|
||||
|
||||
g_module_close (engine->library);
|
||||
engine->library = NULL;
|
||||
|
||||
engine->init = NULL;
|
||||
engine->exit = NULL;
|
||||
engine->create_rc_style = NULL;
|
||||
}
|
||||
|
||||
GtkThemeEngine*
|
||||
gtk_theme_engine_get (const gchar *name)
|
||||
@@ -92,78 +133,17 @@ gtk_theme_engine_get (const gchar *name)
|
||||
|
||||
if (!result)
|
||||
{
|
||||
gchar *fullname;
|
||||
gchar *engine_path;
|
||||
GModule *library;
|
||||
|
||||
#ifndef __EMX__
|
||||
fullname = g_module_build_path (NULL, name);
|
||||
#else
|
||||
fullname = g_malloc (13);
|
||||
gen_8_3_dll_name(name, fullname);
|
||||
#endif
|
||||
engine_path = gtk_rc_find_module_in_path (fullname);
|
||||
#ifdef __EMX__
|
||||
if (!engine_path)
|
||||
{
|
||||
/* try theme name without prefix '_' */
|
||||
memmove(fullname, fullname + 1, strlen(fullname));
|
||||
engine_path = gtk_rc_find_module_in_path (fullname);
|
||||
}
|
||||
#endif
|
||||
result = g_new0 (GtkThemeEngine, 1);
|
||||
result->name = g_strdup (name);
|
||||
|
||||
if (!engine_path)
|
||||
{
|
||||
g_warning (_("Unable to locate loadable module in module_path: \"%s\","),
|
||||
fullname);
|
||||
|
||||
g_free (fullname);
|
||||
return NULL;
|
||||
}
|
||||
g_free (fullname);
|
||||
|
||||
/* load the lib */
|
||||
gtk_module_init ((GtkModule *)result, name,
|
||||
gtk_theme_engine_load, gtk_theme_engine_unload);
|
||||
|
||||
GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
|
||||
|
||||
library = g_module_open (engine_path, 0);
|
||||
g_free(engine_path);
|
||||
if (!library)
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = g_new (GtkThemeEngine, 1);
|
||||
|
||||
result->refcount = 1;
|
||||
result->name = g_strdup (name);
|
||||
result->library = library;
|
||||
result->plugins = NULL;
|
||||
|
||||
/* extract symbols from the lib */
|
||||
if (!g_module_symbol (library, "theme_init",
|
||||
(gpointer *)&result->init) ||
|
||||
!g_module_symbol (library, "theme_exit",
|
||||
(gpointer *)&result->exit) ||
|
||||
!g_module_symbol (library, "theme_create_rc_style",
|
||||
(gpointer *)&result->create_rc_style))
|
||||
{
|
||||
g_warning (g_module_error());
|
||||
g_free (result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* call the theme's init (theme_init) function to let it */
|
||||
/* setup anything it needs to set up. */
|
||||
result->init((GtkThemeEngine *)result);
|
||||
|
||||
g_hash_table_insert (engine_hash, result->name, result);
|
||||
}
|
||||
g_hash_table_insert (engine_hash, result->name, result);
|
||||
}
|
||||
else
|
||||
result->refcount++;
|
||||
|
||||
if (!gtk_module_ref ((GtkModule *)result))
|
||||
return NULL;
|
||||
|
||||
return (GtkThemeEngine *)result;
|
||||
}
|
||||
@@ -172,172 +152,22 @@ void
|
||||
gtk_theme_engine_ref (GtkThemeEngine *engine)
|
||||
{
|
||||
g_return_if_fail (engine != NULL);
|
||||
|
||||
engine->refcount++;
|
||||
|
||||
gtk_module_ref ((GtkModule *)engine);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_theme_engine_unref (GtkThemeEngine *engine)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
|
||||
g_return_if_fail (engine != NULL);
|
||||
g_return_if_fail (engine->refcount > 0);
|
||||
|
||||
engine->refcount--;
|
||||
|
||||
if (engine->refcount == 0)
|
||||
{
|
||||
engine->exit();
|
||||
|
||||
g_hash_table_remove (engine_hash, engine->name);
|
||||
|
||||
tmp_list = engine->plugins;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkThemeEnginePlugin *plugin = tmp_list->data;
|
||||
plugin->engine = NULL;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
g_slist_free (engine->plugins);
|
||||
|
||||
g_module_close (engine->library);
|
||||
g_free (engine->name);
|
||||
g_free (engine);
|
||||
}
|
||||
gtk_module_unref ((GtkModule *)engine);
|
||||
}
|
||||
|
||||
GtkRcStyle *
|
||||
gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
|
||||
{
|
||||
g_return_val_if_fail (engine != NULL, NULL);
|
||||
|
||||
|
||||
return engine->create_rc_style ();
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_theme_engine_plugin_ref (GTypePlugin *plugin)
|
||||
{
|
||||
GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
|
||||
|
||||
if (theme_plugin->engine == NULL)
|
||||
{
|
||||
gtk_theme_engine_get (theme_plugin->engine_name);
|
||||
if (!theme_plugin->engine)
|
||||
{
|
||||
g_warning ("An attempt to create an instance of a type from\n"
|
||||
"a previously loaded theme engine was made after the engine\n"
|
||||
"was unloaded, but the engine could not be reloaded or no longer\n"
|
||||
"implements the type. Bad things will happen.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
gtk_theme_engine_ref (theme_plugin->engine);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_theme_engine_plugin_unref (GTypePlugin *plugin)
|
||||
{
|
||||
GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
|
||||
|
||||
g_return_if_fail (theme_plugin->engine != NULL);
|
||||
|
||||
gtk_theme_engine_unref (theme_plugin->engine);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_theme_engine_complete_type_info (GTypePlugin *plugin,
|
||||
GType g_type,
|
||||
GTypeInfo *info,
|
||||
GTypeValueTable *value_table)
|
||||
{
|
||||
GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
|
||||
|
||||
*info = theme_plugin->info;
|
||||
}
|
||||
|
||||
static GTypePluginVTable gtk_theme_engine_plugin_vtable = {
|
||||
gtk_theme_engine_plugin_ref,
|
||||
gtk_theme_engine_plugin_unref,
|
||||
gtk_theme_engine_complete_type_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* gtk_theme_engine_register_type:
|
||||
* @engine: a #GtkThemeEngine
|
||||
* @parent_type: the type for the parent class
|
||||
* @type_name: name for the type
|
||||
* @type_info: type information structure
|
||||
*
|
||||
* Looks up or registers a type that is implemented with a particular
|
||||
* theme engine. If a type with name @type_name is already registered,
|
||||
* the #GType identifier for the type is returned, otherwise the type
|
||||
* is newly registered, and the resulting #GType identifier returned.
|
||||
*
|
||||
* As long as any instances of the type exist, the a reference will be
|
||||
* held to the theme engine and the theme engine will not be unloaded.
|
||||
*
|
||||
* Return value: the type identifier for the class.
|
||||
**/
|
||||
GType
|
||||
gtk_theme_engine_register_type (GtkThemeEngine *engine,
|
||||
GType parent_type,
|
||||
const gchar *type_name,
|
||||
const GTypeInfo *type_info)
|
||||
{
|
||||
GtkThemeEnginePlugin *plugin;
|
||||
GType type;
|
||||
|
||||
g_return_val_if_fail (engine != NULL, 0);
|
||||
g_return_val_if_fail (type_name != NULL, 0);
|
||||
g_return_val_if_fail (type_info != NULL, 0);
|
||||
|
||||
type = g_type_from_name (type_name);
|
||||
if (type)
|
||||
plugin = (GtkThemeEnginePlugin *)g_type_get_plugin (type);
|
||||
else
|
||||
{
|
||||
plugin = g_new (GtkThemeEnginePlugin, 1);
|
||||
|
||||
plugin->plugin.vtable = >k_theme_engine_plugin_vtable;
|
||||
plugin->engine = NULL;
|
||||
plugin->engine_name = NULL;
|
||||
plugin->parent_type = parent_type;
|
||||
plugin->type = g_type_register_dynamic (parent_type, type_name, (GTypePlugin *)plugin);
|
||||
}
|
||||
|
||||
if (plugin->engine)
|
||||
{
|
||||
if (plugin->engine != engine)
|
||||
{
|
||||
g_warning ("Two different theme engines tried to register '%s'.", type_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (plugin->parent_type != parent_type)
|
||||
{
|
||||
g_warning ("Type '%s' recreated with different parent type.\n"
|
||||
"(was '%s', now '%s')", type_name,
|
||||
g_type_name (plugin->parent_type),
|
||||
g_type_name (parent_type));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin->engine = engine;
|
||||
if (plugin->engine_name)
|
||||
g_free (plugin->engine_name);
|
||||
|
||||
plugin->engine_name = g_strdup (engine->name);
|
||||
|
||||
plugin->info = *type_info;
|
||||
|
||||
engine->plugins = g_slist_prepend (engine->plugins, plugin);
|
||||
}
|
||||
|
||||
return plugin->type;
|
||||
}
|
||||
|
||||
|
@@ -42,12 +42,6 @@ void gtk_theme_engine_ref (GtkThemeEngine *engine);
|
||||
void gtk_theme_engine_unref (GtkThemeEngine *engine);
|
||||
GtkRcStyle * gtk_theme_engine_create_rc_style (GtkThemeEngine *engine);
|
||||
|
||||
GType gtk_theme_engine_register_type (GtkThemeEngine *engine,
|
||||
GType parent_type,
|
||||
const gchar *type_name,
|
||||
const GTypeInfo *type_info);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
170
gtk/queryimmodules.c
Normal file
170
gtk/queryimmodules.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/* GTK+
|
||||
* querymodules.c:
|
||||
*
|
||||
* Copyright (C) 2000 Red Hat Software
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define SOEXT ".dll"
|
||||
#else
|
||||
#define SOEXT ".so"
|
||||
#endif
|
||||
|
||||
#include <pango/pango-utils.h>
|
||||
#include "gtk/gtkrc.h"
|
||||
#include "gtk/gtkimmodule.h"
|
||||
|
||||
void
|
||||
print_escaped (const char *str)
|
||||
{
|
||||
char *tmp = g_strescape (str, NULL);
|
||||
printf ("\"%s\" ", tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
gboolean
|
||||
query_module (const char *dir, const char *name)
|
||||
{
|
||||
void (*list) (const GtkIMContextInfo ***contexts,
|
||||
guint *n_contexts);
|
||||
void (*init) (GtkModule *module);
|
||||
void (*exit) (void);
|
||||
GtkIMContext *(*create) (const gchar *context_id);
|
||||
|
||||
GModule *module;
|
||||
gchar *path;
|
||||
gboolean error = FALSE;
|
||||
|
||||
if (name[0] == G_DIR_SEPARATOR)
|
||||
path = g_strdup (name);
|
||||
else
|
||||
path = g_strconcat (dir, G_DIR_SEPARATOR_S, name, NULL);
|
||||
|
||||
module = g_module_open (path, 0);
|
||||
|
||||
if (!module)
|
||||
{
|
||||
fprintf(stderr, "Cannot load module %s: %s\n", path, g_module_error());
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
if (module &&
|
||||
g_module_symbol (module, "im_module_list", (gpointer)&list) &&
|
||||
g_module_symbol (module, "im_module_init", (gpointer)&init) &&
|
||||
g_module_symbol (module, "im_module_exit", (gpointer)&exit) &&
|
||||
g_module_symbol (module, "im_module_create", (gpointer)&create))
|
||||
{
|
||||
const GtkIMContextInfo **contexts;
|
||||
guint n_contexts;
|
||||
int i;
|
||||
|
||||
print_escaped (path);
|
||||
fputs ("\n", stdout);
|
||||
|
||||
(*list) (&contexts, &n_contexts);
|
||||
|
||||
for (i=0; i<n_contexts; i++)
|
||||
{
|
||||
print_escaped (contexts[i]->context_id);
|
||||
print_escaped (contexts[i]->context_name);
|
||||
print_escaped (contexts[i]->domain);
|
||||
print_escaped (contexts[i]->domain_dirname);
|
||||
print_escaped (contexts[i]->default_locales);
|
||||
fputs ("\n", stdout);
|
||||
}
|
||||
fputs ("\n", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s does not export GTK+ IM module API: %s\n", path,
|
||||
g_module_error());
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
if (module)
|
||||
g_module_close (module);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char cwd[PATH_MAX];
|
||||
int i;
|
||||
char *path;
|
||||
gboolean error = FALSE;
|
||||
|
||||
printf ("# GTK+ Input Method Modules file\n"
|
||||
"# Automatically generated file, do not edit\n"
|
||||
"#\n");
|
||||
|
||||
if (argc == 1) /* No arguments given */
|
||||
{
|
||||
char **dirs;
|
||||
int i;
|
||||
|
||||
path = gtk_rc_get_im_module_path ();
|
||||
|
||||
printf ("# ModulesPath = %s\n#\n", path);
|
||||
|
||||
dirs = pango_split_file_list (path);
|
||||
|
||||
for (i=0; dirs[i]; i++)
|
||||
{
|
||||
DIR *dir = opendir (dirs[i]);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent *dent;
|
||||
|
||||
while ((dent = readdir (dir)))
|
||||
{
|
||||
int len = strlen (dent->d_name);
|
||||
if (len > 3 && strcmp (dent->d_name + len - strlen (SOEXT), SOEXT) == 0)
|
||||
error |= query_module (dirs[i], dent->d_name);
|
||||
}
|
||||
|
||||
closedir (dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getcwd (cwd, PATH_MAX);
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
error |= query_module (cwd, argv[i]);
|
||||
}
|
||||
|
||||
return error ? 1 : 0;
|
||||
}
|
@@ -8746,11 +8746,14 @@ create_main_window (void)
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
||||
void
|
||||
pixbuf_init ()
|
||||
static void
|
||||
test_init ()
|
||||
{
|
||||
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
{
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -8760,7 +8763,7 @@ main (int argc, char *argv[])
|
||||
|
||||
srand (time (NULL));
|
||||
|
||||
pixbuf_init ();
|
||||
test_init ();
|
||||
gtk_set_locale ();
|
||||
|
||||
/* Check to see if we are being run from the correct
|
||||
|
@@ -1419,15 +1419,33 @@ create_view (Buffer *buffer)
|
||||
return view;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_exists (const char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
return stat (filename, &statbuf) == 0;
|
||||
}
|
||||
void
|
||||
test_init ()
|
||||
{
|
||||
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
|
||||
{
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
Buffer *buffer;
|
||||
View *view;
|
||||
int i;
|
||||
|
||||
|
||||
test_init ();
|
||||
gtk_set_locale ();
|
||||
gtk_init (&argc, &argv);
|
||||
gdk_rgb_init (); /* FIXME remove this */
|
||||
|
||||
buffer = create_buffer ();
|
||||
view = create_view (buffer);
|
||||
|
@@ -1 +1 @@
|
||||
SUBDIRS=linux-fb
|
||||
SUBDIRS=linux-fb input
|
||||
|
@@ -1,132 +0,0 @@
|
||||
Tue Jul 18 12:13:19 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
Updates to work with GTK+-2.0 theme engine architecture.
|
||||
It won't even sort of work with GTK+-1.2 any more.
|
||||
|
||||
* configure.in src/Makefile.am: Look for GTK+-2.0,
|
||||
install engine into GTK+-2.0 location.
|
||||
|
||||
* src/pixbuf-style.h src/pixbuf-rc-style.[ch]: New
|
||||
files for GtkRcStyle and GtkStyle subclasses. Parsing,
|
||||
etc, moves to pixbuf-rc-style.[ch]
|
||||
|
||||
* src/pixbuf-draw.c: Chain up to parent implementation
|
||||
when images aren't found for a certain element.
|
||||
|
||||
Sun Jul 9 18:15:58 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in (ACLOCAL): Add -Wall for gcc.
|
||||
|
||||
* src/pixbuf-render.c (pixbuf_render): Fix problem
|
||||
using gdk_rectangle_intersect() from GTK+-1.2.
|
||||
|
||||
* src/pixbuf-render.c src/pixbuf-draw.c: Remove
|
||||
direct access to pixbuf internals.
|
||||
|
||||
Mon Mar 6 11:44:58 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* docs/gap-geometry.fig: Moved into docs/ subdir
|
||||
|
||||
* Makefile.am configure.in autogen.sh src/Makefile.am:
|
||||
automakify
|
||||
|
||||
* src/pixbuf.h src/pixbuf-render.c src/pixbuf-draw.c
|
||||
src/pixbuf-main.c: Move sources into subdir and
|
||||
rename.
|
||||
|
||||
Mon Mar 6 11:02:07 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_pixbuf.c: Handle drawing transparency without a
|
||||
mask correctly.
|
||||
|
||||
* pixmap_theme_main.c pixmap_theme_draw.c: Remove duplicate
|
||||
includes.
|
||||
|
||||
Sun Feb 6 21:34:30 2000 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Started ChangeLog for pixbuf engine, check sources
|
||||
into CVS.
|
||||
|
||||
========== ChangeLog for pixmap engine ===================
|
||||
|
||||
1999-11-22 Martin Baulig <martin@home-of-linux.org>
|
||||
|
||||
* pixmap_theme_main.c (theme_duplicate_style): Really copy the
|
||||
`src_data->img_list', not just the pointer that points to it.
|
||||
|
||||
Tue Oct 5 15:13:29 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_draw.c (apply_theme_image): Don't set
|
||||
background pixmap on pixmaps.
|
||||
|
||||
1999-02-14 Raja R Harinath <harinath@cs.umn.edu>
|
||||
|
||||
* Theme/gtk/Makefile.am.in (Makefile.am): Handle the case when
|
||||
files are deleted.
|
||||
|
||||
Thu Feb 11 21:16:53 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_main.c (theme_data_unref): Free the
|
||||
theme data structure as well as the contents.
|
||||
|
||||
1999-02-03 Raja R Harinath <harinath@cs.umn.edu>
|
||||
|
||||
* Theme/gtk/Makefile.am.in: New file. Theme/gtk/Makefile.am is
|
||||
generated from this file when new *.png files are added.
|
||||
|
||||
1999-01-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
|
||||
* pixmap_theme_main.c (theme_init): Turn on pixmap cache.
|
||||
|
||||
Mon Jan 18 13:37:23 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Theme/gtk/gtkrc: Give buttons a gray background
|
||||
color so they look a little less funny when initially
|
||||
drawing.
|
||||
|
||||
Wed Jan 13 18:58:25 1999 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_draw.c: Fixed pervasive mis-bracketing
|
||||
that was causing drawing if the drawn region and
|
||||
clipping region did NOT intersect, and a couple
|
||||
of errors in computing source and destination
|
||||
regions.
|
||||
|
||||
1998-11-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* pixmap_theme_draw.c: #include <math.h>
|
||||
|
||||
1998-11-07 Raja R Harinath <harinath@cs.umn.edu>
|
||||
|
||||
* Theme/gtk/Makefile.am (theme_DATA):
|
||||
Update to new directory contents.
|
||||
* configure.in: Remove.
|
||||
|
||||
Fri Nov 6 17:26:12 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_main.c: Removed some debugging
|
||||
printf's.
|
||||
|
||||
* Theme/gtk/notebook1.c Theme/gtk/menubar.png: new
|
||||
bigger pixmaps to reduce pixelation.
|
||||
|
||||
* Theme/gtk/gtkrc: Reorganized to use several styles
|
||||
instead of one huge style. Change clist backgrounds
|
||||
to be prettier.
|
||||
|
||||
Thu Nov 5 10:23:46 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_draw.c (draw_shadow_gap): Fixed hard-coded
|
||||
gap_side of '0'.
|
||||
|
||||
Mon Nov 2 14:46:02 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_draw.c (apply_theme_image_shadow_gap): Removed
|
||||
several hundred lines of duplicated code with a bit of
|
||||
reoriganization.
|
||||
|
||||
Wed Oct 28 16:18:04 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* pixmap_theme_main.c (theme_symbols): Removed lots
|
||||
and lots of white space.
|
||||
|
@@ -1,17 +0,0 @@
|
||||
INCLUDES = $(GTK_CFLAGS)
|
||||
|
||||
enginedir = $(libdir)/gtk-2.0/$(GTK_VERSION)/engines
|
||||
|
||||
engine_LTLIBRARIES = libpixmap.la
|
||||
|
||||
libpixmap_la_SOURCES = \
|
||||
pixbuf-draw.c \
|
||||
pixbuf-main.c \
|
||||
pixbuf-render.c \
|
||||
pixbuf-rc-style.c \
|
||||
pixbuf-rc-style.h \
|
||||
pixbuf-style.h \
|
||||
pixbuf.h
|
||||
|
||||
libpixmap_la_LDFLAGS = -module -avoid-version
|
||||
libpixmap_la_LIBADD = -lgdk_pixbuf
|
@@ -1,17 +0,0 @@
|
||||
The code in this directory is a GTK+ theme engine based on the earlier
|
||||
pixmap theme engine.
|
||||
|
||||
The config files are meant to be compatible, but instead of rendering
|
||||
using Imlib, it renders using GdkPixbuf. This makes the memory
|
||||
management much more understandable, and also allows us to use
|
||||
GdkPixbuf's high quality scaling.
|
||||
|
||||
Most of the code was reworked/rewritten in the process to make it more
|
||||
understandable and maintainable.
|
||||
|
||||
There are lots of bugs here, a considersable number of bugs. But it's
|
||||
cleaned up a great deal from the older pixmap engine. Please don't
|
||||
make it uglier again.
|
||||
|
||||
Owen Taylor <otaylor@redhat.com>
|
||||
6 February 2000
|
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include "pixbuf.h"
|
||||
#include "pixbuf-style.h"
|
||||
#include "pixbuf-rc-style.h"
|
||||
#include <gmodule.h>
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
theme_init(GtkThemeEngine * engine)
|
||||
{
|
||||
pixbuf_rc_style_register_type (engine);
|
||||
pixbuf_style_register_type (engine);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
theme_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT GtkRcStyle *
|
||||
theme_create_rc_style (void)
|
||||
{
|
||||
return GTK_RC_STYLE (g_object_new (PIXBUF_TYPE_RC_STYLE, NULL));
|
||||
}
|
||||
|
||||
/* The following function will be called by GTK+ when the module
|
||||
* is loaded and checks to see if we are compatible with the
|
||||
* version of GTK+ that loads us.
|
||||
*/
|
||||
G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
|
||||
const gchar*
|
||||
g_module_check_init (GModule *module)
|
||||
{
|
||||
return gtk_check_version (GTK_MAJOR_VERSION,
|
||||
GTK_MINOR_VERSION,
|
||||
GTK_MICRO_VERSION - GTK_INTERFACE_AGE);
|
||||
}
|
@@ -1,796 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include "pixbuf.h"
|
||||
#include "pixbuf-style.h"
|
||||
#include "pixbuf-rc-style.h"
|
||||
|
||||
static void pixbuf_rc_style_init (PixbufRcStyle *style);
|
||||
static void pixbuf_rc_style_class_init (PixbufRcStyleClass *klass);
|
||||
static void pixbuf_rc_style_finalize (GObject *object);
|
||||
static guint pixbuf_rc_style_parse (GtkRcStyle *rc_style,
|
||||
GScanner *scanner);
|
||||
static void pixbuf_rc_style_merge (GtkRcStyle *dest,
|
||||
GtkRcStyle *src);
|
||||
static GtkStyle *pixbuf_rc_style_create_style (GtkRcStyle *rc_style);
|
||||
|
||||
static void theme_image_unref (ThemeImage *data);
|
||||
|
||||
static struct
|
||||
{
|
||||
gchar *name;
|
||||
guint token;
|
||||
}
|
||||
theme_symbols[] =
|
||||
{
|
||||
{ "image", TOKEN_IMAGE },
|
||||
{ "function", TOKEN_FUNCTION },
|
||||
{ "file", TOKEN_FILE },
|
||||
{ "stretch", TOKEN_STRETCH },
|
||||
{ "recolorable", TOKEN_RECOLORABLE },
|
||||
{ "border", TOKEN_BORDER },
|
||||
{ "detail", TOKEN_DETAIL },
|
||||
{ "state", TOKEN_STATE },
|
||||
{ "shadow", TOKEN_SHADOW },
|
||||
{ "gap_side", TOKEN_GAP_SIDE },
|
||||
{ "gap_file", TOKEN_GAP_FILE },
|
||||
{ "gap_border", TOKEN_GAP_BORDER },
|
||||
{ "gap_start_file", TOKEN_GAP_START_FILE },
|
||||
{ "gap_start_border", TOKEN_GAP_START_BORDER },
|
||||
{ "gap_end_file", TOKEN_GAP_END_FILE },
|
||||
{ "gap_end_border", TOKEN_GAP_END_BORDER },
|
||||
{ "overlay_file", TOKEN_OVERLAY_FILE },
|
||||
{ "overlay_border", TOKEN_OVERLAY_BORDER },
|
||||
{ "overlay_stretch", TOKEN_OVERLAY_STRETCH },
|
||||
{ "arrow_direction", TOKEN_ARROW_DIRECTION },
|
||||
{ "orientation", TOKEN_ORIENTATION },
|
||||
|
||||
{ "HLINE", TOKEN_D_HLINE },
|
||||
{ "VLINE", TOKEN_D_VLINE },
|
||||
{ "SHADOW", TOKEN_D_SHADOW },
|
||||
{ "POLYGON", TOKEN_D_POLYGON },
|
||||
{ "ARROW", TOKEN_D_ARROW },
|
||||
{ "DIAMOND", TOKEN_D_DIAMOND },
|
||||
{ "OVAL", TOKEN_D_OVAL },
|
||||
{ "STRING", TOKEN_D_STRING },
|
||||
{ "BOX", TOKEN_D_BOX },
|
||||
{ "FLAT_BOX", TOKEN_D_FLAT_BOX },
|
||||
{ "CHECK", TOKEN_D_CHECK },
|
||||
{ "OPTION", TOKEN_D_OPTION },
|
||||
{ "CROSS", TOKEN_D_CROSS },
|
||||
{ "RAMP", TOKEN_D_RAMP },
|
||||
{ "TAB", TOKEN_D_TAB },
|
||||
{ "SHADOW_GAP", TOKEN_D_SHADOW_GAP },
|
||||
{ "BOX_GAP", TOKEN_D_BOX_GAP },
|
||||
{ "EXTENSION", TOKEN_D_EXTENSION },
|
||||
{ "FOCUS", TOKEN_D_FOCUS },
|
||||
{ "SLIDER", TOKEN_D_SLIDER },
|
||||
{ "ENTRY", TOKEN_D_ENTRY },
|
||||
{ "HANDLE", TOKEN_D_HANDLE },
|
||||
|
||||
{ "TRUE", TOKEN_TRUE },
|
||||
{ "FALSE", TOKEN_FALSE },
|
||||
|
||||
{ "TOP", TOKEN_TOP },
|
||||
{ "UP", TOKEN_UP },
|
||||
{ "BOTTOM", TOKEN_BOTTOM },
|
||||
{ "DOWN", TOKEN_DOWN },
|
||||
{ "LEFT", TOKEN_LEFT },
|
||||
{ "RIGHT", TOKEN_RIGHT },
|
||||
|
||||
{ "NORMAL", TOKEN_NORMAL },
|
||||
{ "ACTIVE", TOKEN_ACTIVE },
|
||||
{ "PRELIGHT", TOKEN_PRELIGHT },
|
||||
{ "SELECTED", TOKEN_SELECTED },
|
||||
{ "INSENSITIVE", TOKEN_INSENSITIVE },
|
||||
|
||||
{ "NONE", TOKEN_NONE },
|
||||
{ "IN", TOKEN_IN },
|
||||
{ "OUT", TOKEN_OUT },
|
||||
{ "ETCHED_IN", TOKEN_ETCHED_IN },
|
||||
{ "ETCHED_OUT", TOKEN_ETCHED_OUT },
|
||||
{ "HORIZONTAL", TOKEN_HORIZONTAL },
|
||||
{ "VERTICAL", TOKEN_VERTICAL },
|
||||
};
|
||||
|
||||
static GtkRcStyleClass *parent_class;
|
||||
|
||||
GType pixbuf_type_rc_style = 0;
|
||||
|
||||
void
|
||||
pixbuf_rc_style_register_type (GtkThemeEngine *engine)
|
||||
{
|
||||
static const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (PixbufRcStyleClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) pixbuf_rc_style_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (PixbufRcStyle),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) pixbuf_rc_style_init,
|
||||
};
|
||||
|
||||
pixbuf_type_rc_style = gtk_theme_engine_register_type (engine,
|
||||
GTK_TYPE_RC_STYLE,
|
||||
"PixbufRcStyle",
|
||||
&object_info);
|
||||
}
|
||||
|
||||
static void
|
||||
pixbuf_rc_style_init (PixbufRcStyle *style)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
pixbuf_rc_style_class_init (PixbufRcStyleClass *klass)
|
||||
{
|
||||
GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
rc_style_class->parse = pixbuf_rc_style_parse;
|
||||
rc_style_class->merge = pixbuf_rc_style_merge;
|
||||
rc_style_class->create_style = pixbuf_rc_style_create_style;
|
||||
|
||||
object_class->finalize = pixbuf_rc_style_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
pixbuf_rc_style_finalize (GObject *object)
|
||||
{
|
||||
PixbufRcStyle *rc_style = PIXBUF_RC_STYLE (object);
|
||||
|
||||
g_list_foreach (rc_style->img_list, (GFunc) theme_image_unref, NULL);
|
||||
g_list_free (rc_style->img_list);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_file(GScanner *scanner,
|
||||
ThemePixbuf **theme_pb)
|
||||
{
|
||||
guint token;
|
||||
gchar *pixmap;
|
||||
|
||||
/* Skip 'blah_file' */
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (!*theme_pb)
|
||||
*theme_pb = theme_pixbuf_new ();
|
||||
|
||||
pixmap = gtk_rc_find_pixmap_in_path(scanner, scanner->value.v_string);
|
||||
if (pixmap)
|
||||
{
|
||||
theme_pixbuf_set_filename (*theme_pb, pixmap);
|
||||
g_free (pixmap);
|
||||
}
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_border (GScanner *scanner,
|
||||
ThemePixbuf **theme_pb)
|
||||
{
|
||||
guint token;
|
||||
gint left, right, top, bottom;
|
||||
|
||||
/* Skip 'blah_border' */
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_LEFT_CURLY)
|
||||
return G_TOKEN_LEFT_CURLY;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_INT)
|
||||
return G_TOKEN_INT;
|
||||
left = scanner->value.v_int;
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_COMMA)
|
||||
return G_TOKEN_COMMA;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_INT)
|
||||
return G_TOKEN_INT;
|
||||
right = scanner->value.v_int;
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_COMMA)
|
||||
return G_TOKEN_COMMA;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_INT)
|
||||
return G_TOKEN_INT;
|
||||
top = scanner->value.v_int;
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_COMMA)
|
||||
return G_TOKEN_COMMA;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_INT)
|
||||
return G_TOKEN_INT;
|
||||
bottom = scanner->value.v_int;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_RIGHT_CURLY)
|
||||
return G_TOKEN_RIGHT_CURLY;
|
||||
|
||||
if (!*theme_pb)
|
||||
*theme_pb = theme_pixbuf_new ();
|
||||
|
||||
theme_pixbuf_set_border (*theme_pb, left, right, top, bottom);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_stretch(GScanner *scanner,
|
||||
ThemePixbuf **theme_pb)
|
||||
{
|
||||
guint token;
|
||||
gboolean stretch;
|
||||
|
||||
/* Skip 'blah_stretch' */
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token == TOKEN_TRUE)
|
||||
stretch = TRUE;
|
||||
else if (token == TOKEN_FALSE)
|
||||
stretch = FALSE;
|
||||
else
|
||||
return TOKEN_TRUE;
|
||||
|
||||
if (!*theme_pb)
|
||||
*theme_pb = theme_pixbuf_new ();
|
||||
|
||||
theme_pixbuf_set_stretch (*theme_pb, stretch);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_recolorable(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_RECOLORABLE)
|
||||
return TOKEN_RECOLORABLE;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token == TOKEN_TRUE)
|
||||
data->recolorable = 1;
|
||||
else if (token == TOKEN_FALSE)
|
||||
data->recolorable = 0;
|
||||
else
|
||||
return TOKEN_TRUE;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_function(GScanner * scanner,
|
||||
ThemeImage *data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_FUNCTION)
|
||||
return TOKEN_FUNCTION;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if ((token >= TOKEN_D_HLINE) && (token <= TOKEN_D_HANDLE))
|
||||
data->match_data.function = token;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_detail(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_DETAIL)
|
||||
return TOKEN_DETAIL;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (data->match_data.detail)
|
||||
g_free (data->match_data.detail);
|
||||
|
||||
data->match_data.detail = g_strdup(scanner->value.v_string);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_state(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_STATE)
|
||||
return TOKEN_STATE;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token == TOKEN_NORMAL)
|
||||
data->match_data.state = GTK_STATE_NORMAL;
|
||||
else if (token == TOKEN_ACTIVE)
|
||||
data->match_data.state = GTK_STATE_ACTIVE;
|
||||
else if (token == TOKEN_PRELIGHT)
|
||||
data->match_data.state = GTK_STATE_PRELIGHT;
|
||||
else if (token == TOKEN_SELECTED)
|
||||
data->match_data.state = GTK_STATE_SELECTED;
|
||||
else if (token == TOKEN_INSENSITIVE)
|
||||
data->match_data.state = GTK_STATE_INSENSITIVE;
|
||||
else
|
||||
return TOKEN_NORMAL;
|
||||
|
||||
data->match_data.flags |= THEME_MATCH_STATE;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_shadow(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_SHADOW)
|
||||
return TOKEN_SHADOW;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token == TOKEN_NONE)
|
||||
data->match_data.shadow = GTK_SHADOW_NONE;
|
||||
else if (token == TOKEN_IN)
|
||||
data->match_data.shadow = GTK_SHADOW_IN;
|
||||
else if (token == TOKEN_OUT)
|
||||
data->match_data.shadow = GTK_SHADOW_OUT;
|
||||
else if (token == TOKEN_ETCHED_IN)
|
||||
data->match_data.shadow = GTK_SHADOW_ETCHED_IN;
|
||||
else if (token == TOKEN_ETCHED_OUT)
|
||||
data->match_data.shadow = GTK_SHADOW_ETCHED_OUT;
|
||||
else
|
||||
return TOKEN_NONE;
|
||||
|
||||
data->match_data.flags |= THEME_MATCH_SHADOW;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_arrow_direction(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_ARROW_DIRECTION)
|
||||
return TOKEN_ARROW_DIRECTION;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token == TOKEN_UP)
|
||||
data->match_data.arrow_direction = GTK_ARROW_UP;
|
||||
else if (token == TOKEN_DOWN)
|
||||
data->match_data.arrow_direction = GTK_ARROW_DOWN;
|
||||
else if (token == TOKEN_LEFT)
|
||||
data->match_data.arrow_direction = GTK_ARROW_LEFT;
|
||||
else if (token == TOKEN_RIGHT)
|
||||
data->match_data.arrow_direction = GTK_ARROW_RIGHT;
|
||||
else
|
||||
return TOKEN_UP;
|
||||
|
||||
data->match_data.flags |= THEME_MATCH_ARROW_DIRECTION;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_gap_side(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_GAP_SIDE)
|
||||
return TOKEN_GAP_SIDE;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
if (token == TOKEN_TOP)
|
||||
data->match_data.gap_side = GTK_POS_TOP;
|
||||
else if (token == TOKEN_BOTTOM)
|
||||
data->match_data.gap_side = GTK_POS_BOTTOM;
|
||||
else if (token == TOKEN_LEFT)
|
||||
data->match_data.gap_side = GTK_POS_LEFT;
|
||||
else if (token == TOKEN_RIGHT)
|
||||
data->match_data.gap_side = GTK_POS_RIGHT;
|
||||
else
|
||||
return TOKEN_TOP;
|
||||
|
||||
data->match_data.flags |= THEME_MATCH_GAP_SIDE;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_orientation(GScanner * scanner,
|
||||
ThemeImage * data)
|
||||
{
|
||||
guint token;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_ORIENTATION)
|
||||
return TOKEN_ORIENTATION;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_EQUAL_SIGN)
|
||||
return G_TOKEN_EQUAL_SIGN;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
if (token == TOKEN_HORIZONTAL)
|
||||
data->match_data.orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
else if (token == TOKEN_VERTICAL)
|
||||
data->match_data.orientation = GTK_ORIENTATION_VERTICAL;
|
||||
else
|
||||
return TOKEN_HORIZONTAL;
|
||||
|
||||
data->match_data.flags |= THEME_MATCH_ORIENTATION;
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
theme_image_ref (ThemeImage *data)
|
||||
{
|
||||
data->refcount++;
|
||||
}
|
||||
|
||||
static void
|
||||
theme_image_unref (ThemeImage *data)
|
||||
{
|
||||
data->refcount--;
|
||||
if (data->refcount == 0)
|
||||
{
|
||||
if (data->match_data.detail)
|
||||
g_free (data->match_data.detail);
|
||||
if (data->background)
|
||||
theme_pixbuf_destroy (data->background);
|
||||
if (data->overlay)
|
||||
theme_pixbuf_destroy (data->overlay);
|
||||
if (data->gap_start)
|
||||
theme_pixbuf_destroy (data->gap_start);
|
||||
if (data->gap)
|
||||
theme_pixbuf_destroy (data->gap);
|
||||
if (data->gap_end)
|
||||
theme_pixbuf_destroy (data->gap_end);
|
||||
g_free (data);
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
theme_parse_image(GScanner *scanner,
|
||||
PixbufRcStyle *pixbuf_style,
|
||||
ThemeImage **data_return)
|
||||
{
|
||||
guint token;
|
||||
ThemeImage *data;
|
||||
|
||||
data = NULL;
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != TOKEN_IMAGE)
|
||||
return TOKEN_IMAGE;
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
if (token != G_TOKEN_LEFT_CURLY)
|
||||
return G_TOKEN_LEFT_CURLY;
|
||||
|
||||
data = g_malloc(sizeof(ThemeImage));
|
||||
|
||||
data->refcount = 1;
|
||||
|
||||
data->background = NULL;
|
||||
data->overlay = NULL;
|
||||
data->gap_start = NULL;
|
||||
data->gap = NULL;
|
||||
data->gap_end = NULL;
|
||||
|
||||
data->recolorable = FALSE;
|
||||
|
||||
data->match_data.function = 0;
|
||||
data->match_data.detail = NULL;
|
||||
data->match_data.flags = 0;
|
||||
|
||||
token = g_scanner_peek_next_token(scanner);
|
||||
while (token != G_TOKEN_RIGHT_CURLY)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case TOKEN_FUNCTION:
|
||||
token = theme_parse_function(scanner, data);
|
||||
break;
|
||||
case TOKEN_RECOLORABLE:
|
||||
token = theme_parse_recolorable(scanner, data);
|
||||
break;
|
||||
case TOKEN_DETAIL:
|
||||
token = theme_parse_detail(scanner, data);
|
||||
break;
|
||||
case TOKEN_STATE:
|
||||
token = theme_parse_state(scanner, data);
|
||||
break;
|
||||
case TOKEN_SHADOW:
|
||||
token = theme_parse_shadow(scanner, data);
|
||||
break;
|
||||
case TOKEN_GAP_SIDE:
|
||||
token = theme_parse_gap_side(scanner, data);
|
||||
break;
|
||||
case TOKEN_ARROW_DIRECTION:
|
||||
token = theme_parse_arrow_direction(scanner, data);
|
||||
break;
|
||||
case TOKEN_ORIENTATION:
|
||||
token = theme_parse_orientation(scanner, data);
|
||||
break;
|
||||
case TOKEN_FILE:
|
||||
token = theme_parse_file(scanner, &data->background);
|
||||
break;
|
||||
case TOKEN_BORDER:
|
||||
token = theme_parse_border(scanner, &data->background);
|
||||
break;
|
||||
case TOKEN_STRETCH:
|
||||
token = theme_parse_stretch(scanner, &data->background);
|
||||
break;
|
||||
case TOKEN_GAP_FILE:
|
||||
token = theme_parse_file(scanner, &data->gap);
|
||||
break;
|
||||
case TOKEN_GAP_BORDER:
|
||||
token = theme_parse_border(scanner, &data->gap);
|
||||
break;
|
||||
case TOKEN_GAP_START_FILE:
|
||||
token = theme_parse_file(scanner, &data->gap_start);
|
||||
break;
|
||||
case TOKEN_GAP_START_BORDER:
|
||||
token = theme_parse_border(scanner, &data->gap_start);
|
||||
break;
|
||||
case TOKEN_GAP_END_FILE:
|
||||
token = theme_parse_file(scanner, &data->gap_end);
|
||||
break;
|
||||
case TOKEN_GAP_END_BORDER:
|
||||
token = theme_parse_border(scanner, &data->gap_end);
|
||||
break;
|
||||
case TOKEN_OVERLAY_FILE:
|
||||
token = theme_parse_file(scanner, &data->overlay);
|
||||
break;
|
||||
case TOKEN_OVERLAY_BORDER:
|
||||
token = theme_parse_border(scanner, &data->overlay);
|
||||
break;
|
||||
case TOKEN_OVERLAY_STRETCH:
|
||||
token = theme_parse_stretch(scanner, &data->overlay);
|
||||
break;
|
||||
default:
|
||||
g_scanner_get_next_token(scanner);
|
||||
token = G_TOKEN_RIGHT_CURLY;
|
||||
break;
|
||||
}
|
||||
if (token != G_TOKEN_NONE)
|
||||
{
|
||||
/* error - cleanup for exit */
|
||||
theme_image_unref (data);
|
||||
*data_return = NULL;
|
||||
return token;
|
||||
}
|
||||
token = g_scanner_peek_next_token(scanner);
|
||||
}
|
||||
|
||||
token = g_scanner_get_next_token(scanner);
|
||||
|
||||
if (token != G_TOKEN_RIGHT_CURLY)
|
||||
{
|
||||
/* error - cleanup for exit */
|
||||
theme_image_unref (data);
|
||||
*data_return = NULL;
|
||||
return G_TOKEN_RIGHT_CURLY;
|
||||
}
|
||||
|
||||
/* everything is fine now - insert yer cruft */
|
||||
*data_return = data;
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static guint
|
||||
pixbuf_rc_style_parse (GtkRcStyle *rc_style,
|
||||
GScanner *scanner)
|
||||
|
||||
{
|
||||
static GQuark scope_id = 0;
|
||||
PixbufRcStyle *pixbuf_style = PIXBUF_RC_STYLE (rc_style);
|
||||
|
||||
guint old_scope;
|
||||
guint token;
|
||||
gint i;
|
||||
ThemeImage *img;
|
||||
|
||||
/* Set up a new scope in this scanner. */
|
||||
|
||||
if (!scope_id)
|
||||
scope_id = g_quark_from_string("pixbuf_theme_engine");
|
||||
|
||||
/* If we bail out due to errors, we *don't* reset the scope, so the
|
||||
* error messaging code can make sense of our tokens.
|
||||
*/
|
||||
old_scope = g_scanner_set_scope(scanner, scope_id);
|
||||
|
||||
/* Now check if we already added our symbols to this scope
|
||||
* (in some previous call to theme_parse_rc_style for the
|
||||
* same scanner.
|
||||
*/
|
||||
|
||||
if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name))
|
||||
{
|
||||
g_scanner_freeze_symbol_table(scanner);
|
||||
for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++)
|
||||
g_scanner_scope_add_symbol(scanner, scope_id,
|
||||
theme_symbols[i].name,
|
||||
GINT_TO_POINTER(theme_symbols[i].token));
|
||||
g_scanner_thaw_symbol_table(scanner);
|
||||
}
|
||||
|
||||
/* We're ready to go, now parse the top level */
|
||||
|
||||
token = g_scanner_peek_next_token(scanner);
|
||||
while (token != G_TOKEN_RIGHT_CURLY)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case TOKEN_IMAGE:
|
||||
img = NULL;
|
||||
token = theme_parse_image(scanner, pixbuf_style, &img);
|
||||
break;
|
||||
default:
|
||||
g_scanner_get_next_token(scanner);
|
||||
token = G_TOKEN_RIGHT_CURLY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (token != G_TOKEN_NONE)
|
||||
return token;
|
||||
else
|
||||
pixbuf_style->img_list = g_list_append(pixbuf_style->img_list, img);
|
||||
|
||||
token = g_scanner_peek_next_token(scanner);
|
||||
}
|
||||
|
||||
g_scanner_get_next_token(scanner);
|
||||
|
||||
g_scanner_set_scope(scanner, old_scope);
|
||||
|
||||
return G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
pixbuf_rc_style_merge (GtkRcStyle *dest,
|
||||
GtkRcStyle *src)
|
||||
{
|
||||
if (PIXBUF_IS_RC_STYLE (src))
|
||||
{
|
||||
PixbufRcStyle *pixbuf_dest = PIXBUF_RC_STYLE (dest);
|
||||
PixbufRcStyle *pixbuf_src = PIXBUF_RC_STYLE (src);
|
||||
GList *tmp_list1, *tmp_list2;
|
||||
|
||||
if (pixbuf_src->img_list)
|
||||
{
|
||||
/* Copy src image list and append to dest image list */
|
||||
|
||||
tmp_list2 = g_list_last (pixbuf_dest->img_list);
|
||||
tmp_list1 = pixbuf_src->img_list;
|
||||
|
||||
while (tmp_list1)
|
||||
{
|
||||
if (tmp_list2)
|
||||
{
|
||||
tmp_list2->next = g_list_alloc();
|
||||
tmp_list2->next->data = tmp_list1->data;
|
||||
tmp_list2->next->prev = tmp_list2;
|
||||
|
||||
tmp_list2 = tmp_list2->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf_dest->img_list = g_list_append (NULL, tmp_list1->data);
|
||||
tmp_list2 = pixbuf_dest->img_list;
|
||||
}
|
||||
|
||||
theme_image_ref (tmp_list1->data);
|
||||
tmp_list1 = tmp_list1->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent_class->merge (dest, src);
|
||||
}
|
||||
|
||||
/* Create an empty style suitable to this RC style
|
||||
*/
|
||||
static GtkStyle *
|
||||
pixbuf_rc_style_create_style (GtkRcStyle *rc_style)
|
||||
{
|
||||
return GTK_STYLE (g_object_new (PIXBUF_TYPE_STYLE, NULL));
|
||||
}
|
||||
|
@@ -1,49 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include <gtk/gtkrc.h>
|
||||
|
||||
typedef struct _PixbufRcStyle PixbufRcStyle;
|
||||
typedef struct _PixbufRcStyleClass PixbufRcStyleClass;
|
||||
|
||||
extern GType pixbuf_type_rc_style;
|
||||
|
||||
#define PIXBUF_TYPE_RC_STYLE pixbuf_type_rc_style
|
||||
#define PIXBUF_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PIXBUF_TYPE_RC_STYLE, PixbufRcStyle))
|
||||
#define PIXBUF_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIXBUF_TYPE_RC_STYLE, PixbufRcStyleClass))
|
||||
#define PIXBUF_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PIXBUF_TYPE_RC_STYLE))
|
||||
#define PIXBUF_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIXBUF_TYPE_RC_STYLE))
|
||||
#define PIXBUF_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIXBUF_TYPE_RC_STYLE, PixbufRcStyleClass))
|
||||
|
||||
struct _PixbufRcStyle
|
||||
{
|
||||
GtkRcStyle parent_instance;
|
||||
|
||||
GList *img_list;
|
||||
};
|
||||
|
||||
struct _PixbufRcStyleClass
|
||||
{
|
||||
GtkRcStyleClass parent_class;
|
||||
};
|
||||
|
||||
void pixbuf_rc_style_register_type (GtkThemeEngine *engine);
|
@@ -1,365 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include "pixbuf.h"
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
GCache *pixbuf_cache = NULL;
|
||||
|
||||
/* Scale the rectangle (src_x, src_y, src_width, src_height)
|
||||
* onto the rectangle (dest_x, dest_y, dest_width, dest_height)
|
||||
* of the destination, clip by clip_rect and render
|
||||
*/
|
||||
static void
|
||||
pixbuf_render (GdkPixbuf *src,
|
||||
GdkWindow *window,
|
||||
GdkBitmap *mask,
|
||||
GdkRectangle *clip_rect,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint src_width,
|
||||
gint src_height,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint dest_width,
|
||||
gint dest_height)
|
||||
{
|
||||
GdkPixbuf *tmp_pixbuf;
|
||||
GdkRectangle rect;
|
||||
int x_offset, y_offset;
|
||||
gboolean has_alpha = gdk_pixbuf_get_has_alpha (src);
|
||||
gint src_rowstride = gdk_pixbuf_get_rowstride (src);
|
||||
gint src_n_channels = gdk_pixbuf_get_n_channels (src);
|
||||
|
||||
if (dest_width <= 0 || dest_height <= 0)
|
||||
return;
|
||||
|
||||
rect.x = dest_x;
|
||||
rect.y = dest_y;
|
||||
rect.width = dest_width;
|
||||
rect.height = dest_height;
|
||||
|
||||
/* FIXME: Because we use the mask to shape windows, we don't use
|
||||
* clip_rect to clip what we draw to the mask, only to clip
|
||||
* what we actually draw. But this leads to the horrible ineffiency
|
||||
* of scale the whole image to get a little bit of it.
|
||||
*/
|
||||
if (!mask && clip_rect)
|
||||
{
|
||||
/* The temporary is necessary only for GDK+-1.2, and not
|
||||
* for later versions of GDK, where you can have the
|
||||
* same source and dest for gdk_rectangle_intersect().
|
||||
*/
|
||||
GdkRectangle tmp_rect = rect;
|
||||
|
||||
if (!gdk_rectangle_intersect (clip_rect, &tmp_rect, &rect))
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest_width != src_width ||
|
||||
dest_height != src_height)
|
||||
{
|
||||
double x_scale = (double)dest_width / src_width;
|
||||
double y_scale = (double)dest_height / src_height;
|
||||
guchar *pixels;
|
||||
GdkPixbuf *partial_src;
|
||||
|
||||
pixels = (gdk_pixbuf_get_pixels (src)
|
||||
+ src_y * src_rowstride
|
||||
+ src_x * src_n_channels);
|
||||
|
||||
partial_src = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB,
|
||||
has_alpha,
|
||||
8, src_width, src_height,
|
||||
src_rowstride,
|
||||
NULL, NULL);
|
||||
|
||||
tmp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
has_alpha, 8,
|
||||
rect.width, rect.height);
|
||||
|
||||
gdk_pixbuf_scale (partial_src, tmp_pixbuf,
|
||||
0, 0, rect.width, rect.height,
|
||||
dest_x - rect.x, dest_y - rect.y,
|
||||
x_scale, y_scale,
|
||||
GDK_INTERP_BILINEAR);
|
||||
|
||||
gdk_pixbuf_unref (partial_src);
|
||||
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_pixbuf = src;
|
||||
gdk_pixbuf_ref (tmp_pixbuf);
|
||||
|
||||
x_offset = src_x + rect.x - dest_x;
|
||||
y_offset = src_y + rect.y - dest_y;
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
GdkGC *tmp_gc;
|
||||
|
||||
gdk_pixbuf_render_threshold_alpha (tmp_pixbuf, mask,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
128);
|
||||
|
||||
tmp_gc = gdk_gc_new (window);
|
||||
if (clip_rect)
|
||||
gdk_gc_set_clip_rectangle (tmp_gc, clip_rect);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (tmp_pixbuf, window, tmp_gc,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_gc_unref (tmp_gc);
|
||||
}
|
||||
else
|
||||
gdk_pixbuf_render_to_drawable_alpha (tmp_pixbuf, window,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
GDK_PIXBUF_ALPHA_BILEVEL, 128,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_pixbuf_unref (tmp_pixbuf);
|
||||
}
|
||||
|
||||
ThemePixbuf *
|
||||
theme_pixbuf_new (void)
|
||||
{
|
||||
ThemePixbuf *result = g_new (ThemePixbuf, 1);
|
||||
result->filename = NULL;
|
||||
result->pixbuf = NULL;
|
||||
|
||||
result->stretch = TRUE;
|
||||
result->border_left = 0;
|
||||
result->border_right = 0;
|
||||
result->border_bottom = 0;
|
||||
result->border_top = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_destroy (ThemePixbuf *theme_pb)
|
||||
{
|
||||
if (theme_pb->pixbuf)
|
||||
g_cache_remove (pixbuf_cache, theme_pb->pixbuf);
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_set_filename (ThemePixbuf *theme_pb,
|
||||
const char *filename)
|
||||
{
|
||||
if (theme_pb->pixbuf)
|
||||
{
|
||||
g_cache_remove (pixbuf_cache, theme_pb->pixbuf);
|
||||
theme_pb->pixbuf = NULL;
|
||||
}
|
||||
|
||||
if (theme_pb->filename)
|
||||
g_free (theme_pb->filename);
|
||||
|
||||
theme_pb->filename = g_strdup (filename);
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_set_border (ThemePixbuf *theme_pb,
|
||||
gint left,
|
||||
gint right,
|
||||
gint top,
|
||||
gint bottom)
|
||||
{
|
||||
theme_pb->border_left = left;
|
||||
theme_pb->border_right = right;
|
||||
theme_pb->border_top = top;
|
||||
theme_pb->border_bottom = bottom;
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_set_stretch (ThemePixbuf *theme_pb,
|
||||
gboolean stretch)
|
||||
{
|
||||
theme_pb->stretch = stretch;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
pixbuf_cache_value_new (gchar *filename)
|
||||
{
|
||||
GdkPixbuf *result = gdk_pixbuf_new_from_file (filename);
|
||||
if (!result)
|
||||
g_warning("Pixbuf theme: Cannot load pixmap file %s\n", filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
theme_pixbuf_get_pixbuf (ThemePixbuf *theme_pb)
|
||||
{
|
||||
if (!theme_pb->pixbuf)
|
||||
{
|
||||
if (!pixbuf_cache)
|
||||
pixbuf_cache = g_cache_new ((GCacheNewFunc)pixbuf_cache_value_new,
|
||||
(GCacheDestroyFunc)gdk_pixbuf_unref,
|
||||
(GCacheDupFunc)g_strdup,
|
||||
(GCacheDestroyFunc)g_free,
|
||||
g_str_hash, g_direct_hash, g_str_equal);
|
||||
|
||||
theme_pb->pixbuf = g_cache_insert (pixbuf_cache, theme_pb->filename);
|
||||
}
|
||||
|
||||
return theme_pb->pixbuf;
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_render (ThemePixbuf *theme_pb,
|
||||
GdkWindow *window,
|
||||
GdkBitmap *mask,
|
||||
GdkRectangle *clip_rect,
|
||||
guint component_mask,
|
||||
gboolean center,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkPixbuf *pixbuf = theme_pixbuf_get_pixbuf (theme_pb);
|
||||
gint src_x[4], src_y[4], dest_x[4], dest_y[4];
|
||||
gint pixbuf_width = gdk_pixbuf_get_width (pixbuf);
|
||||
gint pixbuf_height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
if (!pixbuf)
|
||||
return;
|
||||
|
||||
if (theme_pb->stretch)
|
||||
{
|
||||
src_x[0] = 0;
|
||||
src_x[1] = theme_pb->border_left;
|
||||
src_x[2] = pixbuf_width - theme_pb->border_right;
|
||||
src_x[3] = pixbuf_width;
|
||||
|
||||
src_y[0] = 0;
|
||||
src_y[1] = theme_pb->border_top;
|
||||
src_y[2] = pixbuf_height - theme_pb->border_bottom;
|
||||
src_y[3] = pixbuf_height;
|
||||
|
||||
dest_x[0] = x;
|
||||
dest_x[1] = x + theme_pb->border_left;
|
||||
dest_x[2] = x + width - theme_pb->border_right;
|
||||
dest_x[3] = x + width;
|
||||
|
||||
dest_y[0] = y;
|
||||
dest_y[1] = y + theme_pb->border_top;
|
||||
dest_y[2] = y + height - theme_pb->border_bottom;
|
||||
dest_y[3] = y + height;
|
||||
|
||||
if (component_mask & COMPONENT_ALL)
|
||||
component_mask = (COMPONENT_ALL - 1) & ~component_mask;
|
||||
|
||||
#define RENDER_COMPONENT(X1,X2,Y1,Y2) \
|
||||
pixbuf_render (pixbuf, window, mask, clip_rect, \
|
||||
src_x[X1], src_y[Y1], \
|
||||
src_x[X2] - src_x[X1], src_y[Y2] - src_y[Y1], \
|
||||
dest_x[X1], dest_y[Y1], \
|
||||
dest_x[X2] - dest_x[X1], dest_y[Y2] - dest_y[Y1]);
|
||||
|
||||
if (component_mask & COMPONENT_NORTH_WEST)
|
||||
RENDER_COMPONENT (0, 1, 0, 1);
|
||||
|
||||
if (component_mask & COMPONENT_NORTH)
|
||||
RENDER_COMPONENT (1, 2, 0, 1);
|
||||
|
||||
if (component_mask & COMPONENT_NORTH_EAST)
|
||||
RENDER_COMPONENT (2, 3, 0, 1);
|
||||
|
||||
if (component_mask & COMPONENT_WEST)
|
||||
RENDER_COMPONENT (0, 1, 1, 2);
|
||||
|
||||
if (component_mask & COMPONENT_CENTER)
|
||||
RENDER_COMPONENT (1, 2, 1, 2);
|
||||
|
||||
if (component_mask & COMPONENT_EAST)
|
||||
RENDER_COMPONENT (2, 3, 1, 2);
|
||||
|
||||
if (component_mask & COMPONENT_SOUTH_WEST)
|
||||
RENDER_COMPONENT (0, 1, 2, 3);
|
||||
|
||||
if (component_mask & COMPONENT_SOUTH)
|
||||
RENDER_COMPONENT (1, 2, 2, 3);
|
||||
|
||||
if (component_mask & COMPONENT_SOUTH_EAST)
|
||||
RENDER_COMPONENT (2, 3, 2, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (center)
|
||||
{
|
||||
x += (width - pixbuf_width) / 2;
|
||||
y += (height - pixbuf_height) / 2;
|
||||
|
||||
pixbuf_render (pixbuf, window, NULL, clip_rect,
|
||||
0, 0,
|
||||
pixbuf_width, pixbuf_height,
|
||||
x, y,
|
||||
pixbuf_width, pixbuf_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkPixmap *tmp_pixmap;
|
||||
GdkGC *tmp_gc;
|
||||
GdkGCValues gc_values;
|
||||
|
||||
tmp_pixmap = gdk_pixmap_new (window,
|
||||
pixbuf_width,
|
||||
pixbuf_height,
|
||||
-1);
|
||||
tmp_gc = gdk_gc_new (tmp_pixmap);
|
||||
gdk_pixbuf_render_to_drawable (pixbuf, tmp_pixmap, tmp_gc,
|
||||
0, 0,
|
||||
0, 0,
|
||||
pixbuf_width, pixbuf_height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_gc_unref (tmp_gc);
|
||||
|
||||
gc_values.fill = GDK_TILED;
|
||||
gc_values.tile = tmp_pixmap;
|
||||
tmp_gc = gdk_gc_new_with_values (window,
|
||||
&gc_values, GDK_GC_FILL | GDK_GC_TILE);
|
||||
if (clip_rect)
|
||||
gdk_draw_rectangle (window, tmp_gc, TRUE,
|
||||
clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
|
||||
else
|
||||
gdk_draw_rectangle (window, tmp_gc, TRUE, x, y, width, height);
|
||||
|
||||
gdk_gc_unref (tmp_gc);
|
||||
gdk_pixmap_unref (tmp_pixmap);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include <gtk/gtkstyle.h>
|
||||
|
||||
typedef struct _PixbufStyle PixbufStyle;
|
||||
typedef struct _PixbufStyleClass PixbufStyleClass;
|
||||
|
||||
extern GType pixbuf_type_style;
|
||||
|
||||
#define PIXBUF_TYPE_STYLE pixbuf_type_style
|
||||
#define PIXBUF_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PIXBUF_TYPE_STYLE, PixbufStyle))
|
||||
#define PIXBUF_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIXBUF_TYPE_STYLE, PixbufStyleClass))
|
||||
#define PIXBUF_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PIXBUF_TYPE_STYLE))
|
||||
#define PIXBUF_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIXBUF_TYPE_STYLE))
|
||||
#define PIXBUF_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIXBUF_TYPE_STYLE, PixbufStyleClass))
|
||||
|
||||
struct _PixbufStyle
|
||||
{
|
||||
GtkStyle parent_instance;
|
||||
};
|
||||
|
||||
struct _PixbufStyleClass
|
||||
{
|
||||
GtkStyleClass parent_class;
|
||||
};
|
||||
|
||||
void pixbuf_style_register_type (GtkThemeEngine *engine);
|
||||
|
||||
|
@@ -1,188 +0,0 @@
|
||||
/* GTK+ Pixbuf Engine
|
||||
* Copyright (C) 1998-2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
/* internals */
|
||||
|
||||
typedef struct _ThemeData ThemeData;
|
||||
typedef struct _ThemeImage ThemeImage;
|
||||
typedef struct _ThemeMatchData ThemeMatchData;
|
||||
typedef struct _ThemePixbuf ThemePixbuf;
|
||||
|
||||
enum
|
||||
{
|
||||
TOKEN_IMAGE = G_TOKEN_LAST + 1,
|
||||
TOKEN_FUNCTION,
|
||||
TOKEN_FILE,
|
||||
TOKEN_STRETCH,
|
||||
TOKEN_RECOLORABLE,
|
||||
TOKEN_BORDER,
|
||||
TOKEN_DETAIL,
|
||||
TOKEN_STATE,
|
||||
TOKEN_SHADOW,
|
||||
TOKEN_GAP_SIDE,
|
||||
TOKEN_GAP_FILE,
|
||||
TOKEN_GAP_BORDER,
|
||||
TOKEN_GAP_START_FILE,
|
||||
TOKEN_GAP_START_BORDER,
|
||||
TOKEN_GAP_END_FILE,
|
||||
TOKEN_GAP_END_BORDER,
|
||||
TOKEN_OVERLAY_FILE,
|
||||
TOKEN_OVERLAY_BORDER,
|
||||
TOKEN_OVERLAY_STRETCH,
|
||||
TOKEN_ARROW_DIRECTION,
|
||||
TOKEN_D_HLINE,
|
||||
TOKEN_D_VLINE,
|
||||
TOKEN_D_SHADOW,
|
||||
TOKEN_D_POLYGON,
|
||||
TOKEN_D_ARROW,
|
||||
TOKEN_D_DIAMOND,
|
||||
TOKEN_D_OVAL,
|
||||
TOKEN_D_STRING,
|
||||
TOKEN_D_BOX,
|
||||
TOKEN_D_FLAT_BOX,
|
||||
TOKEN_D_CHECK,
|
||||
TOKEN_D_OPTION,
|
||||
TOKEN_D_CROSS,
|
||||
TOKEN_D_RAMP,
|
||||
TOKEN_D_TAB,
|
||||
TOKEN_D_SHADOW_GAP,
|
||||
TOKEN_D_BOX_GAP,
|
||||
TOKEN_D_EXTENSION,
|
||||
TOKEN_D_FOCUS,
|
||||
TOKEN_D_SLIDER,
|
||||
TOKEN_D_ENTRY,
|
||||
TOKEN_D_HANDLE,
|
||||
TOKEN_TRUE,
|
||||
TOKEN_FALSE,
|
||||
TOKEN_TOP,
|
||||
TOKEN_UP,
|
||||
TOKEN_BOTTOM,
|
||||
TOKEN_DOWN,
|
||||
TOKEN_LEFT,
|
||||
TOKEN_RIGHT,
|
||||
TOKEN_NORMAL,
|
||||
TOKEN_ACTIVE,
|
||||
TOKEN_PRELIGHT,
|
||||
TOKEN_SELECTED,
|
||||
TOKEN_INSENSITIVE,
|
||||
TOKEN_NONE,
|
||||
TOKEN_IN,
|
||||
TOKEN_OUT,
|
||||
TOKEN_ETCHED_IN,
|
||||
TOKEN_ETCHED_OUT,
|
||||
TOKEN_ORIENTATION,
|
||||
TOKEN_HORIZONTAL,
|
||||
TOKEN_VERTICAL,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMPONENT_NORTH_WEST = 1 << 0,
|
||||
COMPONENT_NORTH = 1 << 1,
|
||||
COMPONENT_NORTH_EAST = 1 << 2,
|
||||
COMPONENT_WEST = 1 << 3,
|
||||
COMPONENT_CENTER = 1 << 4,
|
||||
COMPONENT_EAST = 1 << 5,
|
||||
COMPONENT_SOUTH_EAST = 1 << 6,
|
||||
COMPONENT_SOUTH = 1 << 7,
|
||||
COMPONENT_SOUTH_WEST = 1 << 8,
|
||||
COMPONENT_ALL = 1 << 9
|
||||
} ThemePixbufComponent;
|
||||
|
||||
typedef enum {
|
||||
THEME_MATCH_GAP_SIDE = 1 << 0,
|
||||
THEME_MATCH_ORIENTATION = 1 << 1,
|
||||
THEME_MATCH_STATE = 1 << 2,
|
||||
THEME_MATCH_SHADOW = 1 << 3,
|
||||
THEME_MATCH_ARROW_DIRECTION = 1 << 4
|
||||
} ThemeMatchFlags;
|
||||
|
||||
struct _ThemePixbuf
|
||||
{
|
||||
gchar *filename;
|
||||
GdkPixbuf *pixbuf;
|
||||
gboolean stretch;
|
||||
gint border_left;
|
||||
gint border_right;
|
||||
gint border_bottom;
|
||||
gint border_top;
|
||||
};
|
||||
|
||||
struct _ThemeMatchData
|
||||
{
|
||||
guint function; /* Mandatory */
|
||||
gchar *detail;
|
||||
|
||||
ThemeMatchFlags flags;
|
||||
|
||||
GtkPositionType gap_side;
|
||||
GtkOrientation orientation;
|
||||
GtkStateType state;
|
||||
GtkShadowType shadow;
|
||||
GtkArrowType arrow_direction;
|
||||
};
|
||||
|
||||
struct _ThemeImage
|
||||
{
|
||||
guint refcount;
|
||||
|
||||
ThemePixbuf *background;
|
||||
ThemePixbuf *overlay;
|
||||
ThemePixbuf *gap_start;
|
||||
ThemePixbuf *gap;
|
||||
ThemePixbuf *gap_end;
|
||||
|
||||
gchar recolorable;
|
||||
|
||||
ThemeMatchData match_data;
|
||||
};
|
||||
|
||||
|
||||
ThemePixbuf *theme_pixbuf_new (void);
|
||||
void theme_pixbuf_destroy (ThemePixbuf *theme_pb);
|
||||
void theme_pixbuf_set_filename (ThemePixbuf *theme_pb,
|
||||
const char *filename);
|
||||
GdkPixbuf * theme_pixbuf_get_pixbuf (ThemePixbuf *theme_pb);
|
||||
void theme_pixbuf_set_border (ThemePixbuf *theme_pb,
|
||||
gint left,
|
||||
gint right,
|
||||
gint top,
|
||||
gint bottom);
|
||||
void theme_pixbuf_set_stretch (ThemePixbuf *theme_pb,
|
||||
gboolean stretch);
|
||||
void theme_pixbuf_render (ThemePixbuf *theme_pb,
|
||||
GdkWindow *window,
|
||||
GdkBitmap *mask,
|
||||
GdkRectangle *clip_rect,
|
||||
guint component_mask,
|
||||
gboolean center,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint dest_width,
|
||||
gint dest_height);
|
||||
|
||||
|
||||
|
||||
extern GtkStyleClass pixmap_default_class;
|
@@ -2,5 +2,5 @@ Makefile.in
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
*.la
|
||||
*.lo
|
42
modules/input/Makefile.am
Normal file
42
modules/input/Makefile.am
Normal file
@@ -0,0 +1,42 @@
|
||||
## Makefile.am for gtk+/demos
|
||||
|
||||
INCLUDES = @STRIP_BEGIN@ \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir)/gdk \
|
||||
-DGTK_DISABLE_COMPAT_H \
|
||||
-DGTK_LOCALEDIR=\"$(gtklocaledir)\" \
|
||||
@GTK_DEBUG_FLAGS@ \
|
||||
@GTK_XIM_FLAGS@ \
|
||||
@GTK_LOCALE_FLAGS@ \
|
||||
@PANGO_CFLAGS@ \
|
||||
@GLIB_CFLAGS@ \
|
||||
@more_cflags@ \
|
||||
@STRIP_END@
|
||||
|
||||
DEPS = \
|
||||
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la \
|
||||
$(top_builddir)/gdk/@gdktargetlib@ \
|
||||
$(top_builddir)/gtk/@gtktargetlib@
|
||||
|
||||
LDADDS = @STRIP_BEGIN@ \
|
||||
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la \
|
||||
$(top_builddir)/gdk/@gdktargetlib@ \
|
||||
$(top_builddir)/gtk/@gtktargetlib@ \
|
||||
@more_ldflags@ \
|
||||
@more_libs@ \
|
||||
@GDK_WLIBS@ \
|
||||
@PANGO_LIBS@ \
|
||||
@GLIB_LIBS@ \
|
||||
@GTK_LIBS_EXTRA@ \
|
||||
-lm \
|
||||
@STRIP_END@
|
||||
|
||||
moduledir = $(libdir)/gtk+/gtk-2.0/$(GTK_VERSION)/immodules
|
||||
module_LTLIBRARIES = im-cyrillic-translit.la im-xim.la
|
||||
|
||||
im_cyrillic_translit_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module
|
||||
im_cyrillic_translit_la_SOURCES = imcyrillic-translit.c
|
||||
|
||||
im_xim_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module
|
||||
im_xim_la_SOURCES = gtkimcontextxim.c imxim.c
|
||||
|
744
modules/input/gtkimcontextxim.c
Normal file
744
modules/input/gtkimcontextxim.c
Normal file
@@ -0,0 +1,744 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "locale.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "gtk/gtksignal.h"
|
||||
#include "gtkimcontextxim.h"
|
||||
|
||||
struct _GtkXIMInfo
|
||||
{
|
||||
XIM im;
|
||||
char *locale;
|
||||
XIMStyle style;
|
||||
};
|
||||
|
||||
static void gtk_im_context_xim_class_init (GtkIMContextXIMClass *class);
|
||||
static void gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim);
|
||||
static void gtk_im_context_xim_finalize (GObject *obj);
|
||||
static void gtk_im_context_xim_set_client_window (GtkIMContext *context,
|
||||
GdkWindow *client_window);
|
||||
static gboolean gtk_im_context_xim_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *key);
|
||||
static void gtk_im_context_xim_reset (GtkIMContext *context);
|
||||
static void gtk_im_context_xim_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos);
|
||||
|
||||
static XIC gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim);
|
||||
static GObjectClass *parent_class;
|
||||
|
||||
GType gtk_type_im_context_xim = 0;
|
||||
|
||||
static GSList *open_ims = NULL;
|
||||
|
||||
void
|
||||
gtk_im_context_xim_register_type (GtkModule *module)
|
||||
{
|
||||
static const GTypeInfo im_context_xim_info =
|
||||
{
|
||||
sizeof (GtkIMContextXIMClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gtk_im_context_xim_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextXIM),
|
||||
0,
|
||||
(GtkObjectInitFunc) gtk_im_context_xim_init,
|
||||
};
|
||||
|
||||
gtk_type_im_context_xim =
|
||||
gtk_module_register_type (module,
|
||||
GTK_TYPE_IM_CONTEXT,
|
||||
"GtkIMContextXIM",
|
||||
&im_context_xim_info);
|
||||
}
|
||||
|
||||
#define PREEDIT_MASK (XIMPreeditCallbacks | XIMPreeditPosition | \
|
||||
XIMPreeditArea | XIMPreeditNothing | XIMPreeditNone)
|
||||
#define STATUS_MASK (XIMStatusCallbacks | XIMStatusArea | \
|
||||
XIMStatusNothing | XIMStatusNone)
|
||||
#define ALLOWED_MASK (XIMPreeditCallbacks | XIMPreeditNothing | XIMPreeditNone | \
|
||||
XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone)
|
||||
|
||||
static XIMStyle
|
||||
choose_better_style (XIMStyle style1, XIMStyle style2)
|
||||
{
|
||||
XIMStyle s1, s2, u;
|
||||
|
||||
if (style1 == 0) return style2;
|
||||
if (style2 == 0) return style1;
|
||||
if ((style1 & (PREEDIT_MASK | STATUS_MASK))
|
||||
== (style2 & (PREEDIT_MASK | STATUS_MASK)))
|
||||
return style1;
|
||||
|
||||
s1 = style1 & PREEDIT_MASK;
|
||||
s2 = style2 & PREEDIT_MASK;
|
||||
u = s1 | s2;
|
||||
if (s1 != s2) {
|
||||
if (u & XIMPreeditCallbacks)
|
||||
return (s1 == XIMPreeditCallbacks) ? style1 : style2;
|
||||
else if (u & XIMPreeditPosition)
|
||||
return (s1 == XIMPreeditPosition) ? style1 :style2;
|
||||
else if (u & XIMPreeditArea)
|
||||
return (s1 == XIMPreeditArea) ? style1 : style2;
|
||||
else if (u & XIMPreeditNothing)
|
||||
return (s1 == XIMPreeditNothing) ? style1 : style2;
|
||||
} else {
|
||||
s1 = style1 & STATUS_MASK;
|
||||
s2 = style2 & STATUS_MASK;
|
||||
u = s1 | s2;
|
||||
if (u & XIMStatusCallbacks)
|
||||
return (s1 == XIMStatusCallbacks) ? style1 : style2;
|
||||
else if (u & XIMStatusArea)
|
||||
return (s1 == XIMStatusArea) ? style1 : style2;
|
||||
else if (u & XIMStatusNothing)
|
||||
return (s1 == XIMStatusNothing) ? style1 : style2;
|
||||
else if (u & XIMStatusNone)
|
||||
return (s1 == XIMStatusNone) ? style1 : style2;
|
||||
}
|
||||
return 0; /* Get rid of stupid warning */
|
||||
}
|
||||
|
||||
static void
|
||||
setup_im (GtkXIMInfo *info)
|
||||
{
|
||||
XIMStyles *xim_styles;
|
||||
XIMValuesList *ic_values;
|
||||
int i;
|
||||
|
||||
XGetIMValues (info->im,
|
||||
XNQueryInputStyle, &xim_styles,
|
||||
XNQueryICValuesList, &ic_values);
|
||||
|
||||
info->style = 0;
|
||||
for (i = 0; i < xim_styles->count_styles; i++)
|
||||
if ((xim_styles->supported_styles[i] & ALLOWED_MASK) == xim_styles->supported_styles[i])
|
||||
info->style = choose_better_style (info->style,
|
||||
xim_styles->supported_styles[i]);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < ic_values->count_values; i++)
|
||||
g_print ("%s\n", ic_values->supported_values[i]);
|
||||
for (i = 0; i < xim_styles->count_styles; i++)
|
||||
g_print ("%#x\n", xim_styles->supported_styles[i]);
|
||||
#endif
|
||||
|
||||
XFree (xim_styles);
|
||||
XFree (ic_values);
|
||||
}
|
||||
|
||||
static GtkXIMInfo *
|
||||
get_im (const char *locale)
|
||||
{
|
||||
GSList *tmp_list = open_ims;
|
||||
GtkXIMInfo *info;
|
||||
XIM im = NULL;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
info = tmp_list->data;
|
||||
if (!strcmp (info->locale, locale))
|
||||
return info;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
info = NULL;
|
||||
|
||||
if (XSupportsLocale ())
|
||||
{
|
||||
if (!XSetLocaleModifiers (""))
|
||||
g_warning ("can not set locale modifiers");
|
||||
|
||||
im = XOpenIM (GDK_DISPLAY(), NULL, NULL, NULL);
|
||||
|
||||
if (im)
|
||||
{
|
||||
info = g_new (GtkXIMInfo, 1);
|
||||
open_ims = g_slist_prepend (open_ims, im);
|
||||
|
||||
info->locale = g_strdup (locale);
|
||||
info->im = im;
|
||||
|
||||
setup_im (info);
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_class_init (GtkIMContextXIMClass *class)
|
||||
{
|
||||
GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
im_context_class->set_client_window = gtk_im_context_xim_set_client_window;
|
||||
im_context_class->filter_keypress = gtk_im_context_xim_filter_keypress;
|
||||
im_context_class->reset = gtk_im_context_xim_reset;
|
||||
im_context_class->get_preedit_string = gtk_im_context_xim_get_preedit_string;
|
||||
gobject_class->finalize = gtk_im_context_xim_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_finalize (GObject *obj)
|
||||
{
|
||||
GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (obj);
|
||||
|
||||
if (context_xim->ic)
|
||||
{
|
||||
XDestroyIC (context_xim->ic);
|
||||
context_xim->ic = NULL;
|
||||
}
|
||||
|
||||
g_free (context_xim->mb_charset);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_set_client_window (GtkIMContext *context,
|
||||
GdkWindow *client_window)
|
||||
{
|
||||
GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
|
||||
|
||||
if (context_xim->ic)
|
||||
{
|
||||
XDestroyIC (context_xim->ic);
|
||||
context_xim->ic = NULL;
|
||||
}
|
||||
|
||||
context_xim->client_window = client_window;
|
||||
}
|
||||
|
||||
GtkIMContext *
|
||||
gtk_im_context_xim_new (void)
|
||||
{
|
||||
GtkXIMInfo *info;
|
||||
GtkIMContextXIM *result;
|
||||
gchar *charset;
|
||||
|
||||
info = get_im (setlocale (LC_CTYPE, NULL));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
result = GTK_IM_CONTEXT_XIM (gtk_type_new (GTK_TYPE_IM_CONTEXT_XIM));
|
||||
|
||||
result->im_info = info;
|
||||
|
||||
g_get_charset (&charset);
|
||||
result->mb_charset = g_strdup (charset);
|
||||
|
||||
return GTK_IM_CONTEXT (result);
|
||||
}
|
||||
|
||||
static char *
|
||||
mb_to_utf8 (GtkIMContextXIM *context_xim,
|
||||
const char *str)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *result;
|
||||
|
||||
result = g_convert (str, -1,
|
||||
"UTF-8", context_xim->mb_charset,
|
||||
NULL, NULL, &error);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
g_warning ("Error converting text from IM to UTF-8: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_im_context_xim_filter_keypress (GtkIMContext *context,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
|
||||
XIC ic = gtk_im_context_xim_get_ic (context_xim);
|
||||
gchar static_buffer[256];
|
||||
gchar *buffer = static_buffer;
|
||||
gint buffer_size = sizeof(static_buffer) - 1;
|
||||
gint num_bytes = 0;
|
||||
KeySym keysym;
|
||||
Status status;
|
||||
gboolean result = FALSE;
|
||||
|
||||
XKeyPressedEvent xevent;
|
||||
|
||||
if (!ic)
|
||||
return FALSE;
|
||||
|
||||
xevent.type = KeyPress;
|
||||
xevent.serial = 0; /* hope it doesn't matter */
|
||||
xevent.send_event = event->send_event;
|
||||
xevent.display = GDK_DRAWABLE_XDISPLAY (event->window);
|
||||
xevent.window = GDK_DRAWABLE_XID (event->window);
|
||||
xevent.root = GDK_ROOT_WINDOW();
|
||||
xevent.subwindow = xevent.window;
|
||||
xevent.time = event->time;
|
||||
xevent.x = xevent.x_root = 0;
|
||||
xevent.y = xevent.y_root = 0;
|
||||
xevent.state = event->state;
|
||||
xevent.keycode = event->keyval ? XKeysymToKeycode (xevent.display, event->keyval) : 0;
|
||||
xevent.same_screen = True;
|
||||
|
||||
if (XFilterEvent ((XEvent *)&xevent, GDK_DRAWABLE_XID (context_xim->client_window)))
|
||||
return TRUE;
|
||||
|
||||
again:
|
||||
num_bytes = XmbLookupString (ic, &xevent, buffer, buffer_size, &keysym, &status);
|
||||
|
||||
if (status == XBufferOverflow)
|
||||
{
|
||||
buffer_size = num_bytes;
|
||||
buffer = g_malloc (num_bytes + 1);
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* I don't know how we should properly handle XLookupKeysym or XLookupBoth
|
||||
* here ... do input methods actually change the keysym? we can't really
|
||||
* feed it back to accelerator processing at this point...
|
||||
*/
|
||||
if (status == XLookupChars || status == XLookupBoth)
|
||||
{
|
||||
char *result_utf8;
|
||||
|
||||
buffer[num_bytes] = '\0';
|
||||
|
||||
result_utf8 = mb_to_utf8 (context_xim, buffer);
|
||||
if (result_utf8)
|
||||
{
|
||||
if ((guchar)result_utf8[0] >= 0x20) /* Some IM have a nasty habit of converting
|
||||
* control characters into strings
|
||||
*/
|
||||
{
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "commit", result_utf8);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
g_free (result_utf8);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_reset (GtkIMContext *context)
|
||||
{
|
||||
GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
|
||||
XIC ic = gtk_im_context_xim_get_ic (context_xim);
|
||||
gchar *result;
|
||||
|
||||
if (!ic)
|
||||
return;
|
||||
|
||||
result = XmbResetIC (ic);
|
||||
|
||||
if (result)
|
||||
{
|
||||
char *result_utf8 = mb_to_utf8 (context_xim, result);
|
||||
if (result_utf8)
|
||||
{
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "commit", result_utf8);
|
||||
g_free (result_utf8);
|
||||
}
|
||||
}
|
||||
|
||||
if (context_xim->preedit_length)
|
||||
{
|
||||
context_xim->preedit_length = 0;
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "preedit-changed");
|
||||
}
|
||||
|
||||
XFree (result);
|
||||
}
|
||||
|
||||
/* Mask of feedback bits that we render
|
||||
*/
|
||||
#define FEEDBACK_MASK (XIMReverse | XIMUnderline)
|
||||
|
||||
static void
|
||||
add_feedback_attr (PangoAttrList *attrs,
|
||||
const gchar *str,
|
||||
XIMFeedback feedback,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
PangoAttribute *attr;
|
||||
|
||||
gint start_index = g_utf8_offset_to_pointer (str, start_pos) - str;
|
||||
gint end_index = g_utf8_offset_to_pointer (str, end_pos) - str;
|
||||
|
||||
if (feedback & XIMUnderline)
|
||||
{
|
||||
attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
|
||||
attr->start_index = start_index;
|
||||
attr->end_index = end_index;
|
||||
|
||||
pango_attr_list_change (attrs, attr);
|
||||
}
|
||||
|
||||
if (feedback & XIMReverse)
|
||||
{
|
||||
attr = pango_attr_foreground_new (0xffff, 0xffff, 0xffff);
|
||||
attr->start_index = start_index;
|
||||
attr->end_index = end_index;
|
||||
|
||||
pango_attr_list_change (attrs, attr);
|
||||
|
||||
attr = pango_attr_background_new (0, 0, 0);
|
||||
attr->start_index = start_index;
|
||||
attr->end_index = end_index;
|
||||
|
||||
pango_attr_list_change (attrs, attr);
|
||||
}
|
||||
|
||||
if (feedback & ~FEEDBACK_MASK)
|
||||
g_warning ("Unrendered feedback style: %#lx", feedback & ~FEEDBACK_MASK);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_xim_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
PangoAttrList **attrs,
|
||||
gint *cursor_pos)
|
||||
{
|
||||
GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
|
||||
gchar *utf8 = g_ucs4_to_utf8 (context_xim->preedit_chars, context_xim->preedit_length);
|
||||
|
||||
if (attrs)
|
||||
{
|
||||
int i;
|
||||
XIMFeedback last_feedback = 0;
|
||||
gint start = -1;
|
||||
|
||||
*attrs = pango_attr_list_new ();
|
||||
|
||||
for (i = 0; i < context_xim->preedit_length; i++)
|
||||
{
|
||||
XIMFeedback new_feedback = context_xim->feedbacks[i] & FEEDBACK_MASK;
|
||||
if (new_feedback != last_feedback)
|
||||
{
|
||||
if (start >= 0)
|
||||
add_feedback_attr (*attrs, utf8, last_feedback, start, i);
|
||||
|
||||
last_feedback = new_feedback;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (start >= 0)
|
||||
add_feedback_attr (*attrs, utf8, last_feedback, start, i);
|
||||
}
|
||||
|
||||
if (str)
|
||||
*str = utf8;
|
||||
else
|
||||
g_free (utf8);
|
||||
|
||||
if (cursor_pos)
|
||||
*cursor_pos = context_xim->preedit_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
preedit_start_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XPointer call_data)
|
||||
{
|
||||
GtkIMContext *context = GTK_IM_CONTEXT (client_data);
|
||||
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "preedit_start");
|
||||
g_print ("Starting preedit!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
preedit_done_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XPointer call_data)
|
||||
{
|
||||
GtkIMContext *context = GTK_IM_CONTEXT (client_data);
|
||||
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "preedit_end");
|
||||
g_print ("Ending preedit!\n");
|
||||
}
|
||||
|
||||
static gint
|
||||
xim_text_to_utf8 (GtkIMContextXIM *context, XIMText *xim_text, gchar **text)
|
||||
{
|
||||
gint text_length = 0;
|
||||
GError *error = NULL;
|
||||
gchar *result = NULL;
|
||||
|
||||
if (xim_text && xim_text->string.multi_byte)
|
||||
{
|
||||
if (xim_text->encoding_is_wchar)
|
||||
{
|
||||
g_warning ("Wide character return from Xlib not currently supported");
|
||||
*text = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = g_convert (xim_text->string.multi_byte,
|
||||
-1,
|
||||
"UTF-8",
|
||||
context->mb_charset,
|
||||
NULL, &text_length, &error);
|
||||
|
||||
if (result)
|
||||
{
|
||||
text_length = g_utf8_strlen (result, -1);
|
||||
|
||||
if (text_length != xim_text->length)
|
||||
{
|
||||
g_warning ("Size mismatch when converting text from input method: supplied length = %d\n, result length = %d", xim_text->length, text_length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Error converting text from IM to UCS-4: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
*text = result;
|
||||
return text_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*text = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
preedit_draw_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XIMPreeditDrawCallbackStruct *call_data)
|
||||
{
|
||||
GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
|
||||
|
||||
XIMText *new_xim_text = call_data->text;
|
||||
gint new_text_length;
|
||||
gunichar *new_text = NULL;
|
||||
gint i;
|
||||
gint diff;
|
||||
gint new_length;
|
||||
gchar *tmp;
|
||||
|
||||
gint chg_first = CLAMP (call_data->chg_first, 0, context->preedit_length);
|
||||
gint chg_length = CLAMP (call_data->chg_length, 0, context->preedit_length - chg_first);
|
||||
|
||||
context->preedit_cursor = call_data->caret;
|
||||
|
||||
if (chg_first != call_data->chg_first || chg_length != call_data->chg_length)
|
||||
g_warning ("Invalid change to preedit string, first=%d length=%d (orig length == %d)",
|
||||
call_data->chg_first, call_data->chg_length, context->preedit_length);
|
||||
|
||||
new_text_length = xim_text_to_utf8 (context, new_xim_text, &tmp);
|
||||
if (tmp)
|
||||
{
|
||||
new_text = g_utf8_to_ucs4 (tmp, -1);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
diff = new_text_length - chg_length;
|
||||
new_length = context->preedit_length + diff;
|
||||
|
||||
if (new_length > context->preedit_size)
|
||||
{
|
||||
context->preedit_size = new_length;
|
||||
context->preedit_chars = g_renew (gunichar, context->preedit_chars, new_length);
|
||||
context->feedbacks = g_renew (XIMFeedback, context->feedbacks, new_length);
|
||||
}
|
||||
|
||||
if (diff < 0)
|
||||
{
|
||||
for (i = chg_first + chg_length ; i < context->preedit_length; i++)
|
||||
{
|
||||
context->preedit_chars[i + diff] = context->preedit_chars[i];
|
||||
context->feedbacks[i + diff] = context->feedbacks[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = context->preedit_length - 1; i >= chg_first + chg_length ; i--)
|
||||
{
|
||||
context->preedit_chars[i + diff] = context->preedit_chars[i];
|
||||
context->feedbacks[i + diff] = context->feedbacks[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < new_text_length; i++)
|
||||
{
|
||||
context->preedit_chars[chg_first + i] = new_text[i];
|
||||
context->feedbacks[chg_first + i] = new_xim_text->feedback[i];
|
||||
}
|
||||
|
||||
context->preedit_length += diff;
|
||||
|
||||
if (new_text)
|
||||
g_free (new_text);
|
||||
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "preedit-changed");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
preedit_caret_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XIMPreeditCaretCallbackStruct *call_data)
|
||||
{
|
||||
GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
|
||||
|
||||
if (call_data->direction == XIMAbsolutePosition)
|
||||
{
|
||||
context->preedit_cursor = call_data->position;
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (context), "preedit-changed");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Caret movement command: %d %d %d not supported",
|
||||
call_data->position, call_data->direction, call_data->style);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
status_start_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XPointer call_data)
|
||||
{
|
||||
g_print ("Status start\n");
|
||||
}
|
||||
|
||||
static void
|
||||
status_done_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XPointer call_data)
|
||||
{
|
||||
g_print ("Status done!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
status_draw_callback (XIC xic,
|
||||
XPointer client_data,
|
||||
XIMStatusDrawCallbackStruct *call_data)
|
||||
{
|
||||
GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
|
||||
|
||||
g_print ("Status draw\n");
|
||||
if (call_data->type == XIMTextType)
|
||||
{
|
||||
gchar *text;
|
||||
xim_text_to_utf8 (context, call_data->data.text, &text);
|
||||
|
||||
if (text)
|
||||
g_print (" %s\n", text);
|
||||
}
|
||||
else /* bitmap */
|
||||
{
|
||||
g_print (" bitmap id = %#lx\n", call_data->data.bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
static XIC
|
||||
gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim)
|
||||
{
|
||||
const char *name1 = NULL;
|
||||
XVaNestedList *list1 = NULL;
|
||||
const char *name2 = NULL;
|
||||
XVaNestedList *list2 = NULL;
|
||||
|
||||
if (!context_xim->ic && context_xim->client_window)
|
||||
{
|
||||
if ((context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditCallbacks)
|
||||
{
|
||||
context_xim->preedit_start_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->preedit_start_callback.callback = (XIMProc)preedit_start_callback;
|
||||
context_xim->preedit_done_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->preedit_done_callback.callback = (XIMProc)preedit_done_callback;
|
||||
context_xim->preedit_draw_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->preedit_draw_callback.callback = (XIMProc)preedit_draw_callback;
|
||||
context_xim->preedit_caret_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->preedit_caret_callback.callback = (XIMProc)preedit_caret_callback;
|
||||
|
||||
name1 = XNPreeditAttributes;
|
||||
list1 = XVaCreateNestedList (0,
|
||||
XNPreeditStartCallback, &context_xim->preedit_start_callback,
|
||||
XNPreeditDoneCallback, &context_xim->preedit_done_callback,
|
||||
XNPreeditDrawCallback, &context_xim->preedit_draw_callback,
|
||||
XNPreeditCaretCallback, &context_xim->preedit_caret_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusCallbacks)
|
||||
{
|
||||
XVaNestedList *status_attrs;
|
||||
|
||||
context_xim->status_start_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->status_start_callback.callback = (XIMProc)status_start_callback;
|
||||
context_xim->status_done_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->status_done_callback.callback = (XIMProc)status_done_callback;
|
||||
context_xim->status_draw_callback.client_data = (XPointer)context_xim;
|
||||
context_xim->status_draw_callback.callback = (XIMProc)status_draw_callback;
|
||||
|
||||
status_attrs = XVaCreateNestedList (0,
|
||||
XNStatusStartCallback, &context_xim->status_start_callback,
|
||||
XNStatusDoneCallback, &context_xim->status_done_callback,
|
||||
XNStatusDrawCallback, &context_xim->status_draw_callback,
|
||||
NULL);
|
||||
|
||||
if (name1 == NULL)
|
||||
{
|
||||
name1 = XNStatusAttributes;
|
||||
list1 = status_attrs;
|
||||
}
|
||||
else
|
||||
{
|
||||
name2 = XNStatusAttributes;
|
||||
list2 = status_attrs;
|
||||
}
|
||||
}
|
||||
|
||||
context_xim->ic = XCreateIC (context_xim->im_info->im,
|
||||
XNInputStyle, context_xim->im_info->style,
|
||||
XNClientWindow, GDK_DRAWABLE_XID (context_xim->client_window),
|
||||
name1, list1,
|
||||
name2, list2,
|
||||
NULL);
|
||||
|
||||
if (list1)
|
||||
XFree (list1);
|
||||
if (list2)
|
||||
XFree (list2);
|
||||
}
|
||||
|
||||
return context_xim->ic;
|
||||
}
|
89
modules/input/gtkimcontextxim.h
Normal file
89
modules/input/gtkimcontextxim.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat Software
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_IM_CONTEXT_XIM_H__
|
||||
#define __GTK_IM_CONTEXT_XIM_H__
|
||||
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkmodule.h>
|
||||
#include "x11/gdkx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
extern GType gtk_type_im_context_xim;
|
||||
|
||||
#define GTK_TYPE_IM_CONTEXT_XIM gtk_type_im_context_xim
|
||||
#define GTK_IM_CONTEXT_XIM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
|
||||
#define GTK_IM_CONTEXT_XIM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
|
||||
#define GTK_IS_IM_CONTEXT_XIM(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
|
||||
#define GTK_IS_IM_CONTEXT_XIM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
|
||||
#define GTK_IM_CONTEXT_XIM_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
|
||||
|
||||
|
||||
typedef struct _GtkIMContextXIM GtkIMContextXIM;
|
||||
typedef struct _GtkIMContextXIMClass GtkIMContextXIMClass;
|
||||
|
||||
typedef struct _GtkXIMInfo GtkXIMInfo;
|
||||
|
||||
struct _GtkIMContextXIM
|
||||
{
|
||||
GtkIMContext object;
|
||||
|
||||
GtkXIMInfo *im_info;
|
||||
|
||||
gchar *mb_charset;
|
||||
|
||||
GdkWindow *client_window;
|
||||
|
||||
gint preedit_size;
|
||||
gint preedit_length;
|
||||
gunichar *preedit_chars;
|
||||
XIMFeedback *feedbacks;
|
||||
|
||||
gint preedit_cursor;
|
||||
|
||||
XIMCallback preedit_start_callback;
|
||||
XIMCallback preedit_done_callback;
|
||||
XIMCallback preedit_draw_callback;
|
||||
XIMCallback preedit_caret_callback;
|
||||
|
||||
XIMCallback status_start_callback;
|
||||
XIMCallback status_done_callback;
|
||||
XIMCallback status_draw_callback;
|
||||
|
||||
XIC ic;
|
||||
};
|
||||
|
||||
struct _GtkIMContextXIMClass
|
||||
{
|
||||
GtkIMContextClass parent_class;
|
||||
};
|
||||
|
||||
void gtk_im_context_xim_register_type (GtkModule *module);
|
||||
GtkIMContext *gtk_im_context_xim_new (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __GTK_IM_CONTEXT_XIM_H__ */
|
253
modules/input/imcyrillic-translit.c
Normal file
253
modules/input/imcyrillic-translit.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat Software
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Owen Taylor <otaylor@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "gtk/gtkintl.h"
|
||||
#include "gtk/gtkimcontextsimple.h"
|
||||
#include "gtk/gtkimmodule.h"
|
||||
#include "gtk/gtkmodule.h"
|
||||
|
||||
GType type_cyrillic_translit = 0;
|
||||
|
||||
static void cyrillic_translit_class_init (GtkIMContextSimpleClass *class);
|
||||
static void cyrillic_translit_init (GtkIMContextSimple *im_context);
|
||||
|
||||
static void
|
||||
cyrillic_translit_register_type (GtkModule *module)
|
||||
{
|
||||
static const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (GtkIMContextSimpleClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) cyrillic_translit_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkIMContextSimple),
|
||||
0,
|
||||
(GtkObjectInitFunc) cyrillic_translit_init,
|
||||
};
|
||||
|
||||
type_cyrillic_translit =
|
||||
gtk_module_register_type (module,
|
||||
GTK_TYPE_IM_CONTEXT_SIMPLE,
|
||||
"GtkIMContextCyrillicTranslit",
|
||||
&object_info);
|
||||
}
|
||||
|
||||
/* The sequences here match the sequences used in the emacs quail
|
||||
* mode cryllic-translit; they allow entering all characters
|
||||
* in iso-8859-5
|
||||
*/
|
||||
static guint16 cyrillic_compose_seqs[] = {
|
||||
GDK_apostrophe, 0, 0, 0, 0, 0x44C, /* CYRILLIC SMALL LETTER SOFT SIGN */
|
||||
GDK_apostrophe, GDK_apostrophe, 0, 0, 0, 0x42C, /* CYRILLIC CAPITAL LETTER SOFT SIGN */
|
||||
GDK_slash, GDK_C, GDK_H, 0, 0, 0x040B, /* CYRILLIC CAPITAL LETTER TSHE */
|
||||
GDK_slash, GDK_C, GDK_h, 0, 0, 0x040B, /* CYRILLIC CAPITAL LETTER TSHE */
|
||||
GDK_slash, GDK_D, 0, 0, 0, 0x0402, /* CYRILLIC CAPITAL LETTER DJE */
|
||||
GDK_slash, GDK_E, 0, 0, 0, 0x0404, /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */
|
||||
GDK_slash, GDK_G, 0, 0, 0, 0x0403, /* CYRILLIC CAPITAL LETTER GJE */
|
||||
GDK_slash, GDK_I, 0, 0, 0, 0x0406, /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
|
||||
GDK_slash, GDK_J, 0, 0, 0, 0x0408, /* CYRILLIC CAPITAL LETTER JE */
|
||||
GDK_slash, GDK_K, 0, 0, 0, 0x040C, /* CYRILLIC CAPITAL LETTER KJE */
|
||||
GDK_slash, GDK_L, 0, 0, 0, 0x0409, /* CYRILLIC CAPITAL LETTER LJE */
|
||||
GDK_slash, GDK_N, 0, 0, 0, 0x040A, /* CYRILLIC CAPITAL LETTER NJE */
|
||||
GDK_slash, GDK_S, 0, 0, 0, 0x0405, /* CYRILLIC CAPITAL LETTER DZE */
|
||||
GDK_slash, GDK_S, GDK_H, GDK_T, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCH */
|
||||
GDK_slash, GDK_S, GDK_H, GDK_t, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCH */
|
||||
GDK_slash, GDK_S, GDK_h, GDK_t, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCH */
|
||||
GDK_slash, GDK_T, 0, 0, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCH */
|
||||
GDK_slash, GDK_Z, 0, 0, 0, 0x040F, /* CYRILLIC CAPITAL LETTER DZHE */
|
||||
GDK_slash, GDK_c, GDK_h, 0, 0, 0x045B, /* CYRILLIC SMALL LETTER TSHE */
|
||||
GDK_slash, GDK_d, 0, 0, 0, 0x0452, /* CYRILLIC SMALL LETTER DJE */
|
||||
GDK_slash, GDK_e, 0, 0, 0, 0x0454, /* CYRILLIC SMALL LETTER UKRAINIAN IE */
|
||||
GDK_slash, GDK_g, 0, 0, 0, 0x0453, /* CYRILLIC SMALL LETTER GJE */
|
||||
GDK_slash, GDK_i, 0, 0, 0, 0x0456, /* CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
|
||||
GDK_slash, GDK_j, 0, 0, 0, 0x0458, /* CYRILLIC SMALL LETTER JE */
|
||||
GDK_slash, GDK_k, 0, 0, 0, 0x045C, /* CYRILLIC SMALL LETTER KJE */
|
||||
GDK_slash, GDK_l, 0, 0, 0, 0x0459, /* CYRILLIC SMALL LETTER LJE */
|
||||
GDK_slash, GDK_n, 0, 0, 0, 0x045A, /* CYRILLIC SMALL LETTER NJE */
|
||||
GDK_slash, GDK_s, 0, 0, 0, 0x0455, /* CYRILLIC SMALL LETTER DZE */
|
||||
GDK_slash, GDK_s, GDK_h, GDK_t, 0, 0x0449, /* CYRILLIC SMALL LETTER SHCH */
|
||||
GDK_slash, GDK_t, 0, 0, 0, 0x0449, /* CYRILLIC SMALL LETTER SHCH */
|
||||
GDK_slash, GDK_z, 0, 0, 0, 0x045F, /* CYRILLIC SMALL LETTER DZHE */
|
||||
GDK_A, 0, 0, 0, 0, 0x0410, /* CYRILLIC CAPITAL LETTER A */
|
||||
GDK_B, 0, 0, 0, 0, 0x0411, /* CYRILLIC CAPITAL LETTER BE */
|
||||
GDK_C, 0, 0, 0, 0, 0x0426, /* CYRILLIC CAPITAL LETTER TSE */
|
||||
GDK_C, GDK_H, 0, 0, 0, 0x0427, /* CYRILLIC CAPITAL LETTER CHE */
|
||||
GDK_C, GDK_h, 0, 0, 0, 0x0427, /* CYRILLIC CAPITAL LETTER CHE */
|
||||
GDK_D, 0, 0, 0, 0, 0x0414, /* CYRILLIC CAPITAL LETTER DE */
|
||||
GDK_E, 0, 0, 0, 0, 0x0415, /* CYRILLIC CAPITAL LETTER IE */
|
||||
GDK_E, GDK_apostrophe, 0, 0, 0, 0x042D, /* CYRILLIC CAPITAL LETTER E */
|
||||
GDK_F, 0, 0, 0, 0, 0x0424, /* CYRILLIC CAPITAL LETTER EF */
|
||||
GDK_G, 0, 0, 0, 0, 0x0413, /* CYRILLIC CAPITAL LETTER GE */
|
||||
GDK_H, 0, 0, 0, 0, 0x0425, /* CYRILLIC CAPITAL LETTER HA */
|
||||
GDK_I, 0, 0, 0, 0, 0x0418, /* CYRILLIC CAPITAL LETTER I */
|
||||
GDK_J, 0, 0, 0, 0, 0x0419, /* CYRILLIC CAPITAL LETTER SHORT I */
|
||||
GDK_J, GDK_apostrophe, 0, 0, 0, 0x0419, /* CYRILLIC CAPITAL LETTER SHORT I */
|
||||
GDK_J, GDK_A, 0, 0, 0, 0x042F, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_J, GDK_I, 0, 0, 0, 0x0407, /* CYRILLIC CAPITAL LETTER YI */
|
||||
GDK_J, GDK_O, 0, 0, 0, 0x0401, /* CYRILLIC CAPITAL LETTER YO */
|
||||
GDK_J, GDK_U, 0, 0, 0, 0x042E, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_J, GDK_a, 0, 0, 0, 0x042F, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_J, GDK_i, 0, 0, 0, 0x0407, /* CYRILLIC CAPITAL LETTER YI */
|
||||
GDK_J, GDK_o, 0, 0, 0, 0x0401, /* CYRILLIC CAPITAL LETTER YO */
|
||||
GDK_J, GDK_u, 0, 0, 0, 0x042E, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_K, 0, 0, 0, 0, 0x041A, /* CYRILLIC CAPITAL LETTER KA */
|
||||
GDK_K, GDK_H, 0, 0, 0, 0x0425, /* CYRILLIC CAPITAL LETTER HA */
|
||||
GDK_L, 0, 0, 0, 0, 0x041B, /* CYRILLIC CAPITAL LETTER EL */
|
||||
GDK_M, 0, 0, 0, 0, 0x041C, /* CYRILLIC CAPITAL LETTER EM */
|
||||
GDK_N, 0, 0, 0, 0, 0x041D, /* CYRILLIC CAPITAL LETTER EN */
|
||||
GDK_O, 0, 0, 0, 0, 0x041E, /* CYRILLIC CAPITAL LETTER O */
|
||||
GDK_P, 0, 0, 0, 0, 0x041F, /* CYRILLIC CAPITAL LETTER PE */
|
||||
GDK_Q, 0, 0, 0, 0, 0x042F, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_R, 0, 0, 0, 0, 0x0420, /* CYRILLIC CAPITAL LETTER ER */
|
||||
GDK_S, 0, 0, 0, 0, 0x0421, /* CYRILLIC CAPITAL LETTER ES */
|
||||
GDK_S, GDK_H, 0, 0, 0, 0x0428, /* CYRILLIC CAPITAL LETTER SHA */
|
||||
GDK_S, GDK_H, GDK_C, GDK_H, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_S, GDK_H, GDK_C, GDK_h, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_S, GDK_H, GDK_c, GDK_h, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_S, GDK_H, GDK_c, GDK_h, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_S, GDK_J, 0, 0, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_S, GDK_h, 0, 0, 0, 0x0428, /* CYRILLIC CAPITAL LETTER SHA */
|
||||
GDK_S, GDK_j, 0, 0, 0, 0x0429, /* CYRILLIC CAPITAL LETTER SHCA */
|
||||
GDK_T, 0, 0, 0, 0, 0x0422, /* CYRILLIC CAPITAL LETTER TE */
|
||||
GDK_U, 0, 0, 0, 0, 0x0423, /* CYRILLIC CAPITAL LETTER U */
|
||||
GDK_U, GDK_apostrophe, 0, 0, 0, 0x040E, /* CYRILLIC CAPITAL LETTER SHORT */
|
||||
GDK_V, 0, 0, 0, 0, 0x0412, /* CYRILLIC CAPITAL LETTER VE */
|
||||
GDK_W, 0, 0, 0, 0, 0x0412, /* CYRILLIC CAPITAL LETTER VE */
|
||||
GDK_X, 0, 0, 0, 0, 0x0425, /* CYRILLIC CAPITAL LETTER HA */
|
||||
GDK_Y, 0, 0, 0, 0, 0x042B, /* CYRILLIC CAPITAL LETTER YERU */
|
||||
GDK_Y, GDK_A, 0, 0, 0, 0x042F, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_Y, GDK_I, 0, 0, 0, 0x0407, /* CYRILLIC CAPITAL LETTER YI */
|
||||
GDK_Y, GDK_O, 0, 0, 0, 0x0401, /* CYRILLIC CAPITAL LETTER YO */
|
||||
GDK_Y, GDK_U, 0, 0, 0, 0x042E, /* CYRILLIC CAPITAL LETTER YU */
|
||||
GDK_Y, GDK_a, 0, 0, 0, 0x042F, /* CYRILLIC CAPITAL LETTER YA */
|
||||
GDK_Y, GDK_i, 0, 0, 0, 0x0407, /* CYRILLIC CAPITAL LETTER YI */
|
||||
GDK_Y, GDK_o, 0, 0, 0, 0x0401, /* CYRILLIC CAPITAL LETTER YO */
|
||||
GDK_Y, GDK_u, 0, 0, 0, 0x042E, /* CYRILLIC CAPITAL LETTER YU */
|
||||
GDK_Z, 0, 0, 0, 0, 0x0417, /* CYRILLIC CAPITAL LETTER ZE */
|
||||
GDK_Z, GDK_H, 0, 0, 0, 0x0416, /* CYRILLIC CAPITAL LETTER ZHE */
|
||||
GDK_Z, GDK_h, 0, 0, 0, 0x0416, /* CYRILLIC CAPITAL LETTER ZHE */
|
||||
GDK_a, 0, 0, 0, 0, 0x0430, /* CYRILLIC SMALL LETTER A */
|
||||
GDK_b, 0, 0, 0, 0, 0x0431, /* CYRILLIC SMALL LETTER BE */
|
||||
GDK_c, 0, 0, 0, 0, 0x0446, /* CYRILLIC SMALL LETTER TSE */
|
||||
GDK_c, GDK_h, 0, 0, 0, 0x0447, /* CYRILLIC SMALL LETTER CHE */
|
||||
GDK_d, 0, 0, 0, 0, 0x0434, /* CYRILLIC SMALL LETTER DE */
|
||||
GDK_e, 0, 0, 0, 0, 0x0435, /* CYRILLIC SMALL LETTER IE */
|
||||
GDK_e, GDK_apostrophe, 0, 0, 0, 0x044D, /* CYRILLIC SMALL LETTER E */
|
||||
GDK_f, 0, 0, 0, 0, 0x0444, /* CYRILLIC SMALL LETTER EF */
|
||||
GDK_g, 0, 0, 0, 0, 0x0433, /* CYRILLIC SMALL LETTER GE */
|
||||
GDK_h, 0, 0, 0, 0, 0x0445, /* CYRILLIC SMALL LETTER HA */
|
||||
GDK_i, 0, 0, 0, 0, 0x0438, /* CYRILLIC SMALL LETTER I */
|
||||
GDK_j, 0, 0, 0, 0, 0x0439, /* CYRILLIC SMALL LETTER SHORT I */
|
||||
GDK_j, GDK_apostrophe, 0, 0, 0, 0x0439, /* CYRILLIC SMALL LETTER SHORT I */
|
||||
GDK_j, GDK_a, 0, 0, 0, 0x044F, /* CYRILLIC SMALL LETTER YU */
|
||||
GDK_j, GDK_i, 0, 0, 0, 0x0457, /* CYRILLIC SMALL LETTER YI */
|
||||
GDK_j, GDK_o, 0, 0, 0, 0x0451, /* CYRILLIC SMALL LETTER YO */
|
||||
GDK_j, GDK_u, 0, 0, 0, 0x044E, /* CYRILLIC SMALL LETTER YA */
|
||||
GDK_k, 0, 0, 0, 0, 0x043A, /* CYRILLIC SMALL LETTER KA */
|
||||
GDK_k, GDK_h, 0, 0, 0, 0x0445, /* CYRILLIC SMALL LETTER HA */
|
||||
GDK_l, 0, 0, 0, 0, 0x043B, /* CYRILLIC SMALL LETTER EL */
|
||||
GDK_m, 0, 0, 0, 0, 0x043C, /* CYRILLIC SMALL LETTER EM */
|
||||
GDK_n, 0, 0, 0, 0, 0x043D, /* CYRILLIC SMALL LETTER EN */
|
||||
GDK_o, 0, 0, 0, 0, 0x043E, /* CYRILLIC SMALL LETTER O */
|
||||
GDK_p, 0, 0, 0, 0, 0x043F, /* CYRILLIC SMALL LETTER PE */
|
||||
GDK_q, 0, 0, 0, 0, 0x044F, /* CYRILLIC SMALL LETTER YA */
|
||||
GDK_r, 0, 0, 0, 0, 0x0440, /* CYRILLIC SMALL LETTER ER */
|
||||
GDK_s, 0, 0, 0, 0, 0x0441, /* CYRILLIC SMALL LETTER ES */
|
||||
GDK_s, GDK_h, 0, 0, 0, 0x0448, /* CYRILLIC SMALL LETTER SHA */
|
||||
GDK_s, GDK_h, GDK_c, GDK_h, 0, 0x0449, /* CYRILLIC SMALL LETTER SHCA */
|
||||
GDK_s, GDK_j, 0, 0, 0, 0x0449, /* CYRILLIC SMALL LETTER SHCA */
|
||||
GDK_t, 0, 0, 0, 0, 0x0442, /* CYRILLIC SMALL LETTER TE */
|
||||
GDK_u, 0, 0, 0, 0, 0x0443, /* CYRILLIC SMALL LETTER U */
|
||||
GDK_u, GDK_apostrophe, 0, 0, 0, 0x045E, /* CYRILLIC SMALL LETTER SHORT */
|
||||
GDK_v, 0, 0, 0, 0, 0x0432, /* CYRILLIC SMALL LETTER VE */
|
||||
GDK_w, 0, 0, 0, 0, 0x0432, /* CYRILLIC SMALL LETTER VE */
|
||||
GDK_x, 0, 0, 0, 0, 0x0445, /* CYRILLIC SMALL LETTER HA */
|
||||
GDK_y, 0, 0, 0, 0, 0x044B, /* CYRILLIC SMALL LETTER YERU */
|
||||
GDK_y, GDK_a, 0, 0, 0, 0x044F, /* CYRILLIC SMALL LETTER YU */
|
||||
GDK_y, GDK_i, 0, 0, 0, 0x0457, /* CYRILLIC SMALL LETTER YI */
|
||||
GDK_y, GDK_o, 0, 0, 0, 0x0451, /* CYRILLIC SMALL LETTER YO */
|
||||
GDK_y, GDK_u, 0, 0, 0, 0x044E, /* CYRILLIC SMALL LETTER YA */
|
||||
GDK_z, 0, 0, 0, 0, 0x0437, /* CYRILLIC SMALL LETTER ZE */
|
||||
GDK_z, GDK_h, 0, 0, 0, 0x0436, /* CYRILLIC SMALL LETTER ZHE */
|
||||
GDK_asciitilde, 0, 0, 0, 0, 0x44A, /* CYRILLIC SMALL LETTER HARD SIGN */
|
||||
GDK_asciitilde, GDK_asciitilde, 0, 0, 0, 0x42A, /* CYRILLIC CAPITAL LETTER HARD SIGN */
|
||||
};
|
||||
|
||||
static void
|
||||
cyrillic_translit_class_init (GtkIMContextSimpleClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
cyrillic_translit_init (GtkIMContextSimple *im_context)
|
||||
{
|
||||
gtk_im_context_simple_add_table (im_context,
|
||||
cyrillic_compose_seqs,
|
||||
4,
|
||||
G_N_ELEMENTS (cyrillic_compose_seqs) / (4 + 2));
|
||||
}
|
||||
|
||||
static const GtkIMContextInfo cyrillic_translit_info = {
|
||||
"cyrillic_translit", /* ID */
|
||||
N_("Cyrillic (Transliterated)"), /* Human readable name */
|
||||
"gtk+", /* Translation domain */
|
||||
GTK_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */
|
||||
"" /* Languages for which this module is the default */
|
||||
};
|
||||
|
||||
static const GtkIMContextInfo *info_list[] = {
|
||||
&cyrillic_translit_info
|
||||
};
|
||||
|
||||
void
|
||||
im_module_init (GtkModule *module)
|
||||
{
|
||||
cyrillic_translit_register_type (module);
|
||||
}
|
||||
|
||||
void
|
||||
im_module_exit (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
im_module_list (const GtkIMContextInfo ***contexts,
|
||||
int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
GtkIMContext *
|
||||
im_module_create (const gchar *context_id)
|
||||
{
|
||||
if (strcmp (context_id, "cyrillic_translit") == 0)
|
||||
return GTK_IM_CONTEXT (gtk_type_new (type_cyrillic_translit));
|
||||
else
|
||||
return NULL;
|
||||
}
|
63
modules/input/imxim.c
Normal file
63
modules/input/imxim.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gtk/gtkintl.h"
|
||||
#include "gtk/gtkimmodule.h"
|
||||
#include "gtkimcontextxim.h"
|
||||
#include <string.h>
|
||||
|
||||
static const GtkIMContextInfo xim_ja_info = {
|
||||
"xim", /* ID */
|
||||
N_("X Input Method"), /* Human readable name */
|
||||
"gtk+", /* Translation domain */
|
||||
GTK_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */
|
||||
"ja" /* Languages for which this module is the default */
|
||||
};
|
||||
|
||||
static const GtkIMContextInfo *info_list[] = {
|
||||
&xim_ja_info
|
||||
};
|
||||
|
||||
void
|
||||
im_module_init (GtkModule *module)
|
||||
{
|
||||
gtk_im_context_xim_register_type (module);
|
||||
}
|
||||
|
||||
void
|
||||
im_module_exit (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
im_module_list (const GtkIMContextInfo ***contexts,
|
||||
int *n_contexts)
|
||||
{
|
||||
*contexts = info_list;
|
||||
*n_contexts = G_N_ELEMENTS (info_list);
|
||||
}
|
||||
|
||||
GtkIMContext *
|
||||
im_module_create (const gchar *context_id)
|
||||
{
|
||||
if (strcmp (context_id, "xim") == 0)
|
||||
return gtk_im_context_xim_new ();
|
||||
else
|
||||
return NULL;
|
||||
}
|
@@ -8746,11 +8746,14 @@ create_main_window (void)
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
||||
void
|
||||
pixbuf_init ()
|
||||
static void
|
||||
test_init ()
|
||||
{
|
||||
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
{
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -8760,7 +8763,7 @@ main (int argc, char *argv[])
|
||||
|
||||
srand (time (NULL));
|
||||
|
||||
pixbuf_init ();
|
||||
test_init ();
|
||||
gtk_set_locale ();
|
||||
|
||||
/* Check to see if we are being run from the correct
|
||||
|
@@ -1419,15 +1419,33 @@ create_view (Buffer *buffer)
|
||||
return view;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_exists (const char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
return stat (filename, &statbuf) == 0;
|
||||
}
|
||||
void
|
||||
test_init ()
|
||||
{
|
||||
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
|
||||
{
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
Buffer *buffer;
|
||||
View *view;
|
||||
int i;
|
||||
|
||||
|
||||
test_init ();
|
||||
gtk_set_locale ();
|
||||
gtk_init (&argc, &argv);
|
||||
gdk_rgb_init (); /* FIXME remove this */
|
||||
|
||||
buffer = create_buffer ();
|
||||
view = create_view (buffer);
|
||||
|
Reference in New Issue
Block a user