view src/casetab.c @ 1720:4f5e3ac5d822

* frame.h (struct frame): New fields `can_have_scrollbars' and `has_vertical_scrollbars'. (FRAME_CAN_HAVE_SCROLLBARS, FRAME_HAS_VERTICAL_SCROLLBARS): New accessors, for both the MULTI_FRAME and non-MULTI_FRAME. (VERTICAL_SCROLLBAR_WIDTH, WINDOW_VERTICAL_SCROLLBAR, WINDOW_VERTICAL_SCROLLBAR_COLUMN, WINDOW_VERTICAL_SCROLLBAR_HEIGHT): New macros. * window.h (struct window): New field `vertical_scrollbar'. * xterm.h (struct x_display): vertical_scrollbars, judge_timestamp, vertical_scrollbar_extra: New fields. (struct scrollbar): New struct. (VERTICAL_SCROLLBAR_PIXEL_WIDTH, VERTICAL_SCROLLBAR_PIXEL_HEIGHT, VERTICAL_SCROLLBAR_LEFT_BORDER, VERTICAL_SCROLLBAR_RIGHT_BORDER, VERTICAL_SCROLLBAR_TOP_BORDER, VERTICAL_SCROLLBAR_BOTTOM_BORDER, CHAR_TO_PIXEL_WIDTH, CHAR_TO_PIXEL_HEIGHT, PIXEL_TO_CHAR_WIDTH, PIXEL_TO_CHAR_HEIGHT): New accessors and macros. * frame.c (make_frame): Initialize the `can_have_scrollbars' and `has_vertical_scrollbars' fields of the frame. * term.c (term_init): Note that TERMCAP terminals don't support scrollbars. (mouse_position_hook): Document new args. (set_vertical_scrollbar_hook, condemn_scrollbars_hook, redeem_scrollbar_hook, judge_scrollbars_hook): New hooks. * termhooks.h: Declare and document them. (enum scrollbar_part): New type. (struct input_event): Describe the new form of the scrollbar_click event type. Change `part' from a Lisp_Object to an enum scrollbar_part. Add a new field `scrollbar'. * keyboard.c (kbd_buffer_get_event): Pass appropriate new parameters to *mouse_position_hook, and make_lispy_movement. * xfns.c (x_set_vertical_scrollbar): New function. (x_figure_window_size): Use new macros to calculate frame size. (Fx_create_frame): Note that X Windows frames do support scroll bars. Default to "yes". * xterm.c: #include <X11/cursorfont.h> and "window.h". (x_vertical_scrollbar_cursor): New variable. (x_term_init): Initialize it. (last_mouse_bar, last_mouse_bar_frame, last_mouse_part, last_mouse_scroll_range_start, last_mouse_scroll_range_end): New variables. (XTmouse_position): Use them to return scrollbar movement events. Take new arguments, for that purpose. (x_window_to_scrollbar, x_scrollbar_create, x_scrollbar_set_handle, x_scrollbar_remove, x_scrollbar_move, XTset_scrollbar, XTcondemn_scrollbars, XTredeem_scrollbar, XTjudge_scrollbars, x_scrollbar_expose, x_scrollbar_background_expose, x_scrollbar_handle_click, x_scrollbar_handle_motion): New functions to implement scrollbars. (x_term_init): Set the termhooks.h hooks to point to them. (x_set_window_size): Use new macros to calculate frame size. Set vertical_scrollbar_extra field. (x_make_frame_visible): Use the frame accessor FRAME_HAS_VERTICAL_SCROLLBARS to decide if we need to map the frame's subwindows as well. (XTread_socket): Use new size-calculation macros from xterm.h when processing ConfigureNotify events. (x_wm_set_size_hint): Use PIXEL_TO_CHAR_WIDTH and PIXEL_TO_CHAR_HEIGHT macros. * ymakefile (xdisp.o): This now depends on termhooks.h. (xterm.o): This now depends on window.h. * xterm.h (struct x_display): Delete v_scrollbar, v_thumbup, v_thumbdown, v_slider, h_scrollbar, h_thumbup, h_thumbdown, h_slider, v_scrollbar_width, h_scrollbar_height fields. * keyboard.c (Qvscrollbar_part, Qvslider_part, Qvthumbup_part, Qvthumbdown_part, Qhscrollbar_part, Qhslider_part, Qhthumbup_part, Qhthumbdown_part, Qscrollbar_click): Deleted; part of an obsolete interface. (head_table): Removed from here as well. (syms_of_keyboard): And here. * keyboard.h: And here. (POSN_SCROLLBAR_BUTTON): Removed. * xscrollbar.h: File removed - no longer necessary. * xfns.c: Don't #include it any more. (Qhorizontal_scroll_bar, Qvertical_scroll_bar): Deleted. (syms_of_xfns): Don't initialize or staticpro them. (gray_bits): Salvaged from xscrollbar.h. (x_window_to_scrollbar): Deleted. (x_set_horizontal_scrollbar): Deleted. (enum x_frame_parm, x_frame_parms): Remove references to x_set_horizontal_scrollbar. (x_set_foreground_color, x_set_background_color, x_set_border_pixel): Remove special code to support scrollbars. (Fx_create_frame): Remove old scrollbar setup code. (install_vertical_scrollbar, install_horizontal_scrollbar, adjust_scrollbars, x_resize_scrollbars): Deleted. * xterm.c (construct_mouse_click): This doesn't need to take care of scrollbar clicks anymore. (XTread_socket): Remove old code to support scrollbars. Call new functions instead for events which occur in scrollbar windows. (XTupdate_end): Remove call to adjust_scrollbars; the main redisplay code takes care of that now. (enum window_type): Deleted. * ymakefile: Note that xfns.o no longer depends on xscrollbar.h. * xterm.c (x_set_mouse_position): Clip mouse position to be within frame. * xterm.c: Adjust the first line of each page to have a reasonable description. This makes pages-directory more useful. * xterm.c (x_do_pending_expose): Declare this routine only if HAVE_X11 is not #defined; X11 doesn't need it. (XTread_socket): Protect call to x_do_pending_expose with `#ifdef HAVE_X11'. * xterm.c (notice_mouse_movement): Deleted; obsolete and unused. Properly handle focus shift events, so the cursor is filled and hollow at the appropriate times, even in titleless windows. * xterm.c (x_focus_event_frame): New variable. (XTread_socket): When we receive a FocusIn event that's not NotifyPointer, record the frame in x_focus_event_frame. When we receive a FocusOut event that's not NotifyPointer, clear it. When we get a LeaveNotify event, don't take it seriously if we still have focus. * xterm.c (XTread_socket): Remove special code in EnterNotify case to handle scrollbars and fake mouse motion events. Change the meaning of focus redirection to make switching windows work properly. Fredirect_frame_focus has the details. * frame.h (focus_frame): Doc fix. [not MULTI_FRAME] (FRAME_FOCUS_FRAME): Make this Qnil, which indicates no focus redirection, instead of zero, which is selected_frame. * frame.c (make_frame): Initialize f->focus_frame to Qnil, rather than making it point to frame itself. (Fselect_frame): If changing the selected frame from FOO to BAR, make all redirections to FOO shift to BAR as well. Doc fix. (Fredirect_frame_focus): Doc fix. Accept nil as a valid redirection, not just as a default for FRAME. (Fframe_focus): Doc fix. * keyboard.c (kbd_buffer_store_event, kbd_buffer_get_event): Deal with focus redirections being nil. * xterm.c (XTframe_rehighlight): Doc fix. Deal with focus redirections being nil. * xterm.c (x_error_quitter): Just abort, so we can look at the core to see what happened. It's a pain to remember that you can't assign to FRAME->visible. Let's change all references to the `visible' member of struct frame to use the accessor macros, and then write a setter for the `visible' field that does the right thing. * frame.h (FRAME_VISIBLE_P): Make this not an l-value. (FRAME_SET_VISIBLE): New macro. * frame.c (make_terminal_frame, Fdelete_frame): Use FRAME_SET_VISIBLE. (Fframe_visible_p, Fvisible_frame_list): Use FRAME_VISIBLE_P and FRAME_ICONIFIED_P. * dispnew.c (Fredraw_display): Use the FRAME_VISIBLE_P and FRAME_GARBAGED_P accessors. * xdisp.c (redisplay): Use the FRAME_VISIBLE_P accessor. * xfns.c (x_set_foreground_color, x_set_background_color, x_set_cursor_color, x_set_border_pixel, x_set_icon_type): Use the FRAME_VISIBLE_P accessor. (Fx_create_frame): Use FRAME_SET_VISIBILITY. * xterm.c (clear_cursor, x_display_bar_cursor, x_display_box_cursor): Use FRAME_SET_VISIBILITY.
author Jim Blandy <jimb@redhat.com>
date Thu, 24 Dec 1992 06:21:14 +0000
parents 5fe52748a72c
children 952f2a18f83d
line wrap: on
line source

/* GNU Emacs routines to deal with case tables.
   Copyright (C) 1987 Free Software Foundation, Inc.

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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Written by Howard Gayle.  See chartab.c for details. */

#include "config.h"
#include "lisp.h"
#include "buffer.h"

Lisp_Object Qcase_table_p;
Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
Lisp_Object Vascii_canon_table, Vascii_eqv_table;

void compute_trt_inverse ();

DEFUN ("case-table-p", Fcase_table_p, Scase_table_p, 1, 1, 0,
  "Return t iff ARG is a case table.\n\
See `set-case-table' for more information on these data structures.")
  (table)
     Lisp_Object table;
{
  Lisp_Object down, up, canon, eqv;
  down = Fcar_safe (table);
  up = Fcar_safe (Fcdr_safe (table));
  canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table)));
  eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table))));

#define STRING256_P(obj) \
  (XTYPE (obj) == Lisp_String && XSTRING (obj)->size == 256)

  return (STRING256_P (down)
	  && (NILP (up) || STRING256_P (up))
	  && ((NILP (canon) && NILP (eqv))
	      || (STRING256_P (canon) && STRING256_P (eqv)))
	  ? Qt : Qnil);
}

static Lisp_Object
check_case_table (obj)
     Lisp_Object obj;
{
  register Lisp_Object tem;

  while (tem = Fcase_table_p (obj), NILP (tem))
    obj = wrong_type_argument (Qcase_table_p, obj, 0);
  return (obj);
}   

DEFUN ("current-case-table", Fcurrent_case_table, Scurrent_case_table, 0, 0, 0,
  "Return the case table of the current buffer.")
  ()
{
  Lisp_Object down, up, canon, eqv;
  
  down = current_buffer->downcase_table;
  up = current_buffer->upcase_table;
  canon = current_buffer->case_canon_table;
  eqv = current_buffer->case_eqv_table;

  return Fcons (down, Fcons (up, Fcons (canon, Fcons (eqv, Qnil))));
}

DEFUN ("standard-case-table", Fstandard_case_table,
  Sstandard_case_table, 0, 0, 0,
  "Return the standard case table.\n\
This is the one used for new buffers.")
  ()
{
  return Fcons (Vascii_downcase_table,
		Fcons (Vascii_upcase_table,
		       Fcons (Vascii_canon_table,
			      Fcons (Vascii_eqv_table, Qnil))));
}

static Lisp_Object set_case_table ();

DEFUN ("set-case-table", Fset_case_table, Sset_case_table, 1, 1, 0,
  "Select a new case table for the current buffer.\n\
A case table is a list (DOWNCASE UPCASE CANONICALIZE EQUIVALENCES)\n\
 where each element is either nil or a string of length 256.\n\
DOWNCASE maps each character to its lower-case equivalent.\n\
UPCASE maps each character to its upper-case equivalent;\n\
 if lower and upper case characters are in 1-1 correspondence,\n\
 you may use nil and the upcase table will be deduced from DOWNCASE.\n\
CANONICALIZE maps each character to a canonical equivalent;\n\
 any two characters that are related by case-conversion have the same\n\
 canonical equivalent character.\n\
EQUIVALENCES is a map that cyclicly permutes each equivalence class\n\
 (of characters with the same canonical equivalent).\n\
Both CANONICALIZE and EQUIVALENCES may be nil, in which case\n\
 both are deduced from DOWNCASE and UPCASE.")
  (table)
     Lisp_Object table;
{
  return set_case_table (table, 0);
}

DEFUN ("set-standard-case-table",
       Fset_standard_case_table, Sset_standard_case_table, 1, 1, 0,
  "Select a new standard case table for new buffers.\n\
See `set-case-table' for more info on case tables.")
  (table)
     Lisp_Object table;
{
  return set_case_table (table, 1);
}

static Lisp_Object
set_case_table (table, standard)
     Lisp_Object table;
     int standard;
{
  Lisp_Object down, up, canon, eqv;

  check_case_table (table);

  down = Fcar_safe (table);
  up = Fcar_safe (Fcdr_safe (table));
  canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table)));
  eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table))));

  if (NILP (up))
    {
      up = Fmake_string (make_number (256), make_number (0));
      compute_trt_inverse (XSTRING (down)->data, XSTRING (up)->data);
    }

  if (NILP (canon))
    {
      register int i;
      unsigned char *upvec = XSTRING (up)->data;
      unsigned char *downvec = XSTRING (down)->data;

      canon = Fmake_string (make_number (256), make_number (0));
      eqv = Fmake_string (make_number (256), make_number (0));

      /* Set up the CANON vector; for each character,
	 this sequence of upcasing and downcasing ought to
	 get the "preferred" lowercase equivalent.  */
      for (i = 0; i < 256; i++)
	XSTRING (canon)->data[i] = downvec[upvec[downvec[i]]];

      compute_trt_inverse (XSTRING (canon)->data, XSTRING (eqv)->data);
    }

  if (standard)
    {
      Vascii_downcase_table = down;
      Vascii_upcase_table = up;
      Vascii_canon_table = canon;
      Vascii_eqv_table = eqv;
    }
  else
    {
      current_buffer->downcase_table = down;
      current_buffer->upcase_table = up;
      current_buffer->case_canon_table = canon;
      current_buffer->case_eqv_table = eqv;
    }
  return table;
}

/* Given a translate table TRT, store the inverse mapping into INVERSE.
   Since TRT is not one-to-one, INVERSE is not a simple mapping.
   Instead, it divides the space of characters into equivalence classes.
   All characters in a given class form one circular list, chained through
   the elements of INVERSE.  */

void
compute_trt_inverse (trt, inverse)
     register unsigned char *trt;
     register unsigned char *inverse;
{
  register int i = 0400;
  register unsigned char c, q;

  while (i--)
    inverse[i] = i;
  i = 0400;
  while (i--)
    {
      if ((q = trt[i]) != (unsigned char) i)
	{
	  c = inverse[q];
	  inverse[q] = i;
	  inverse[i] = c;
	}
    }
}

init_casetab_once ()
{
  register int i;
  Lisp_Object tem;

  tem = Fmake_string (make_number (256), make_number (0));
  Vascii_downcase_table = tem;
  Vascii_canon_table = tem;

  for (i = 0; i < 256; i++)
    XSTRING (tem)->data[i] = (i >= 'A' && i <= 'Z') ? i + 040 : i;

  tem = Fmake_string (make_number (256), make_number (0));
  Vascii_upcase_table = tem;
  Vascii_eqv_table = tem;

  for (i = 0; i < 256; i++)
    XSTRING (tem)->data[i]
      = ((i >= 'A' && i <= 'Z')
	 ? i + ('a' - 'A')
	 : ((i >= 'a' && i <= 'z')
	    ? i + ('A' - 'a')
	    : i));
}

syms_of_casetab ()
{
  Qcase_table_p = intern ("case-table-p");
  staticpro (&Qcase_table_p);
  staticpro (&Vascii_downcase_table);
  staticpro (&Vascii_upcase_table);
  staticpro (&Vascii_canon_table);
  staticpro (&Vascii_eqv_table);

  defsubr (&Scase_table_p);
  defsubr (&Scurrent_case_table);
  defsubr (&Sstandard_case_table);
  defsubr (&Sset_case_table);
  defsubr (&Sset_standard_case_table);

#if 0
  DEFVAR_LISP ("ascii-downcase-table", &Vascii_downcase_table,
	       "String mapping ASCII characters to lowercase equivalents.");
  DEFVAR_LISP ("ascii-upcase-table", &Vascii_upcase_table,
	       "String mapping ASCII characters to uppercase equivalents.");
#endif
}