Logo Search packages:      
Sourcecode: jnethack version File versions  Download package

amiwind.c

/*    SCCS Id: @(#)amiwind.c     3.2    96/02/17
/*    Copyright (c) Olaf Seibert (KosmoSoft), 1989, 1992      */
/*    Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996  */
/* NetHack may be freely redistributed.  See license for details. */

#include "NH:sys/amiga/windefs.h"
#include "NH:sys/amiga/winext.h"
#include "NH:sys/amiga/winproto.h"

/* Have to undef CLOSE as display.h and intuition.h both use it */
#undef CLOSE

#ifdef AMII_GRAPHICS    /* too early in the file? too late? */

#ifdef AMIFLUSH
static struct Message *FDECL(GetFMsg,(struct MsgPort *));
#endif

static int BufferGetchar(void);
static void ProcessMessage( register struct IntuiMessage *message );

#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch))

struct Library *ConsoleDevice;

#include "NH:sys/amiga/amimenu.c"

/* Now our own variables */

struct IntuitionBase *IntuitionBase;
struct Screen *HackScreen;
struct Window *pr_WindowPtr;
struct MsgPort *HackPort;
struct IOStdReq ConsoleIO;
char Initialized = 0;
WEVENT lastevent;

#ifdef HACKFONT
struct GfxBase *GfxBase;
struct Library *DiskfontBase;
#endif

extern struct Library *ConsoleDevice;

#define KBDBUFFER   10
static unsigned char KbdBuffer[KBDBUFFER];
unsigned char KbdBuffered;

#ifdef HACKFONT

struct TextFont *TextsFont = NULL;
struct TextFont *HackFont = NULL;
struct TextFont *RogueFont = NULL;

UBYTE FontName[] = "NetHack:hack.font";
    /* # chars in "NetHack:": */
#define         SIZEOF_DISKNAME 8

#endif

struct TextAttr Hack80 = {
#ifdef HACKFONT
    &FontName[SIZEOF_DISKNAME],
#else
    (UBYTE *) "topaz.font",
#endif
    8, FS_NORMAL, FPF_DISKFONT | FPF_DESIGNED
      | FPF_ROMFONT
};

struct TextAttr TextsFont13 = {
    (UBYTE *) "courier.font",
    13, FS_NORMAL, FPF_DISKFONT | FPF_DESIGNED
#ifndef     HACKFONT
      | FPF_ROMFONT
#endif
};

/* Avoid doing a ReplyMsg through a window that no longer exists. */
static enum {NoAction, CloseOver} delayed_key_action = NoAction;

/*
 * Open a window that shares the HackPort IDCMP. Use CloseShWindow()
 * to close.
 */

struct Window *OpenShWindow(nw)
struct NewWindow *nw;
{
    register struct Window *win;
    register ULONG idcmpflags;

    if (!HackPort)  /* Sanity check */
      return (struct Window *) 0;

    idcmpflags = nw->IDCMPFlags;
    nw->IDCMPFlags = 0;
    if (!(win = OpenWindow((void *)nw)))
    {
      nw->IDCMPFlags = idcmpflags;
      return (struct Window *) 0;
    }

    nw->IDCMPFlags = idcmpflags;
    win->UserPort = HackPort;
    ModifyIDCMP(win, idcmpflags);
    return win;
}


/*
 * Close a window that shared the HackPort IDCMP port.
 */

void FDECL(CloseShWindow, (struct Window *));
void CloseShWindow(win)
struct Window *win;
{
    register struct IntuiMessage *msg;

    if( !HackPort )
      panic("HackPort NULL in CloseShWindow" );
    if (!win)
      return;

    Forbid();
    /* Flush all messages for all windows to avoid typeahead and other
     * similar problems...
     */
    while( msg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
      ReplyMsg( (struct Message *) msg );
    KbdBuffered = 0;
    win->UserPort = (struct MsgPort *) 0;
    ModifyIDCMP(win, 0L);
    Permit();
    CloseWindow(win);
}

static int BufferGetchar()
{
    register int c;

    if (KbdBuffered > 0) {
      c = KbdBuffer[0];
      KbdBuffered--;
      /* Move the remaining characters */
      if( KbdBuffered < sizeof( KbdBuffer ) )
          memcpy( KbdBuffer, KbdBuffer+1, KbdBuffered );
      return c;
    }

    return NO_CHAR;
}

/*
 *  This should remind you remotely of DeadKeyConvert, but we are cheating
 *  a bit. We want complete control over the numeric keypad, and no dead
 *  keys... (they are assumed to be on Alted keys).
 *
 *  Also assumed is that the IntuiMessage is of type RAWKEY.  For some
 *  reason, IECODE_UP_PREFIX events seem to be lost when they  occur while
 *  our console window is inactive. This is particulary  troublesome with
 *  qualifier keys... Is this because I never RawKeyConvert those events???
 */

int ConvertKey(message)
register struct IntuiMessage *message;
{
    static struct InputEvent theEvent;
    static char       numpad[] = "bjnh.lyku";
    static char  ctrl_numpad[] = "\x02\x0A\x0E\x08.\x0C\x19\x0B\x15";
    static char shift_numpad[] = "BJNH.LYKU";

    unsigned char buffer[10];
    struct Window *w = message->IDCMPWindow;
    register int length;
    register ULONG qualifier;
    char numeric_pad, shift, control, alt;

    if( amii_wins[ WIN_MAP ] )
      w = amii_wins[ WIN_MAP ]->win;
    qualifier = message->Qualifier;

    control = (qualifier &  IEQUALIFIER_CONTROL) != 0;
    shift   = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
    alt     = (qualifier & (IEQUALIFIER_LALT   | IEQUALIFIER_RALT  )) != 0;

    /* Allow ALT to function as a META key ... */
    /* But make it switchable - alt is needed for some non-US keymaps */
    if(flags.altmeta)
      qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT);
    numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 0;

    /*
     *  Shortcut for HELP and arrow keys. I suppose this is allowed.
     *  The defines are in intuition/intuition.h, and the keys don't
     *  serve 'text' input, normally. Also, parsing their escape
     *  sequences is such a mess...
     */

    switch (message->Code) {
      case RAWHELP:
          if( alt )
          {
            EditColor();
            return( -1 );
          }
#ifdef      CLIPPING
          else if( control )
          {
            EditClipping();

            CO = ( w->Width - w->BorderLeft - w->BorderRight  ) / mxsize;
            LI = ( w->Height - w->BorderTop - w->BorderBottom ) / mysize;
            clipxmax = CO + clipx;
            clipymax = LI + clipy;
            if( CO < COLNO || LI < ROWNO )
            {
                amii_cliparound( u.ux, u.uy );
            }
            else
            {
                clipping = FALSE;
                clipx = clipy = 0;
            }
            BufferQueueChar( 'R'-64 );
            return(-1);
          }
#endif
          else if( WINVERS_AMIV && shift )
          {
            if( WIN_OVER == WIN_ERR )
            {
                WIN_OVER = amii_create_nhwindow( NHW_OVER );
                BufferQueueChar( 'R'-64 );
            }
            else
            {
                delayed_key_action = CloseOver;
            }
            return( -1 );
          }
          return( '?' );
          break;
      case CURSORLEFT:
          length = '4';
          numeric_pad = 1;
          goto arrow;
      case CURSORDOWN:
          length = '2';
          numeric_pad = 1;
          goto arrow;
      case CURSORUP:
          length = '8';
          numeric_pad = 1;
          goto arrow;
      case CURSORRIGHT:
          length = '6';
          numeric_pad = 1;
          goto arrow;
    }

    theEvent.ie_Class = IECLASS_RAWKEY;
    theEvent.ie_Code = message->Code;
    theEvent.ie_Qualifier = numeric_pad ? IEQUALIFIER_NUMERICPAD : qualifier;
    theEvent.ie_EventAddress = (APTR) (message->IAddress);

    length = RawKeyConvert(&theEvent, (char *)buffer, 
      (long) sizeof(buffer), NULL);

    if (length == 1) {   /* Plain ASCII character */
      length = buffer[0];
      /*
       *  If iflags.num_pad is set, movement is by 4286.
       *  If not set, translate 4286 into hjkl.
       *  This way, the numeric pad can /always/ be used
       *  for moving, though best results are when it is off.
       */
arrow:
      if (!iflags.num_pad && numeric_pad && length >= '1' && length <= '9') {
          length -= '1';
          if (control) {
            length = ctrl_numpad[length];
          } else if (shift) {
            length = shift_numpad[length];
          } else {
            length = numpad[length];
          }
      }
      if (alt && flags.altmeta)
          length |= 0x80;
      return(length);
    } /* else shift, ctrl, alt, amiga, F-key, shift-tab, etc */
    else if( length > 1 )
    {
      int i;

      if( length == 3 && buffer[ 0 ] == 155 && buffer[ 2 ] == 126 )
      {
          int got = 1;
          switch( buffer[ 1 ] )
          {
            case 53: mxsize = mysize = 8; break;
            case 54: mxsize = mysize = 16; break;
            case 55: mxsize = mysize = 24; break;
            case 56: mxsize = mysize = 32; break;
            case 57: mxsize = mysize = 48; break;
            default: got = 0; break;
          }
#ifdef OPT_DISPMAP
          dispmap_sanity();
#endif

          if( got )
          {
            CO = (w->Width-w->BorderLeft-w->BorderRight)/mxsize;
            LI = (w->Height-w->BorderTop-w->BorderBottom)/mysize;
            clipxmax = CO + clipx;
            clipymax = LI + clipy;
            if( CO < COLNO || LI < ROWNO )
            {
                amii_cliparound( u.ux, u.uy );
            }
            else
            {
                  CO = COLNO;
                  LI = ROWNO;
            }
            reclip = 1;
            doredraw();
            flush_screen( 1 );
            reclip = 0;
            /*BufferQueueChar( 'R'-64 );*/
            return( -1 );
          }
      }
      printf( "Unrecognized key: %d ", (int)buffer[0]);
      for( i = 1; i < length; ++i )
          printf( "%d ", (int)buffer[i]);
      printf( "\n" );
    }
    return( -1 );
}

/*
 *  Process an incoming IntuiMessage.
 *  It would certainly look nicer if this could be done using a
 *  PA_SOFTINT message port, but we cannot call RawKeyConvert()
 *  during a software interrupt.
 *  Anyway, amikbhit()/kbhit() is called often enough, and usually gets
 *  ahead of input demands, when the user types ahead.
 */

static void ProcessMessage(message)
register struct IntuiMessage *message;
{
    int c;
    int cnt;
    menu_item *mip;
    static int skip_mouse=0;    /* need to ignore next mouse event on
                         * a window activation */
    struct Window *w = message->IDCMPWindow;

    switch(message->Class) {
    case ACTIVEWINDOW:
      if( alwaysinvent && WIN_INVEN != WIN_ERR &&
                      w == amii_wins[ WIN_INVEN ]->win )
      {
          cnt = DoMenuScroll( WIN_INVEN, 0, PICK_NONE, &mip );
      }
      else if( scrollmsg && WIN_MESSAGE != WIN_ERR &&
                      w == amii_wins[ WIN_MESSAGE ]->win )
      {
          cnt = DoMenuScroll( WIN_MESSAGE, 0, PICK_NONE, &mip );
      }
      else
      {
          skip_mouse=1;
      }
      break;

    case MOUSEBUTTONS:
      {
          if( skip_mouse )
          {
            skip_mouse=0;
            break;
          }

          if( !amii_wins[ WIN_MAP ] || w != amii_wins[ WIN_MAP ]->win )
            break;

          if( message->Code == SELECTDOWN )
          {
            lastevent.type = WEMOUSE;
            lastevent.un.mouse.x = message->MouseX;
            lastevent.un.mouse.y = message->MouseY;
                /* With shift equals RUN */
            lastevent.un.mouse.qual = (message->Qualifier &
              (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) != 0;
          }
      }
      break;

    case MENUPICK:
      {
          USHORT thismenu;
          struct MenuItem *item;

          thismenu = message->Code;
          while (thismenu != MENUNULL)
          {
            item = ItemAddress(HackMenu, (ULONG) thismenu);
            if (KbdBuffered < KBDBUFFER)
                BufferQueueChar(item->Command); /* Unused: No COMMSEQ */
            thismenu = item->NextSelect;
          }
      }
      break;

    case REFRESHWINDOW:
      {
          if( scrollmsg
            && amii_wins[ WIN_MESSAGE ]
            && w == amii_wins[ WIN_MESSAGE ]->win
          ){
            cnt = DoMenuScroll( WIN_MESSAGE, 0, PICK_NONE, &mip );
          }
      }
      break;

    case CLOSEWINDOW:
      if( WIN_INVEN != WIN_ERR && w == amii_wins[ WIN_INVEN ]->win )
      {
          dismiss_nhwindow( WIN_INVEN );
      }
      if( WINVERS_AMIV
          && ( WIN_OVER != WIN_ERR && w == amii_wins[ WIN_OVER ]->win )
      ){
          destroy_nhwindow( WIN_OVER );
          WIN_OVER = WIN_ERR;
      }
      break;

    case RAWKEY:
      if (!(message->Code & IECODE_UP_PREFIX)){
          /* May queue multiple characters
           * but doesn't do that yet...
           */
          if( ( c = ConvertKey(message) ) > 0 )
            BufferQueueChar( c );
        }
        break;

    case GADGETDOWN:
      if( WIN_MESSAGE != WIN_ERR && w == amii_wins[ WIN_MESSAGE ]->win )
      {
          cnt = DoMenuScroll( WIN_MESSAGE, 0, PICK_NONE, &mip );
      }
      else if( WIN_INVEN != WIN_ERR && w == amii_wins[ WIN_INVEN ]->win )
      {
          cnt = DoMenuScroll( WIN_INVEN, 0, PICK_NONE, &mip );
      }
      break;

    case NEWSIZE:
      if( WIN_MESSAGE != WIN_ERR && w == amii_wins[ WIN_MESSAGE ]->win )
      {
          if( WINVERS_AMIV )
          {
            /* Make sure that new size is honored for good. */
            SetAPen( w->RPort, amii_msgBPen );
            SetBPen( w->RPort, amii_msgBPen );
            SetDrMd( w->RPort, JAM2 );
            RectFill( w->RPort, w->BorderLeft, w->BorderTop,
              w->Width - w->BorderRight-1,
              w->Height - w->BorderBottom-1 );
          }
          ReDisplayData( WIN_MESSAGE );
      }
      else if( WIN_INVEN != WIN_ERR && w == amii_wins[ WIN_INVEN ]->win )
      {
          ReDisplayData( WIN_INVEN );
      }
      else if( WINVERS_AMIV
             && ( WIN_OVER != WIN_ERR && w == amii_wins[ WIN_OVER ]->win )
      ){
          BufferQueueChar( 'R'-64 );
      }
      else if( WIN_MAP != WIN_ERR && w == amii_wins[ WIN_MAP ]->win )
      {
#ifdef      CLIPPING
          CO = (w->Width-w->BorderLeft-w->BorderRight)/mxsize;
          LI = (w->Height-w->BorderTop-w->BorderBottom)/mysize;
          clipxmax = CO + clipx;
          clipymax = LI + clipy;
          if( CO < COLNO || LI < ROWNO )
          {
            amii_cliparound( u.ux, u.uy );
          }
          else
          {
            clipping = FALSE;
            clipx = clipy = 0;
          }
          BufferQueueChar( 'R'-64 );
#endif
      }
      break;
    }
    ReplyMsg((struct Message *) message);

    switch(delayed_key_action){
    case CloseOver:
      amii_destroy_nhwindow( WIN_OVER );
      WIN_OVER = WIN_ERR;
      delayed_key_action = NoAction;
    case NoAction:
      ;     /* null */
    }
}

#endif /* AMII_GRAPHICS */
/*
 *  Get all incoming messages and fill up the keyboard buffer,
 *  thus allowing Intuition to (maybe) free up the IntuiMessages.
 *  Return when no more messages left, or keyboard buffer half full.
 *  We need to do this since there is no one-to-one correspondence
 *  between characters and incoming messages.
 */

#if defined(TTY_GRAPHICS) && !defined(AMII_GRAPHICS)
int kbhit(){
      return 0
}
#else
int
kbhit()
{
    int c;
# ifdef TTY_GRAPHICS
            /* a kludge to defuse the mess in allmain.c */
            /* I hope this is the right approach */
    if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)return 0;
# endif
    c = amikbhit();
    if( c <= 0 )
      return( 0 );
    return( c );
}
#endif

#ifdef AMII_GRAPHICS

int
amikbhit()
{
    register struct IntuiMessage *message;
    while( KbdBuffered < KBDBUFFER / 2 )
    {
#ifdef AMIFLUSH
      message = (struct IntuiMessage *) GetFMsg(HackPort);
#else
      message = (struct IntuiMessage *) GetMsg(HackPort);
#endif
      if(message)
      {
          ProcessMessage(message);
          if( lastevent.type != WEUNK && lastevent.type != WEKEY )
            break;
      }
      else
          break;
    }
    return ( lastevent.type == WEUNK ) ? KbdBuffered : -1;
}

/*
 *  Get a character from the keyboard buffer, waiting if not available.
 *  Ignore other kinds of events that happen in the mean time.
 */

int WindowGetchar( )
{
    while ((lastevent.type = WEUNK), amikbhit() <= 0) {
      WaitPort(HackPort);
    }
    return BufferGetchar();
}

WETYPE WindowGetevent()
{
    lastevent.type = WEUNK;
    while (amikbhit() == 0)
    {
      WaitPort(HackPort);
    }

    if( KbdBuffered )
    {
      lastevent.type = WEKEY;
      lastevent.un.key = BufferGetchar();
    }
    return( lastevent.type );
}

/*
 *  Clean up everything. But before we do, ask the user to hit return
 *  when there is something that s/he should read.
 */

void amii_cleanup()
{
    register struct IntuiMessage *msg;

    /* Close things up */
    if( HackPort )
    {
      amii_raw_print("");
      amii_getret();
    }

    if (ConsoleIO.io_Device)
      CloseDevice( (struct IORequest *)&ConsoleIO );
    ConsoleIO.io_Device = 0;

    if( ConsoleIO.io_Message.mn_ReplyPort )
      DeletePort( ConsoleIO.io_Message.mn_ReplyPort );
    ConsoleIO.io_Message.mn_ReplyPort = 0;

    /* Strip messages before deleting the port */
    if( HackPort )
    {
      Forbid();
      while (msg = (struct IntuiMessage *) GetMsg(HackPort))
          ReplyMsg((struct Message *) msg);
      kill_nhwindows( 1 );
      DeletePort( HackPort );
      HackPort = NULL;
      Permit();
    }

    /* Close the screen, under v37 or greater it is a pub screen and there may
     * be visitors, so check close status and wait till everyone is gone.
     */
    if( HackScreen )
    {
#ifdef  INTUI_NEW_LOOK
      if( IntuitionBase->LibNode.lib_Version >= 37 )
      {
          while( CloseScreen( HackScreen ) == FALSE )
          {
            struct EasyStruct easy =
            {
                sizeof( struct EasyStruct ),
                0,
                "Nethack Problem",
                "Can't Close Screen, Close Visiting Windows",
                "Okay"
            };
            EasyRequest( NULL, &easy, NULL, NULL );
          }
      }
      else
#endif
      {
          CloseScreen(HackScreen);
      }
      HackScreen = NULL;
    }

#ifdef HACKFONT
    if (HackFont)
    {
      CloseFont(HackFont);
      HackFont = NULL;
    }

    if( TextsFont )
    {
      CloseFont( TextsFont );
      TextsFont = NULL;
    }

    if( RogueFont )
    {
      CloseFont( RogueFont );
      RogueFont = NULL;
    }

    if( DiskfontBase )
    {
      CloseLibrary(DiskfontBase);
      DiskfontBase = NULL;
    }
#endif

    if( WINVERS_AMIV && LayersBase)
    {
      CloseLibrary((struct Library *)LayersBase);
      LayersBase = NULL;
    }

    if (GfxBase) {
      CloseLibrary((struct Library *)GfxBase);
      GfxBase = NULL;
    }

    if (IntuitionBase) {
      CloseLibrary((struct Library *)IntuitionBase);
      IntuitionBase = NULL;
    }

#ifdef      SHAREDLIB
    if (DOSBase) {
      CloseLibrary((struct Library *)DOSBase);
      DOSBase = NULL;
    }
#endif

    ((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr;

    Initialized = 0;
}

#endif      /* AMII_GRAPHICS */

#ifndef     SHAREDLIB
void Abort(rc)
long rc;
{
    int fault = 1;
#ifdef CHDIR
    extern char orgdir[];
    chdir(orgdir);
#endif
#ifdef AMII_GRAPHICS
    if (Initialized
      && ConsoleDevice
      && windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows) {
      printf("\n\nAbort with alert code %08lx...\n", rc);
      amii_getret();
    } else
#endif
      printf("\n\nAbort with alert code %08lx...\n",rc);
      /* Alert(rc);              this is too severe */
#ifdef __SASC
# ifdef     INTUI_NEW_LOOK
    if( IntuitionBase->LibNode.lib_Version >= 37 )
    {
      struct EasyStruct es =
      {
            sizeof( struct EasyStruct ),
            0,
            "NetHack Panic Request",
            "NetHack is Aborting with code == 0x%08lx",
            "Continue Abort|Return to Program|Clean up and exit",
      };
      fault = EasyRequest( NULL, &es, NULL, (long)rc );
      if( fault == 2 )
          return;
    }
# endif
    if( fault == 1 )
    {
/*  __emit(0x4afc);     /* illegal instruction */
    __emit(0x40fc);     /* divide by */
    __emit(0x0000);     /*  #0  */
      /* NOTE: don't move amii_cleanup() above here - */
      /* it is too likely to kill the system     */
      /* before it can get the SnapShot out, if  */
      /* there is something really wrong.    */
    }
#endif
#ifdef AMII_GRAPHICS
    if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
      amii_cleanup();
#endif
#undef exit
#ifdef AZTEC_C
    _abort();
#endif
    exit((int) rc);
}

void
CleanUp()
{
      amii_cleanup();
}
#endif

#ifdef AMII_GRAPHICS

#ifdef AMIFLUSH
/* This routine adapted from AmigaMail IV-37 by Michael Sinz */
static struct Message *
GetFMsg(port)
    struct MsgPort *port;
    {
    struct IntuiMessage *msg,*succ,*succ1;

    if(msg=(struct IntuiMessage *)GetMsg(port)){
      if(!flags.amiflush)return((struct Message *)msg);
      if(msg->Class==RAWKEY){
          Forbid();
          succ=(struct IntuiMessage *)(port->mp_MsgList.lh_Head);
          while(succ1=(struct IntuiMessage *)
            (succ->ExecMessage.mn_Node.ln_Succ)){
            if(succ->Class==RAWKEY){
                Remove((struct Node *)succ);
                ReplyMsg((struct Message *)succ);
            }
            succ=succ1;
          }
          Permit();
      }
    }
    return((struct Message *)msg);
}
#endif

struct NewWindow *
DupNewWindow( win )
    struct NewWindow *win;
{
    struct NewWindow *nwin;
    struct Gadget *ngd, *gd, *pgd = NULL;
    struct PropInfo *pip;
    struct StringInfo *sip;

    /* Copy the (Ext)NewWindow structure */

    nwin = (struct NewWindow *)alloc( sizeof( struct NewWindow ) );
    *nwin = *win;

    /* Now do the gadget list */

    nwin->FirstGadget = NULL;
    for( gd = win->FirstGadget; gd; gd = gd->NextGadget )
    {
      ngd = (struct Gadget *)alloc( sizeof( struct Gadget ) );
      *ngd = *gd;
      if( gd->GadgetType == STRGADGET )
      {
          sip = (struct StringInfo *)alloc( sizeof( struct StringInfo ) );
          *sip = *((struct StringInfo *)gd->SpecialInfo);
          sip->Buffer = (UBYTE *) alloc( sip->MaxChars );
          *sip->Buffer = 0;
          ngd->SpecialInfo = (APTR)sip;
      }
      else if( gd->GadgetType == PROPGADGET )
      {
          pip = (struct PropInfo *)alloc( sizeof( struct PropInfo ) );
          *pip = *((struct PropInfo *)gd->SpecialInfo);
          ngd->SpecialInfo = (APTR)pip;
      }
      if( pgd )
          pgd->NextGadget = ngd;
      else
          nwin->FirstGadget = ngd;
      pgd = ngd;
      ngd->NextGadget = NULL;
    }
    return( nwin );
}

void
FreeNewWindow( win )
    struct NewWindow *win;
{
    register struct Gadget *gd, *pgd;
    register struct StringInfo *sip;

    for( gd = win->FirstGadget; gd; gd = pgd )
    {
      pgd = gd->NextGadget;
      if( gd->GadgetType == STRGADGET )
      {
          sip = (struct StringInfo *)gd->SpecialInfo;
          free( sip->Buffer );
          free( sip );
      }
      else if( gd->GadgetType == PROPGADGET )

      {
          free( (struct PropInfo *)gd->SpecialInfo );
      }
      free( gd );
    }
    free( win );
}

void
bell()
{
    if (flags.silent) return;
    DisplayBeep(NULL);
}

void
amii_delay_output()
{
    /* delay 50 ms */
    Delay(2L);
}

void
amii_number_pad(state)
int state;
{
}
#endif  /* AMII_GRAPHICS */

#ifndef     SHAREDLIB
void
amiv_loadlib( void )
{
}

void
amii_loadlib( void )
{
}

/* fatal error */
/*VARARGS1*/
void error VA_DECL(const char *, s)
    VA_START(s);
    VA_INIT(s, char *);

    putchar('\n');
    vprintf(s, VA_ARGS);
    putchar('\n');

    VA_END();
    Abort(0L);
}
#endif

Generated by  Doxygen 1.6.0   Back to index