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 }