Compare commits

...

13 Commits

Author SHA1 Message Date
Owen Taylor
257e0f26ef Rip out support for multiple locales; that simple doesn't work reliably
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]:
2000-09-19 15:17:13 +00:00
Owen Taylor
f787ebb03f Start at XIM input method module.
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.
2000-09-19 04:01:21 +00:00
Owen Taylor
5d24f08d0a Handle empty attribute lists properly.
Mon Sep 18 11:50:51 2000  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtktextlayout.c (add_preedit_attrs): Handle
	empty attribute lists properly.
2000-09-18 17:38:05 +00:00
Owen Taylor
f3eb790c9e Return non-zero exit status if errors were encountered querying any
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.
2000-09-18 15:42:55 +00:00
Owen Taylor
9624060bda added input/ to subdirs 2000-09-16 18:07:54 +00:00
Owen Taylor
d24b426b92 Add modules/input/Makefile
Sat Sep 16 14:04:30 2000  Owen Taylor  <otaylor@redhat.com>

	* configure.in: Add modules/input/Makefile
2000-09-16 18:06:13 +00:00
Owen Taylor
f109da8d74 include gtkmodule.h gtkoldeditable.h, don't include gtkthemes.h.
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.
2000-09-16 18:02:58 +00:00
Owen Taylor
e31ae4384b Add gtk_text_layout_set_preedit_string() to set preedit string and
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.
2000-09-16 17:46:57 +00:00
Owen Taylor
850653e8c7 Adopt to match above changes.
* gtk/gtktext.c gtk/gtkcombo.c gtk/gtkspinbutton.c:
	Adopt to match above changes.
2000-09-16 17:38:14 +00:00
Owen Taylor
cc7c62e0e2 Convert GtkEditable from a class into an interface
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.c 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.
2000-09-16 17:29:50 +00:00
Owen Taylor
0dcf14976d Add the ability to add extra tables beyond the default one, and also the
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.
2000-09-16 17:23:29 +00:00
Owen Taylor
4ca0a710cd Support routines for loading GtkIMContext implementations dynamically at
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.
2000-09-16 17:15:52 +00:00
Owen Taylor
6ae1449a66 Move most of the generic code from gtkthemes into a new abstraction
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.
2000-09-16 17:11:25 +00:00
66 changed files with 8154 additions and 6567 deletions

167
ChangeLog
View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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])

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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>

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
View 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
View 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__

View File

@@ -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);
}
}

View File

@@ -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
View 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 = &gtk_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
View 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
View 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
View 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__ */

View File

@@ -184,7 +184,6 @@ gtk_preview_init (GtkPreview *preview)
void
gtk_preview_uninit (void)
{
/* unimplemented */
}

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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,

View File

@@ -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 == &gtk_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 == &gtk_text_right_mark_type ||
seg->type == &gtk_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 != &gtk_text_right_mark_type &&
seg->next->type != &gtk_text_left_mark_type &&
seg->next->type != &gtk_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 == &gtk_text_right_mark_type ||
seg->type == &gtk_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
}

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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 = &gtk_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;
}

View File

@@ -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
View 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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -1 +1 @@
SUBDIRS=linux-fb
SUBDIRS=linux-fb input

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -2,5 +2,5 @@ Makefile.in
Makefile
.deps
.libs
*.lo
*.la
*.la
*.lo

42
modules/input/Makefile.am Normal file
View 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

View 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;
}

View 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__ */

View 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
View 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;
}

View File

@@ -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

View File

@@ -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);