view lwlib/lwlib-Xol.c @ 18260:a642c99198ec

(PTR_TO_OFFSET): New macro. (POS_AS_IN_BUFFER): New macro. (SYNTAX_ENTRY_VIA_PROPERTY): Set to take `syntax-table' text property into account when doing SYNTAX (c). (re_compile_fastmap): disable fastmap if any of wordbound notwordbound wordbeg wordend notsyntaxspec syntaxspec are seen. (re_search_2): SETUP_SYNTAX_TABLE_FOR_OBJECT at the start. (re_match_object): New variable. (re_match_2): SETUP_SYNTAX_TABLE_FOR_OBJECT at the start. (re_match_2_internal): For any of wordbound notwordbound wordbeg wordend notsyntaxspec syntaxspec call UPDATE_SYNTAX_TABLE before doing SYNTAX (c). [emacs]: Include charset.h and category.h [!emacs] (BASE_LEADING_CODE_P, WORD_BOUNDARY_P, CHAR_HEAD_P, SINGLE_BYTE_CHAR_P, SAME_CHARSET_P, MULTIBYTE_FORM_LENGTH, STRING_CHAR_AND_LENGTH, GET_CHAR_AFTER_2, GET_CHAR_BEFORE_2): New dummy macros. (enum re_opcode_t): New member categoryspec and notcategoryspec. (STORE_CHARACTER_AND_INCR, EXTRACT_CHARACTER, CHARSET_LOOKUP_RANGE_TABLE_WITH_COUNT, CHARSET_LOOKUP_RANGE_TABLE, CHARSET_BITMAP_SIZE, CHARSET_RANGE_TABLE_EXISTS_P, CHARSET_RANGE_TABLE CHARSET_PAST_RANGE_TABLE): New macros. (TRANSLATE): Cast return value to unsigned char, not char. (struct range_table_work_area): New structure. (EXTEND_RANGE_TABLE_WORK_AREA, SET_RANGE_TABLE_WORK_AREA, FREE_RANGE_TABLE_WORK_AREA, CLEAR_RANGE_TABLE_WORK_USED, RANGE_TABLE_WORK_USED, RANGE_TABLE_WORK_ELT): New macros. (FREE_STACK_RETURN): Call FREE_RANGE_TABLE_WORK_AREA. (regex_compile): Declare `c' and `c1' as int to store multibyte characters. Declare range_table_work and initialize it. Initialize bufp->multibyte to 0 if not emacs. For case '[' and `default', code re-written to handle multibyte characters. Add code for case 'c' and 'C' to handle category spec. (re_compile_fastmap): New local variables k, simple_char_max, and match_any_multibyte_characters. Use macro CHARSET_BITMAP_SIZE. Handle multibyte characters in cases charset, charset_not, wordchar, notwordchar, anychar, syntaxspec, notsyntaxspec, categoryspec, notcategoryspec. (STOP_ADDR_VSTRING, POS_ADDR_VSTRING): New macros. (re_search_2): Code re-written to handle multibyte characters. (AT_WORD_BOUNDARY): Macro disabled. (re_match_2_internal): New local variable multibyte. `d' is incremented while paying attention to multibyte characters if necessary. For case charset, charsetnot, wordbound, notwordbound, wordbeg, wordend, matchsyntax, and matchnotsyntax, code re-written to handle multibyte characters. Add code for case categoryspec and notcategoryspec. Declare c, c1 as unsigned int, not unsigned char.
author Richard M. Stallman <rms@gnu.org>
date Sun, 15 Jun 1997 19:00:12 +0000
parents 0a94cd2c51c4
children 7fb1caba0f51
line wrap: on
line source

#include "lwlib-Xol.h"
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/CompositeP.h>
#include <X11/Shell.h>
#include <Xol/Menu.h>
#include <Xol/OpenLook.h>
#include <Xol/MenuButton.h>
#include <Xol/OblongButt.h>
#include <Xol/ControlAre.h>
#include <Xol/Stub.h>
#include <Xol/StaticText.h>

/* forward declarations */
static void
update_menu_widget (widget_instance* instance, Widget widget,
		    widget_value* val);

/* Menu callbacks */
static void
pre_hook (Widget w, caddr_t client_data, caddr_t call_data)
{
  OlVirtualEvent ve = (OlVirtualEvent)call_data;
  widget_instance* instance = (widget_instance*)client_data;

  if (w->core.being_destroyed)
    return;

  if (XtParent (w) == instance->widget)
    {
      if (ve->xevent->type == ButtonPress && instance->info->pre_activate_cb)
	instance->info->pre_activate_cb (instance->widget, instance->info->id,
					 NULL);
    }
}

static void
post_hook (Widget w, caddr_t client_data, caddr_t call_data)
{
  widget_instance* instance = (widget_instance*)client_data;
  
  if (w->core.being_destroyed)
    return;
  
  if (instance->info->post_activate_cb)
    instance->info->post_activate_cb (w, instance->info->id, NULL);
}

static void
pick_hook (Widget w, caddr_t client_data, caddr_t call_data)
{
  widget_instance* instance = 0;
  widget_value* val = (widget_value*)client_data;

  if (w->core.being_destroyed)
    return;

  XtVaGetValues (w, XtNuserData, &instance, 0);

  if (!instance)
    return;

  if (instance->info->selection_cb && val && val->enabled
      && !val->contents)
    instance->info->selection_cb (w, instance->info->id, val->call_data);
}

/* creation functions */
static Widget
xol_create_menubar (widget_instance* instance)
{
  Widget widget =
    XtVaCreateWidget (instance->info->name, controlAreaWidgetClass,
		      instance->parent, 0);
  return widget;
}

static Widget
xol_create_popup_menu (widget_instance* instance)
{
  Widget popup_shell =
    XtCreatePopupShell (instance->info->name, menuShellWidgetClass,
			instance->parent, NULL, 0);
  return popup_shell;
}

widget_creation_entry 
xol_creation_table [] =
{
  {"menubar", xol_create_menubar},
  {"popup", xol_create_popup_menu},
  {NULL, NULL}
};

Widget 
xol_create_dialog (widget_instance* instance)
{
  return NULL;
}

Boolean
lw_olit_widget_p (Widget widget)
{
  return True;
}

/* update functions */
static void
destroy_all_children (Widget widget)
{
  Widget* children;
  unsigned int number;
  int i;

  children = (Widget *) XtCompositeChildren (widget, &number);
  if (children)
    {
      /* Unmanage all children and destroy them.  They will only be 
       * really destroyed when we get out of DispatchEvent. */
      for (i = 0; i < number; i++)
	{
	  Widget child = children [i];
	  if (!child->core.being_destroyed)
	    {
	      XtUnmanageChild (child);
	      XtDestroyWidget (child);
	    }
	}
      XtFree (children);
    }
}

static Boolean
all_dashes_p (char* s)
{
  char* t;
  for (t = s; *t; t++)
    if (*t != '-')
      return False;
  return True;
}

static void
make_menu_in_widget (widget_instance* instance, Widget widget,
		     widget_value* val)
{
  widget_value* cur;
  Widget button;
  Arg al [256];
  int ac;
  String label;

  for (cur = val; cur; cur = cur->next)
    {    
      ac = 0;
      XtSetArg (al [ac], XtNsensitive, cur->enabled); ac++;
      XtSetArg (al [ac], XtNuserData, instance); ac++;
      XtSetArg (al [ac], XtNacceleratorText, cur->key); ac++;
      
/*      label = (char *) resource_string (widget, cur->name);*/
      label = cur->name;
      if (label)
	{
	  XtSetArg (al [ac], XtNlabel, label); ac++;
	}

      if (all_dashes_p (cur->name))
	{
	  /* no separator in OpenLook just make some space. */
	  XtSetArg (al [ac], XtNheight, 5); ac++;
	  XtSetArg (al [ac], XtNwidth, 5); ac++;
	  button = XtCreateWidget (cur->name, stubWidgetClass, widget, al, ac);
	}
      else if (!cur->contents)
	{
	  if (!cur->call_data)
	    button =
	      XtCreateManagedWidget (cur->name, staticTextWidgetClass, widget,
				     al, ac);
	  else
	    {
	      button =
		XtCreateManagedWidget (cur->name, oblongButtonWidgetClass,
				       widget, al, ac);
	      XtAddCallback (button, XtNselect, pick_hook, cur);
	    }
	}
      else
	{
	  Widget menu = NULL;
	  button =
	    XtCreateManagedWidget (cur->name, menuButtonWidgetClass, widget,
				   al, ac);
	  XtVaGetValues (button, XtNmenuPane, &menu, 0);
	  if (!menu)
	    abort ();
	  make_menu_in_widget (instance, menu, cur->contents);
	  OlAddCallback (button, XtNconsumeEvent, pre_hook, instance);
	}
    }
}

static void
update_one_menu_entry (widget_instance* instance, Widget widget,
		       widget_value* val)
{
  Arg al [256];
  int ac;
  Widget menu;
  widget_value* contents;

  if (val->change == NO_CHANGE)
    return;

  /* update the sensitivity */
  XtVaSetValues (widget, XtNsensitive, val->enabled, 0);

  /* update the pulldown/pullaside as needed */
  ac = 0;
  menu = NULL;
  XtVaGetValues (widget, XtNmenuPane, &menu, 0);
  contents = val->contents;

  if (!menu)
    {
      if (contents)
	{
	  /* in OLIT this would have to be a structural change on the
	     button. */
	  abort ();
	}
    }
  else if (!contents)
    {
      /* in OLIT this would have to be a structural change on the button. */
      abort ();
    }
  else if (contents->change != NO_CHANGE)
    update_menu_widget (instance, menu, val);
}

static void
update_menu_widget (widget_instance* instance, Widget widget,
		    widget_value* val)

{
  if (val->change == STRUCTURAL_CHANGE
      || val->contents->change == STRUCTURAL_CHANGE)
    {
      destroy_all_children (widget);
      make_menu_in_widget (instance, widget, val->contents);
    }
  else
    {
      /* Update all the buttons of the composite widget in order. */
      Widget* children;
      unsigned int num_children;
      int i;
      widget_value* cur;
      
      children = (Widget *) XtCompositeChildren (widget, &num_children);
      if (children)
	{
	  for (i = 0, cur = val->contents; i < num_children; i++)
	    {
	      if (!cur)
		abort ();
	      if (children [i]->core.being_destroyed
		  || strcmp (XtName (children [i]), cur->name))
		continue;
	      update_one_menu_entry (instance, children [i], cur);
	      cur = cur->next;
	    }
	  XtFree (children);
	}
      if (cur)
	abort ();
    }
}

void
xol_update_one_widget (widget_instance* instance, Widget widget,
		       widget_value* val, Boolean deep_p)
{
  Widget menu = widget;

  if (XtIsShell (widget))
    XtVaGetValues (widget, XtNmenuPane, &menu, 0);

  update_menu_widget (instance, menu, val);
}

void
xol_update_one_value (widget_instance* instance, Widget widget,
		      widget_value* val)
{
  return;
}

void
xol_pop_instance (widget_instance* instance, Boolean up)
{
}

void
xol_popup_menu (Widget widget)
{
  OlMenuPost (widget);
}

/* Destruction of instances */
void
xol_destroy_instance (widget_instance* instance)
{
  XtDestroyWidget (instance->widget);
}