Mercurial > hg > xemacs-beta
comparison src/specifier.c @ 444:576fb035e263 r21-2-37
Import from CVS: tag r21-2-37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:36:19 +0200 |
parents | abe6d1db359e |
children | 3d3049ae1304 |
comparison
equal
deleted
inserted
replaced
443:a8296e22da4e | 444:576fb035e263 |
---|---|
547 and associate them with particular locales (buffer, window, frame, | 547 and associate them with particular locales (buffer, window, frame, |
548 device, global), and then the instance (i.e. actual value) is | 548 device, global), and then the instance (i.e. actual value) is |
549 retrieved in a specific domain (window, frame, device) by looking | 549 retrieved in a specific domain (window, frame, device) by looking |
550 through the possible instantiators (i.e. settings). This process is | 550 through the possible instantiators (i.e. settings). This process is |
551 called \"instantiation\". | 551 called \"instantiation\". |
552 | 552 |
553 To put settings into a specifier, use `set-specifier', or the | 553 To put settings into a specifier, use `set-specifier', or the |
554 lower-level functions `add-spec-to-specifier' and | 554 lower-level functions `add-spec-to-specifier' and |
555 `add-spec-list-to-specifier'. You can also temporarily bind a setting | 555 `add-spec-list-to-specifier'. You can also temporarily bind a setting |
556 to a specifier using `let-specifier'. To retrieve settings, use | 556 to a specifier using `let-specifier'. To retrieve settings, use |
557 `specifier-specs', or its lower-level counterpart | 557 `specifier-specs', or its lower-level counterpart |
1984 recompute_cached_specifier_everywhere (specifier); | 1984 recompute_cached_specifier_everywhere (specifier); |
1985 RETURN_UNGCPRO (Qnil); | 1985 RETURN_UNGCPRO (Qnil); |
1986 } | 1986 } |
1987 | 1987 |
1988 DEFUN ("add-spec-list-to-specifier", Fadd_spec_list_to_specifier, 2, 3, 0, /* | 1988 DEFUN ("add-spec-list-to-specifier", Fadd_spec_list_to_specifier, 2, 3, 0, /* |
1989 Add a spec-list (a list of specifications) to SPECIFIER. | 1989 Add SPEC-LIST (a list of specifications) to SPECIFIER. |
1990 The format of a spec-list is | 1990 The format of SPEC-LIST is |
1991 | 1991 |
1992 ((LOCALE (TAG-SET . INSTANTIATOR) ...) ...) | 1992 ((LOCALE (TAG-SET . INSTANTIATOR) ...) ...) |
1993 | 1993 |
1994 where | 1994 where |
1995 LOCALE := a window, a buffer, a frame, a device, or 'global | 1995 LOCALE := a window, a buffer, a frame, a device, or 'global |
2554 { | 2554 { |
2555 Lisp_Object buffer = Qnil; | 2555 Lisp_Object buffer = Qnil; |
2556 Lisp_Object window = Qnil; | 2556 Lisp_Object window = Qnil; |
2557 Lisp_Object frame = Qnil; | 2557 Lisp_Object frame = Qnil; |
2558 Lisp_Object device = Qnil; | 2558 Lisp_Object device = Qnil; |
2559 Lisp_Object tag = Qnil; | 2559 Lisp_Object tag = Qnil; /* #### currently unused */ |
2560 struct device *d; | 2560 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2561 Lisp_Specifier *sp; | |
2562 | |
2563 sp = XSPECIFIER (specifier); | |
2564 | 2561 |
2565 /* Attempt to determine buffer, window, frame, and device from the | 2562 /* Attempt to determine buffer, window, frame, and device from the |
2566 domain. */ | 2563 domain. */ |
2567 /* #### get image instances out of domains! */ | 2564 /* #### get image instances out of domains! */ |
2568 if (IMAGE_INSTANCEP (domain)) | 2565 if (IMAGE_INSTANCEP (domain)) |
2580 No. Errors are handled in Lisp primitives implementation. | 2577 No. Errors are handled in Lisp primitives implementation. |
2581 Invalid domain is a design error here - kkm. */ | 2578 Invalid domain is a design error here - kkm. */ |
2582 abort (); | 2579 abort (); |
2583 | 2580 |
2584 if (NILP (buffer) && !NILP (window)) | 2581 if (NILP (buffer) && !NILP (window)) |
2585 buffer = XWINDOW (window)->buffer; | 2582 buffer = WINDOW_BUFFER (XWINDOW (window)); |
2586 if (NILP (frame) && !NILP (window)) | 2583 if (NILP (frame) && !NILP (window)) |
2587 frame = XWINDOW (window)->frame; | 2584 frame = XWINDOW (window)->frame; |
2588 if (NILP (device)) | 2585 if (NILP (device)) |
2589 /* frame had better exist; if device is undeterminable, something | 2586 /* frame had better exist; if device is undeterminable, something |
2590 really went wrong. */ | 2587 really went wrong. */ |
2591 device = XFRAME (frame)->device; | 2588 device = FRAME_DEVICE (XFRAME (frame)); |
2592 | 2589 |
2593 /* device had better be determined by now; abort if not. */ | 2590 /* device had better be determined by now; abort if not. */ |
2594 d = XDEVICE (device); | 2591 tag = DEVICE_CLASS (XDEVICE (device)); |
2595 tag = DEVICE_CLASS (d); | |
2596 | 2592 |
2597 depth = make_int (1 + XINT (depth)); | 2593 depth = make_int (1 + XINT (depth)); |
2598 if (XINT (depth) > 20) | 2594 if (XINT (depth) > 20) |
2599 { | 2595 { |
2600 maybe_error (Qspecifier, errb, "Apparent loop in specifier inheritance"); | 2596 maybe_error (Qspecifier, errb, "Apparent loop in specifier inheritance"); |
2834 (Lisp_Object specifier, struct window *w, | 2830 (Lisp_Object specifier, struct window *w, |
2835 Lisp_Object oldval), | 2831 Lisp_Object oldval), |
2836 int struct_frame_offset, | 2832 int struct_frame_offset, |
2837 void (*value_changed_in_frame) | 2833 void (*value_changed_in_frame) |
2838 (Lisp_Object specifier, struct frame *f, | 2834 (Lisp_Object specifier, struct frame *f, |
2839 Lisp_Object oldval)) | 2835 Lisp_Object oldval), |
2836 int always_recompute) | |
2840 { | 2837 { |
2841 Lisp_Specifier *sp = XSPECIFIER (specifier); | 2838 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2842 assert (!GHOST_SPECIFIER_P (sp)); | 2839 assert (!GHOST_SPECIFIER_P (sp)); |
2843 | 2840 |
2844 if (!sp->caching) | 2841 if (!sp->caching) |
2845 sp->caching = xnew_and_zero (struct specifier_caching); | 2842 sp->caching = xnew_and_zero (struct specifier_caching); |
2846 sp->caching->offset_into_struct_window = struct_window_offset; | 2843 sp->caching->offset_into_struct_window = struct_window_offset; |
2847 sp->caching->value_changed_in_window = value_changed_in_window; | 2844 sp->caching->value_changed_in_window = value_changed_in_window; |
2848 sp->caching->offset_into_struct_frame = struct_frame_offset; | 2845 sp->caching->offset_into_struct_frame = struct_frame_offset; |
2849 sp->caching->value_changed_in_frame = value_changed_in_frame; | 2846 sp->caching->value_changed_in_frame = value_changed_in_frame; |
2847 sp->caching->always_recompute = always_recompute; | |
2850 Vcached_specifiers = Fcons (specifier, Vcached_specifiers); | 2848 Vcached_specifiers = Fcons (specifier, Vcached_specifiers); |
2851 if (BODILY_SPECIFIER_P (sp)) | 2849 if (BODILY_SPECIFIER_P (sp)) |
2852 GHOST_SPECIFIER(sp)->caching = sp->caching; | 2850 GHOST_SPECIFIER(sp)->caching = sp->caching; |
2853 recompute_cached_specifier_everywhere (specifier); | 2851 recompute_cached_specifier_everywhere (specifier); |
2854 } | 2852 } |
2856 static void | 2854 static void |
2857 recompute_one_cached_specifier_in_window (Lisp_Object specifier, | 2855 recompute_one_cached_specifier_in_window (Lisp_Object specifier, |
2858 struct window *w) | 2856 struct window *w) |
2859 { | 2857 { |
2860 Lisp_Object window; | 2858 Lisp_Object window; |
2861 Lisp_Object newval, *location; | 2859 Lisp_Object newval, *location, oldval; |
2862 | 2860 |
2863 assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier))); | 2861 assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier))); |
2864 | 2862 |
2865 XSETWINDOW (window, w); | 2863 XSETWINDOW (window, w); |
2866 | 2864 |
2877 method the instantiation that specifier_instance will do will | 2875 method the instantiation that specifier_instance will do will |
2878 always create a new copy. Thus EQ will always fail. Unfortunately | 2876 always create a new copy. Thus EQ will always fail. Unfortunately |
2879 calling equal is no good either as this doesn't take into account | 2877 calling equal is no good either as this doesn't take into account |
2880 things attached to the specifier - for instance strings on | 2878 things attached to the specifier - for instance strings on |
2881 extents. --andyp */ | 2879 extents. --andyp */ |
2882 if (!EQ (newval, *location)) | 2880 if (!EQ (newval, *location) || XSPECIFIER (specifier)->caching->always_recompute) |
2883 { | 2881 { |
2884 Lisp_Object oldval = *location; | 2882 oldval = *location; |
2885 *location = newval; | 2883 *location = newval; |
2886 (XSPECIFIER (specifier)->caching->value_changed_in_window) | 2884 (XSPECIFIER (specifier)->caching->value_changed_in_window) |
2887 (specifier, w, oldval); | 2885 (specifier, w, oldval); |
2888 } | 2886 } |
2889 } | 2887 } |
2891 static void | 2889 static void |
2892 recompute_one_cached_specifier_in_frame (Lisp_Object specifier, | 2890 recompute_one_cached_specifier_in_frame (Lisp_Object specifier, |
2893 struct frame *f) | 2891 struct frame *f) |
2894 { | 2892 { |
2895 Lisp_Object frame; | 2893 Lisp_Object frame; |
2896 Lisp_Object newval, *location; | 2894 Lisp_Object newval, *location, oldval; |
2897 | 2895 |
2898 assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier))); | 2896 assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier))); |
2899 | 2897 |
2900 XSETFRAME (frame, f); | 2898 XSETFRAME (frame, f); |
2901 | 2899 |
2905 better be able to deal. If not, set a default so this | 2903 better be able to deal. If not, set a default so this |
2906 never happens or correct it in the value_changed_in_frame | 2904 never happens or correct it in the value_changed_in_frame |
2907 method. */ | 2905 method. */ |
2908 location = (Lisp_Object *) | 2906 location = (Lisp_Object *) |
2909 ((char *) f + XSPECIFIER (specifier)->caching->offset_into_struct_frame); | 2907 ((char *) f + XSPECIFIER (specifier)->caching->offset_into_struct_frame); |
2910 if (!EQ (newval, *location)) | 2908 if (!EQ (newval, *location) || XSPECIFIER (specifier)->caching->always_recompute) |
2911 { | 2909 { |
2912 Lisp_Object oldval = *location; | 2910 oldval = *location; |
2913 *location = newval; | 2911 *location = newval; |
2914 (XSPECIFIER (specifier)->caching->value_changed_in_frame) | 2912 (XSPECIFIER (specifier)->caching->value_changed_in_frame) |
2915 (specifier, f, oldval); | 2913 (specifier, f, oldval); |
2916 } | 2914 } |
2917 } | 2915 } |