Article 2758 of comp.sources.unix:
Submitted-By: mik@cs.su.oz.au (Michael Koelling)
Posting-Number: Volume 29, Issue 98
Archive-Name: red-96/part03

#!/bin/sh
# This is `part03' (part 3 of a multipart archive).
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
# File `Red/Utility/messages.cc' is being continued...
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if test ! -r _sharseq.tmp; then
  echo 'Please unpack part 1 first!'
  exit 1
fi
shar_sequence=`cat _sharseq.tmp`
if test "$shar_sequence" != 3; then
  echo "Please unpack part $shar_sequence next!"
  exit 1
fi
if test ! -f _sharnew.tmp; then
  echo 'x - still skipping Red/Utility/messages.cc'
else
  echo 'x - continuing file Red/Utility/messages.cc'
  sed 's/^X//' << 'SHAR_EOF' >> '_sharuue.tmp' &&
XM("`@(")T:&4@<&%R86UE=&5R<R!F;W(@=&AE(')O=71I;F4@8V%L;"Y<;EQN
XM(@H@("`@(D%T('1H92!T;W`@;V8@=&AE(&1I86QO9RP@=&AE('-I9VYA='5R
XM92!O9B!T:&4@<F]U=&EN92!I<R!S:&]W;BX@(%EO=5QN(@H@("`@(F-A;B!S
XM964@=&AE<F4L('=H870@:VEN9"!O9B!P87)A;65T97)S(&%R92!E>'!E8W1E
XM9"X@(%1H92!T97AT(&%R96%<;B(*("`@(")T:&4@8F]T=&]M(&ES('5S960@
XM=&\@96YT97(@=&AE('!A<F%M971E<G,N("!4:&4@;&ES="!I;B!T:&4@;6ED
XM9&QE7&XB"B`@("`B;&ES=',@86QL('!R979I;W5S(&-A;&QS("T@;VYE(&-L
XM:6-K(&]N(&$@;&ES="!E;&5M96YT+"!S96QE8W1S('1H871<;B(*("`@(")P
XM87)A;65T97(@8V]M8FEN871I;VX@=&\@<F5P96%T('1H870@8V%L;"Y<;EQN
XM(@H@("`@(EEO=2!C86X@86QS;R!C;&EC:R!O;B!A;B!O8FIE8W0@:6X@=&AE
XM(&UA:6X@4')O:F5C="!7:6YD;W<@*&]N('1H95QN(@H@("`@(F]B:F5C="!B
XM96YC:"D@=&\@:6YS97)T('1H870@;V)J96-T)W,@;F%M92!A<R!A('!A<F%M
XM971E<BXB.PH*("!H96QP6TAL<$9U;F-297-=(#T*("`@(")4:&ES(&ES('1H
XM92!&=6YC=&EO;B!297-U;'0@86YD($]B:F5C="!);G-P96-T($1I86QO9RX@
XM("XN+B(["@H@(&AE;'!;2&QP5&]O36%N>5!A<ET@/0H@("`@(E-O<G)Y+"!T
XM:&ES(&5N=FER;VYM96YT(&-A;B!C=7)R96YT;'D@<&%S<R!O;FQY(#$P(&EN
XM=&5R86-T:79E7&XB"B`@("`B;V)J96-T<R!A<R!P87)A;65T97)S+B`@4V]M
XM96]N92!W87,@=&]O(&QA>GD@=&\@;6%K92!A(&)E='1E<EQN(@H@("`@(FEM
XM<&QE;65N=&%T:6]N+B(["@H@(&AE;'!;2&QP3F]#;VUP:6QE72`]"B`@("`B
XM3F]T:&EN9R!T;R!C;VUP:6QE+B`@06QL(&-L87-S97-<;B(*("`@(")A<F4@
XM=7`@=&\@9&%T92XB.PH*("`O+R`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM"@H@('%U97-T:6]N<R`](&YE=R!154535$E/3BH@
XM6TY27T]&7U%515-424].4UT["@H@('%U97-T:6]N<UM1=5)E;6]V94-L87-S
XM72`](&YE=R!154535$E/3B`H"B`@("`B1&\@>6]U('=A;G0@=&\@<F5M;W9E
XM('1H92!C;&%S<R!F<F]M7&YY;W5R('!R;VIE8W0_+EQN(@H@("`@(BA)9B!I
XM="!I<R!N;W0@82!L:6)R87)Y(&-L87-S+"!I="!W:6QL(&)E(&1E;&5T961<
XM;G!E<FUA;F5N=&QY(2DB+`H@("`@(E)E;6]V92(L($Y53$PL('1R=64I.PH*
XM("!Q=65S=&EO;G-;4753879E0VAA;F=E<UT@/2!N97<@455%4U1)3TX@*`H@
XM("`@(E1H92!T97AT(&AA<R!B965N(&-H86YG960N7&Y3879E(&-H86YG97,_
XM(BP@"B`@("`B4V%V92(L(")$;VXG="!S879E(BP@=')U92D["@H@('%U97-T
XM:6]N<UM1=5)E=F5R=%T@/2!N97<@455%4U1)3TX@*`H@("`@(E)E=F5R="!D
XM:7-C87)D<R!A;&P@8VAA;F=E<R!S:6YC92!T:&4@;&%S="!S879E+EQN07)E
XM('EO=2!S=7)E/R(L(`H@("`@(E)E=F5R="(L($Y53$PL('1R=64I.PH*("!Q
XM=65S=&EO;G-;475+97E$969A=6QT<UT@/2!N97<@455%4U1)3TX@*`H@("`@
XM(E-E='1I;F<@=&AE(&ME>2!B:6YD:6YG<R!B86-K('1O(&1E9F%U;'1S7&XB
XM"B`@("`B<&5R;6%N96YT;'D@9&5L971E<R!Y;W5R('!E<G-O;F%L(&ME>2!B
XM:6YD:6YG<RY<;EQN(@H@("`@(D1O('EO=2!W86YT('1O(&1O('1H870_(BP*
XM("`@(")3970@1&5F875L=',B+"!.54Q,+"!T<G5E*3L*"B`@<75E<W1I;VYS
XM6U%U0V]M<&EL95T@/2!N97<@455%4U1)3TX@*`H@("`@(EEO=2!C86X@;F]T
XM(&-R96%T92!A;B!O8FIE8W0@=VET:&]U="!C;VUP:6QI;F<@=&AE7&XB"B`@
XM("`B8VQA<W,@9FER<W0N7&Y<;B(*("`@(")$;R!Y;W4@=V%N="!T;R!C;VUP
XM:6QE(&%N9"!T:&5N(&-R96%T92!A;B!O8FIE8W0_(BP*("`@(")#;VUP:6QE
XM("8@0W)E871E(BP@3E5,3"P@=')U92D["@H@('%U97-T:6]N<UM1=51E<FUI
XM;F%T94UA8VAI;F5=(#T@;F5W(%%515-424].("@*("`@(")4:&4@;6%C:&EN
XM92!I<R!S=&EL;"!E>&-U=&EN9R`H:70@:&%S(&IU<W0@8F5E;EQN(@H@("`@
XM(FEN=&5R<G5P=&5D*2Y<;EQN(@H@("`@(D1O('EO=2!W86YT('1O('1E<FUI
XM;F%T92!T:&%T(&5X96-U=&EO;B!A;F0@<W1A<G1<;B(*("`@(")A(&YE=R!O
XM;F4_(BP*("`@(")497)M:6YA=&4B+"!.54Q,+"!T<G5E*3L*?0H*+R\@+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0HO+R!S:&]W7VAE;'`Z($1I<W!L
XM87D@86X@:&5L<"!M97-S86=E(&EN(&$@9&EA;&]G(&)O>"X*+R\@+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0H*=F]I9"!-15-304=%4SHZ<VAO=U]H
XM96QP("A7:61G970@<&%R96YT+"!-97-S86=E260@;7-G*0I["B`@1$E!3$]'
XM("ID;&<["@H@(&1L9R`](&YE=R!$24%,3T<@*'!A<F5N="P@:&5L<%MM<V==
XM+"!&86QS92P@+3$I.PI]"@HO+R`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM"B\O('-H;W=?97)R;W(Z($1I<W!L87D@86X@97)R;W(@;65S<V%G92!I
XM;B!A(&1I86QO9R!B;W@N"B\O("TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2T*"G9O:60@34534T%'15,Z.G-H;W=?97)R;W(@*%=I9&=E="!P87)E;G0L
XM($UE<W-A9V5)9"!M<V<I"GL*("!$24%,3T<@*F1L9SL*"B`@9&QG(#T@;F5W
XM($1)04Q/1R`H<&%R96YT+"!E<G)O<EMM<V==+"!4<G5E+"!M<V<I.PI]"@HO
XM+R`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM"B\O(&-L;W-E7V1I86QO
XM9SH@0VQO<V4@82!H96QP(&]R(&5R<F]R(&1I86QO9RX*+R\@+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+0H*=F]I9"!-15-304=%4SHZ8VQO<V5?9&EA
XM;&]G("A$24%,3T<J(&1L9RD*>PH@(&1E;&5T92!D;&<["GT*"B\O("TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T*+R\@<VAO=U]Q=65S=&EO;CH@1&ES
XM<&QA>2!A('%U97-T:6]N(&EN(&$@9&EA;&]G(&)O>"X*+R\@+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+0H*=F]I9"!-15-304=%4SHZ<VAO=U]Q=65S
XM=&EO;B`H5VED9V5T('!A<F5N="P@475E<W1I;VY)1"!1260L"@D)"0E8=$-A
XM;&QB86-K4')O8R!C86QL8F%C:RP@6'10;VEN=&5R(&-A;&QE<BD*>PH@("AV
XM;VED*2!N97<@455%4U1)3TY?1$Q'("AP87)E;G0L(`H)"2`@("!Q=65S=&EO
XM;G-;44ED72T^=&5X="P@<75E<W1I;VYS6U%)9%TM/GEE<U]L86)E;"P@"@D)
XM("`@('%U97-T:6]N<UM1261=+3YN;U]L86)E;"P@<75E<W1I;VYS6U%)9%TM
XM/FAA<U]C86YC96PL(`H)"2`@("!C86QL8F%C:RP@8V%L;&5R*3L*?0H*+R\@
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0HO+R!C;&]S95]Q=65S=&EO
XM;CH@0VQO<V4@82!Q=65S=&EO;B!D:6%L;V<N"B\O("TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
XM+2TM+2TM+2TM+2TM+2T*"EAT4&]I;G1E<B!-15-304=%4SHZ8VQO<V5?<75E
XM<W1I;VX@*%AT4&]I;G1E<B!D;&<L(%=I9&=E="!B=71T;VXL(`H)"0D)("`@
XM(&)O;VPF('EE<U]N;RD*>PH@(%AT4&]I;G1E<B!C86QL97(["@H@(&-A;&QE
XM<B`]("@H455%4U1)3TY?1$Q'*BED;&<I+3YG971?86YS=V5R("AB=71T;VXL
XM('EE<U]N;RD["B`@9&5L971E("A154535$E/3E]$3$<J*61L9SL*("!R971U
X-<FX@8V%L;&5R.PI]"F5L
X`
Xend
SHAR_EOF
  echo 'File Red/Utility/messages.cc is complete' &&
  echo 'uudecoding file Red/Utility/messages.cc' &&
  uudecode _sharuue.tmp < _sharuue.tmp && rm -f _sharuue.tmp &&
  $shar_touch -am 0512222696 'Red/Utility/messages.cc' &&
  chmod 0640 'Red/Utility/messages.cc' ||
  echo 'restore of Red/Utility/messages.cc failed'
  shar_count="`wc -c < 'Red/Utility/messages.cc'`"
  test 19678 -eq "$shar_count" ||
    echo "Red/Utility/messages.cc: original size 19678, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/messages.h ==============
if test -f 'Red/Utility/messages.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/messages.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/messages.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/messages.h' &&
X#ifndef _MESSAGES_H
X#define _MESSAGES_H
X
X// ============================================================================
X//
X//  Class name: MESSAGES
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	MESSAGES is part of the Blue Language integrated environment.
X//
X//	... (to be continued)
X//
X//	MESSAGES implements...
X//
X// ============================================================================
X
X#include <Xm/Xm.h>
X#include "dialog.h"
X#include "question.h"
X
X// IDs for help messages and error messages shown in pop-up dialogs
X
Xenum MessageId {
X  ErrLoadProject, ErrSaveProject, ErrSaveCode, ErrNewProject, ErrSelectFirst, 
X  ErrSaveBindings, ErrReadPrefs, ErrReadKeys, ErrFinishFirst, ErrNotCompiled, 
X  ErrLinking, ErrNoName, ErrCrtManifest, ErrRuntime, 
X  NR_OF_ERRORS,
X
X  HlpNYI, HlpFileSelect, HlpFind, HlpPref, HlpUserFunc,
X  HlpAbout, HlpCopyright, HlpMouse, HlpErrors, HlpReadOnly,
X  HlpCantRedefine, HlpChangingPref, HlpFuncCall, HlpFuncRes, HlpTooManyPar, 
X  HlpNoCompile, 
X  NR_OF_HELP
X};
X
Xenum QuestionID {
X  QuRemoveClass, QuSaveChanges, QuRevert, QuKeyDefaults, QuCompile, 
X  QuTerminateMachine, 
X  NR_OF_QUESTIONS
X};
X
Xclass MESSAGES {
X
X  friend void show_help (Widget w, XtPointer msg_number, XtPointer call_data);
X  friend void MESSAGES__close_dialog (Widget w, XtPointer user_data, 
X				    XtPointer call_data);
X
X  public:
X    MESSAGES ();
X
X    void show_help (Widget parent, MessageId msg);
X
X    void show_error (Widget parent, MessageId msg);
X
X    void close_dialog (DIALOG* dlg);
X
X    void show_question (Widget parent, 
X			QuestionID QId,
X			XtCallbackProc callback,
X			XtPointer caller);
X
X
X    XtPointer close_question (XtPointer dlg, Widget button, bool& yes_no);
X
X	// Close the question dialog box.
X	// 'dlg' is the dialog pointer passed on by the callback, 'button' is
X	// the widget that caused the callback. The following values are 
X	// returned: 
X	//   'yes_no' is true, if 'yes' was clicked, false for 'no'.
X	//   The function result is the caller that posed this question.
X
X
X  private:
X    char **help;		// array with the help messages
X    char **error;		// array with the error messages
X    QUESTION **questions;
X};
X
Xextern MESSAGES *messages;	// declare the GLOBAL messages object
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/messages.h' &&
  chmod 0640 'Red/Utility/messages.h' ||
  echo 'restore of Red/Utility/messages.h failed'
  shar_count="`wc -c < 'Red/Utility/messages.h'`"
  test 2243 -eq "$shar_count" ||
    echo "Red/Utility/messages.h: original size 2243, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/pdf ==============
if test -f 'Red/Utility/pdf' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/pdf (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/pdf (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/pdf' &&
X0x0
X0
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/pdf' &&
  chmod 0640 'Red/Utility/pdf' ||
  echo 'restore of Red/Utility/pdf failed'
  shar_count="`wc -c < 'Red/Utility/pdf'`"
  test 6 -eq "$shar_count" ||
    echo "Red/Utility/pdf: original size 6, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/question.h ==============
if test -f 'Red/Utility/question.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/question.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/question.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/question.h' &&
X#ifndef _QUESTION_H
X#define _QUESTION_H
X
X// ============================================================================
X//
X//  Class name: QUESTION
X//
X//  Author: M. Koelling							1996
X//
X//  Description:
X//
X//	QUESTION is part of the Blue Language integrated environment.
X//
X//	... (to be continued)
X//
X// ============================================================================
X
Xclass QUESTION {
X
X  public:
X
X    QUESTION (char *txt, char *yes, char *no, bool canc)
X	: text(txt), yes_label(yes), no_label(no), has_cancel(canc) {};
X
X    char *text;
X    char *yes_label;
X    char *no_label;
X    bool has_cancel;
X};
X
X#endif
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/question.h' &&
  chmod 0640 'Red/Utility/question.h' ||
  echo 'restore of Red/Utility/question.h failed'
  shar_count="`wc -c < 'Red/Utility/question.h'`"
  test 628 -eq "$shar_count" ||
    echo "Red/Utility/question.h: original size 628, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/stdfunc.cc ==============
if test -f 'Red/Utility/stdfunc.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/stdfunc.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/stdfunc.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/stdfunc.cc' &&
X#include "stdfunc.h"
X
X// name_equal: string equality, case tolerant
X
Xbool name_equal (char *s, char *t)
X{
X  while (*s) {
X    if (tolower(*s++) != tolower(*t++))
X      return false;
X  }
X  return *t == '\0';
X}
X  
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/stdfunc.cc' &&
  chmod 0640 'Red/Utility/stdfunc.cc' ||
  echo 'restore of Red/Utility/stdfunc.cc failed'
  shar_count="`wc -c < 'Red/Utility/stdfunc.cc'`"
  test 211 -eq "$shar_count" ||
    echo "Red/Utility/stdfunc.cc: original size 211, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/question_dlg.cc ==============
if test -f 'Red/Utility/question_dlg.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/question_dlg.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/question_dlg.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/question_dlg.cc' &&
X// ============================================================================
X//  File: question_dlg.cc					-mik- 1995
X//
X//  Implementation of class QUESTION_DLG.  See question_dlg.h for description.
X//  Question_Dlg is part of the Blue programming environment.
X// ============================================================================
X
X#include <Xm/MessageB.h>
X
X#include "question_dlg.h"
X#include "../Utility/utility.h"
X
X
X// ============================= CALLBACKS =================================
X
X// QUESTION DIALOG: cancel is for all of them
X
Xvoid question_dlg_cancel_cb (Widget w, XtPointer dlg, XtPointer call_data)
X{
X  delete (QUESTION_DLG*)dlg;
X}
X
X// ========================== END OF CALLBACKS ==============================
X
X// -------------------------------------------------------------------------
X//  QUESTION_DLG: Contructor. Create a file selection dialog and show it on 
X//	screen.
X// -------------------------------------------------------------------------
X
XQUESTION_DLG::QUESTION_DLG (Widget parent, char* question, char* yes, char* no, 
X			    bool has_cancel,
X			    XtCallbackProc callback, XtPointer caller)
X{
X  Arg al[10];
X  int ac;
X
X  XmString q_string = XmStringCreateLtoR (question, XmSTRING_DEFAULT_CHARSET);
X  XmString yes_string = XmStringCreateLtoR (yes, XmSTRING_DEFAULT_CHARSET);
X
X  called_by = caller;
X
X  ac=0;
X  XtSetArg (al[ac], XmNnoResize, True); ac++;
X  XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++;
X  XtSetArg (al[ac], XmNautoUnmanage, False); ac++;
X  XtSetArg (al[ac], XmNmessageString, q_string); ac++;
X  XtSetArg (al[ac], XmNokLabelString, yes_string); ac++;
X  dialog = XmCreateQuestionDialog (parent, "DialogQuestion", al, ac);
X
X  XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
X  if (has_cancel)
X    XtAddCallback (dialog, XmNcancelCallback, question_dlg_cancel_cb, this);
X  else
X    XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
X  XtAddCallback (dialog, XmNokCallback, callback, this);
X  if (no != NULL) {
X    no_button = utility->create_button (dialog, "NoButton", 
X				        callback, (int)this, this);
X    utility->set_label (no_button, no);
X  }
X  else
X    no_button = NULL;
X
X  XtManageChild (dialog);
X  XmStringFree (q_string);
X  XmStringFree (yes_string);
X}
X
X// -------------------------------------------------------------------------
X//  ~QUESTION_DLG: Destructor. The file selection dialog is removed from screen
X//	and all data structures deallocated.
X// -------------------------------------------------------------------------
X
XQUESTION_DLG::~QUESTION_DLG ()
X{
X  XtDestroyWidget (dialog);
X}
X
X// -------------------------------------------------------------------------
X//  get_answer: Return information about the editor that posed this question
X//	and whether the button pressed was yes or no.
X// -------------------------------------------------------------------------
X
XXtPointer QUESTION_DLG::get_answer (Widget button, bool& yes_no)
X{
X  if (button == no_button)
X    yes_no = false;
X  else
X    yes_no = true;
X  return called_by;
X}
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/question_dlg.cc' &&
  chmod 0640 'Red/Utility/question_dlg.cc' ||
  echo 'restore of Red/Utility/question_dlg.cc failed'
  shar_count="`wc -c < 'Red/Utility/question_dlg.cc'`"
  test 3084 -eq "$shar_count" ||
    echo "Red/Utility/question_dlg.cc: original size 3084, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/question_dlg.h ==============
if test -f 'Red/Utility/question_dlg.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/question_dlg.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/question_dlg.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/question_dlg.h' &&
X#ifndef _QUESTION_DLG_H
X#define _QUESTION_DLG_H
X
X// ============================================================================
X//
X//  Class name: QUESTION_DLG
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	QUESTION_DLG is part of the Blue Language integrated environment.
X//
X//	QUESTION_DLG implements a dialog to post a yes/no question.  It can
X//	have three buttons: the "yes" choice, the "no" choice and "cancel".
X//
X// ============================================================================
X
X#include <Xm/Xm.h>
X
Xclass QUESTION_DLG {
X
X  friend void question_dlg_cancel_cb (Widget w, XtPointer dlg, 
X			XtPointer call_data);
X
X  public:
X    QUESTION_DLG (Widget parent,
X		  char* question,		// The text of the question
X		  char* yes,			// Text of the "yes" button
X		  char* no, 			// Text of the "no" button or
X						//  NULL if no "no" button
X		  bool has_cancel,		// True for Cancel button
X		  XtCallbackProc callback,	// (only for yes/no)
X		  XtPointer caller);
X
X	// Pop up a question dialog.  If the cancel button is pressed, the 
X	// callback will never get called.  If yes or no get clicked, the 
X	// callback will be called with the question_dlg as an argument.
X	// This can then be used to find out the answer.  The question_dlg
X	// should be deleted in the callback.
X
X
X    ~QUESTION_DLG ();
X
X
X    XtPointer get_answer (Widget button, bool& yes_no);
X
X	// Find out whether the button pressed in this dialog (button) was
X	//  the yes or no button.  Also return the object that posed this 
X	//  question.
X
X  private:
X
X    XtPointer called_by;		// the editor which called this dialog
X    Widget dialog;
X    Widget no_button;
X};
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/question_dlg.h' &&
  chmod 0640 'Red/Utility/question_dlg.h' ||
  echo 'restore of Red/Utility/question_dlg.h failed'
  shar_count="`wc -c < 'Red/Utility/question_dlg.h'`"
  test 1666 -eq "$shar_count" ||
    echo "Red/Utility/question_dlg.h: original size 1666, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/stdfunc.h ==============
if test -f 'Red/Utility/stdfunc.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/stdfunc.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/stdfunc.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/stdfunc.h' &&
X#ifndef _STD_FUNC_H
X#define _STD_FUNC_H
X
Xextern "C" int rename (const char *oldname, const char *newname);
Xextern "C" void bcopy (register char *s1, register char *s2, int len);
X
X// for realloc
X#include <stdlib.h>
X#include <ctype.h>		// fir "isalpha", "isspace", ...
X
X// name_equal: string equality, case tolerant
X
Xextern "C" bool name_equal (char *s, char *t);
Xextern "C" void cleanup_and_exit ();
X
X#endif
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/stdfunc.h' &&
  chmod 0640 'Red/Utility/stdfunc.h' ||
  echo 'restore of Red/Utility/stdfunc.h failed'
  shar_count="`wc -c < 'Red/Utility/stdfunc.h'`"
  test 407 -eq "$shar_count" ||
    echo "Red/Utility/stdfunc.h: original size 407, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/support.cc ==============
if test -f 'Red/Utility/support.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/support.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/support.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/support.cc' &&
X// ============================================================================
X//
X//  File name: support.cc
X//
X//  Author: M. Koelling
X//
X//  Description:
X//
X//	Implementation of support functions.
X//
X// ============================================================================
X
X#include "../Project/defines.h"
X
X// ---------------------------------------------------------------------------
X//  replace_suffix: Takes a 'filename' which is expected to end in a Blue 
X//	suffix (in the format ".xxx") and replaces that suffix with the new
X//	suffix given in 'suffix'.
X//	The new filename is returned in a new string, the old filename remains
X//	unchanged.
X// ---------------------------------------------------------------------------
X
Xchar *replace_suffix (char *filename, char *suffix)
X{
X  char* newname;
X  int len, i;
X
X  len = strlen(filename);
X  newname = new char [len + 1];
X  strcpy (newname, filename);
X  for (i=0; i<SUFFIX_LEN; i++) 
X    newname[len - SUFFIX_LEN + i] = suffix[i];
X  return newname;
X}
X
X// ---------------------------------------------------------------------------
X//  new_strdup: This routine is used to ensure that any strings passed to the
X//	exception handlers can be delete()d. It is intended to be a replacement
X//	for the standard strdup() routine and uses new() instead of malloc().
X//	ARGS
X//	   s = the string to be duplicated
X//	 RETURNS
X//	   A pointer new()ly allocated buffer containing the string
X// ---------------------------------------------------------------------------
X
Xchar *new_strdup(const char *s)
X{
X  return strcpy(new char[strlen(s) + 1], s);
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/support.cc' &&
  chmod 0640 'Red/Utility/support.cc' ||
  echo 'restore of Red/Utility/support.cc failed'
  shar_count="`wc -c < 'Red/Utility/support.cc'`"
  test 1600 -eq "$shar_count" ||
    echo "Red/Utility/support.cc: original size 1600, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/support.h ==============
if test -f 'Red/Utility/support.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/support.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/support.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/support.h' &&
X#ifndef _SUPPORT_H
X#define _SUPPORT_H
X
X// ============================================================================
X//
X//  File name: support.h
X//
X//  Author: M. Koelling
X//
X//  Description:
X//
X//	This file contains a few support functions that are used in different 
X//	places and do not belong to any particular object.
X//
X//	They are C functions.
X//
X// ============================================================================
X
Xchar *replace_suffix (char *filename, char *suffix);
X
X	// Create a new string with a filename from 'filename', where the
X	// original suffix in 'filename' is replaced by the new suffix
X	// given in 'suffix'.
X	// The filename MUST have a suffix of SUFFIX_LEN
X	// 'suffix' MUST be of length SUFFIX_LEN
X	// The old filename remains unchanged.
X
X
X#define	STRDUP(s)	new_strdup((s))
X
Xchar* new_strdup (const char *s);
X
X	//   This routine is used to ensure that any strings passed to the
X	//   exception handlers can be delete()d. It is intended to be a 
X	//   replacement or the standard strdup() routine and uses new() 
X	//   instead of malloc().
X	// ARGS
X	//   s = the string to be duplicated
X	// RETURNS
X	//   A pointer new()ly allocated buffer containing the string
X
X
X
X#endif
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/support.h' &&
  chmod 0640 'Red/Utility/support.h' ||
  echo 'restore of Red/Utility/support.h failed'
  shar_count="`wc -c < 'Red/Utility/support.h'`"
  test 1210 -eq "$shar_count" ||
    echo "Red/Utility/support.h: original size 1210, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/template.cc ==============
if test -f 'Red/Utility/template.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/template.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/template.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/template.cc' &&
X// ============================================================================
X//  File: tt.cc						-mik- 1995
X//
X//  Implementation of class TT.  See tt.h for description.
X//  Tt is part of the Blue programming environment.
X// ============================================================================
X
X#include "tt.h"
X
X// -------------------------------------------------------------------------
X//  
X// -------------------------------------------------------------------------
X
XTT::TT ()
X{
X}
X
X// -------------------------------------------------------------------------
X//  
X// -------------------------------------------------------------------------
X
XTT::~TT ()
X{
X}
X
X// -------------------------------------------------------------------------
X//  
X// -------------------------------------------------------------------------
X
Xvoid TT:: ()
X{
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/template.cc' &&
  chmod 0640 'Red/Utility/template.cc' ||
  echo 'restore of Red/Utility/template.cc failed'
  shar_count="`wc -c < 'Red/Utility/template.cc'`"
  test 853 -eq "$shar_count" ||
    echo "Red/Utility/template.cc: original size 853, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/template.h ==============
if test -f 'Red/Utility/template.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/template.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/template.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/template.h' &&
X#ifndef _TT_H
X#define _TT_H
X
X// ============================================================================
X//
X//  Class name: TT		(part of the BLUE programming environment)
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	TT is part of the Blue Language integrated environment.
X//
X//	TT implements...
X//
X// ============================================================================
X//  VERSION	BY	DATE	DESCRIPTION
X// ----------------------------------------------------------------------------
X//  0.1		mik	6/95	first test version
X// ============================================================================
X
X
Xclass TT {
X
X  public:
X    TT ();
X    ~TT ();
X
X  private:
X
X};
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/template.h' &&
  chmod 0640 'Red/Utility/template.h' ||
  echo 'restore of Red/Utility/template.h failed'
  shar_count="`wc -c < 'Red/Utility/template.h'`"
  test 702 -eq "$shar_count" ||
    echo "Red/Utility/template.h: original size 702, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/textregion.cc ==============
if test -f 'Red/Utility/textregion.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/textregion.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/textregion.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/textregion.cc' &&
X// ============================================================================
X//  File: textregion.cc						-mik- 1995
X//
X//  Implementation of class TEXTREGION.  See textregion.h for description.
X//  Textregion is part of the Blue programming environment.
X// ============================================================================
X
X#include "textregion.h"
X
X// -------------------------------------------------------------------------
X//  set: Set the values of this region
X// -------------------------------------------------------------------------
X
Xvoid TEXTREGION::set (int sline, int scol, int eline, int ecol)
X{
X  start_line = sline;
X  start_col = scol;
X  end_line = eline;
X  end_col = ecol;
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/textregion.cc' &&
  chmod 0640 'Red/Utility/textregion.cc' ||
  echo 'restore of Red/Utility/textregion.cc failed'
  shar_count="`wc -c < 'Red/Utility/textregion.cc'`"
  test 707 -eq "$shar_count" ||
    echo "Red/Utility/textregion.cc: original size 707, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/textregion.h ==============
if test -f 'Red/Utility/textregion.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/textregion.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/textregion.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/textregion.h' &&
X#ifndef _TEXTREGION_H
X#define _TEXTREGION_H
X
X// ============================================================================
X//
X//  Class name: TEXTREGION     	(part of the BLUE programming environment)
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	TEXTREGION is part of the Blue Language integrated environment.
X//
X//	TEXTREGION is used to specify an area in a text.  It uses four integer
X//	values, definig the start line and column and the end line and column
X//	of the region defined by this instance.
X//
X//	The value (-1, -1, -1, -1) for the four fields is used to indicate an
X//	invalid region (no region) in cases where no valid region can be 
X//	defined.
X//
X// ============================================================================
X//  VERSION	BY	DATE	DESCRIPTION
X// ----------------------------------------------------------------------------
X//  0.1		mik	1/96	first test version
X// ============================================================================
X
X
Xclass TEXTREGION {
X
X  public:
X    void set (int sline, int scol,	// set the four values defining this
X	 int eline, int ecol);		//  region
X
X    int start_line;			// line number of start of region
X    int start_col;		       	// column number of start of region
X    int end_line;			// line number of end of region
X    int end_col;			// column number of end of region
X};
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/textregion.h' &&
  chmod 0640 'Red/Utility/textregion.h' ||
  echo 'restore of Red/Utility/textregion.h failed'
  shar_count="`wc -c < 'Red/Utility/textregion.h'`"
  test 1371 -eq "$shar_count" ||
    echo "Red/Utility/textregion.h: original size 1371, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/types.h ==============
if test -f 'Red/Utility/types.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/types.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/types.h (binary)'
  sed 's/^X//' << 'SHAR_EOF' > _sharuue.tmp &&
Xbegin 600 Red/Utility/types.h
XM(VEF;F1E9B!?5%E015-?2`HC9&5F:6YE(%]465!%4U]("@HC:6YC;'5D92`\
XM6&TO6&TN:#X*"F-L87-S($5$251/4CL*='EP961E9B!V;VED("A%1$E43U(Z
XM.BI#;V1E4'1R*2@I.PH*='EP961E9B!S=')U8W0@>PD)+R\@<W1R=6-T=7)E
XM(&9O<B!A<'!L:6-A=&EO;B!D969I;F5D(')E<V]U<F-E<PH@("`@6$9O;G13
XM=')U8W0@*F5D:71F;VYT.PDO+R!F;VYT(&9O<B!E9&ET('=I;F1O=PH@("`@
XM6$9O;G13=')U8W0@*FEN9F]F;VYT.PDO+R!F;VYT(&9O<B!I;F9O96UA=&EO
XM;B!A<F5A"B`@("!C:&%R("IM86Y?8G)O=W-E<CL)"2\O('!A=&@@;F%M92!O
XM9B!W96(@8G)O=W-E<B`H9F]R(&UA;G5A;"D*("`@(&-H87(@*FUA;E]U<FP[
XM"0DO+R!54DP@;V8@;6%N=6%L"B`@("!C:&%R("IM;W1D,3L)"2\O('=E;&-O
XM;64@;65S<V%G92!I;B!I;F9O("AL:6YE(#$I"B`@("!C:&%R("IM;W1D,CL)
XM"2\O('=E;&-O;64@;65S<V%G92!I;B!I;F9O("AL:6YE(#(I"B`@("!";V]L
XM96%N(&EC;VYI8SL*("`@(&-H87(@*F1E8G5G7V9L86=S.PD)+R\@82!S=')I
XM;F<@8V]N=&%I;FEN9R!D96)U9R!F;&%G<PI]($%P<&QI8V%T:6]N1&%T82P@
X<*D%P<&QI8V%T:6]N1&%T85!T<CL*"B-E;F1I9D%P
X`
Xend
SHAR_EOF
  echo 'uudecoding file Red/Utility/types.h' &&
  uudecode _sharuue.tmp < _sharuue.tmp && rm -f _sharuue.tmp &&
  $shar_touch -am 0512222696 'Red/Utility/types.h' &&
  chmod 0640 'Red/Utility/types.h' ||
  echo 'restore of Red/Utility/types.h failed'
  shar_count="`wc -c < 'Red/Utility/types.h'`"
  test 613 -eq "$shar_count" ||
    echo "Red/Utility/types.h: original size 613, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/utility.cc ==============
if test -f 'Red/Utility/utility.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/utility.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/utility.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/utility.cc' &&
X#include <Xm/Xm.h>
X#include <Xm/Form.h>
X#include <Xm/PushBG.h>
X#include <Xm/ToggleBG.h>
X#include <Xm/LabelG.h>
X#include <Xm/SeparatoG.h>
X#include <Xm/RowColumn.h>
X#include <Xm/CascadeB.h>
X#include <Xm/List.h>
X#include <Xm/TextF.h>
X#include <Xm/ScrollBar.h>
X
X#include "utility.h"
X#include "debug.h"
X
X// this is the GLOBAL utility object:
XUTILITY *utility;
X
X
X#define OBJECT_COLOUR  "FireBrick3"
X#define SHADOW_COLOUR "gray50"
X#define CLASS_COLOUR  "lightslategray"
X#define ENUM_COLOUR  "CadetBlue"
X#define ACTIVE_COLOUR "DarkOrange"
X#define ARROW_COLOUR "IndianRed4"
X
XUTILITY::UTILITY (Widget toplev)
X{
X  Arg al[10];
X  int ac;
X
X  toplevel = toplev;
X  display = XtDisplay (toplev);
X  screen = XtScreen (toplev);
X  screen_num = DefaultScreen (display);
X  screen_depth = get_depth ();
X
X  blue_icon = edit_icon = 0;
X  arrow_pix = darrow_pix = red_arrow_pix = red_darrow_pix = alpha_pix = 0;
X  stop_pix = error_pix = exec_pix = arrhead_left = arrhead_right = 0;
X
X  black = BlackPixelOfScreen (screen);
X  white = WhitePixelOfScreen (screen);
X  objectColour = get_colour (OBJECT_COLOUR, True);
X  shadowColour = get_colour (SHADOW_COLOUR, True);
X  classColour = get_colour (CLASS_COLOUR, True);
X  enumColour = get_colour (ENUM_COLOUR, True);
X  activeColour = get_colour (ACTIVE_COLOUR, True);
X  arrowColour = get_colour (ARROW_COLOUR, True);
X  backgroundColour = 0;
X
X  //create dialogs
X
X  fs_dialog = new FS_DIALOG (toplevel);
X}
X
XUTILITY::~UTILITY ()
X{
X  delete fs_dialog;
X}
X
X// -------------------------------------------------------------------------
X// create_pixmaps: This is part of the initialisation of this class. It is 
X//	separate from the constructor, because a reference to the main
X//	drawing area is needed (after realization!) to get its background
X//	colour.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::create_pixmaps (Widget form, Widget draw_area)
X{
X#include "../Bitmaps/blue_icon.xbm"
X#include "../Bitmaps/edit_icon.xbm"
X#include "../Bitmaps/debug_icon.xbm"
X#include "../Bitmaps/red_logo.xbm"
X
X#include "../Bitmaps/longline.xbm"
X
X#include "../Bitmaps/darrow.xbm"
X#include "../Bitmaps/arrow.xbm"
X#include "../Bitmaps/alpha.xbm"
X#include "../Bitmaps/stop.xbm"
X#include "../Bitmaps/error.xbm"
X#include "../Bitmaps/exec.xbm"
X
X#include "../Bitmaps/arrowhead_left.xbm"
X#include "../Bitmaps/arrowhead_right.xbm"
X
X  Arg al[10];
X  int ac;
X  Pixel drawBackgroundPixel, redPixel, pinkPixel;
X
X  if (edit_icon == 0) {			// make sure to do this only once
X
X    // get background colors from widgets
X    ac=0;
X    XtSetArg (al[ac], XmNbackground, &backgroundColour); ac++;
X    XtGetValues (form, al, ac);
X
X    edit_icon = create_pixmap (edit_icon_bits, edit_icon_width,
X				  edit_icon_height, black, white);
X
X    logo = create_pixmap (red_logo_bits, red_logo_width,
X			  red_logo_height, black, backgroundColour);
X
X    pinkPixel = get_colour ("DeepPink4", True);
X
X    longline_pix = create_pixmap (longline_bits, longline_width, longline_height,
X				  pinkPixel, white);
X
X  #ifndef RED_ONLY
X
X    ac=0;
X    XtSetArg (al[ac], XmNbackground, &drawBackgroundPixel); ac++;
X    XtGetValues (draw_area, al, ac);
X
X    redPixel = get_colour ("red", True);
X
X    blue_icon = create_pixmap (blue_icon_bits, blue_icon_width,
X				  blue_icon_height, black, white);
X
X    debug_icon = create_pixmap (debug_icon_bits, debug_icon_width,
X				  debug_icon_height, black, white);
X
X    arrow_pix = create_pixmap (arrow_bits, arrow_width, arrow_height,
X				  black, backgroundColour);
X
X    darrow_pix = create_pixmap (darrow_bits, darrow_width, darrow_height,
X				  black, backgroundColour);
X
X    red_arrow_pix = create_pixmap (arrow_bits,arrow_width,arrow_height,
X				  redPixel, backgroundColour);
X
X    red_darrow_pix = create_pixmap (darrow_bits, darrow_width, darrow_height,
X				  redPixel, backgroundColour);
X
X    alpha_pix = create_pixmap (alpha_bits, alpha_width, alpha_height,
X				  black, backgroundColour);
X
X    stop_pix = create_pixmap (stop_bits, stop_width, stop_height,
X				  redPixel, white);
X
X    error_pix = create_pixmap (error_bits, error_width, error_height,
X				  redPixel, white);
X
X    exec_pix = create_pixmap (exec_bits, exec_width, exec_height,
X				  black, white);
X    execstop_pix = exec_pix;
X
X    arrhead_left = create_pixmap (arrowhead_left_bits, arrowhead_left_width, 
X				  arrowhead_left_height, 
X				  arrowColour ^ drawBackgroundPixel, 
X				  0);
X
X    arrhead_right = create_pixmap (arrowhead_right_bits,
X				  arrowhead_right_width, arrowhead_right_height,
X				  arrowColour ^ drawBackgroundPixel, 
X				  0);
X  #endif
X  }
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_label (Widget parent, char *name)
X{
X  Widget label;
X
X  label = XmCreateLabelGadget (parent, name, NULL, 0);
X  XtManageChild (label);
X  return label;
X}
X
X// -------------------------------------------------------------------------
X//  create_button: Create a push button or toggle button.  The user data
X//	field is usually used to store the object the button belongs to.
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_button (Widget parent, char *name,
X			      XtCallbackProc callback, int callarg,
X			      XtPointer user_data)
X{
X  Widget button;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNuserData, user_data); ac++;
X  button = XmCreatePushButtonGadget (parent, name, al, ac);
X  XtManageChild (button);
X  XtAddCallback (button, XmNactivateCallback, callback, (XtPointer)callarg);
X  return button;
X}
X
X// -------------------------------------------------------------------------
X//  create_toggle: Create a toggle button.  
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_toggle (Widget parent, char *name, Boolean is_on,
X			      XtCallbackProc callback, XtPointer callarg)
X{
X  Widget button;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNset, is_on); ac++;
X  button = XmCreateToggleButtonGadget (parent, name, al, ac);
X  XtManageChild (button);
X  if (callback)
X    XtAddCallback (button, XmNvalueChangedCallback, callback, callarg);
X  return button;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_rc_area (Widget parent, char *name, XtArgVal orientation,
X				XtArgVal align)
X{
X  Widget area;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNorientation, orientation); ac++;
X  XtSetArg (al[ac], XmNentryAlignment, align); ac++;
X  area = XmCreateRowColumn (parent, name, al, ac);
X  XtManageChild (area);
X  return area;
X}
X
X// -------------------------------------------------------------------------
X// create_form: Create and attach a form. 
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_form (Widget parent, char *name)
X{
X  Widget area;
X
X  area = XmCreateForm (parent, name, NULL, 0);
X  XtManageChild (area);
X  return area;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_list (Widget parent, char *name, Boolean constant, 
X			     XtCallbackProc click_cb, XtPointer callarg1,
X			     XtCallbackProc double_cl_cb, XtPointer callarg2,
X			     Widget left_neighbour, Widget right_neighbour,
X			     Widget top_neighbour, Widget bottom_neighbour)
X{
X  Widget list;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X
X  if (left_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (left_neighbour != NULL) {
X    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNleftWidget, left_neighbour); ac++;
X  }
X
X  if (right_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (right_neighbour != NULL) {
X    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNrightWidget, right_neighbour); ac++;
X  }
X
X  if (top_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (top_neighbour != NULL) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNtopWidget, top_neighbour); ac++;
X  }
X
X  if (bottom_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (bottom_neighbour != NULL) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNbottomWidget, bottom_neighbour); ac++;
X  }
X
X  if (constant)
X    XtSetArg (al[ac], XmNlistSizePolicy, XmCONSTANT); ac++;
X  list = XmCreateScrolledList (parent, name, al, ac);
X  XtAddCallback (list, XmNbrowseSelectionCallback, click_cb, callarg1);
X  if (double_cl_cb)
X    XtAddCallback (list, XmNdefaultActionCallback, double_cl_cb, callarg2);
X  XtManageChild (list);
X  return list;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_text_field (Widget parent, char *name)
X{
X  Widget txt;
X
X  txt = XmCreateTextField (parent, name, NULL, 0);
X  XtManageChild (txt);
X  return txt;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_menu_bar (Widget parent, char *name)
X{
X  Widget mbar;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
X  XtSetArg (al[ac], XmNtopOffset, 0); ac++;
X  XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
X  XtSetArg (al[ac], XmNleftOffset, 0); ac++;
X  XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
X  XtSetArg (al[ac], XmNrightOffset, 0); ac++;
X  mbar = XmCreateMenuBar (parent, name, al, ac);
X  XtManageChild (mbar);
X  return mbar;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_menu (Widget parent, char *name, Boolean tear_off)
X{
X  Widget menu, cascade;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  if (tear_off) {
X    XtSetArg (al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
X  }
X  menu = XmCreatePulldownMenu (parent, name, al, ac);
X
X  ac=0;
X  XtSetArg (al[ac], XmNsubMenuId, menu); ac++;
X  XtSetArg (al[ac], XmNlabelString, XmStringCreateLtoR(name,XmSTRING_DEFAULT_CHARSET)); ac++;
X  cascade = XmCreateCascadeButton (parent, name, al, ac);
X  XtManageChild (cascade);
X
X  return menu;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_help_menu (Widget parent, char *name)
X{
X  Widget menu, cascade;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  menu = XmCreatePulldownMenu (parent, name, al, ac);
X  ac=0;
X  XtSetArg (al[ac], XmNsubMenuId, menu); ac++;
X  cascade = XmCreateCascadeButton (parent, name, al, ac);
X  XtManageChild (cascade);
X
X  // put into menu bar as help menu
X  ac=0;
X  XtSetArg (al[ac], XmNmenuHelpWidget, cascade); ac++;
X  XtSetValues (parent, al, ac);
X
X  return menu;
X}
X
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_item (Widget parent, char *name,
X			     XtCallbackProc callback, int callarg,
X			     XtPointer user_data)
X{
X  Widget item;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNuserData, user_data); ac++;
X  item = XmCreatePushButtonGadget (parent, name, al, ac);
X  XtManageChild (item);
X  XtAddCallback (item, XmNactivateCallback, callback, (XtPointer)callarg);
X  XtSetSensitive (item, True);
X  return item;
X}
X
X
X// -------------------------------------------------------------------------
X// -------------------------------------------------------------------------
X
XWidget UTILITY::create_separator (Widget parent)
X{
X  Widget sep = XmCreateSeparatorGadget (parent, "sep", NULL, 0);
X  
X  XtManageChild (sep);
X  return sep;
X}
X
X// =========================================================================
X
X// -------------------------------------------------------------------------
X//  get_selection: I want to paste. Give me the current X Windows selection.
X//	This function does not return the selection directly, but organises
X//	that the "do_paste" function of the editor is called when the
X//	selection is available.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::get_selection (XtPointer editor, Widget w, 
X			XtSelectionCallbackProc paste_callback, Time time)
X{
X  XtGetSelectionValue (w, XA_PRIMARY, XA_STRING, paste_callback, editor, time);
X}
X
X// -------------------------------------------------------------------------
X//  own_selection: Tell other X Windows applications that I own the 
X//	selection now!
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::own_selection (Widget w, XtConvertSelectionProc tell_callback,
X			XtLoseSelectionProc lost_callback, Time time)
X{
X  XtOwnSelection (w, XA_PRIMARY, time, tell_callback, lost_callback, NULL);
X}
X
X
X// =========================================================================
X
X// -------------------------------------------------------------------------
X// -------------------------------------------------------------------------
X
XDimension UTILITY::get_height (Widget w)
X{
X  Arg al[10];
X  int ac;
X  Dimension height;
X
X  ac=0;
X  XtSetArg (al[ac], XmNheight, &height); ac++;
X  XtGetValues (w, al, ac);
X
X  return height;
X}
X
X// -------------------------------------------------------------------------
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_height (Widget w, Dimension height)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNheight, height); ac++;
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  set_sensitive: Sets a buttin or menu item to be sensitive or insensitive
X//	depending on the boolean parameter.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_sensitive (Widget w, Boolean sens)
X{
X  XtSetSensitive (w, sens);
X}
X
X// -------------------------------------------------------------------------
X//  set_sensitive: Sets a buttin or menu item to be sensitive or insensitive
X//	depending on the boolean parameter.
X// -------------------------------------------------------------------------
X
XBoolean UTILITY::is_sensitive (Widget w)
X{
X  return XtIsSensitive (w);
X}
X
X// -------------------------------------------------------------------------
X//  set_label: Change the label text of a label or button widget.  
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_label (Widget w, char* text)
X{
X  int ac;
X  Arg al[10];
X  XmString s;
X
X  s = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
X  ac=0;
X  XtSetArg (al[ac], XmNlabelString, s); ac++;
X  XtSetValues (w, al, ac);
X//  XmStringFree (s);
X}
X
X// -------------------------------------------------------------------------
X//  set_title: Change the title of a dialog.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_title (Widget w, char* window_title, char* icon_title)
X{
X  int ac;
X  Arg al[10];
X
X  ac=0;
X  XtSetArg (al[ac], XmNtitle, window_title); ac++;
X  XtSetArg (al[ac], XmNiconName, icon_title); ac++;
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  set_dlg_title: Change the title of a dialog.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_dlg_title (Widget w, char* text)
X{
X  int ac;
X  Arg al[10];
X
X  ac=0;
X  XtSetArg (al[ac], XmNdialogTitle, XmStringCreateSimple (text)); ac++;
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  read_toggle: return the value of a toggle widget.
X// -------------------------------------------------------------------------
X
XBoolean UTILITY::read_toggle (Widget toggle)
X{
X  Boolean value;
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNset, &value); ac++;
X  XtGetValues (toggle, al, ac);
X
X  return value;
X}
X
X// -------------------------------------------------------------------------
X// -------------------------------------------------------------------------
X
XPixel UTILITY::get_colour (char* name, Boolean prefer_black)
X{
X  Colormap colmap;
X  XColor color_def;
X
X  if (screen_depth == 1)
X    if (prefer_black)
X      return BlackPixelOfScreen (screen);
X    else
X      return WhitePixelOfScreen (screen);
X
X  colmap = DefaultColormap (display, screen_num);
X
X  if (!XParseColor (display, colmap, name, &color_def)) {
X    soft_error ("Blue: Could not parse colour name:"); soft_error (name);
X  }
X  else if (!XAllocColor (display, colmap, &color_def)) {
X    soft_error ("Blue: Could not allocate color:"); soft_error (name);
X  }
X  else
X    return color_def.pixel;
X
X  // only reached if colour allocation was unsuccessful
X
X  if (prefer_black)
X    return BlackPixelOfScreen (screen);
X  else
X    return WhitePixelOfScreen (screen);
X}
X
X// -------------------------------------------------------------------------
X//  set_color: Set foreground of w to colour
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_colour (Widget w, Pixel colour)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNforeground, colour); ac++;
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X// set_scrollbar: Set current value and size of a scrollbar.  
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_scrollbar (Widget scr, int val, int size, int max)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNvalue, val); ac++;
X  XtSetArg (al[ac], XmNsliderSize, size); ac++;
X  XtSetArg (al[ac], XmNmaximum, max); ac++;
X  XtSetValues (scr, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  create_pixmap: Create a pixmap from data.
X// -------------------------------------------------------------------------
X
XPixmap UTILITY::create_pixmap (char bits[],
X			       unsigned int width, unsigned int height,
X			       Pixel foreground, Pixel background)
X{
X  // create the pixmap
X  return (XCreatePixmapFromBitmapData (display,
X			RootWindowOfScreen (screen),
X			bits, width, height,
X			foreground, background,
X			screen_depth));
X}
X
X// -------------------------------------------------------------------------
X//  create_empty_pixmap: Create a pixmap from data.
X// -------------------------------------------------------------------------
X
XPixmap UTILITY::create_empty_pixmap (unsigned int width, unsigned int height)
X{
X  return (XCreatePixmap (display, RootWindowOfScreen (screen),
X			width, height, screen_depth));
X}
X
X// -------------------------------------------------------------------------
X//  put_pixmap: Put a pixmap on a label or button.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::put_pixmap (Widget w, Pixmap pix, Pixmap disab_pix)
X{
X  Arg al[10];
X  int ac;
X 
X  ac=0;
X  XtSetArg (al[ac], XmNlabelType, XmPIXMAP); ac++;
X  XtSetArg (al[ac], XmNlabelPixmap, pix); ac++;
X  if (disab_pix != 0) {
X    XtSetArg (al[ac], XmNlabelInsensitivePixmap, disab_pix); ac++;
X  }
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  attach: Attach a widget in a form. Legal value for neighbours are
X//	AtForm:	     attach to form
X//	NULL:	     don't attach
X//	widget:	     attach to widget
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::attach (Widget w, 
X		      Widget left_neighbour, Widget right_neighbour,
X		      Widget top_neighbour, Widget bottom_neighbour)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X
X  if (left_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (left_neighbour != NULL) {
X    XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNleftWidget, left_neighbour); ac++;
X  }
X
X  if (right_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (right_neighbour != NULL) {
X    XtSetArg (al[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNrightWidget, right_neighbour); ac++;
X  }
X
X  if (top_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (top_neighbour != NULL) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNtopWidget, top_neighbour); ac++;
X  }
X
X  if (bottom_neighbour == AtForm) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
X  }
X  else if (bottom_neighbour != NULL) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNbottomWidget, bottom_neighbour); ac++;
X  }
X
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  attach_top: 
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::attach_top (Widget w, Widget attach_to)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  if (attach_to == NULL) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
X  }
X  else if (attach_to == AtForm) {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
X  }
X  else {
X    XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNtopWidget, attach_to); ac++;
X  }
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  attach_bottom: attach the bottom of widget w to something. 
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::attach_bottom (Widget w, Widget attach_to)
X{
X  Arg al[10];
X  int ac;
X
X  ac=0;
X  XtSetArg (al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
X
X  if (attach_to == NULL) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
X  }
X  else if (attach_to == AtForm) {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
X  }
X  else {
X    XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
X    XtSetArg (al[ac], XmNbottomWidget, attach_to); ac++;
X  }
X  XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
X  XtSetValues (w, al, ac);
X}
X
X// -------------------------------------------------------------------------
X//  set_cursor: Set cursor for widget w to shape 'cursor'.
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::set_cursor (Widget w, char cursor)
X{
X  Cursor curs;
X
X  curs = XCreateFontCursor (display, cursor);
X  XDefineCursor (display, XtWindow(w), curs);
X  XFlush (display);
X}
X
X// -------------------------------------------------------------------------
X//  restore_cursor: Return the cursor to its previous shape
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::restore_cursor (Widget w)
X{
X  XUndefineCursor (display, XtWindow(w));
X  XFlush (display);
X}
X
X// -------------------------------------------------------------------------
X//  draw_string_centered
X// -------------------------------------------------------------------------
X
Xvoid UTILITY::draw_string_centered (Drawable drawable, GC& gc, 
X			XFontStruct* font, char* str, 
X			 int x, int y, int width, Pixel col)
X{
X  int length, dir, ascent, descent, offset;
X  XCharStruct overall;
X
X  length = strlen(str);
X  XTextExtents (font, str, length, &dir, &ascent, &descent, &overall);
X
X  offset = (width-overall.width)/2;
X  if (offset<0)
X    offset = 0;
X  XSetForeground (display, gc, col);
X  XDrawString (display, drawable, gc, x+offset, y+ascent+3, str, length);
X}
X
X// ======================= private functions ===============================
X
X// -------------------------------------------------------------------------
X//  get_depth: Return depth of display.
X// -------------------------------------------------------------------------
X
Xunsigned int UTILITY::get_depth ()
X{
X  Window r;
X  unsigned int wd, ht, bw, depth;
X  int x, y;
X
X  XGetGeometry (display, RootWindowOfScreen (screen),
X	&r, &x, &y, &wd, &ht, &bw, &depth);
X  return depth;
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/utility.cc' &&
  chmod 0640 'Red/Utility/utility.cc' ||
  echo 'restore of Red/Utility/utility.cc failed'
  shar_count="`wc -c < 'Red/Utility/utility.cc'`"
  test 24004 -eq "$shar_count" ||
    echo "Red/Utility/utility.cc: original size 24004, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/utility.h ==============
if test -f 'Red/Utility/utility.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/utility.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/utility.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Utility/utility.h' &&
X#ifndef _UTIL_H
X#define _UTIL_H
X
X// ============================================================================
X//
X//  Class name: UTILITY
X//
X//  Author: M. Koelling
X//
X//  Description:
X//
X//	UTILITY is a graphics utility used by all classes that need to use
X//	graphical elements.  It offers a set of routines needed in this project
X//	and some X Windows resources, such as fonts and pixmaps.  The routines
X//	serve as an abstraction over X Windows, the resources avoid multiplying
X//	identical resources in different instances of the same class.
X//
X// ============================================================================
X
X// first: declarations of standard functions:
X
X#include <Xm/Xm.h>
X
X#include "fs_dialog.h"
X
X// Codes for all dialogs used in Blue:
X
Xenum DialogCode {NewClassDlg, NewProjectDlg};
X
Xconst Widget AtForm = (Widget)-1;	// constant for "attach to form"
X
Xclass UTILITY {
X
X  public:
X    UTILITY (Widget toplev);
X
X    ~UTILITY ();
X
X    void create_pixmaps (Widget form, Widget draw_area);
X
X    // --------- widget creation functions -------------------------------------
X
X    Widget create_label (Widget parent,
X			 char *name);
X
X    Widget create_button (Widget parent,
X			  char *name,
X			  XtCallbackProc callback,
X			  int callarg,
X			  XtPointer user_data);
X
X    Widget create_toggle (Widget parent,
X			  char *name,
X			  Boolean is_on,
X			  XtCallbackProc callback,
X			  XtPointer callarg);
X
X    Widget create_rc_area (Widget parent,
X			   char *name,
X			   XtArgVal orientation,
X			   XtArgVal align);
X
X    Widget create_form (Widget parent,
X			char *name);
X
X    Widget create_list (Widget parent,
X		        char *name, 
X			Boolean constant, 
X			XtCallbackProc click_cb, 
X			XtPointer callarg1,
X			XtCallbackProc double_cl_cb, 
X			XtPointer callarg2,
X			Widget left_neighbour, 
X			Widget right_neighbour,
X			Widget top_neighbour, 
X			Widget bottom_neighbour);
X
X    Widget create_text_field (Widget parent,
X			char *name);
X
X    Widget create_menu_bar (Widget parent,
X			    char *name);
X
X    Widget create_menu (Widget parent,
X		        char *name,
X			Boolean tear_off);
X
X    Widget create_help_menu (Widget parent,
X			     char *name);
X
X    Widget create_item (Widget parent, 
X		        char *name,
X			XtCallbackProc callback,
X			int callarg,
X			XtPointer user_data);
X
X    Widget create_separator (Widget parent);
X
X    // ---------------- X selection functions --------------------------------
X
X    void get_selection (XtPointer editor, 
X			Widget w, 
X			XtSelectionCallbackProc paste_callback, 
X			Time time);
X
X    void own_selection (Widget w, 
X			XtConvertSelectionProc tell_callback,
X			XtLoseSelectionProc lost_callback, 
X			Time time);
X
X    // ---------------- misc. functions --------------------------------------
X
X    Dimension get_height (Widget w);		// get the height of a widget
X
X    void set_height (Widget w,			// set the height of a widget
X		Dimension height);
X
X    void set_sensitive (Widget w,		// sets sensitivity for a
X		Boolean sens);			//  item or button
X
X    Boolean is_sensitive (Widget w);		// True if w is sensitive
X
X    void set_label (Widget w,			// set label text to 'text'
X		char* text);
X
X    void set_title (Widget w,			// set window and icon title
X		char* window_title,
X		char* icon_title);
X
X    void set_dlg_title (Widget w,		// set dialog title to 'text'
X		char* text);
X
X    Boolean read_toggle (Widget toggle);	// Get value of toggle button
X
X    Pixel get_colour (char* name,		// load a pixel by name
X		Boolean prefer_black);
X
X    void set_colour (Widget w,			// Set foreground of w to colour
X		Pixel colour);
X
X    void set_scrollbar (Widget scr, 		// set current val of scrollbar
X			int val,		//  logical value
X			int size,		//  logical size
X			int max);		//  logical max
X
X    Pixmap create_pixmap (char bits[],		// create and return a pixmap
X			unsigned int width,	// from bitmap data
X			unsigned int height,
X			Pixel foreground,
X			Pixel background);
X
X    Pixmap create_empty_pixmap (
X			unsigned int width,
X			unsigned int height);
X
X    void put_pixmap (Widget w,			// put pixmap on label
X			Pixmap pix,
X			Pixmap disab_pix);
X
X    void attach (Widget w,			// attach widget in form
X		 Widget left_neighbour,
X		 Widget right_neighbour,
X		 Widget top_neighbour,
X		 Widget bottom_neighbour);
X
X    void attach_top (Widget w,			// attach w to attach_to
X		     Widget attach_to);		//  (can be NULL or AtForm)
X
X    void attach_bottom (Widget w,		// attach w to attach_to
X		        Widget attach_to);	//  (can be NULL or AtForm)
X
X    void set_cursor (Widget w, char cursor);
X    void restore_cursor (Widget w);
X
X    void draw_string_centered (Drawable drawable, 
X		GC& gc, 
X		XFontStruct* font,
X		char* str, 
X		int x, 
X		int y, 
X		int width,
X		Pixel col);
X
X  // variables:
X
X    Pixmap blue_icon, edit_icon, debug_icon, logo;
X    Pixmap longline_pix;
X    Pixmap arrow_pix, darrow_pix,
X	   red_arrow_pix, red_darrow_pix, alpha_pix;
X    Pixmap stop_pix, error_pix, exec_pix, execstop_pix;
X    Pixmap arrhead_left, arrhead_right;
X
X    FS_DIALOG* fs_dialog;
X
X    Pixel black,				// colours used for drawing 
X	  white,
X	  backgroundColour,		// background, set in "create_pixmaps"
X	  objectColour,			// object icon fill
X	  shadowColour, 		// shadow of classes and objects
X	  classColour,			// class fill normal
X	  enumColour,			// class fill for enumerations
X	  activeColour,			// class fill while active (compiling)
X	  arrowColour;			// "uses" arrows
X
X  private:
X
X    unsigned int get_depth ();			// get depth of display
X
X    Display* display;
X    Screen* screen;
X    int screen_num;
X    unsigned int screen_depth;
X    Widget toplevel;
X};
X
Xextern UTILITY *utility;		// declare global object
X
X#endif
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Utility/utility.h' &&
  chmod 0640 'Red/Utility/utility.h' ||
  echo 'restore of Red/Utility/utility.h failed'
  shar_count="`wc -c < 'Red/Utility/utility.h'`"
  test 5651 -eq "$shar_count" ||
    echo "Red/Utility/utility.h: original size 5651, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Utility/utility_callbacks.i ==============
if test -f 'Red/Utility/utility_callbacks.i' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Utility/utility_callbacks.i (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Utility/utility_callbacks.i (empty)'
  > 'Red/Utility/utility_callbacks.i' &&
  $shar_touch -am 0512222696 'Red/Utility/utility_callbacks.i' &&
  chmod 0640 'Red/Utility/utility_callbacks.i' ||
  echo 'restore of Red/Utility/utility_callbacks.i failed'
  shar_count="`wc -c < 'Red/Utility/utility_callbacks.i'`"
  test 0 -eq "$shar_count" ||
    echo "Red/Utility/utility_callbacks.i: original size 0, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/Makefile ==============
if test ! -d 'Red/Red'; then
  echo 'x - creating directory Red/Red'
  mkdir 'Red/Red'
fi
if test -f 'Red/Red/Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/Makefile (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/Makefile' &&
X#
X# Makefile for Red, the editor of the Blue integrated environment. -mik- 95
X#
X
X# RO_FLAG will be set from outside for red-only compilation
XRO_FLAG = 
X
XOBJECTS = keymap.o function.o screen.o info.o line.o buffer.o bufferpos.o \
X	  finder.o action.o actionstack.o userfunc.o red.o editor.o
X
XUTILITY_DIR = ../Utility
XPROJECT_DIR = ../Project
XDEBUGGER_DIR = ../Debugger
X
Xall: $(OBJECTS)
X
Xclean:
X	rm -f *~ blue core
X
Xrealclean:
X	rm -f *.o *~ blue core
X
Xfunction.o: function.h function.cc \
X	    $(UTILITY_DIR)/types.h $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o function.o function.cc
X
Xkeymap.o: keymap.h keymap.cc function.h \
X	$(UTILITY_DIR)/debug.h $(UTILITY_DIR)/types.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o keymap.o keymap.cc
X
Xuserfunc.o: userfunc.h userfunc.cc function.h keymap.h editor.h defines.h \
X	$(UTILITY_DIR)/debug.h \
X	$(UTILITY_DIR)/utility.h $(UTILITY_DIR)/support.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o userfunc.o userfunc.cc
X
Xscreen.o: screen.h screen.cc $(UTILITY_DIR)/utility.h $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o screen.o screen.cc
X
Xinfo.o: info.h info.cc $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o info.o info.cc
X
Xline.o: line.h line.cc $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o line.o line.cc
X
Xbufferpos.o: bufferpos.h bufferpos.cc line.h $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o bufferpos.o bufferpos.cc
X
Xbuffer.o: buffer.h buffer.cc bufferpos.h line.h \
X	$(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o buffer.o buffer.cc
X
Xfinder.o: finder.h finder.cc \
X	$(UTILITY_DIR)/utility.h \
X	$(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o finder.o finder.cc
X
Xaction.o: action.h action.cc
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o action.o action.cc
X
Xactionstack.o: actionstack.h actionstack.cc action.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o actionstack.o actionstack.cc
X
Xifdef RO_FLAG
Xeditor.o: editor.h editor_init.i editor_event.i editor_edit.i editor_move.i \
X	editor_display.i editor_func.i editor_debug.i editor_callbacks.i \
X	editor.cc \
X	red.h screen.h info.h buffer.h bufferpos.h keymap.h userfunc.h \
X	actionstack.h \
X	$(UTILITY_DIR)/types.h \
X	$(UTILITY_DIR)/utility.h $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o editor.o editor.cc
Xelse
Xeditor.o: editor.h editor_init.i editor_event.i editor_edit.i editor_move.i \
X	editor_display.i editor_func.i editor_debug.i editor_callbacks.i \
X	editor.cc \
X	red.h screen.h info.h buffer.h bufferpos.h keymap.h userfunc.h \
X	actionstack.h \
X	$(PROJECT_DIR)/iclass.h $(PROJECT_DIR)/xclass.h \
X	$(UTILITY_DIR)/types.h \
X	$(UTILITY_DIR)/utility.h $(UTILITY_DIR)/debug.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o editor.o editor.cc
Xendif
X
Xred.o: red.h red.cc red_dlg.i red_file.i red_callbacks.i \
X	editor.h function.h keymap.h userfunc.h finder.h defines.h \
X	$(UTILITY_DIR)/utility.h  $(UTILITY_DIR)/types.h \
X	$(UTILITY_DIR)/fs_dialog.h  $(UTILITY_DIR)/list.h \
X	$(UTILITY_DIR)/debug.h \
X	$(UTILITY_DIR)/question_dlg.h  $(UTILITY_DIR)/messages.h
X	$(CC) $(CCFLAGS) $(RO_FLAG) -o red.o red.cc
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Red/Makefile' &&
  chmod 0640 'Red/Red/Makefile' ||
  echo 'restore of Red/Red/Makefile failed'
  shar_count="`wc -c < 'Red/Red/Makefile'`"
  test 3012 -eq "$shar_count" ||
    echo "Red/Red/Makefile: original size 3012, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/action.cc ==============
if test -f 'Red/Red/action.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/action.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/action.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/action.cc' &&
X// ============================================================================
X//  File: action.cc						-mik- 1995
X//
X//  Implementation of class ACTION.  See action.h for description.
X//  Action is part of the Blue programming environment.
X// ============================================================================
X
X#include "Xm/Xm.h"
X#include "action.h"
X#include "../Utility/debug.h"
X
X// -------------------------------------------------------------------------
X//  ACTION: Constructor.
X// -------------------------------------------------------------------------
X
XACTION::ACTION ()
X{
X  type = UndefAction;
X  text = NULL;
X}
X
X// -------------------------------------------------------------------------
X//  ~ACTION: Destructor.
X// -------------------------------------------------------------------------
X
XACTION::~ACTION ()
X{
X  delete text;
X}
X
X// -------------------------------------------------------------------------
X//  set_insertion
X// -------------------------------------------------------------------------
X
Xvoid ACTION::set_insertion (int startl, int startc, int endl, int endc, 
X			    bool link)
X{
X  type = InsAction;
X  sline = startl;
X  scol = startc;
X  eline = endl;
X  ecol = endc;
X  linked = link;
X
X  delete [] text;
X  text = NULL;
X}
X
X// -------------------------------------------------------------------------
X//  set_deletion
X// -------------------------------------------------------------------------
X
Xvoid ACTION::set_deletion (int line, int col, char* seg, char chr, bool link)
X{
X  type = DelAction;
X  sline = line;
X  scol = col;
X  delete [] text;	// delete previous
X  text = seg;
X  ch = chr;
X  linked = link;
X}
X
X// -------------------------------------------------------------------------
X//  set_undef: Set this action to undefined.
X// -------------------------------------------------------------------------
X
Xvoid ACTION::set_undef ()
X{
X  type = UndefAction;
X  delete [] text;	// delete previous
X  text = NULL;
X}
X
X// -------------------------------------------------------------------------
X//  get_type: Return the type of this action (insertion or deletion).
X// -------------------------------------------------------------------------
X
XActionType ACTION::get_type ()
X{
X  return type;
X}
X
X// -------------------------------------------------------------------------
X//  get_ins_info: Return the information about this insertion. (The type of
X//	 this action MUST be InsAction!)
X// -------------------------------------------------------------------------
X
Xvoid ACTION::get_ins_info (int& startl, int& startc, int& endl, int& endc)
X{
X  assert (type == InsAction);
X
X  startl = sline;
X  startc = scol;
X  endl = eline;
X  endc = ecol;
X}
X
X// -------------------------------------------------------------------------
X//  get_del_info: Return the information about this deletion. (The type of
X//	 this action MUST be DelAction!)
X// -------------------------------------------------------------------------
X
Xvoid ACTION::get_del_info (int& line, int& col, char*& seg, char& chr)
X{
X  assert (type == DelAction);
X  line = sline;
X  col = scol;
X  seg = text;
X  chr = ch;
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Red/action.cc' &&
  chmod 0640 'Red/Red/action.cc' ||
  echo 'restore of Red/Red/action.cc failed'
  shar_count="`wc -c < 'Red/Red/action.cc'`"
  test 3096 -eq "$shar_count" ||
    echo "Red/Red/action.cc: original size 3096, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/action.h ==============
if test -f 'Red/Red/action.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/action.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/action.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/action.h' &&
X#ifndef _ACTION_H
X#define _ACTION_H
X
X// ============================================================================
X//
X//  Class name: ACTION		  (part of the BLUE programming environment)
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	ACTION is part of the Blue Language integrated environment.
X//
X//	ACTION is a 
X//
X// ============================================================================
X
X
Xenum ActionType { InsAction, DelAction, UndefAction };
X
Xclass ACTION {
X
X  public:
X
X    ACTION ();
X    ~ACTION ();
X
X    void set_insertion (int startl, int startc, int endl, int endc, bool link);
X
X	// Record an insertion in this action record.  "start" is the position
X	// where the inserted text starts, "end" is the end.
X
X
X    void set_deletion (int line, int col, char* seg, char chr, bool link);
X
X	// Record a deletion in this action record.  "pos" is the position
X	// where the text was deleted.  If the deletion was only one character,
X	// "seg" is NULL and chr holds the character.  Otherwise "seg" holds
X	// a pointer to the segment holding the deleted text.
X
X
X    void set_undef ();
X
X	// Set this action to undefined.
X
X
X    ActionType get_type ();
X
X	// Return type of this action
X
X
X    void get_ins_info (int& startl, int& startc, int& endl, int& endc);
X
X	// Return the information about this insertion. (The type of this
X	// action MUST be InsAction!)
X
X
X    void get_del_info (int& line, int& col, char*& seg, char& chr);
X
X	// Return the information about this deletion. (The type of this
X	// action MUST be DelAction!)
X
X
X    bool is_linked ()
X      { return linked; };
X
X	// Return true, if this action is linked to the previous action (which
X	// means that when this action is undone, the previous action should
X	// be undone also).
X
X
X  private:
X
X    ActionType type;	// shows whether this action was insertion or deletion
X
X    int sline, scol;	// start position of insertion or position of deletion
X    int eline, ecol;	// end position of insertion (unused for deletion)
X
X    char* text;		// the text deleted (if more than one character)
X    char ch;		// the character deleted (if only one character)
X			//  (both of these are unused for an insertion)
X    bool linked;	// if true, the action is linked to the previous action
X			//  (both will be undone in one step)
X};
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Red/action.h' &&
  chmod 0640 'Red/Red/action.h' ||
  echo 'restore of Red/Red/action.h failed'
  shar_count="`wc -c < 'Red/Red/action.h'`"
  test 2306 -eq "$shar_count" ||
    echo "Red/Red/action.h: original size 2306, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/actionstack.cc ==============
if test -f 'Red/Red/actionstack.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/actionstack.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/actionstack.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/actionstack.cc' &&
X// ============================================================================
X//  File: actionstack.cc					-mik- 1995
X//
X//  Implementation of class ACTIONSTACK.  See actionstack.h for description.
X//  Actionstack is part of the Blue programming environment.
X// ============================================================================
X
X#include "actionstack.h"
X
X// -------------------------------------------------------------------------
X//  ACTIONSTACK: Initialise the stack to hold pointers to valid actions
X//	(undefined ones), and set the stack pointers to represent an empty
X//	stack.
X// -------------------------------------------------------------------------
X
XACTIONSTACK::ACTIONSTACK ()
X{
X  int i;
X
X  for (i=0; i<ACT_STACK_SIZE; i++)
X    stack[i] = new ACTION ();
X
X  newest = current = 0;
X  thats_all = True;
X}
X
X// -------------------------------------------------------------------------
X//  ~ACTIONSTACK: delete all the action objects in the action stack.
X// -------------------------------------------------------------------------
X
XACTIONSTACK::~ACTIONSTACK ()
X{
X  int i;
X
X  for (i=0; i<ACT_STACK_SIZE; i++)
X    delete stack[i];
X}
X
X// -------------------------------------------------------------------------
X//  enter: Enter an action to the top of the action stack.  Note: if the 
X//	stack is full, the oldest element is overwritten.  So it's really
X//	a ring, not a stack...
X//	The action is not really entered here.  This function merely selects
X//	and returns the next action record to be used.  It is filled 
X//	directly from outside then.
X// -------------------------------------------------------------------------
X
XACTION* ACTIONSTACK::new_action ()
X{
X  newest = next (newest);
X  if (newest == current)		// caught up with current pointer
X    thats_all = True;			// can't go back further then!
X  return stack[newest];
X}
X
X// -------------------------------------------------------------------------
X//  get_action: Return the last action (pointed to by current) and set
X//	current to the action before that.  Return NULL, if no further
X//	action is available.
X// -------------------------------------------------------------------------
X
XACTION* ACTIONSTACK::get_action ()
X{
X  ACTION* act;
X
X  if (thats_all)			// at end of stack
X    return NULL;
X  else {
X    act = stack[current];
X    current = prev(current);
X    if (current == newest)
X      thats_all = True;
X    if (act->get_type() == UndefAction) {
X      thats_all = True;
X      return NULL;
X    }
X    else
X      return act;
X  }
X}
X
X// -------------------------------------------------------------------------
X//  reset: Reset the scan pointer to the action last entered.
X// -------------------------------------------------------------------------
X
Xvoid ACTIONSTACK::reset ()
X{
X  current = newest;
X  thats_all = False;
X}
X
X// -------------------------------------------------------------------------
X//  clear: Remove all actions from stack
X// -------------------------------------------------------------------------
X
Xvoid ACTIONSTACK::clear ()
X{
X  int i = 0;
X
X  while ((i < ACT_STACK_SIZE) && (stack[i]->get_type() != UndefAction))
X    stack[i]->set_undef ();
X
X  newest = current = 0;
X  thats_all = True;
X}
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Red/actionstack.cc' &&
  chmod 0640 'Red/Red/actionstack.cc' ||
  echo 'restore of Red/Red/actionstack.cc failed'
  shar_count="`wc -c < 'Red/Red/actionstack.cc'`"
  test 3190 -eq "$shar_count" ||
    echo "Red/Red/actionstack.cc: original size 3190, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/actionstack.h ==============
if test -f 'Red/Red/actionstack.h' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/actionstack.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/actionstack.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/actionstack.h' &&
X#ifndef _ACTIONSTACK_H
X#define _ACTIONSTACK_H
X
X// ============================================================================
X//
X//  Class name: ACTIONSTACK	  (part of the BLUE programming environment)
X//
X//  Author: M. Koelling							1995
X//
X//  Description:
X//
X//	ACTIONSTACK is part of the Blue Language integrated environment.
X//
X//	ACTIONSTACK implements...
X//
X// ============================================================================
X
X#include "Xm/Xm.h"
X#include "action.h"
X
Xconst int ACT_STACK_SIZE = 80;
X
Xclass ACTIONSTACK {
X
X  public:
X
X    ACTIONSTACK ();
X
X    ~ACTIONSTACK ();
X
X    ACTION* new_action ();
X
X	// Return an action object to be used for recording a new action.
X
X
X    ACTION* get_action ();
X
X	// Return the last action.  Consecutive calls to "get_action" will
X	// scan backwards through the action stack.  A call to reset resets
X	// the scan to the last action entered.
X
X    void reset ();
X
X	// Reset the action scan pointer.  The next call to "get_action" will
X	// return the last action entered.
X
X    void clear ();
X
X	// Clear the whole stack.  Start to collect actions from scratch after
X	// this.
X
X  private:
X
X    int next (int idx)
X      { return (idx+1) % ACT_STACK_SIZE; };
X
X	// Return the next index in the array, including wrap around.
X
X
X    int prev (int idx)
X      { return idx==0 ? ACT_STACK_SIZE-1 : idx-1; };
X
X	// Return the previous index in the array, including wrap around.
X
X
X    ACTION* stack[ACT_STACK_SIZE];
X
X    int newest;		// pointer to last element inserted
X    int current;	// pointer to next element that will be returned
X    Boolean thats_all;	// True, if no more action records are available
X};
X
X#endif
X
SHAR_EOF
  $shar_touch -am 0512222696 'Red/Red/actionstack.h' &&
  chmod 0640 'Red/Red/actionstack.h' ||
  echo 'restore of Red/Red/actionstack.h failed'
  shar_count="`wc -c < 'Red/Red/actionstack.h'`"
  test 1660 -eq "$shar_count" ||
    echo "Red/Red/actionstack.h: original size 1660, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Red/Red/buffer.cc ==============
if test -f 'Red/Red/buffer.cc' && test X"$1" != X"-c"; then
  echo 'x - skipping Red/Red/buffer.cc (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Red/Red/buffer.cc (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Red/Red/buffer.cc' &&
X#include <fstream.h>
X#include <ctype.h>
X
X#include "buffer.h"
X#include "../Utility/stdfunc.h"
X#include "../Utility/debug.h"
X
X//----------------------------------------------------------------------------
X// BUFFER: Create a new, empty buffer and set Point to the first character
X//	position.  An empty buffer consists of two lines: an (empty) text line
X//	and an end-of-buffer mark (called endmark).  These are cicular, doubly
X//	linked. The filename is stored, but the file not yet loaded.
X//----------------------------------------------------------------------------
X
XBUFFER::BUFFER ()
X  : NewLine(10), TAB_length(8), TAB(9)
X{
X  pt.line_no = 1;
X  pt.column = 0;
X  pt.line = new LINE (20, NULL, 0);
X  endmark = new LINE (0, NULL, 0);
X  pt.line->prev = pt.line->next = endmark;
X  endmark->prev = endmark->next = pt.line;
X
X  pt2 = pt;
X  lines = 1;
X  selection_on = False;
X}
X
X//----------------------------------------------------------------------------
X// ~BUFFER: Close this buffer.  Simple thing: return all lines to the system.
X//	Later, this might be optimised to hold an own list of unused lines and
X//	return the buffer lines to the line manager.
X//----------------------------------------------------------------------------
X
XBUFFER::~BUFFER ()
X{
X  clear_buffer ();
X  delete pt.line;
X  delete endmark;
X}
X
X//----------------------------------------------------------------------------
X// insert_char: Insert a character at point position.  Remember, that the 
X//	column can be greater than the line length.  If so, insert at the end
X//	of the line.
X//----------------------------------------------------------------------------
X
Xvoid BUFFER::insert_char (char ch)
X{
X  pt.line->insert (ch, pt.column);
X  pt.column++;
X}
X
X//----------------------------------------------------------------------------
X//----------------------------------------------------------------------------
X
Xvoid BUFFER::insert_string (char* str, int len)
X{
X  pt.line->insert_string (str, len, pt.column);
X  pt.column = pt.column+len;
X}
X
X//----------------------------------------------------------------------------
X// insert_newline: Insert a new line at point.  If point is in the middle of
X//	an existing line, that line is cut of and the tail is taken over as 
X//	the contents of the new one.
X//----------------------------------------------------------------------------
X
Xvoid BUFFER::insert_newline ()
X{
X  LINE* ln;
X  int newlength;
X
X  newlength = pt.line->length - pt.column;
X  ln = new LINE (newlength+10, &(pt.line->text[pt.column]), newlength);
X  pt.line->length = pt.column;
X
X  pt.line->next->prev = ln;	// link new line into list
X  ln->next = pt.line->next;
X  pt.line->next = ln;
X  ln->prev = pt.line;
X
X  lines++;
X  point_to_next_line ();
X  pt.column = 0;
X}
X
X//----------------------------------------------------------------------------
X// delete_char: Delete a character at point position.  This is also used to
X//	delete a line break: delete at the end of a line joins two lines.  The
X//	function result indicates what happened.  These are the return values
X//	and their meanings:
X//	   NewLine    a line break has been deleted (lines are joined)
X//	   '\0'  	point was at end of buffer. Nothing deleted.
X//	   other	the character which has been deleted
X//----------------------------------------------------------------------------
X
Xchar BUFFER::delete_char ()
X{
X  char ch;
X
X  if (pt.column == pt.line->length) {	// delete newline
X
X    if (pt.line->next == endmark)	// at end of buffer
X      return '\0';
X
X    pt.line->append (pt.line->next->text, pt.line->next->length);
X    internal_delete_line (pt.line->next);
X    return NewLine;
X  }
X  else {				// delete within line
X    ch = pt.line->text[pt.column];
X    pt.line->remove (pt.column);
X    return ch;
X  }
X}
X
X//----------------------------------------------------------------------------
X//  cut: Cut the pt2 to pt. That is: remove the selected text from the buffer.
X//	No saving of the selection to the paste buffer takes place here. (That
X//	has to be done on some higher level...) If the selection is empty,
X//	nothing happens.  Leaves point at the spot where the selection has
X//	been.  Selection is off after this.  The selection does not have to
X//	be on to cut, but pt and pt2 must be set correctly.
X//----------------------------------------------------------------------------
X
Xvoid BUFFER::cut ()
X{
X  LINE* ln;
X  LINE* tmp;
X
X  if ((mark.is_behind (pt2)) && (mark.is_before(pt)))	// mark gets cut!
X    mark = pt2;
X
X  if (pt2.line == pt.line) {
X    pt2.line->delete_part (pt2.column, pt.column);
X    pt = pt2;
X  }
X  else {
X    pt2.line->delete_tail (pt2.column);		// cut off first line
X    ln = pt2.line->next;
X    while (ln != pt.line) {			// cut out middle lines
X      tmp = ln;
X      ln = ln->next;
X      delete (tmp);
X      lines--;
X    }
X    pt2.line->next = pt.line;
X    pt.line->prev = pt2.line;
X    pt.line->delete_head (pt.column);		// cut beginning of last line
X    pt = pt2;
X    delete_char ();				// join first and last line
X  }
X  pt.line->select = NoSelection;		// in case it was on...
X  selection_on = False;
X}
X
X//----------------------------------------------------------------------------
X// indent: Indent the cursor to the start of the next word in the next 
X//	nonblank line above.  If there in no word in the nonblank line above
X//	after the cursor position, return False.
X//----------------------------------------------------------------------------
X
XBoolean BUFFER::indent () 
X{
X
X  LINE* ln;
X  int ind, ptcol, col;
X
X  ln = pt.line->prev;					// find previous line 
X  while ((ln != endmark) && (ln->length == 0))		//  (skipping blank lines)
X    ln = ln->prev;
X
X  if (ln == endmark)					// no previous line
X    return False;
X
X  ptcol = index_to_screencol (pt.line, pt.column);	// find screen column of pt
X
X  ind = screencol_to_index (ln, ptcol);			// find index in prev line
X  if (ind == -1)
X    return False;					// line too short
X
X  // find start of next word
X
X  while ((ind < ln->length) && (ln->text[ind] != ' ') && (ln->text[ind] != TAB))
X    ind++;
X  while ((ind < ln->length) && ((ln->text[ind] == ' ') || (ln->text[ind] == TAB)))
X    ind++;
X  if (ind == ln->length)				// eoln reached
X    if (((ln->text[0] != ' ') && (ln->text[0] != TAB))
X         || ((ln->text[ind-1] != ' ') && (ln->text[ind-1] != TAB)))
X      return False;
X
X  col = index_to_screencol (ln, ind);			// find target screen col
X
X  // Now col is the column we want to set pt to.  col>ptcol
X  while ((pt.column > 0) && (pt.line->text[pt.column-1] == ' ')) {  // delete spaces
X    pt.line->remove (--(pt.column));
X    ptcol--;
X  }
X
X  while ((ptcol / TAB_length + 1) * TAB_length <= col) {
X    pt.line->insert (TAB, pt.column++);
X    ptcol = (ptcol / TAB_length + 1) * TAB_length;
X  }
X  while (ptcol < col) {
X    pt.line->insert (' ', pt.column++);
X    ptcol++;
X  }
X  return True;
X}
X	
X//----------------------------------------------------------------------------
X// insert_half_tab: Insert spaces and/or TABs to next half-tab position.
X//	Returns the number of spaces inserted.  If the number (n) is:
X//	    - positive:	n spaces have been inserted
X//	    - negative: n spaces have been deleted, and a TAB inserted
X//	    - = 0:	a TAB has been inserted
X//----------------------------------------------------------------------------
X
Xint BUFFER::insert_half_tab () 
X{
X  int spaces;			// number of spaces inserted
X  int removed_spaces;		// number of spaces removed
X  int col;			// screen column of point
X
X  col = index_to_screencol (pt.line, pt.column);	// find point screen col
X  spaces = 4 - (col % 4);
X  pt.line->insert_string ("    ", spaces, pt.column);
X  removed_spaces = spaces_to_tab (pt.column + spaces);
X  pt.column = screencol_to_index (pt.line, col+spaces);
X  return (spaces - removed_spaces);
X}
X
X//----------------------------------------------------------------------------
X// inc_indent: Increment the indentation of the current line.  This is done by
X//	inserting a space atthe position of the first non-blank character and,
X//	if appripriate, converting some spaces into tabs.
X//----------------------------------------------------------------------------
X
Xvoid BUFFER::inc_indent () 
SHAR_EOF
  : || echo 'restore of Red/Red/buffer.cc failed'
fi
echo 'End of archive part 3'
echo 'File Red/Red/buffer.cc is continued in part 4'
echo 4 > _sharseq.tmp
exit 0


