annotate src/gccache-gtk.c @ 4976:16112448d484

Rename xfree(FOO, TYPE) -> xfree(FOO) -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-02-04 Ben Wing <ben@xemacs.org> * alloc.c (release_breathing_space): * alloc.c (resize_string): * alloc.c (sweep_lcrecords_1): * alloc.c (SWEEP_FIXED_TYPE_BLOCK_1): * alloc.c (ADDITIONAL_FREE_compiled_function): * alloc.c (compact_string_chars): * alloc.c (ADDITIONAL_FREE_string): * alloc.c (sweep_strings): * alloca.c (xemacs_c_alloca): * alsaplay.c (alsa_play_sound_file): * buffer.c (init_initial_directory): * buffer.h: * buffer.h (BUFFER_FREE): * console-stream.c (stream_delete_console): * console-tty.c (free_tty_console_struct): * data.c (Fnumber_to_string): * device-gtk.c (gtk_init_device): * device-gtk.c (free_gtk_device_struct): * device-gtk.c (gtk_delete_device): * device-msw.c (mswindows_delete_device): * device-msw.c (msprinter_delete_device): * device-tty.c (free_tty_device_struct): * device-tty.c (tty_delete_device): * device-x.c (x_init_device): * device-x.c (free_x_device_struct): * device-x.c (x_delete_device): * dialog-msw.c (handle_directory_dialog_box): * dialog-x.c (dbox_descriptor_to_widget_value): * dired-msw.c (Fmswindows_insert_directory): * dired.c (free_user_cache): * dired.c (user_name_completion_unwind): * doc.c (unparesseuxify_doc_string): * doc.c (Fsubstitute_command_keys): * doprnt.c (emacs_doprnt_1): * dumper.c (pdump_load_finish): * dumper.c (pdump_file_free): * dumper.c (pdump_file_unmap): * dynarr.c: * dynarr.c (Dynarr_free): * editfns.c (uncache_home_directory): * editfns.c (Fset_time_zone_rule): * elhash.c: * elhash.c (pdump_reorganize_hash_table): * elhash.c (maphash_unwind): * emacs.c (make_arg_list_1): * emacs.c (free_argc_argv): * emacs.c (sort_args): * emacs.c (Frunning_temacs_p): * emodules.c (attempt_module_delete): * eval.c (free_pointer): * event-Xt.c (unselect_filedesc): * event-Xt.c (emacs_Xt_select_process): * event-gtk.c (unselect_filedesc): * event-gtk.c (dragndrop_data_received): * event-msw.c (winsock_closer): * event-msw.c (mswindows_dde_callback): * event-msw.c (mswindows_wnd_proc): * event-stream.c (finalize_command_builder): * event-stream.c (free_command_builder): * extents.c (free_gap_array): * extents.c (free_extent_list): * extents.c (free_soe): * extents.c (extent_fragment_delete): * extents.c (extent_priority_sort_function): * file-coding.c (make_coding_system_1): * file-coding.c (coding_finalizer): * file-coding.c (set_coding_stream_coding_system): * file-coding.c (chain_finalize_coding_stream_1): * file-coding.c (chain_finalize): * file-coding.c (free_detection_state): * file-coding.c (coding_category_symbol_to_id): * fileio.c: * fileio.c (Ffile_name_directory): * fileio.c (if): * fileio.c (Ffile_symlink_p): * filelock.c (FREE_LOCK_INFO): * filelock.c (current_lock_owner): * font-mgr.c (Ffc_name_unparse): * font-mgr.c (Ffc_pattern_duplicate): * frame-gtk.c (gtk_delete_frame): * frame-msw.c (mswindows_delete_frame): * frame-msw.c (msprinter_delete_frame): * frame-x.c (x_cde_destroy_callback): * frame-x.c (Fcde_start_drag_internal): * frame-x.c (x_cde_transfer_callback): * frame-x.c (x_delete_frame): * frame.c (update_frame_title): * frame.c (Fset_frame_pointer): * gc.c (register_for_finalization): * gccache-gtk.c (free_gc_cache): * gccache-gtk.c (gc_cache_lookup): * gccache-x.c (free_gc_cache): * gccache-x.c (gc_cache_lookup): * glyphs-eimage.c: * glyphs-eimage.c (jpeg_instantiate_unwind): * glyphs-eimage.c (gif_instantiate_unwind): * glyphs-eimage.c (png_instantiate_unwind): * glyphs-eimage.c (png_instantiate): * glyphs-eimage.c (tiff_instantiate_unwind): * glyphs-gtk.c (convert_EImage_to_GDKImage): * glyphs-gtk.c (gtk_finalize_image_instance): * glyphs-gtk.c (gtk_init_image_instance_from_eimage): * glyphs-gtk.c (gtk_xpm_instantiate): * glyphs-msw.c (convert_EImage_to_DIBitmap): * glyphs-msw.c (mswindows_init_image_instance_from_eimage): * glyphs-msw.c (mswindows_initialize_image_instance_mask): * glyphs-msw.c (xpm_to_eimage): * glyphs-msw.c (mswindows_xpm_instantiate): * glyphs-msw.c (xbm_create_bitmap_from_data): * glyphs-msw.c (mswindows_finalize_image_instance): * glyphs-x.c (convert_EImage_to_XImage): * glyphs-x.c (x_finalize_image_instance): * glyphs-x.c (x_init_image_instance_from_eimage): * glyphs-x.c (x_xpm_instantiate): * gui-x.c (free_popup_widget_value_tree): * hash.c (free_hash_table): * hash.c (grow_hash_table): * hash.c (pregrow_hash_table_if_necessary): * imgproc.c (build_EImage_quantable): * insdel.c (uninit_buffer_text): * intl-win32.c (convert_multibyte_to_internal_malloc): * intl.c: * intl.c (Fset_current_locale): * keymap.c: * keymap.c (where_is_recursive_mapper): * keymap.c (where_is_internal): * lisp.h: * lisp.h (xfree): * lstream.c (Lstream_close): * lstream.c (resizing_buffer_closer): * mule-coding.c: * mule-coding.c (iso2022_finalize_detection_state): * nt.c: * nt.c (mswindows_get_long_filename): * nt.c (nt_get_resource): * nt.c (init_mswindows_environment): * nt.c (get_cached_volume_information): * nt.c (mswindows_opendir): * nt.c (mswindows_closedir): * nt.c (mswindows_readdir): * nt.c (mswindows_stat): * nt.c (mswindows_getdcwd): * nt.c (Fmswindows_long_file_name): * ntplay.c (nt_play_sound_file): * ntplay.c (play_sound_data_1): * number-gmp.c (gmp_free): * number-gmp.c (init_number_gmp): * number-mp.c (bignum_to_string): * number-mp.c (BIGNUM_TO_TYPE): * number.c (bignum_print): * number.c (bignum_convfree): * number.c (ratio_print): * number.c (bigfloat_print): * number.c (bigfloat_finalize): * objects-gtk.c (gtk_finalize_color_instance): * objects-gtk.c (gtk_finalize_font_instance): * objects-msw.c (mswindows_finalize_color_instance): * objects-msw.c (mswindows_finalize_font_instance): * objects-tty.c (tty_finalize_color_instance): * objects-tty.c (tty_finalize_font_instance): * objects-tty.c (tty_font_list): * objects-x.c (x_finalize_color_instance): * objects-x.c (x_finalize_font_instance): * process.c: * process.c (finalize_process): * realpath.c: * redisplay.c (add_propagation_runes): * regex.c: * regex.c (xfree): * regex.c (REGEX_FREE_STACK): * regex.c (FREE_STACK_RETURN): * regex.c (regex_compile): * regex.c (regexec): * regex.c (regfree): * scrollbar-gtk.c (gtk_free_scrollbar_instance): * scrollbar-gtk.c (gtk_release_scrollbar_instance): * scrollbar-msw.c (mswindows_free_scrollbar_instance): * scrollbar-msw.c (unshow_that_mofo): * scrollbar-x.c (x_free_scrollbar_instance): * scrollbar-x.c (x_release_scrollbar_instance): * select-gtk.c (emacs_gtk_selection_handle): * select-msw.c (mswindows_own_selection): * select-x.c: * select-x.c (x_handle_selection_request): * select-x.c (unexpect_property_change): * select-x.c (x_handle_property_notify): * select-x.c (receive_incremental_selection): * select-x.c (x_get_window_property_as_lisp_data): * select-x.c (Fx_get_cutbuffer_internal): * specifier.c (finalize_specifier): * syntax.c (uninit_buffer_syntax_cache): * sysdep.c (qxe_allocating_getcwd): * sysdep.c (qxe_lstat): * sysdep.c (copy_in_passwd): * sysdep.c (qxe_ctime): * sysdep.c (closedir): * sysdep.c (DIRSIZ): * termcap.c (tgetent): * termcap.c (tprint): * tests.c (Ftest_data_format_conversion): * text.c (new_dfc_convert_copy_data): * text.h (eifree): * text.h (eito_alloca): * text.h (eito_external): * toolbar-msw.c (mswindows_output_toolbar): * ui-gtk.c (CONVERT_RETVAL): * ui-gtk.c (__allocate_object_storage): * unicode.c (free_from_unicode_table): * unicode.c (free_to_unicode_table): * unicode.c (free_charset_unicode_tables): * win32.c (mswindows_read_link_1): Rename: xfree(VAL, TYPE)->xfree(VAL) Command used: gr 'xfree *\((.*),.*\);' 'xfree (\1);' *.[ch] Followed by grepping for 'xfree.*,' and fixing anything left. Rationale: Having to specify the TYPE argument is annoying and error-prone. It was originally put in to work around warnings due to strict aliasing but years and years ago I rewrote it in a way that doesn't use the TYPE argument at all and no one has complained since then. (And anyway, XEmacs is far from ever being in compliance with strict aliasing and would require far-reaching changes to get that way.)
author Ben Wing <ben@xemacs.org>
date Thu, 04 Feb 2010 07:28:14 -0600
parents b3ce27ca7647
children 6f2158fa75ed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
1 /* Efficient caching of Gtk GCs (graphics contexts).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
2 Copyright (C) 1993 Free Software Foundation, Inc.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
3 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
4
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
5 This file is part of XEmacs.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
6
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
7 XEmacs is free software; you can redistribute it and/or modify it
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
9 Free Software Foundation; either version 2, or (at your option) any
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
10 later version.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
11
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
15 for more details.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
16
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
18 along with XEmacs; see the file COPYING. If not, write to
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
20 Boston, MA 02111-1307, USA. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
21
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
22 /* Synched up with: Not in FSF. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
23
4908
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
24 /* XEmacs uses a lot of different display attributes; for example, assume
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
25 that only four fonts are in use (normal, bold, italic, and bold-italic).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
26 Then assume that one stipple or background is used for text selections,
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
27 and another is used for highlighting mousable regions. That makes 16
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
28 GCs already. Add in the fact that another GC may be needed to display
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
29 the text cursor in any of those regions, and you've got 32. Add in
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
30 more fonts, and it keeps increasing exponentially.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
31
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
32 We used to keep these GCs in a cache of merged (fully qualified) faces.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
33 However, a lot of other code in xterm.c used XChangeGC of existing GCs,
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
34 which is kind of slow and kind of random. Also, managing the face cache
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
35 was tricky because it was hard to know when a face was no longer visible
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
36 on the frame -- we had to mark all frames as garbaged whenever a face
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
37 was changed, which caused an unpleasant amount of flicker (since faces are
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
38 created/destroyed (= changed) whenever a frame is created/destroyed.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
39
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
40 So this code maintains a cache at the GC level instead of at the face
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
41 level. There is an upper limit on the size of the cache, after which we
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
42 will stop creating GCs and start reusing them (reusing the least-recently-
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
43 used ones first). So if faces get changed, their GCs will eventually be
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
44 recycled. Also more sharing of GCs is possible.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
45
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
46 This code uses hashtables. It could be that, if the cache size is small
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
47 enough, a linear search might be faster; but I doubt it, since we need
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
48 `equal' comparisons, not `eq', and I expect that the optimal cache size
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
49 will be ~100.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
50
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
51 Written by jwz, 14 jun 93
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
52 Hacked by William Perry, apr 2000
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
53 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
54
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
55 #include <config.h>
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
56 #include "lisp.h"
4908
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
57 #include "hash.h"
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
58
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
59 #include "gccache-gtk.h"
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
60
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
61 #define GC_CACHE_SIZE 100
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
62
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
63 #define GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
64
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
65 struct gcv_and_mask {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
66 GdkGCValues gcv;
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
67 unsigned long mask; /* contains a GdkGCValuesMask bitmask. */
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
68 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
69
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
70 struct gc_cache_cell {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
71 GdkGC *gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
72 struct gcv_and_mask gcvm;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
73 struct gc_cache_cell *prev, *next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
74 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
75
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
76 struct gc_cache {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
77 GdkWindow *window; /* used only as arg to XCreateGC */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
78 int size;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
79 struct gc_cache_cell *head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
80 struct gc_cache_cell *tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
81 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
82 struct hash_table * table;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
83 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
84
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
85 int create_count;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
86 int delete_count;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
87 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
88
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
89 #ifdef GCCACHE_HASH
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
90 static Hashcode
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
91 gc_cache_hash (const void *arg)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
92 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
93 const struct gcv_and_mask *gcvm = (const struct gcv_and_mask *) arg;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
94 unsigned long *longs = (unsigned long *) &gcvm->gcv;
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
95 Hashcode hash = gcvm->mask;
778
2923009caf47 [xemacs-hg @ 2002-03-16 10:38:59 by ben]
ben
parents: 462
diff changeset
96 unsigned int i;
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
97 /* This could look at the mask and only use the used slots in the
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
98 hash code. That would win in that we wouldn't have to initialize
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
99 every slot of the gcv when calling gc_cache_lookup. But we need
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
100 the hash function to be as fast as possible; some timings should
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
101 be done. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
102 for (i = 0; i < (sizeof (GdkGCValues) / sizeof (unsigned long)); i++)
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
103 hash = (hash << 1) ^ *longs++;
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
104 return hash;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
105 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
106
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
107 #endif /* GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
108
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
109 static int
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
110 gc_cache_eql (const void *arg1, const void *arg2)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
111 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
112 /* See comment in gc_cache_hash */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
113 const struct gcv_and_mask *gcvm1 = (const struct gcv_and_mask *) arg1;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
114 const struct gcv_and_mask *gcvm2 = (const struct gcv_and_mask *) arg2;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
115
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
116 return !memcmp(&gcvm1->gcv, &gcvm2->gcv, sizeof(gcvm1->gcv))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
117 && gcvm1->mask == gcvm2->mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
118 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
119
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
120 struct gc_cache *
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
121 make_gc_cache (GtkWidget *widget)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
122 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
123 struct gc_cache *cache = xnew (struct gc_cache);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
124 cache->window = widget->window;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
125 cache->size = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
126 cache->head = cache->tail = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
127 cache->create_count = cache->delete_count = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
128 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
129 cache->table =
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
130 make_general_hash_table (GC_CACHE_SIZE, gc_cache_hash, gc_cache_eql);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
131 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
132 return cache;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
133 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
134
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
135 void
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
136 free_gc_cache (struct gc_cache *cache)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
137 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
138 struct gc_cache_cell *rest, *next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
139 rest = cache->head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
140 while (rest)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
141 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
142 gdk_gc_destroy(rest->gc);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
143 next = rest->next;
4976
16112448d484 Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents: 4908
diff changeset
144 xfree (rest);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
145 rest = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
146 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
147 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
148 free_hash_table (cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
149 #endif
4976
16112448d484 Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents: 4908
diff changeset
150 xfree (cache);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
151 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
152
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
153 GdkGC *
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
154 gc_cache_lookup (struct gc_cache *cache, GdkGCValues *gcv, unsigned long mask)
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
155 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
156 struct gc_cache_cell *cell, *next, *prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
157 struct gcv_and_mask gcvm;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
158
2500
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
159 if ((!!cache->head) != (!!cache->tail)) ABORT ();
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
160 if (cache->head && (cache->head->prev || cache->tail->next)) ABORT ();
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
161
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
162 /* Gdk does not have the equivalent of 'None' for the clip_mask, so
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
163 we need to check it carefully, or gdk_gc_new_with_values will
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
164 coredump */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
165 if ((mask & GDK_GC_CLIP_MASK) && !gcv->clip_mask)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
166 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
167 mask &= ~GDK_GC_CLIP_MASK;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
168 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
169
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
170 gcvm.mask = mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
171 gcvm.gcv = *gcv; /* this copies... */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
172
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
173 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
174
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
175 if (gethash (&gcvm, cache->table, (const void **) &cell))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
176
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
177 #else /* !GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
178
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
179 cell = cache->tail; /* start at the end (most recently used) */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
180 while (cell)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
181 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
182 if (gc_cache_eql (&gcvm, &cell->gcvm))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
183 break;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
184 else
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
185 cell = cell->prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
186 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
187
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
188 /* #### This whole file needs some serious overhauling. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
189 if (!(mask | GDK_GC_TILE) && cell->gcvm.gcv.tile)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
190 cell = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
191 else if (!(mask | GDK_GC_STIPPLE) && cell->gcvm.gcv.stipple)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
192 cell = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
193
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
194 if (cell)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
195
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
196 #endif /* !GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
197
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
198 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
199 /* Found a cell. Move this cell to the end of the list, so that it
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
200 will be less likely to be collected than a cell that was accessed
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
201 less recently.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
202 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
203 if (cell == cache->tail)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
204 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
205
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
206 next = cell->next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
207 prev = cell->prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
208 if (prev) prev->next = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
209 if (next) next->prev = prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
210 if (cache->head == cell) cache->head = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
211 cell->next = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
212 cell->prev = cache->tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
213 cache->tail->next = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
214 cache->tail = cell;
2500
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
215 if (cache->head == cell) ABORT ();
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
216 if (cell->next) ABORT ();
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
217 if (cache->head->prev) ABORT ();
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
218 if (cache->tail->next) ABORT ();
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
219 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
220 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
221
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
222 /* else, cache miss. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
223
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
224 if (cache->size == GC_CACHE_SIZE)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
225 /* Reuse the first cell on the list (least-recently-used).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
226 Remove it from the list, and unhash it from the table.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
227 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
228 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
229 cell = cache->head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
230 cache->head = cell->next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
231 cache->head->prev = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
232 if (cache->tail == cell) cache->tail = 0; /* only one */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
233 gdk_gc_destroy (cell->gc);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
234 cache->delete_count++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
235 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
236 remhash (&cell->gcvm, cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
237 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
238 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
239 else if (cache->size > GC_CACHE_SIZE)
2500
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
240 ABORT ();
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
241 else
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
242 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
243 /* Allocate a new cell (don't put it in the list or table yet). */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
244 cell = xnew (struct gc_cache_cell);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
245 cache->size++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
246 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
247
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
248 /* Now we've got a cell (new or reused). Fill it in. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
249 memcpy (&cell->gcvm.gcv, gcv, sizeof (GdkGCValues));
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
250 cell->gcvm.mask = mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
251
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
252 /* Put the cell on the end of the list. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
253 cell->next = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
254 cell->prev = cache->tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
255 if (cache->tail) cache->tail->next = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
256 cache->tail = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
257 if (! cache->head) cache->head = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
258
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
259 cache->create_count++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
260 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
261 /* Hash it in the table */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
262 puthash (&cell->gcvm, cell, cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
263 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
264
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
265 /* Now make and return the GC. */
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
266 cell->gc = gdk_gc_new_with_values (cache->window, gcv, (GdkGCValuesMask) mask);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
267
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
268 /* debug */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
269 assert (cell->gc == gc_cache_lookup (cache, gcv, mask));
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
270
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
271 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
272 }