view lisp/loadhist.el @ 59146:9bde7721ad0f

* dispextern.h: Change HAVE_CARBON to MAC_OS. (struct glyph_string): Likewise. * emacs.c (main) [MAC_OS8]: Call mac_term_init instead of mac_initialize. * fileio.c (Fnext_read_file_uses_dialog_p, Fread_file_name): Change TARGET_API_MAC_CARBON to HAVE_CARBON. * fns.c (vector): Change MAC_OSX to MAC_OS. * frame.c (x_set_frame_parameters, x_report_frame_params) (x_set_fullscreen): Remove #ifndef HAVE_CARBON. (x_set_border_width, Vdefault_frame_scroll_bars): Change HAVE_CARBON to MAC_OS. * image.c [MAC_OS]: Include sys/stat.h. [MAC_OS && !MAC_OSX]: Include sys/param.h, ImageCompression.h, and QuickTimeComponents.h. * mac.c [!MAC_OSX] (mac_wait_next_event): Add extern. [!MAC_OSX] (select): Use mac_wait_next_event. [!MAC_OSX] (run_mac_command): Change EXEC_SUFFIXES to Vexec_suffixes. [!MAC_OSX] (select, run_mac_command): Change `#ifdef TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'. (mac_clear_font_name_table): Add extern. (Fmac_clear_font_name_table): New defun. (syms_of_mac): Defsubr it. [MAC_OSX] (SELECT_POLLING_PERIOD_USEC): New define. [MAC_OSX] (select_and_poll_event): New function. [MAC_OSX] (sys_select): Use it. [MAC_OSX && SELECT_USE_CFSOCKET] (socket_callback): New function. [MAC_OSX && SELECT_USE_CFSOCKET] (SELECT_TIMEOUT_THRESHOLD_RUNLOOP, EVENT_CLASS_SOCK): New defines. [MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Use CFSocket and RunLoop for simultaneously monitoring two kinds of inputs, window events and process outputs, without periodically polling. * macfns.c (mac_initialized): Remove extern. (stricmp): Put in #if 0. All callers changed to use xstricmp in xfaces.c. (strnicmp): Decrement `n' at the end of each loop, not the beginning. (check_mac): Use the term "Mac native windows" instead of "Mac OS". (check_x_display_info, x_display_info_for_name): Sync with xfns.c. (mac_get_rdb_resource): New function (from w32reg.c). (x_get_string_resource): Use it. (install_window_handler): Add extern. (mac_window): New function. (Fx_create_frame): Use it instead of make_mac_frame. Set parameter for Qfullscreen. Call x_wm_set_size_hint. (Fx_open_connection, Fx_close_connection): New defuns. (syms_of_macfns): Defsubr them. (x_create_tip_frame) [TARGET_API_MAC_CARBON]: Add kWindowNoUpdatesAttribute to the window attribute. (x_create_tip_frame) [!TARGET_API_MAC_CARBON]: Use NewCWindow. (x_create_tip_frame): Don't call ShowWindow. (Fx_show_tip): Call ShowWindow. (Fx_file_dialog): Change `#ifdef TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'. (mac_frame_parm_handlers): Set handlers for Qfullscreen. (syms_of_macfns) [MAC_OSX]: Initialize mac_in_use to 0. * macgui.h [!MAC_OSX]: Don't include Controls.h. Include Windows.h. (Window): Typedef to WindowPtr and move outside `#if TARGET_API_MAC_CARBON'. (XSizeHints): New struct. * macterm.c (x_update_begin, x_update_end) [TARGET_API_MAC_CARBON]: Disable screen updates during update of a frame. (x_draw_glyph_string_background, x_draw_glyph_string_foreground) [MAC_OS8]: Use XDrawImageString/XDrawImageString16. (construct_mouse_click): Put in #if 0. (x_check_fullscreen, x_check_fullscreen_move): Remove decls. (x_scroll_bar_create, x_scroll_bar_handle_click): Change `#ifdef TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'. (activate_scroll_bars, deactivate_scroll_bars) [!TARGET_API_MAC_CARBON]: Use ActivateControl/DeactivateControl. (x_make_frame_visible) [TARGET_API_MAC_CARBON]: Reposition window if the position is neither user-specified nor program-specified. (x_free_frame_resources): Free size_hints. (x_wm_set_size_hint): Allocate size_hints if needed. Set size_hints. (mac_clear_font_name_table): New function. (mac_do_list_fonts): Initialize font_name_table if needed. (x_list_fonts): Don't initialize font_name_table. Add BLOCK_INPUT around mac_do_list_fonts. (mac_unload_font): New function. (x_load_font): Add BLOCK_INPUT around XLoadQueryFont. (init_mac_drag_n_drop, mac_do_receive_drag): Enclose declarations and definitions with #if TARGET_API_MAC_CARBON. [USE_CARBON_EVENTS] (mac_handle_window_event): Add decl. (install_window_handler): Add decl. (do_window_update): Add BeginUpdate/EndUpdate for the tooltip window. Use UpdateControls. Get the rectangle that should be updated and restrict the target of expose_frame to it. (do_grow_window): Set minimum height/width according to size_hints. (do_grow_window) [TARGET_API_MAC_CARBON]: Use ResizeWindow. (do_zoom_window): Don't use x_set_window_size. [USE_CARBON_EVENTS] (mac_handle_window_event): New function. (install_window_handler): New function. [!USE_CARBON_EVENTS] (mouse_region): New variable. [!USE_CARBON_EVENTS] (mac_wait_next_event): New function. (XTread_socket) [USE_CARBON_EVENTS]: Move call to GetEventDispatcherTarget inside BLOCK_INPUT. (XTread_socket) [!USE_CARBON_EVENTS]: Use mac_wait_next_event. Update mouse_region when mouse is moved. (make_mac_frame): Remove. (make_mac_terminal_frame): Put in #ifdef MAC_OS8. Initialize mouse pointer shapes. Change values of f->left_pos and f->top_pos. Don't use make_mac_frame. Use NewCWindow. Don't call ShowWindow. (mac_initialize_display_info) [MAC_OSX]: Create mac_id_name from Vinvocation_name and Vsystem_name. (mac_make_rdb): New function (from w32term.c). (mac_term_init): Use it. Add BLOCK_INPUT. Error if display has already been opened. Don't pass argument to mac_initialize_display_info. Don't set dpyinfo->height/width. Add entries to x_display_list and x_display_name_list. (x_delete_display): New function. (mac_initialize): Don't call mac_initialize_display_info. (syms_of_macterm) [!MAC_OSX]: Don't call Fprovide. * macterm.h (check_mac): Add extern. (struct mac_output): New member size_hints. (FRAME_SIZE_HINTS): New macro. (mac_unload_font): Add extern. * xdisp.c (expose_window, expose_frame): Remove kludges for Mac. * xfaces.c (clear_font_table) [MAC_OS]: call mac_unload_font.
author Steven Tamm <steventamm@mac.com>
date Mon, 27 Dec 2004 17:27:30 +0000
parents 8d106818ca97
children 55722dde9e0a
line wrap: on
line source

;;; loadhist.el --- lisp functions for working with feature groups

;; Copyright (C) 1995, 1998, 2000 Free Software Foundation, Inc.

;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
;; Maintainer: FSF
;; Keywords: internal

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; GNU Emacs 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 General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; These functions exploit the load-history system variable.
;; Entry points include `unload-feature', `symbol-file', and
;; `feature-file', documented in the Emacs Lisp manual.

;;; Code:

(defun feature-symbols (feature)
  "Return the file and list of definitions associated with FEATURE.
The value is actually the element of `load-history'
for the file that did (provide FEATURE)."
   (catch 'foundit
     (mapc (lambda (x)
	     (if (member (cons 'provide feature) (cdr x))
		 (throw 'foundit x)))
	   load-history)
     nil))

(defun feature-file (feature)
  "Return the file name from which a given FEATURE was loaded.
Actually, return the load argument, if any; this is sometimes the name of a
Lisp file without an extension.  If the feature came from an `eval-buffer' on
a buffer with no associated file, or an `eval-region', return nil."
  (if (not (featurep feature))
      (error "%S is not a currently loaded feature" feature)
    (car (feature-symbols feature))))

(defun file-provides (file)
  "Return the list of features provided by FILE."
  (let ((symbols (cdr (assoc file load-history)))
	provides)
    (mapc (lambda (x)
	    (if (and (consp x) (eq (car x) 'provide))
		(setq provides (cons (cdr x) provides))))
	  symbols)
    provides))

(defun file-requires (file)
  "Return the list of features required by FILE."
  (let ((symbols (cdr (assoc file load-history)))
	requires)
    (mapc (lambda (x)
	    (if (and (consp x) (eq (car x) 'require))
		(setq requires (cons (cdr x) requires))))
	  symbols)
    requires))

(defsubst file-set-intersect (p q)
  "Return the set intersection of two lists."
  (let ((ret nil))
    (dolist (x p ret)
      (if (memq x q) (setq ret (cons x ret))))
    ret))

(defun file-dependents (file)
  "Return the list of loaded libraries that depend on FILE.
This can include FILE itself."
  (let ((provides (file-provides file))
	(dependents nil))
    (dolist (x load-history dependents)
      (if (file-set-intersect provides (file-requires (car x)))
	  (setq dependents (cons (car x) dependents))))
    dependents))

(defun read-feature (prompt)
  "Read a feature name \(string\) from the minibuffer.
Prompt with PROMPT and completing from `features', and
return the feature \(symbol\)."
  (intern (completing-read prompt
			   (mapcar (lambda (feature)
				     (list (symbol-name feature)))
				   features)
			   nil t)))

(defvaralias 'loadhist-hook-functions 'unload-feature-special-hooks)
(defvar unload-feature-special-hooks
  '(after-change-functions
    after-insert-file-functions auto-fill-function
    before-change-functions blink-paren-function
    buffer-access-fontify-functions command-line-functions
    comment-indent-function kill-buffer-query-functions
    kill-emacs-query-functions lisp-indent-function
    mouse-position-function
    redisplay-end-trigger-functions temp-buffer-show-function
    window-scroll-functions window-size-change-functions
    write-region-annotate-functions)
  "A list of special hooks from Info node `(elisp)Standard Hooks'.

These are symbols with hook-type values whose names don't end in
`-hook' or `-hooks', from which `unload-feature' tries to remove
pertinent symbols.")

(defvar unload-hook-features-list nil
  "List of features of the package being unloaded.

This is meant to be used by FEATURE-unload-hook hooks, see the
documentation of `unload-feature' for details.")

;;;###autoload
(defun unload-feature (feature &optional force)
  "Unload the library that provided FEATURE, restoring all its autoloads.
If the feature is required by any other loaded code, and prefix arg FORCE
is nil, raise an error.

This function tries to undo modifications made by the package to
hooks.  Packages may define a hook FEATURE-unload-hook that is called
instead of the normal heuristics for doing this.  Such a hook should
undo all the relevant global state changes that may have been made by
loading the package or executing functions in it.  It has access to
the package's feature list (before anything is unbound) in the
variable `unload-hook-features-list' and could remove features from it
in the event that the package has done something normally-ill-advised,
such as redefining an Emacs function."
  (interactive (list (read-feature "Feature: ") current-prefix-arg))
  (if (not (featurep feature))
      (error "%s is not a currently loaded feature" (symbol-name feature)))
  (if (not force)
      (let* ((file (feature-file feature))
	     (dependents (delete file (copy-sequence (file-dependents file)))))
	(if dependents
	    (error "Loaded libraries %s depend on %s"
		   (prin1-to-string dependents) file))))
  (let* ((unload-hook-features-list (feature-symbols feature))
         (file (car unload-hook-features-list))
         (unload-hook (intern-soft (concat (symbol-name feature)
                                           "-unload-hook"))))
    ;; Try to avoid losing badly when hooks installed in critical
    ;; places go away.  (Some packages install things on
    ;; `kill-buffer-hook', `activate-menubar-hook' and the like.)
    ;; First off, provide a clean way for package FOO to arrange
    ;; this by adding hooks on the variable `FOO-unload-hook'.
    (if unload-hook
        (run-hooks unload-hook)
      ;; Otherwise, do our best.  Look through the obarray for symbols
      ;; which seem to be hook variables or special hook functions and
      ;; remove anything from them which matches the feature-symbols
      ;; about to get zapped.  Obviously this won't get anonymous
      ;; functions which the package might just have installed, and
      ;; there might be other important state, but this tactic
      ;; normally works.
      (mapatoms
       (lambda (x)
         (if (or (and (boundp x)        ; Random hooks.
                      (consp (symbol-value x))
                      (string-match "-hooks?\\'" (symbol-name x)))
                 (and (boundp x)       ; Known abnormal hooks etc.
                      (memq x unload-feature-special-hooks)))
	     (dolist (y (cdr unload-hook-features-list))
	       (remove-hook x y))))))
    (if (fboundp 'elp-restore-function)	; remove ELP stuff first
	(dolist (elt (cdr unload-hook-features-list))
	  (if (symbolp elt)
	      (elp-restore-function elt))))
    (mapc
     (lambda (x)
       (cond ((stringp x) nil)
             ((consp x)
              ;; Remove any feature names that this file provided.
              (if (eq (car x) 'provide)
                  (setq features (delq (cdr x) features)))
              (when (eq (car x) 'defvar)
		;; Kill local values as much as possible.
		(dolist (buf (buffer-list))
		  (with-current-buffer buf
		    (kill-local-variable (cdr x))))
		;; Get rid of the default binding if we can.
		(unless (local-variable-if-set-p (cdr x))
		  (makunbound (cdr x)))))
	     (t
	      (when (fboundp x)
		(if (fboundp 'ad-unadvise)
		    (ad-unadvise x))
		(fmakunbound x)
		(let ((aload (get x 'autoload)))
		  (if aload (fset x (cons 'autoload aload))))))))
     (cdr unload-hook-features-list))
    ;; Delete the load-history element for this file.
    (let ((elt (assoc file load-history)))
      (setq load-history (delq elt load-history)))))

(provide 'loadhist)

;;; arch-tag: 70bb846a-c413-4f01-bf88-78dba4ac0798
;;; loadhist.el ends here