#include "exec/types.h" #include "exec/ports.h" #include "exec/io.h" #include "exec/memory.h" #include "graphics/gfx.h" #include "devices/timer.h" #include "libraries/dos.h" #include "workbench/startup.h" #include "proto/exec.h" #include "proto/graphics.h" #include "proto/layers.h" #include "proto/intuition.h" #include "proto/timer.h" #include "proto/dos.h" #include "string.h" #include "ctype.h" #include "dos.h" #include "hp11/hp11.h" #include "hp11/amiga/internal.h" #include "hp11/amiga/amiga.h" #include "hp11/amiga/menus.h" #define MAXWIDTH 29 /* X distance between 2 keys */ #define MAXHEIGHT 29 /* Y distance bewteen 2 keys */ #define KEYWIDTH 20 /* Width of actual key */ #define KEYHEIGHT 16 /* Height of actual key */ #define TOPKEYHEIGHT 9 /* Height of top of key */ #define KEYX (19 + HP11X) /* Position of first key */ #define KEYY (61 + HP11Y) #define CHAROFFX -1 /* offset in display for first char */ #define CHAROFFY 3 #define CHARWIDTH 14 /* Size of char */ #define CHARHEIGHT 13 #define SCRX0 (53 + HP11X) /* Limits of display for chars */ #define SCRX1 (208 + HP11X) #define SCRY0 (11 + HP11Y) #define SCRY1 (37 + HP11Y) #define fX (SCRX0 + 3 * CHARWIDTH + 2) /* Position of indicators */ #define gX (SCRX0 + 4 * CHARWIDTH - 1) #define GX (SCRX0 + (int)(6.5 * CHARWIDTH)) #define RADX (GX + 5) #define PRGMX (SCRX0 + 10 * CHARWIDTH - 6) #define USERX (SCRX0 + CHARWIDTH) #define INDICY (SCRY0 + 19) #define CR 13 #define BS 8 #define ESC 27 #define COPY 0xc0 /* minterm for straight copy */ struct Library *TimerBase; /* Base for calling timer routines */ extern struct Border *hp11char[]; /* Character descriptions (as connected lines) */ /* Indicator shapes (as bitmaps) */ extern struct Image fImage, gImage, USERImage, GImage, RADImage, PRGMImage; extern struct Image off_image; /* Image for sleep */ extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; struct LayersBase *LayersBase; struct Window *hp11; /* The window containing the hp11 */ /* These informations are for RelKey() */ /* The method by which the latest key was obtained : From the menus, from the CLOSE gadget, from the keyboard, or by selecting with the mouse */ static enum {menu, gadget, keyboard, mouse} keytype; /* The keycode of the last key read */ static short lastkey; /* The Time at which the last key was read */ static ULONG secs, micros; /* Path to executable */ char *hp11name; char hp11path[PATHLEN]; static struct timerequest *timer; /* The timer which is used */ static struct NewWindow hp11new = { /* Desired window */ 0,0, /* Position of top left corner */ HP11WIDTH + 6, HP11HEIGHT + 14, /* Width, Height */ -1,-1, /* Use default pens to draw window */ CLOSEWINDOW | MOUSEBUTTONS | VANILLAKEY | MENUPICK, WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH, NULL, NULL, "HP11C", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN /* It opens in the main screen */ }; static struct IntuiText canceltext = { AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE, AUTOITEXTFONT, "Cancel", AUTONEXTTEXT }; static struct IntuiText nomemtext = { AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 20, 10, AUTOITEXTFONT, "Not enough memory", NULL }; char *mygetpath(to, l) register char *to; register BPTR l; { register BPTR tl; register int notfirst = FALSE; register struct FileInfoBlock *fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), 0); if (!fib) return(NULL); to[0] = '\0'; do { if (!Examine(l, fib)) return(NULL); if (fib->fib_DirEntryType > 0) strins(to, "/"); if (fib->fib_FileName[0] == '\0') strins(to, "RAM"); else strins(to, fib->fib_FileName); tl = l; l = ParentDir(l); if (notfirst) UnLock(tl); notfirst = TRUE; } while (l); *(strchr(to, '/')) = ':'; FreeMem((char *)fib, sizeof(struct FileInfoBlock)); return(to); } void split(char *file, char *path, char **name) { int l = strlen(file); *name = file + l; while (--l >= 0 && (*--*name != '/' && **name != ':')) ; if (l < 0) path[0] = '\0'; else { ++*name; strncpy(path, file, l + 1); path[l + 1] = '\0'; } } /* Delete a timer */ static void DeleteTimer(struct timerequest *tr) { TimerBase = (struct Library *)(-1); /* Don't call any more ! */ if (tr != NULL) { /* Remove the port */ if (tr->tr_node.io_Message.mn_ReplyPort) DeletePort(tr->tr_node.io_Message.mn_ReplyPort); CloseDevice((struct IORequest *)tr); /* Close the device */ DeleteExtIO((struct IORequest *)tr); /* Free the IO request */ } } /* Create a timer of type unit */ static struct timerequest *CreateTimer(ULONG unit) { register long error; register struct MsgPort *timerport; register struct timerequest *timermsg; if ((timerport = CreatePort(NULL, 0)) == NULL) /* first get a port */ return(NULL); /* failed */ if ((timermsg = (struct timerequest *) /* Then create an IO request for the timer */ CreateExtIO(timerport, sizeof(struct timerequest))) == NULL) return(NULL); /* failed */ if ((error = OpenDevice(TIMERNAME, unit, (struct IORequest *)timermsg, 0)) != 0) /* Finally, open the timer device */ { /* failed */ DeleteTimer(timermsg); return(NULL); } TimerBase = (struct Library *)timermsg->tr_node.io_Device; /* Allow calls to the time arithmetic routines */ return(timermsg); } /* Wait for a specified duration */ static void WaitFor(struct timeval *tv) { timer->tr_node.io_Command = TR_ADDREQUEST; timer->tr_time = *tv; DoIO((struct IORequest *)timer); /* Wait for completion of request */ } /* Obtain the system time, assume global timer contains a valid timer */ static void GetSysTime(struct timeval *tv) { timer->tr_node.io_Command = TR_GETSYSTIME; DoIO((struct IORequest *)timer); *tv = timer->tr_time; /* Copy obtained time */ } /* Reverse the key on the keyboard (as if user was holding it down) */ static void ReverseKey(int key) { register int kx, ky, h; if (key == 30) h = KEYHEIGHT - 1; /* ON, higher than average */ else if (key == 25) h = MAXHEIGHT + TOPKEYHEIGHT - 1; /* ENTER, even taller */ else h = TOPKEYHEIGHT - 1; /* -------------------- */ /* Check for bug when using short int */ kx = (key % 10) * MAXWIDTH + KEYX; /* Calc. key position */ ky = (key / 10) * MAXHEIGHT + KEYY; SetDrMd(hp11->RPort, COMPLEMENT); /* Draw in reverse */ RectFill(hp11->RPort, (long)kx, (long)ky, (long)(kx + (KEYWIDTH - 1)), (long)(ky + h)); } /* From positions x & y, deduce which key was pressed */ static int DecodeKey(int x, int y) { register int kx, ky, px, py; kx = (x - KEYX) / MAXWIDTH; px = (x - KEYX) % MAXWIDTH; ky = (y - KEYY) / MAXHEIGHT; py = (y - KEYY) % MAXHEIGHT; if (/* first, check if in keyboard. x & y are tested (instead of kx, ky) because kx & ky suffer a roundoff towards zero for negative values */ (x >= KEYX && y >= KEYY && kx <= 9 && ky <= 3) && /* now the condition on width */ (px < KEYWIDTH && px >= 0) /* same for all keys */ && /* condition on height, 2 cases for ENTER is different */ ( (kx == 5 && (ky == 2 || (ky == 3 && py < KEYHEIGHT) && (ky = 2))) /* ENTER, set ky to correct value when ky == 3 */ || /* condition on height */ (py < KEYHEIGHT && py >= 0) ) ) return(ky * 10 + kx); else return(-1); } /* Mouse was pressed at x,y. Is this a key ? */ static int GetMouseKey(int x, int y) { int key; if ((key = DecodeKey(x, y)) != -1) { /* yes */ ReverseKey(key); keytype = mouse; /* info for RelKey() */ } return(key); } /* Key keycode was pressed by the user */ static int GetKeyKey(int _keycode) { register int key = -1, keycode = tolower(_keycode); switch (keycode) { case ESC: key = 30; break; case '7': case '8': case '9': key = keycode - ('7' - 6); break; case '4': case '5': case '6': key = keycode - ('4' - 16); break; case '1': case '2': case '3': key = keycode - ('1' - 26); break; case '0': key = 36; break; case '.': key = 37; break; case '^': key = 3; break; case '*': key = 19; break; case '-': key = 29; break; case '+': key = 39; break; case '/': key = 9; break; case '_': key = 5; break; case CR : key = 25; break; case 'f': key = 31; break; case 'g': key = 32; break; case BS : key = 24; break; case 's': key = 12; break; case 'c': key = 13; break; case 't': key = 14; break; } if (key != -1) { /* A valid key was given */ ReverseKey(key); keytype = keyboard; /* for RelKey() */ } return(key); } /* Get a key from the keyboard with/without waiting */ int PollKey(wait) int wait; { register int key; register struct IntuiMessage *msg; register ULONG class; register UWORD code; register WORD x, y; register APTR address; key = -1; /* no key yet */ do { if (wait) WaitPort(hp11->UserPort); /* No active waits in multi-tasking ! */ msg = (struct IntuiMessage *)GetMsg(hp11->UserPort); /* Get the message if there is one */ if (msg) { /* yes, there is */ /* Copy relevant information */ class = msg->Class; code = msg->Code; address = msg->IAddress; x = msg->MouseX; y = msg->MouseY; secs = msg->Seconds; micros = msg->Micros; ReplyMsg((struct Message *)msg); /* & reply to it */ switch (class) { /* type of message */ case CLOSEWINDOW: /* Window closed = Quit */ quit = TRUE; key = BRESET; keytype = gadget; break; case MOUSEBUTTONS: /* A mouse button was pressed */ if (code == SELECTDOWN) key = GetMouseKey(x, y); break; case VANILLAKEY: /* a key was pressed */ key = GetKeyKey(code); break; case MENUPICK: /* A menu option was chosen */ key = MenuHandler(code); /* Call menu handler */ keytype = menu; /* for RelKey() */ break; } } } while (key == -1 && (msg || wait)); /* Exit if key read or, if not waiting, no message ready */ lastkey = key; /* save key for RelKey() */ return(key); } /* Wait for latest key to be released, returns true if button released over key (valid only for mouse) */ BOOL RelKey() { register WORD x, y; register BOOL Released; register struct IntuiMessage *msg; struct timeval event, now, delay; register int key = lastkey; /* key last pressed */ lastkey = -1; /* Only release it once ! */ if (key != -1) switch (keytype) { case keyboard: /* Key reversed for a max of .08 secs (There is no easy way to wait for its release on the keyboard) */ event.tv_secs = secs; event.tv_micro = micros; GetSysTime(&now); SubTime(&now, &event); /* Time elapsed since key pressed */ delay.tv_secs = 0; delay.tv_micro = 80000; if (CmpTime(&now, &delay) == 1) { /* now < delay */ SubTime(&delay, &now); WaitFor(&delay); /* Wait long enough */ } ReverseKey(key); /* un-reverse key */ return(TRUE); case mouse: Released = FALSE; do { /* Wait for mouse button to be released */ WaitPort(hp11->UserPort); msg = (struct IntuiMessage *)GetMsg(hp11->UserPort); x = msg->MouseX; y = msg->MouseY; Released = (msg->Class == MOUSEBUTTONS && msg->Code == SELECTUP); ReplyMsg((struct Message *)msg); } while (!Released); ReverseKey(key); /* un-reverse key */ return((BOOL)(DecodeKey(x, y) == key)); /* Button released over key? */ } return(TRUE); /* if already released */ } /* load picture from open file file, width pixel wide, height pixels high, depth bitplanes deep into bitmap bm & colormap cols (if non-null) */ static BOOL LoadBitMap(LONG file, struct BitMap *bm, int width, int height, int depth) { register int i; register LONG nb, plsize; InitBitMap(bm, (long)depth, (long)width, (long)height); plsize = bm->BytesPerRow * bm->Rows; /* size of 1 plane */ /* Allocate enough memory for all planes, initialise plane pointers */ if (!(bm->Planes[0] = (PLANEPTR)AllocMem(plsize * depth, MEMF_CHIP))) return((BOOL) FALSE); for (i = 1; i < depth; i++) bm->Planes[i] = bm->Planes[0] + plsize * i; /* Read data from disk */ for (i = 0; i < bm->Depth; i++) { nb = Read(file, bm->Planes[i], plsize); if (nb < plsize) return((BOOL) FALSE); } return((BOOL) TRUE); } void alert(struct Window *win, char *msg1, char *msg2) { static struct TextAttr alert_attr = { "topaz.font", 8 }; struct TextFont *alert_font; struct IntuiText text1, text2, negative; const static struct IntuiText template = { 0, 1, JAM1, 8, 0, &alert_attr }; int width, height; int ysize; alert_font = OpenFont(&alert_attr); ysize = alert_font ? alert_font->tf_YSize : 8; text1 = text2 = negative = template; text1.TopEdge = 8; text1.IText = msg1; width = IntuiTextLength(&text1) + 40; height = 37 + 2 * ysize; if (msg2 != NULL) { int w; text1.NextText = &text2; text2.TopEdge = text1.TopEdge + ysize; text2.IText = msg2; height += ysize; w = IntuiTextLength(&text2) + 20; if (w > width) width = w; } negative.LeftEdge = 6; negative.TopEdge = 4; negative.IText = "Ok"; AutoRequest(win, &text1, NULL, &negative, 0L, 0L, width, height); } /* Amiga specific initialisation */ #define argw ((struct WBStartup *)argv) BOOL AmigaInit(argc, argv) int argc; APTR argv; { register LONG file; register BOOL loaded; struct BitMap hp11bitmap; BPTR hp11dir, old; char filename[PATHLEN + 8]; if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33))) /* Open graphics library (1.2) */ return(FALSE); if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 33))) /* Open intuition library (1.2) */ return(FALSE); if (!(LayersBase = (struct LayersBase *)OpenLibrary("layers.library", 0))) return(FALSE); /* Find path to command (if possible) */ if (argc == 0) /* WB */ { old = CurrentDir(argw->sm_ArgList[0].wa_Lock); split(argw->sm_ArgList[0].wa_Name, hp11path, &hp11name); hp11dir = Lock(hp11path, ACCESS_READ); if (!mygetpath(hp11path, hp11dir)) hp11path[0] = '\0'; CurrentDir(old); UnLock(hp11dir); } else { /* CLI */ split(((char **)argv)[0], hp11path, &hp11name); } /* Read the picture */ if (!(file = Open(strcat(strcpy(filename, hp11path), "hp11.pic"), MODE_OLDFILE))) if (!(file = Open("hp11.pic", MODE_OLDFILE))) { alert(NULL, "Can't find hp11.pic", NULL); return(FALSE); } loaded = LoadBitMap(file, &hp11bitmap, HP11WIDTH, HP11HEIGHT, 2); Close(file); if (!loaded) return(FALSE); /* Open the window */ if (!(hp11 = OpenWindow(&hp11new))) return(FALSE); /* Move picture into window */ BltBitMapRastPort(&hp11bitmap, 0, 0, hp11->RPort, HP11X, HP11Y, HP11WIDTH, HP11HEIGHT, COPY); FreeMem(hp11bitmap.Planes[0], (long)(hp11bitmap.BytesPerRow * hp11bitmap.Rows * hp11bitmap.Depth)); /* Create timer */ if ((timer = CreateTimer(UNIT_MICROHZ)) == NULL) return(FALSE); /* Init menus */ return(MenusInit(argc, argv)); } #undef argw void AmigaCleanUp() { MenusCleanUp(); if (timer) DeleteTimer(timer); /* Close timer */ if (hp11) CloseWindow(hp11); if (LayersBase) CloseLibrary((struct Library *)LayersBase); if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); /* Close libraries */ if (GfxBase) CloseLibrary((struct Library *)GfxBase); } /* Display s */ void Display(s) register char *s; { register int posx; register int chr; register struct RastPort *rport = hp11->RPort; /* Clear display */ SetDrMd(rport, JAM1); SetAPen(rport, 2); RectFill(rport, SCRX0 + 1, SCRY0, SCRX1 - 1, SCRY1); /* Initial position */ posx = SCRX0 + CHAROFFX; while (*s) { switch (*s) { /* Position of char in char array */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': chr = *s - '0'; break; case '-': chr = 10; break; case 'E': chr = 11; break; case 'r': chr = 12; break; case 'o': chr = 13; break; case 'R': chr = 14; break; case 'u': chr = 15; break; case 'n': chr = 16; break; case 'i': chr = 17; break; case 'g': chr = 18; break; case '.': chr = 19; break; case ',': chr = 20; break; case 'P': chr = 21; break; default: chr = -1; break; } if (chr != -1) DrawBorder(rport, hp11char[chr], (long)posx, SCRY0 + CHAROFFY); if (*s != '.' && *s != ',') posx += CHARWIDTH; s++; } } /* Set image to be drawn/erased according to on */ static void SetCol(struct Image *im, int on) { if (on) { im->PlanePick = 3; im->PlaneOnOff = 0; } else { im->PlanePick = 0; im->PlaneOnOff = 2; } } /* Display the indicators */ void Dispf(on) int on; { SetCol(&fImage, on); DrawImage(hp11->RPort, &fImage, fX, INDICY); } void Dispg(on) int on; { SetCol(&gImage, on); DrawImage(hp11->RPort, &gImage, gX, INDICY); } void DispUSER(on) int on; { SetCol(&USERImage, on); DrawImage(hp11->RPort, &USERImage, USERX, INDICY); } void DispG(on) int on; { SetCol(&GImage, on); DrawImage(hp11->RPort, &GImage, GX, INDICY); } void DispRAD(on) int on; { SetCol(&RADImage, on); DrawImage(hp11->RPort, &RADImage, RADX, INDICY); } void DispPRGM(on) int on; { SetCol(&PRGMImage, on); DrawImage(hp11->RPort, &PRGMImage, PRGMX, INDICY); } void beep(void) { DisplayBeep(NULL); } static struct Window *MakeIcon(struct Image *image, struct BitMap *bm, struct BitMap *tmpbm, LONG x, LONG y, LONG w, LONG h) { register struct Window *win; register ULONG size; static struct NewWindow new_win = { 0, 0, 0, 0, -1, -1, MOUSEBUTTONS | MOUSEMOVE | INACTIVEWINDOW | NOCAREREFRESH, SMART_REFRESH | BORDERLESS | REPORTMOUSE | RMBTRAP, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; new_win.LeftEdge = x; new_win.TopEdge = y; new_win.Width = w; new_win.Height = h; InitBitMap(bm, 2, w, h); size = bm->BytesPerRow * bm->Rows; /* size of 1 plane */ bm->Planes[0] = (PLANEPTR)image->ImageData; bm->Planes[1] = (PLANEPTR)(image->ImageData) + size; InitBitMap(tmpbm, 2, w, h); if (!(tmpbm->Planes[0] = (PLANEPTR)AllocMem(2 * size, MEMF_CHIP))) return(NULL); tmpbm->Planes[1] = tmpbm->Planes[0] + size; if (win = OpenWindow(&new_win)) DrawImage(win->RPort, image, 0, 0); else FreeMem(tmpbm->Planes[0], 2 * size); return(win); } static void GetBounds(struct Window *win, LONG *mx, LONG *my, LONG w, LONG h, LONG wx, LONG wy) { struct Screen *scr = win->WScreen; *mx = scr->MouseX - wx; *my = scr->MouseY - wy; if (*mx + w > scr->Width) *mx = scr->Width - w; else if (*mx < 0) *mx = 0; if (*my + h > scr->Height) *my = scr->Height - h; else if (*my < 0) *my = 0; } static void SwapImage(struct BitMap *scrbm, struct BitMap *drawing, struct BitMap *buf, LONG x, LONG y, LONG w, LONG h) { BltBitMap(scrbm, x, y, buf, 0, 0, w, h, COPY, 0xff, NULL); BltBitMap(drawing, 0, 0, scrbm, x, y, w, h, COPY, 0xff, NULL); BltBitMap(buf, 0, 0, drawing, 0, 0, w, h, COPY, 0xff, NULL); } static void Iconize(struct Image *image, LONG x, LONG y) { register struct Window *win; register struct Screen *scr; register struct IntuiMessage *msg; LONG mx, my, wx, wy; register LONG w, h; ULONG oldsecs = 0, oldmicros = 0; BOOL cont, moved; register BOOL down, wasdown; struct BitMap image_bm, tmpbm; w = image->Width; h = image->Height; win = MakeIcon(image, &image_bm, &tmpbm, x, y, w, h); if (win) { scr = win->WScreen; cont = TRUE; down = FALSE; do { moved = FALSE; wasdown = down; WaitPort(win->UserPort); while (msg = (struct IntuiMessage *)GetMsg(win->UserPort)) { switch (msg->Class) { case MOUSEBUTTONS: if (msg->Code == SELECTUP) { if (DoubleClick(oldsecs, oldmicros, msg->Seconds, msg->Micros)) cont = FALSE; else { oldsecs = msg->Seconds; oldmicros = msg->Micros; } } down = (msg->Code == SELECTDOWN); break; case INACTIVEWINDOW: down = FALSE; break; case MOUSEMOVE: moved = TRUE; break; } ReplyMsg((struct Message *)msg); } if (!wasdown && down) { wx = win->MouseX; wy = win->MouseY; GetBounds(win, &mx, &my, w, h, wx, wy); LockLayers(&scr->LayerInfo); SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h); } else if (wasdown) if (down) { if (moved) { SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h); GetBounds(win, &mx, &my, w, h, wx, wy); SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h); } } else { SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h); UnlockLayers(&scr->LayerInfo); MoveWindow(win, (long)(mx - win->LeftEdge), (long)(my - win->TopEdge)); } } while (cont || down); CloseWindow(win); FreeMem(tmpbm.Planes[0], 2 * RASSIZE(w, h)); } } void sleep() { struct BitMap hp11bitmap; struct RastPort hp11rport; register LONG plsize; register LONG x, y; /* Save picture in bitmap */ InitBitMap(&hp11bitmap, 2, HP11WIDTH, HP11HEIGHT); plsize = hp11bitmap.BytesPerRow * hp11bitmap.Rows; /* size of 1 plane */ /* Allocate enough memory for all planes, initialise plane pointers */ if (!(hp11bitmap.Planes[0] = (PLANEPTR)AllocMem(plsize * 2, MEMF_CHIP))) Message("Not enough memory"); else { hp11bitmap.Planes[1] = hp11bitmap.Planes[0] + plsize; InitRastPort(&hp11rport); hp11rport.BitMap = &hp11bitmap; ClipBlit(hp11->RPort, HP11X, HP11Y, &hp11rport, 0, 0, HP11WIDTH, HP11HEIGHT, COPY); Forbid(); x = hp11->LeftEdge; y = hp11->TopEdge; Permit(); ClearMenuStrip(hp11); CloseWindow(hp11); Iconize(&off_image, x, y); /* Open the window */ hp11new.LeftEdge = x; hp11new.TopEdge = y; if (!(hp11 = OpenWindow(&hp11new))) { AutoRequest(NULL, &nomemtext, NULL, &canceltext, NULL, NULL, 250, 60); quit = TRUE; } else { /* Move picture into window */ BltBitMapRastPort(&hp11bitmap, 0, 0, hp11->RPort, HP11X, HP11Y, HP11WIDTH, HP11HEIGHT, COPY); FreeMem(hp11bitmap.Planes[0], (long)(hp11bitmap.BytesPerRow * hp11bitmap.Rows * hp11bitmap.Depth)); SetMenuStrip(hp11, hp11menu); on = TRUE; } } }