diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e0891e6..a4191917 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.13) -project( "Einstein" VERSION "2022.4.18" ) +project( "Einstein" VERSION "2022.4.19" ) # ---- Configuration for all targets on all platforms diff --git a/Drivers/Einstein.rex.src b/Drivers/Einstein.rex.src index c108b83d..b1e05427 100644 --- a/Drivers/Einstein.rex.src +++ b/Drivers/Einstein.rex.src @@ -35,6 +35,7 @@ package "obj/EinsteinSerialVoyager.pkg" package "obj/EinsteinInTranslator.pkg" package "obj/EinsteinOutTranslator.pkg" package "obj/EinsteinNativeCalls.pkg" +package "PrinterDriver/printerDriver.pkg" // Handlers & NS runtime. package "NSRuntime/Einstein NS Runtime.pkg" // NewtTest 1.1i diff --git a/Drivers/PrinterDriver/EinsteinDriver.cp b/Drivers/PrinterDriver/EinsteinDriver.cp new file mode 100644 index 00000000..ac8bb71b --- /dev/null +++ b/Drivers/PrinterDriver/EinsteinDriver.cp @@ -0,0 +1 @@ +/* File: EinsteinDriver.cp Contains: Newton printer driver for the Einstein emulator. This is an implementation of the TDotPrinterDriver protocol. Copyright: (c)2022, Matthias Melcher, based on the Kodak sample printer driver included in the DDK © 1992-1994 by Apple Computer, Inc., all rights reserved. */ #ifndef __EINSTEINDRIVER_H #include "EinsteinDriver.impl.h" // **Master File Name** (.impl.h) #endif #ifndef __string_h #include "string.h" #endif #ifndef __stdio_h #include "stdio.h" #endif #ifndef __COMMMANAGERINTERFACE_H #include "CommManagerInterface.h" #endif #ifndef __COMMSERVICES_H #include "CommServices.h" #endif #ifndef __ENDPOINT_H #include "Endpoint.h" #endif #ifndef __SERIALOPTIONS_H #include "SerialOptions.h" #endif /* NATIVE_PRIM 0x0C01, PDNew NATIVE_PRIM 0x0C02, PDDelete NATIVE_PRIM 0x0C03, PDOpen NATIVE_PRIM 0x0C04, PDClose NATIVE_PRIM 0x0C05, PDOpenPage NATIVE_PRIM 0x0C06, PDClosePage NATIVE_PRIM 0x0C07, PDImageBand NATIVE_PRIM 0x0C08, PDCancelJob NATIVE_PRIM 0x0C09, PDIsProblemResolved NATIVE_PRIM 0x0C0A, PDGetPageInfo NATIVE_PRIM 0x0C0B, PDGetBandPrefs NATIVE_PRIM 0x0C0C, PDFaxEndPage */ extern "C" { void PDNew(DRIVERCLASSNAME *self); void PDDelete(DRIVERCLASSNAME *self); NewtonErr PDOpen(DRIVERCLASSNAME *self); NewtonErr PDClose(DRIVERCLASSNAME *self); NewtonErr PDOpenPage(DRIVERCLASSNAME *self); NewtonErr PDClosePage(DRIVERCLASSNAME *self); NewtonErr PDImageBand(DRIVERCLASSNAME *self, PixelMap* theBand, const Rect* minRect); void PDCancelJob(DRIVERCLASSNAME *self, Boolean asyncCancel); PrProblemResolution PDIsProblemResolved(DRIVERCLASSNAME *self); void PDGetPageInfo(DRIVERCLASSNAME *self, PrPageInfo* info); void PDGetBandPrefs(DRIVERCLASSNAME *self, DotPrinterPrefs* prefs); NewtonErr PDFaxEndPage(DRIVERCLASSNAME *self, long pageCount); } PROTOCOL_IMPL_SOURCE_MACRO(DRIVERCLASSNAME) /*----- Globals -----*/ // IMPORTANT: LOADED PROTOCOLS MAY NOT HAVE GLOBALS // If you have driver-global data, it belongs in your object. /*----- Driver Functions -----*/ /*----------------------------------------------------------------------------- NewtonErr Open(void) Initialize and Open the driver. Remember, if this call fails, no other calls will follow. So you must clean up anything you do here (especially allocations). -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::Open(void) { fAsyncIntf = nil; fCurrentError = noErr; // PRINT(("DRIVERCLASSNAME::Open")); { // check user-specified psuedo-driver RefVar routingSlip = fConnect->fConnectInfo; RefVar prRef = GetFrameSlot(routingSlip, SYM(printer)); RefVar modelRef = GetFrameSlot(prRef, SYM(prmodel)); fHWType = (EinsteinVersion) RINT(modelRef); } return PDOpen(this); } /*----------------------------------------------------------------------------- void Delete(void) Historical entry point. Probably shouldn't be used. -----------------------------------------------------------------------------*/ void DRIVERCLASSNAME::Delete(void) { PDDelete(this); } /*----------------------------------------------------------------------------- NewtonErr Close(void) Close the driver. This call should follow this format: send final commands close connection cleanup allocations -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::Close() { return PDClose(this); } /*----------------------------------------------------------------------------- NewtonErr OpenPage(void) Send any commands required to begin a new page. -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::OpenPage() { return PDOpenPage(this); } /*----------------------------------------------------------------------------- NewtonErr ClosePage(void) Send any commands required to finish a page. -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::ClosePage() { return PDClosePage(this); } /*----------------------------------------------------------------------------- NewtonErr ImageBand(PixelMap* theBand, const Rect* minBounds) -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::ImageBand(PixelMap* theBand, const Rect* minBounds) { return PDImageBand(this, theBand, minBounds); } /*----------------------------------------------------------------------------- void CancelJob(Boolean asyncCancel) Called by the print loop if we are going to early-abort a print job. The print loop will still call the appropriate close() calls. This just warns the driver that something fishy is going on. -----------------------------------------------------------------------------*/ void DRIVERCLASSNAME::CancelJob(Boolean asyncCancel) { PDCancelJob(this, asyncCancel); return; } /*----------------------------------------------------------------------------- PrProblemResolution IsProblemResolved(void); Report on the possible resolution of the current problem or error. -----------------------------------------------------------------------------*/ PrProblemResolution DRIVERCLASSNAME::IsProblemResolved(void) { return PDIsProblemResolved(this); } /*----------------------------------------------------------------------------- void GetPageInfo(PrPageInfo* result) -----------------------------------------------------------------------------*/ void DRIVERCLASSNAME::GetPageInfo(PrPageInfo* result) { PrPageInfo dummy; dummy.printerDPI.x = Long2Fixed(300); dummy.printerDPI.y = Long2Fixed(300); dummy.printerPageSize.v = (Short) 10.375*300; dummy.printerPageSize.h = (Short) (2400); *result = dummy; PDGetPageInfo(this, result); return; } /*----------------------------------------------------------------------------- void GetBandPrefs(DotPrinterPrefs* result) -----------------------------------------------------------------------------*/ void DRIVERCLASSNAME::GetBandPrefs(DotPrinterPrefs* result) { DotPrinterPrefs dummy; dummy.minBand = 50; // 50 because of 50 pin head dummy.optimumBand = 50; dummy.asyncBanding = false; dummy.wantMinBounds = true; *result = dummy; PDGetBandPrefs(this, result); return; } /*----------------------------------------------------------------------------- NewtonErr FaxEndPage(long pageCount) This method is used only by the fax driver. For all others, leave empty. -----------------------------------------------------------------------------*/ NewtonErr DRIVERCLASSNAME::FaxEndPage(long pageCount) { return PDFaxEndPage(this, pageCount); } \ No newline at end of file diff --git a/Drivers/PrinterDriver/EinsteinDriver.impl.h b/Drivers/PrinterDriver/EinsteinDriver.impl.h new file mode 100644 index 00000000..77bf5cef --- /dev/null +++ b/Drivers/PrinterDriver/EinsteinDriver.impl.h @@ -0,0 +1 @@ +/* File: EinsteinDriver.impl.h Contains: Protocol Implementation header for sample driver Copyright: © 1992-1994 by Apple Computer, Inc., all rights reserved. */ #ifndef __EINSTEINDRIVER_H #define __EINSTEINDRIVER_H #ifndef __DOTDRIVERS_H #include "DotDrivers.h" #endif #define DRIVERCLASSNAME TEinsteinDriver // **Driver Protocol Name** class TEndpoint; typedef enum { k180si = 0, k701 } EinsteinVersion; PROTOCOL DRIVERCLASSNAME : public TDotPrinterDriver PROTOCOLVERSION(1.0) { // Everything in the "public" section is specified by the // protocol definition in "DotDrivers.h". Don't change it. public: PROTOCOL_IMPL_HEADER_MACRO(DRIVERCLASSNAME); void Delete(void); NewtonErr Open(void); NewtonErr Close(void); NewtonErr OpenPage(void); NewtonErr ClosePage(void); NewtonErr ImageBand(PixelMap* theBand, const Rect* minRect); void CancelJob(Boolean asyncCancel); PrProblemResolution IsProblemResolved(void); void GetPageInfo(PrPageInfo* info); void GetBandPrefs(DotPrinterPrefs* prefs); NewtonErr FaxEndPage(long pageCount); // New method for 2.0 // These two fields are automatically created by the // protocol interface (see DotDrivers.h). You will be // able to access them from your code. // PrintConnect* fConnect; // TPrinter* fPrinter; private: // Driver-specific items go here, as private items. void Cleanup(); Boolean InitConnection(); void SendData(Ptr data, long length); void SendString(char* str); void ReleaseConnection(); TEndpoint* fAsyncIntf; EinsteinVersion fHWType; NewtonErr fCurrentError; }; #endif \ No newline at end of file diff --git a/Drivers/PrinterDriver/EinsteinDriver.pf b/Drivers/PrinterDriver/EinsteinDriver.pf new file mode 100644 index 00000000..123b6099 --- /dev/null +++ b/Drivers/PrinterDriver/EinsteinDriver.pf @@ -0,0 +1 @@ +# # File: EinsteinDriver.pf # # Contains: Pram source to build sample print driver # # Copyright: © 1992-1994 by Apple Computer, Inc., all rights reserved. # # # one entry each for the driver(s) we are building # each entry must contain name, driverName, imagingName, and type. # only multiplexed drivers will use the last field; # set it to zero otherwise. # Name driverName imagingName type prModel "EinsteinPrtr 72dpi" TEinsteinDriver TDotPrinter serialSym 0 "EinsteinPrtr 150dpi" TEinsteinDriver TDotPrinter serialSym 1 "EinsteinPrtr 300dpi" TEinsteinDriver TDotPrinter serialSym 2 \ No newline at end of file diff --git a/Drivers/PrinterDriver/EinsteinDriverPrims.a b/Drivers/PrinterDriver/EinsteinDriverPrims.a new file mode 100644 index 00000000..7af7aaae --- /dev/null +++ b/Drivers/PrinterDriver/EinsteinDriverPrims.a @@ -0,0 +1 @@ +; ============================== ; File: EinsteinDriverPrims.s ; Project: Einstein ; ; Copyright 2022 by Matthias Melcher (einstein@messagepad.org) ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License along ; with this program; if not, write to the Free Software Foundation, Inc., ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ; ============================== MACRO NATIVE_PRIM $id, $symbol AREA $symbol, CODE, READONLY EXPORT $symbol stmdb sp!, {lr} ldr lr, id_for_$symbol mcr p10, 0, lr, c0, c0 ldmia sp!, {pc} id_for_$symbol DCD $id MEND NATIVE_PRIM 0x0C01, PDNew NATIVE_PRIM 0x0C02, PDDelete NATIVE_PRIM 0x0C03, PDOpen NATIVE_PRIM 0x0C04, PDClose NATIVE_PRIM 0x0C05, PDOpenPage NATIVE_PRIM 0x0C06, PDClosePage NATIVE_PRIM 0x0C07, PDImageBand NATIVE_PRIM 0x0C08, PDCancelJob NATIVE_PRIM 0x0C09, PDIsProblemResolved NATIVE_PRIM 0x0C0A, PDGetPageInfo NATIVE_PRIM 0x0C0B, PDGetBandPrefs NATIVE_PRIM 0x0C0C, PDFaxEndPage END ; =========================================================================== ; ; THEGODDESSOFTHENETHASTWISTINGFINGERSANDHERVOICEISLIKEAJAVELININTHENIGHTDUDE ; ; =========================================================================== ; \ No newline at end of file diff --git a/Drivers/PrinterDriver/FilesInBuild b/Drivers/PrinterDriver/FilesInBuild new file mode 100644 index 00000000..1dd28efa --- /dev/null +++ b/Drivers/PrinterDriver/FilesInBuild @@ -0,0 +1 @@ +# DDK project created on Tuesday, August 20, 1996 4:38:22 PM # by Newton C++ Tools #PackageofParts LocalLinkOptions="-dupok " LocalARMCppOptions="-cfront -W " LocalCfronttOptions="" LocalCfrontCOptions="-W " LocalCOptions="-d forARM " LocalPackerOptions=" -packageid 'xxxx' -copyright 'Copyright (c) 1997 Apple Computer, Inc.'" # add/change/delete lines like those below for other include files needed by your source files. -i "{DDK_Includes-dir}" -ic "{DDK_Includes-dir}Bootstrap" -ic "{DDK_Includes-dir}CLibrary" -ic "{DDK_Includes-dir}CommAPI" -ic "{DDK_Includes-dir}Communications" -ic "{DDK_Includes-dir}Frames" -ic "{DDK_Includes-dir}HAL" -ic "{DDK_Includes-dir}OS600" -ic "{DDK_Includes-dir}Packages" -ic "{DDK_Includes-dir}Power" -ic "{DDK_Includes-dir}PSS" -ic "{DDK_Includes-dir}QD" -ic "{DDK_Includes-dir}Toolbox" -ic "{DDK_Includes-dir}UtilityClasses" -ic "{DDK_Includes-dir}Printing" -srcdirs ':' -tpart -protocol -aif "{Objects-dir}printerDriver.bin" -autoload -autoRemove # add lines here with the names of your protocol source files EinsteinDriverPrims.s EinsteinDriver.cp -clike EinsteinDriver.impl.h # ARMCpp will compile files named with the suffix .cp # ARMCfront will compile files named with the suffix .cf # ARMCpp -ansic will compile files named with the suffix .c # ARMAsm will compile files named with the suffix .a "{DDK_Libraries-dir}CardGlue.a.o" # Repeat the -tpart line above for other -protocol parts or -frame parts, etc # and follow it with source/library file lines to build it # use a line like this Ô-clike ExampleTool.impl.hÕ for the .impl.h files of a protocol -tpart -frames "{Objects-dir}EinsteinDriver.pf.part" -notify 'prnt' ¶"¶" EinsteinDriver.pf # following line defines the final build target name followed by the Òpackage nameÓ # and any other Packer options you didn't define above in the LocalPackerOptions= definition. -tpackage "{Objects-dir}printerDriver.pkg" "printerDriver" -version 01 \ No newline at end of file diff --git a/Drivers/PrinterDriver/Makefile b/Drivers/PrinterDriver/Makefile new file mode 100644 index 00000000..bda460f2 --- /dev/null +++ b/Drivers/PrinterDriver/Makefile @@ -0,0 +1 @@ +# This makefile was produced at 2:07:23 PM on Tue, Jan 14, 1997 # by MakeMake 2.0d45 (3/16/1994) by Rick Holzgrafe, scott douglass, Jeff Holcomb. MAKEFILE = Makefile Objects-dir = :{NCT-ObjectOut}: LIB = "{NCT-lib}" {NCT-lib-options} {LocalLibOptions} LINK = "{NCT-link}" LINKOPTS = {NCT-link-options} {LocalLinkOptions} Asm = "{NCT-asm}" {NCT-asm-options} {LocalAsmOptions} CFront = "{NCT-cfront}" {NCT-cfront-options} {LocalCFrontOptions} CFrontC = "{NCT-cfront-c}" {NCT-cfront-c-options} {LocalCfrontCOptions} C = "{NCT-ARM6c}" {NCT-ARM6c-options} ARMCPlus = "{NCT-ARMCpp}" {NCT-ARMCpp-options} {LocalARMCppOptions} ProtocolOptions = -package Pram = "{NCT-pram}" {NCT-pram-options} {LocalPRAMOptions} SETFILE = {NCT-setfile-cmd} LocalLinkOptions = -dupok LocalARMCppOptions = -cfront -W LocalCfronttOptions = LocalCfrontCOptions = -W LocalCOptions = -d forARM LocalPackerOptions = -packageid 'xxxx' -copyright 'Copyright (c) 1997 Apple Computer, Inc.' COUNT = Count COUNTOPTS = CTAGS = CTags CTAGSOPTS = -local -update DELETE = Delete DELETEOPTS = -i FILES = Files FILESOPTS = -l LIBOPTS = PRINT = Print PRINTOPTS = REZ = Rez SETFILEOPTS = -t 'MPST' -c 'MPS ' "{Objects-dir}" Ä : TARGETS = "{Objects-dir}printerDriver.bin" ¶ "{Objects-dir}EinsteinDriver.pf.part" "{Objects-dir}printerDriver.pkg" # For "{Objects-dir}printerDriver.bin" OBJS_00 = "{Objects-dir}EinsteinDriver.cp.o" ¶ "{Objects-dir}EinsteinDriver.impl.h.o" ¶ "{Objects-dir}EinsteinDriverPrims.a.o" ¶ # For "{Objects-dir}printerDriver.bin" LIBS_00 = "{DDK_Libraries-dir}CardGlue.a.o" # For "{Objects-dir}EinsteinDriver.pf.part" EXDEPS_01 = EinsteinDriver.pf # For "{Objects-dir}printerDriver.pkg" EXDEPS_02 = "{Objects-dir}printerDriver.bin" ¶ "{Objects-dir}EinsteinDriver.pf.part" AOptions = -i "{DDK_Includes-dir}" COptions = -i "{DDK_Includes-dir}" -i "{DDK_Includes-dir}Bootstrap" ¶ -i "{DDK_Includes-dir}CLibrary" -i "{DDK_Includes-dir}CommAPI" ¶ -i "{DDK_Includes-dir}Communications" -i "{DDK_Includes-dir}Frames" ¶ -i "{DDK_Includes-dir}HAL" -i "{DDK_Includes-dir}OS600" ¶ -i "{DDK_Includes-dir}Packages" -i "{DDK_Includes-dir}Power" ¶ -i "{DDK_Includes-dir}PSS" -i "{DDK_Includes-dir}QD" ¶ -i "{DDK_Includes-dir}Toolbox" -i "{DDK_Includes-dir}UtilityClasses" ¶ -i "{DDK_Includes-dir}Printing" {NCT_DebugSwitch} {LocalCOptions} POptions = -i "{DDK_Includes-dir}" ROptions = -i "{DDK_Includes-dir}" -a all Ä {TARGETS} "{Objects-dir}printerDriver.bin" ÄÄ {OBJS_00} {LIBS_00} {LINK} {LINKOPTS} -o {Targ} {OBJS_00} {LIBS_00} "{Objects-dir}printerDriver.bin" ÄÄ {OBJS_00} {LIBS_00} {SETFILE} {SETFILEOPTS} {Targ} "{Objects-dir}printerDriver.pkg" ÄÄ {EXDEPS_02} "{NCT-packer}" -o {Targ} "printerDriver" {NCT-packer-options} {LocalPackerOptions} -version 01 ¶ -protocol -aif "{Objects-dir}printerDriver.bin" -autoload -autoRemove ¶ -frames "{Objects-dir}EinsteinDriver.pf.part" -notify 'prnt' "" "{Objects-dir}printerDriver.pkg" ÄÄ {EXDEPS_02} {SETFILE} -t "pkg " -c {NCT-package-creator} {Targ} clean Ä {DELETE} {DELETEOPTS} {OBJS_00} clobber Ä clean {DELETE} {DELETEOPTS} {TARGETS} files Ä {FILES} {FILESOPTS} {TARGETS} {MAKEFILE} "{NCTTools}DDKBuildMakefile.Post" ¶ {OBJS_00} print Ä {PRINT} {PRINTOPTS} {MAKEFILE} "{NCTTools}DDKBuildMakefile.Post" tags Ä {CTAGS} {CTAGSOPTS} {NewerDeps} -i "{DDK_Includes-dir}" ¶ -i "{DDK_Includes-dir}Bootstrap" -i "{DDK_Includes-dir}CLibrary" ¶ -i "{DDK_Includes-dir}CommAPI" -i "{DDK_Includes-dir}Communications" ¶ -i "{DDK_Includes-dir}Frames" -i "{DDK_Includes-dir}HAL" ¶ -i "{DDK_Includes-dir}OS600" -i "{DDK_Includes-dir}Packages" ¶ -i "{DDK_Includes-dir}Power" -i "{DDK_Includes-dir}PSS" ¶ -i "{DDK_Includes-dir}QD" -i "{DDK_Includes-dir}Toolbox" ¶ -i "{DDK_Includes-dir}UtilityClasses" -i "{DDK_Includes-dir}Printing" "{Objects-dir}EinsteinDriverPrims.a.o" Ä ¶ EinsteinDriverPrims.a "{Objects-dir}EinsteinDriver.cp.o" Ä ¶ EinsteinDriver.cp EinsteinDriver.impl.h ¶ "{DDK_Includes-dir}Printing:DotDrivers.h" ¶ "{DDK_Includes-dir}Printing:ConfigPrinting.h" ¶ "{DDK_Includes-dir}ConfigGlobal.h" "{DDK_Includes-dir}Newton.h" ¶ "{DDK_Includes-dir}CLibrary:stdlib.h" ¶ "{DDK_Includes-dir}CLibrary:string.h" ¶ "{DDK_Includes-dir}CLibrary:stddef.h" "{DDK_Includes-dir}NewtonTypes.h" ¶ "{DDK_Includes-dir}NewtonWidgets.h" "{DDK_Includes-dir}NewtonTime.h" ¶ "{DDK_Includes-dir}Toolbox:CompMath.h" ¶ "{DDK_Includes-dir}Toolbox:ConfigToolbox.h" ¶ "{DDK_Includes-dir}NewtonMemory.h" ¶ "{DDK_Includes-dir}NewtonExceptions.h" ¶ "{DDK_Includes-dir}CLibrary:setjmp.h" "{DDK_Includes-dir}NewtonDebug.h" ¶ "{DDK_Includes-dir}CLibrary:stdio.h" ¶ "{DDK_Includes-dir}Printing:PrintTypes.h" ¶ "{DDK_Includes-dir}QD:NewtQD.h" "{DDK_Includes-dir}QD:ConfigQD.h" ¶ "{DDK_Includes-dir}Frames:Objects.h" ¶ "{DDK_Includes-dir}Frames:ConfigFrames.h" ¶ "{DDK_Includes-dir}OS600:OSErrors.h" "{DDK_Includes-dir}NewtErrors.h" ¶ "{DDK_Includes-dir}Packages:PartHandler.h" ¶ "{DDK_Includes-dir}Packages:PackageTypes.h" ¶ "{DDK_Includes-dir}OS600:KernelTypes.h" ¶ "{DDK_Includes-dir}OS600:ConfigOS600.h" ¶ "{DDK_Includes-dir}Toolbox:FixedMath.h" ¶ "{DDK_Includes-dir}CommAPI:UserAbort.h" ¶ "{DDK_Includes-dir}UtilityClasses:AEventHandler.h" ¶ "{DDK_Includes-dir}UtilityClasses:ItemComparer.h" ¶ "{DDK_Includes-dir}UtilityClasses:ItemTester.h" ¶ "{DDK_Includes-dir}UtilityClasses:AEvents.h" ¶ "{DDK_Includes-dir}UtilityClasses:TimerQueue.h" ¶ "{DDK_Includes-dir}OS600:LongTime.h" ¶ "{DDK_Includes-dir}OS600:UserPorts.h" ¶ "{DDK_Includes-dir}OS600:UserObjects.h" ¶ "{DDK_Includes-dir}OS600:SharedTypes.h" ¶ "{DDK_Includes-dir}OS600:UserSharedMem.h" ¶ "{DDK_Includes-dir}OS600:UserGlobals.h" "{DDK_Includes-dir}NewtConfig.h" ¶ "{DDK_Includes-dir}HammerConfigBits.h" ¶ "{DDK_Includes-dir}Printing:PrintErrors.h" ¶ "{DDK_Includes-dir}Printing:DriverCallbacks.h" ¶ "{DDK_Includes-dir}OS600:Protocols.h" ¶ "{DDK_Includes-dir}CommAPI:CommManagerInterface.h" ¶ "{DDK_Includes-dir}OS600:SystemEvents.h" ¶ "{DDK_Includes-dir}OS600:NameServer.h" ¶ "{DDK_Includes-dir}CommAPI:OptionArray.h" ¶ "{DDK_Includes-dir}Toolbox:NewtMemory.h" ¶ "{DDK_Includes-dir}CommAPI:CommOptions.h" ¶ "{DDK_Includes-dir}CommAPI:CommServices.h" ¶ "{DDK_Includes-dir}CommAPI:Endpoint.h" ¶ "{DDK_Includes-dir}CommAPI:Transport.h" ¶ "{DDK_Includes-dir}Communications:SerialOptions.h" "{Objects-dir}EinsteinDriver.impl.h.o" Ä ¶ EinsteinDriver.impl.h "{DDK_Includes-dir}Printing:DotDrivers.h" ¶ "{DDK_Includes-dir}Printing:ConfigPrinting.h" ¶ "{DDK_Includes-dir}ConfigGlobal.h" "{DDK_Includes-dir}Newton.h" ¶ "{DDK_Includes-dir}CLibrary:stdlib.h" ¶ "{DDK_Includes-dir}CLibrary:string.h" ¶ "{DDK_Includes-dir}CLibrary:stddef.h" "{DDK_Includes-dir}NewtonTypes.h" ¶ "{DDK_Includes-dir}NewtonWidgets.h" "{DDK_Includes-dir}NewtonTime.h" ¶ "{DDK_Includes-dir}Toolbox:CompMath.h" ¶ "{DDK_Includes-dir}Toolbox:ConfigToolbox.h" ¶ "{DDK_Includes-dir}NewtonMemory.h" ¶ "{DDK_Includes-dir}NewtonExceptions.h" ¶ "{DDK_Includes-dir}CLibrary:setjmp.h" "{DDK_Includes-dir}NewtonDebug.h" ¶ "{DDK_Includes-dir}CLibrary:stdio.h" ¶ "{DDK_Includes-dir}Printing:PrintTypes.h" ¶ "{DDK_Includes-dir}QD:NewtQD.h" "{DDK_Includes-dir}QD:ConfigQD.h" ¶ "{DDK_Includes-dir}Frames:Objects.h" ¶ "{DDK_Includes-dir}Frames:ConfigFrames.h" ¶ "{DDK_Includes-dir}OS600:OSErrors.h" "{DDK_Includes-dir}NewtErrors.h" ¶ "{DDK_Includes-dir}Packages:PartHandler.h" ¶ "{DDK_Includes-dir}Packages:PackageTypes.h" ¶ "{DDK_Includes-dir}OS600:KernelTypes.h" ¶ "{DDK_Includes-dir}OS600:ConfigOS600.h" ¶ "{DDK_Includes-dir}Toolbox:FixedMath.h" ¶ "{DDK_Includes-dir}CommAPI:UserAbort.h" ¶ "{DDK_Includes-dir}UtilityClasses:AEventHandler.h" ¶ "{DDK_Includes-dir}UtilityClasses:ItemComparer.h" ¶ "{DDK_Includes-dir}UtilityClasses:ItemTester.h" ¶ "{DDK_Includes-dir}UtilityClasses:AEvents.h" ¶ "{DDK_Includes-dir}UtilityClasses:TimerQueue.h" ¶ "{DDK_Includes-dir}OS600:LongTime.h" ¶ "{DDK_Includes-dir}OS600:UserPorts.h" ¶ "{DDK_Includes-dir}OS600:UserObjects.h" ¶ "{DDK_Includes-dir}OS600:SharedTypes.h" ¶ "{DDK_Includes-dir}OS600:UserSharedMem.h" ¶ "{DDK_Includes-dir}OS600:UserGlobals.h" "{DDK_Includes-dir}NewtConfig.h" ¶ "{DDK_Includes-dir}HammerConfigBits.h" ¶ "{DDK_Includes-dir}Printing:PrintErrors.h" ¶ "{DDK_Includes-dir}Printing:DriverCallbacks.h" ¶ "{DDK_Includes-dir}OS600:Protocols.h" .cp.o Ä .cp {ARMCPlus} {depDir}{Default}.cp {COptions} -o {targDir}{Default}.cp.o .cf.o Ä .cf {CFront} {depDir}{Default}.cf {COptions} {NCT-cfront-redirection} "{{CPlusScratch}}"X{Default}.cf -o {targDir}{Default}.cf.o {CFrontC} "{{CPlusScratch}}"X{Default}.cf -o {targDir}{Default}.cf.o ; Delete -i "{{CPlusScratch}}"X{Default}.cf .c.o Ä .c {C} {depDir}{Default}.c -o {targDir}{Default}.c.o {COptions} .exp.o Ä .exp "{NCTTools}"NCTBuildMain {depDir}{Default}.exp "{{CPlusScratch}}" {Asm} "{{CplusScratch}}"{Default}.exp.main.a -o {targDir}{Default}.exp.o ; Delete -i "{{CPlusScratch}}"{Default}.exp.main.a .a.o Ä .a {Asm} {depDir}{Default}.a -o {targDir}{Default}.a.o {AOptions} # defualt rule for Pram tool build of Printer DDK form part containing UI strings for System printer selection dialogs .pf.part Ä .pf {Pram} {depDir}{Default}.pf -o {targDir}{Default}.pf.part # # Rules for building protocol glue # # .h.o caller glue (what callers link against) # .impl.h.o implementation glue (linked into provider) # .h.o Ä .h ProtocolGen -InterfaceGlue {depDir}{Default}.h {COptions} -stdout > "{{CPlusScratch}}"{Default}.glue.a {Asm} "{{CPlusScratch}}"{Default}.glue.a -o {targDir}{Default}.h.o ; Delete -i "{{CPlusScratch}}"{Default}.glue.a .impl.h.o Ä .impl.h ProtocolGen -ImplementationGlue {depDir}{Default}.impl.h {ProtocolOptions} {COptions} -stdout >"{{CPlusScratch}}"{Default}.impl.a {Asm} "{{CPlusScratch}}"{Default}.impl.a -o {targDir}{Default}.impl.h.o ; Delete -i "{{CPlusScratch}}"{Default}.impl.a # backward compatability rule for old apple DDK's .j.c.o Ä .j.c {C} {depDir}{Default}.j.c -o {targDir}{Default}.j.c.o {COptions} \ No newline at end of file diff --git a/Drivers/PrinterDriver/Makeout b/Drivers/PrinterDriver/Makeout new file mode 100644 index 00000000..e69de29b diff --git a/Drivers/PrinterDriver/printerDriver.pkg b/Drivers/PrinterDriver/printerDriver.pkg new file mode 100644 index 00000000..cfbab7fa Binary files /dev/null and b/Drivers/PrinterDriver/printerDriver.pkg differ diff --git a/Emulator/CMakeLists.txt b/Emulator/CMakeLists.txt index cbf8f62e..50895497 100644 --- a/Emulator/CMakeLists.txt +++ b/Emulator/CMakeLists.txt @@ -10,6 +10,7 @@ include ( Emulator/NativeCalls/CMakeLists.txt ) include ( Emulator/Network/CMakeLists.txt ) include ( Emulator/PCMCIA/CMakeLists.txt ) include ( Emulator/Platform/CMakeLists.txt ) +include ( Emulator/Printer/CMakeLists.txt ) include ( Emulator/ROM/CMakeLists.txt ) include ( Emulator/Screen/CMakeLists.txt ) include ( Emulator/Serial/CMakeLists.txt ) diff --git a/Emulator/Printer/CMakeLists.txt b/Emulator/Printer/CMakeLists.txt new file mode 100644 index 00000000..42110747 --- /dev/null +++ b/Emulator/Printer/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Add source files required to build Einstein. +# + +list ( APPEND cmake_sources + Emulator/Printer/CMakeLists.txt +) + +list ( APPEND common_sources + Emulator/Printer/TPrinterManager.cpp + Emulator/Printer/TPrinterManager.h +) + +list ( APPEND app_sources + Emulator/Printer/TFLPrinterManager.cpp + Emulator/Printer/TFLPrinterManager.h +) diff --git a/Emulator/Printer/TFLPrinterManager.cpp b/Emulator/Printer/TFLPrinterManager.cpp new file mode 100644 index 00000000..8d02c205 --- /dev/null +++ b/Emulator/Printer/TFLPrinterManager.cpp @@ -0,0 +1,432 @@ +// ============================== +// File: TFLPrinterManager.h +// Project: Einstein +// +// Copyright 2022 by Matthias Melcher (einstein@messagepad.org). +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// ============================== +// $Id$ +// ============================== + +#include "TFLPrinterManager.h" + +#include "Emulator/TMemory.h" + +#include +#include +#include + +#include + +#if TARGET_OS_WIN32 +#include +#include +#else +#include +#include +#endif + +// Einstein. + +// -------------------------------------------------------------------------- // +// Constantes +// -------------------------------------------------------------------------- // + +// -------------------------------------------------------------------------- // +// * TFLPrinterManager(TLog*) +// -------------------------------------------------------------------------- // +TFLPrinterManager::TFLPrinterManager(TLog* inLog /* = nil */) : + TPrinterManager(inLog) +{ + (void) mLog; +} + +/** + Delete the printer manager and the printer driver if allocated. + + Safely finsh the printing process and delete the FLTK driver + from the main thread. + */ +TFLPrinterManager::~TFLPrinterManager() +{ + // Tell the main thread to delete the printer driver at the next occasion. + if (mPrinter) + { + // Is the page still open? + if (mState == State::PageOpen) + ClosePage(mDrvr); + + // Is the printer still active? + if (mState == State::Open) + Close(mDrvr); + + // Is the FLTK printer driver allocated? + Fl::awake( + [](void* inPrinter) { delete (Fl_Printer*) inPrinter; }, + mPrinter); + mPrinter = nullptr; + mState = State::Uninitialized; + } +} + +/** + Close any active printer connection. + + Safely finsh the printing process and prepare for another print run. + */ +void +TFLPrinterManager::Delete(KUInt32 inDrvr) +{ + // KPrintf("Delete\n"); + if (mPrinter) + { + // Is the page still open? + if (mState == State::PageOpen) + ClosePage(inDrvr); + + // Is the printer still active? + if (mState == State::Open) + Close(inDrvr); + } +} + +/** + Allocate the FLTK printer driver if needed and open the host printer dialog. + + Must be done from the main thread. + */ +KUInt32 +TFLPrinterManager::Open(KUInt32 inDrvr) +{ + // KPrintf("Open\n"); + + KUInt32 ret = 0; + + if (!mPrinter) + { + mDrvr = inDrvr; + Fl::lock(); + mPrinter = new Fl_Printer(); + Fl::unlock(); + mState = State::Allocated; + } + + // Is the page still open? + if (mState == State::PageOpen) + ClosePage(inDrvr); + + if (mState != State::Open) + { + mPromise = new std::promise; + mFuture = mPromise->get_future(); + + Fl::awake( + [](void* userdata) { + TFLPrinterManager* self = (TFLPrinterManager*) userdata; + self->SyncOpen(); + }, + this); + + mFuture.wait(); + ret = mFuture.get(); + if (ret == 1) + { + ret = kPR_ERR_UserCancel; + } else if (ret >= 2) + { + ret = kPR_ERR_PrinterError; + } else + { + ret = 0; + mState = State::Open; + } + + delete mPromise; + } + SetScale(inDrvr); + return ret; +} + +void +TFLPrinterManager::SetScale(KUInt32 inDrvr) +{ + switch (GetSubType(inDrvr)) + { + case kSubtype72dpi: + mPrinter->scale(1.0); // FLTK default is 72dpi + break; + case kSubtype150dpi: + mPrinter->scale(72.0 / 150.0); // FLTK default is 72dpi + break; + case kSubtype300dpi: + mPrinter->scale(72.0 / 300.0); // FLTK default is 72dpi + break; + } +} + +void +TFLPrinterManager::SyncOpen() +{ + int ret = mPrinter->begin_job(); + mPromise->set_value(ret); +} + +KUInt32 +TFLPrinterManager::Close(KUInt32 inDrvr) +{ + // KPrintf("Close\n"); + + KUInt32 ret = 0; + + if (!mPrinter) + return kPR_ERR_NewtonError; + + // Is the page still open? + if (mState == State::PageOpen) + ClosePage(inDrvr); + + if (mState == State::Open) + { + mPromise = new std::promise; + mFuture = mPromise->get_future(); + + Fl::awake( + [](void* userdata) { + TFLPrinterManager* self = (TFLPrinterManager*) userdata; + self->SyncClose(); + }, + this); + + mFuture.wait(); + + mState = State::Allocated; + + delete mPromise; + } + + return ret; +} + +void +TFLPrinterManager::SyncClose() +{ + mPrinter->end_job(); + mPromise->set_value(0); +} + +KUInt32 +TFLPrinterManager::OpenPage(KUInt32 inDrvr) +{ + // KPrintf("OpenPage\n"); + + mPrinter->begin_page(); + mPrinter->push_current(mPrinter); + SetScale(inDrvr); + mPrinter->pop_current(); + return 0; +} + +KUInt32 +TFLPrinterManager::ClosePage(KUInt32 inDrvr) +{ + (void) inDrvr; + // KPrintf("ClosePage\n"); + + mPrinter->end_page(); + return 0; +} + +KUInt32 +TFLPrinterManager::ImageBand(KUInt32 inDrvr, KUInt32 inBand, KUInt32 inRect) +{ + (void) inDrvr; + (void) inBand; + (void) inRect; + // KPrintf("ImageBand\n"); + + // TODO: we currently only support 1 bit bitmaps + // TODO: we should give an error message for unsupported bitmap formats + // #define kPixMapStorage 0xC0000000 // to mask off the appropriate bits + // #define kPixMapHandle 0x00000000 // baseAddr is a handle + // #define kPixMapPtr 0x40000000 // baseAddr is a pointer + // #define kPixMapOffset 0x80000000 // baseAddr is an offset from the PixelMap + // #define kPixMapLittleEndian 0x20000000 // pixMap is little endian + // #define kPixMapAllocated 0x10000000 // pixMap "owns" the bits memory + // #ifdef QD_Gray + // #define kPixMapGrayTable 0x08000000 // grayTable field exists + // #define kPixMapNoPad 0x04000000 // direct pixel format, no pad byte + // #define kPixMapByComponent 0x02000000 // direct pixel format, stored by component + // #define kPixMapAntiAlias 0x01000000 // antialiasing ink text + // #endif + // #define kPixMapVersionMask 0x0000F000 // version of this struct + // #define kPixMapDeviceType 0x00000F00 // bits 8..11 are device type code + // #define kPixMapDevScreen 0x00000000 // screen or offscreen bitmap + // #define kPixMapDevDotPrint 0x00000100 // dot matrix printer + // #define kPixMapDevPSPrint 0x00000200 // postscript printer + // #define kPixMapDepth 0x000000FF // bits 0..7 are chunky pixel depth + struct PixelMap { + KUInt32 baseAddr; + KUInt16 rowBytes, pad; // 300, pads to long + KUInt16 top, left, bottom, right; + KUInt32 pixMapFlags; // 0x40000101, ptr, dot printer, 1 bit + // Point deviceRes; // resolution of input device (0 indicates kDefaultDPI + // UChar* grayTable; // gray tone table + } band; + + mMemory->FastReadBuffer(inBand, sizeof(band), (KUInt8*) &band); + band.baseAddr = htonl(band.baseAddr); + band.rowBytes = htons(band.rowBytes); + band.top = htons(band.top); + band.left = htons(band.left); + band.bottom = htons(band.bottom); + band.right = htons(band.right); + band.pixMapFlags = htonl(band.pixMapFlags); + + // KPrintf("T:%d, L:%d, B:%d, R:%d\n", band.top, band.left, band.bottom, band.right); + + Fl::lock(); + Fl_Printer::push_current(mPrinter); + SetScale(inDrvr); + mPrinter->origin(0, 0); + + fl_push_no_clip(); + fl_color(FL_BLACK); + + int w = band.right - band.left; + int h = band.bottom - band.top; + int rowWords = (band.rowBytes + 3) / 4; // row bytes must be 32bit aligned + int bytes = rowWords * 4 * h; + KUInt8* bits = (KUInt8*) malloc(bytes); + mMemory->FastReadBuffer(band.baseAddr, bytes, bits); + + int nBlack = 0; + int nWhite = 0; + KUInt8* gray = (KUInt8*) malloc(w * h); + KUInt8* dst = gray; + for (int y = 0; y < h; y++) + { + KUInt8* src = bits + y * rowWords * 4; + KUInt8 b = 0; + for (int x = 0; x < w; x++) + { + if ((x & 7) == 0) + b = *src++; + *dst++ = (b & 128) ? 0 : 255; + if (b & 128) + nBlack++; + else + nWhite++; + b = b << 1; + } + } + if (nBlack) + { + Fl_RGB_Image* img = new Fl_RGB_Image(gray, w, h, 1); + img->draw(band.left, band.top); + delete img; + } + free(bits); + free(gray); + + fl_pop_clip(); + + Fl_Printer::pop_current(); + Fl::unlock(); + + return 0; +} + +void +TFLPrinterManager::CancelJob(KUInt32 inDrvr, KUInt32 inAsyncCancel) +{ + (void) inDrvr; + (void) inAsyncCancel; + // KPrintf("CancelJob\n"); +} + +void +TFLPrinterManager::GetPageInfo(KUInt32 inDrvr, KUInt32 inInfo) +{ + // KPrintf("GetPageInfo\n"); + + struct PrPageInfo { + KUInt32 horizontalDPI; // DPI as a fixed point value + KUInt32 verticalDPI; + KUInt16 width; // page width in pixels + KUInt16 height; + } pageInfo; + mMemory->FastReadBuffer(inInfo, sizeof(pageInfo), (KUInt8*) &pageInfo); + + switch (GetSubType(inDrvr)) + { + case kSubtype72dpi: + pageInfo.horizontalDPI = htonl(72 << 16); + pageInfo.verticalDPI = htonl(72 << 16); + break; + case kSubtype150dpi: + pageInfo.horizontalDPI = htonl(150 << 16); + pageInfo.verticalDPI = htonl(150 << 16); + break; + case kSubtype300dpi: + pageInfo.horizontalDPI = htonl(300 << 16); + pageInfo.verticalDPI = htonl(300 << 16); + break; + } + int wdt = 0, hgt = 0; + mPrinter->printable_rect(&wdt, &hgt); + pageInfo.width = htons(wdt); + pageInfo.height = htons(hgt); + mMemory->FastWriteBuffer(inInfo, sizeof(pageInfo), (KUInt8*) &pageInfo); +} + +void +TFLPrinterManager::GetBandPrefs(KUInt32 inDrvr, KUInt32 inPrefs) +{ + // typedef struct DotPrinterPrefs { + // long minBand; /* smallest useable band */ + // long optimumBand; /* a good size to try to default */ + // Boolean asyncBanding; /* true if band data sent async */ + // Boolean wantMinBounds; /* true if minrect is useful */ + // } DotPrinterPrefs; + (void) inDrvr; + (void) inPrefs; + // KPrintf("GetBandPrefs\n"); +} + +KUInt8 +TFLPrinterManager::GetSubType(KUInt32 inDrvr) +{ + KUInt8 subtype = 255; + mMemory->ReadB(inDrvr + 31, subtype); + return subtype; +} + +// ============================================================================= // +// As in Protestant Europe, by contrast, where sects divided endlessly into // +// smaller competing sects and no church dominated any other, all is different // +// in the fragmented world of IBM. That realm is now a chaos of conflicting // +// norms and standards that not even IBM can hope to control. You can buy a // +// computer that works like an IBM machine but contains nothing made or sold by // +// IBM itself. Renegades from IBM constantly set up rival firms and establish // +// standards of their own. When IBM recently abandoned some of its original // +// standards and decreed new ones, many of its rivals declared a puritan // +// allegiance to IBM's original faith, and denounced the company as a divisive // +// innovator. Still, the IBM world is united by its distrust of icons and // +// imagery. IBM's screens are designed for language, not pictures. Graven // +// images may be tolerated by the luxurious cults, but the true IBM faith relies // +// on the austerity of the word. // +// -- Edward Mendelson, "The New Republic", February 22, 1988 // +// ============================================================================= // diff --git a/Emulator/Printer/TFLPrinterManager.h b/Emulator/Printer/TFLPrinterManager.h new file mode 100644 index 00000000..9b80cddb --- /dev/null +++ b/Emulator/Printer/TFLPrinterManager.h @@ -0,0 +1,133 @@ +// ============================== +// File: TFLPrinterManager.h +// Project: Einstein +// +// Copyright 2022 by Matthias Melcher (einstein@messagepad.org). +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// ============================== +// $Id$ +// ============================== + +#ifndef _TFLPRINTERMANAGER_H +#define _TFLPRINTERMANAGER_H + +#include "Emulator/Printer/TPrinterManager.h" + +#include + +class TLog; +class TMemory; +class Fl_Printer; + +/// +/// Class to handle a single printer. +/// This class is subclassed by host implementations. +/// +class TFLPrinterManager : public TPrinterManager +{ +public: + /// + /// Constructor from a log. + /// + /// \param inLog log interface (can be null) + /// + TFLPrinterManager(TLog* inLog = nil); + + /// + /// Destructor. + /// + ~TFLPrinterManager() override; + + /// + /// Printer is no longer used + /// + void Delete(KUInt32 inDrvr) override; + + /// + /// Open a connection to the host printer + /// + KUInt32 Open(KUInt32 inDrvr) override; + void SyncOpen(); + + /// + /// Close the connection to the printer + /// + KUInt32 Close(KUInt32 inDrvr) override; + void SyncClose(); + + /// + /// Start to print a page + /// + KUInt32 OpenPage(KUInt32 inDrvr) override; + // void SyncOpenPage(); + + /// + /// Finish printing a page + /// + KUInt32 ClosePage(KUInt32 inDrvr) override; + // void SyncClosePage(); + + /// + /// NewtonOS sends a band of pixel data to be printed + /// + KUInt32 ImageBand(KUInt32 inDrvr, KUInt32 inBand, KUInt32 inRect) override; + + /// + /// User or Newton wants to cancel the current print job. + /// + void CancelJob(KUInt32 inDrvr, KUInt32 inAsyncCancel) override; + + /// + /// Fill in the Info structure about our paper size and print resolution + /// + void GetPageInfo(KUInt32 inDrvr, KUInt32 inInfo) override; + + /// + /// Fill in the structure to have bands delivered a certain way + /// + void GetBandPrefs(KUInt32 inDrvr, KUInt32 inPrefs) override; + +protected: + static constexpr KUInt8 kSubtype72dpi = 0; + static constexpr KUInt8 kSubtype150dpi = 1; + static constexpr KUInt8 kSubtype300dpi = 2; + + KUInt8 GetSubType(KUInt32 inDrvr); + + void SetScale(KUInt32 inDrvr); + + enum class State { + Uninitialized, + Allocated, + Open, + PageOpen + }; + State mState = State::Uninitialized; + + Fl_Printer* mPrinter = nullptr; + + KUInt32 mDrvr = 0; + + std::promise* mPromise; + std::future mFuture; +}; + +#endif +// _TFLPRINTERMANAGER_H + +// ========================================= // +// TRANSACTION CANCELLED - FARECARD RETURNED // +// ========================================= // diff --git a/Emulator/Printer/TPrinterManager.cpp b/Emulator/Printer/TPrinterManager.cpp new file mode 100644 index 00000000..8fb9ee81 --- /dev/null +++ b/Emulator/Printer/TPrinterManager.cpp @@ -0,0 +1,150 @@ +// ============================== +// File: TPrinterManager.h +// Project: Einstein +// +// Copyright 2022 by Matthias Melcher (einstein@messagepad.org). +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// ============================== +// $Id$ +// ============================== + +#include "TPrinterManager.h" + +#include + +#ifdef TARGET_OS_WIN32 +#include +#else +#include +#endif + +// Einstein. + +// -------------------------------------------------------------------------- // +// Constantes +// -------------------------------------------------------------------------- // + +// -------------------------------------------------------------------------- // +// * TPrinterManager(TLog*) +// -------------------------------------------------------------------------- // +TPrinterManager::TPrinterManager(TLog* inLog) : + mLog(inLog) +{ + (void) mLog; +} + +// -------------------------------------------------------------------------- // +// * ~TPrinterManager() +// -------------------------------------------------------------------------- // +TPrinterManager::~TPrinterManager() +{ +} + +void +TPrinterManager::Delete(KUInt32 inDrvr) +{ + (void) inDrvr; +} + +KUInt32 +TPrinterManager::Open(KUInt32 inDrvr) +{ + (void) inDrvr; + return 0; +} + +KUInt32 +TPrinterManager::Close(KUInt32 inDrvr) +{ + (void) inDrvr; + return 0; +} + +KUInt32 +TPrinterManager::OpenPage(KUInt32 inDrvr) +{ + (void) inDrvr; + return 0; +} + +KUInt32 +TPrinterManager::ClosePage(KUInt32 inDrvr) +{ + (void) inDrvr; + return 0; +} + +KUInt32 +TPrinterManager::ImageBand(KUInt32 inDrvr, KUInt32 inBand, KUInt32 inRect) +{ + (void) inDrvr; + (void) inBand; + (void) inRect; + return 0; +} + +void +TPrinterManager::CancelJob(KUInt32 inDrvr, KUInt32 inAsyncCancel) +{ + (void) inDrvr; + (void) inAsyncCancel; +} + +KUInt32 +TPrinterManager::IsProblemResolved(KUInt32 inDrvr) +{ + (void) inDrvr; + return 1; +} + +void +TPrinterManager::GetPageInfo(KUInt32 inDrvr, KUInt32 inInfo) +{ + (void) inDrvr; + (void) inInfo; +} + +void +TPrinterManager::GetBandPrefs(KUInt32 inDrvr, KUInt32 inPrefs) +{ + (void) inDrvr; + (void) inPrefs; +} + +KUInt32 +TPrinterManager::FaxEndPage(KUInt32 inDrvr, KUInt32 inPageCount) +{ + (void) inDrvr; + (void) inPageCount; + return 0; +} + +// ============================================================================= // +// As in Protestant Europe, by contrast, where sects divided endlessly into // +// smaller competing sects and no church dominated any other, all is different // +// in the fragmented world of IBM. That realm is now a chaos of conflicting // +// norms and standards that not even IBM can hope to control. You can buy a // +// computer that works like an IBM machine but contains nothing made or sold by // +// IBM itself. Renegades from IBM constantly set up rival firms and establish // +// standards of their own. When IBM recently abandoned some of its original // +// standards and decreed new ones, many of its rivals declared a puritan // +// allegiance to IBM's original faith, and denounced the company as a divisive // +// innovator. Still, the IBM world is united by its distrust of icons and // +// imagery. IBM's screens are designed for language, not pictures. Graven // +// images may be tolerated by the luxurious cults, but the true IBM faith relies // +// on the austerity of the word. // +// -- Edward Mendelson, "The New Republic", February 22, 1988 // +// ============================================================================= // diff --git a/Emulator/Printer/TPrinterManager.h b/Emulator/Printer/TPrinterManager.h new file mode 100644 index 00000000..853d0f6d --- /dev/null +++ b/Emulator/Printer/TPrinterManager.h @@ -0,0 +1,136 @@ +// ============================== +// File: TPrinterManager.h +// Project: Einstein +// +// Copyright 2022 by Matthias Melcher (einstein@messagepad.org). +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// ============================== +// $Id$ +// ============================== + +#ifndef _TPRINTERMANAGER_H +#define _TPRINTERMANAGER_H + +#include + +class TLog; +class TMemory; + +#define ERRBASE_PRINTING (-44000) // Printing errors +#define PR_ERROR_BASE (ERRBASE_PRINTING) +#define kPR_ERR_PrinterError (PR_ERROR_BASE) +#define kPR_ERR_NewtonError (PR_ERROR_BASE - 1) +#define kPR_ERR_NotFound (PR_ERROR_BASE - 2) +#define kPR_ERR_Busy /* out-box should try again! */ (PR_ERROR_BASE - 3) +#define kPR_ERR_UserCancel (PR_ERROR_BASE - 4) +#define kPR_ERR_LostContact (PR_ERROR_BASE - 5) +#define kPR_ERR_TooComplex (PR_ERROR_BASE - 6) + +/// +/// Class to handle a single printer. +/// This class is subclassed by host implementations. +/// +class TPrinterManager +{ +public: + /// + /// Constructor from a log. + /// + /// \param inLog log interface (can be null) + /// + TPrinterManager(TLog* inLog = nil); + + /// + /// Destructor. + /// + virtual ~TPrinterManager(); + + /// + /// Printer is no longer used + /// + virtual void Delete(KUInt32 inDrvr); + + /// + /// Open a connection to the host printer + /// + virtual KUInt32 Open(KUInt32 inDrvr); + + /// + /// Close the connection to the printer + /// + virtual KUInt32 Close(KUInt32 inDrvr); + + /// + /// Start to print a page + /// + virtual KUInt32 OpenPage(KUInt32 inDrvr); + + /// + /// Finish printing a page + /// + virtual KUInt32 ClosePage(KUInt32 inDrvr); + + /// + /// NewtonOS sends a band of pixel data to be printed + /// + virtual KUInt32 ImageBand(KUInt32 inDrvr, KUInt32 inBand, KUInt32 inRect); + + /// + /// User or Newton wants to cancel the current print job. + /// + virtual void CancelJob(KUInt32 inDrvr, KUInt32 inAsyncCancel); + + /// + /// NewtonOS wants to know if the current problem was solved + /// + virtual KUInt32 IsProblemResolved(KUInt32 inDrvr); + + /// + /// Fill in the Info structure about our paper size and print resolution + /// + virtual void GetPageInfo(KUInt32 inDrvr, KUInt32 inInfo); + + /// + /// Fill in the structure to have bands delivered a certain way + /// + virtual void GetBandPrefs(KUInt32 inDrvr, KUInt32 inPrefs); + + /// + /// For Fax connections only + /// + virtual KUInt32 FaxEndPage(KUInt32 inDrvr, KUInt32 inPageCount); + + /// + /// We need to be able to read and write NewtonOS memory. + /// + void + SetMemory(TMemory* inMemory) + { + mMemory = inMemory; + } + +protected: + TMemory* mMemory = nullptr; ///< Reference to emulated memory. + + TLog* mLog = nullptr; ///< Reference to the log. +}; + +#endif +// _TPRINTERMANAGER_H + +// ========================================= // +// TRANSACTION CANCELLED - FARECARD RETURNED // +// ========================================= // diff --git a/Emulator/TEmulator.cpp b/Emulator/TEmulator.cpp index 356b2f51..da6d2e03 100644 --- a/Emulator/TEmulator.cpp +++ b/Emulator/TEmulator.cpp @@ -75,7 +75,8 @@ TEmulator::TEmulator( TSoundManager* inSoundManager, TScreenManager* inScreenManager, TNetworkManager* inNetworkManager, - KUInt32 inRAMSize /* = 4194304 */) : + KUInt32 inRAMSize /* = 4194304 */, + TPrinterManager* inPrinterManager /* = nullptr */) : SerialPorts(this, inLog), mMemory(inLog, inROMImage, inFlashPath, inRAMSize), mProcessor(inLog, &mMemory), @@ -83,6 +84,7 @@ TEmulator::TEmulator( mDMAManager(nil), mPlatformManager(nil), mNetworkManager(inNetworkManager), + mPrinterManager(inPrinterManager), mSoundManager(inSoundManager), mScreenManager(inScreenManager), mFileManager(NULL), @@ -143,6 +145,7 @@ TEmulator::TEmulator( mDMAManager(nil), mPlatformManager(nil), mNetworkManager(nil), + mPrinterManager(nil), mSoundManager(nil), mScreenManager(nil), mLog(inLog), diff --git a/Emulator/TEmulator.h b/Emulator/TEmulator.h index 527ee065..34ad6840 100644 --- a/Emulator/TEmulator.h +++ b/Emulator/TEmulator.h @@ -79,7 +79,8 @@ class TEmulator TSoundManager* inSoundManager, TScreenManager* inScreenManager, TNetworkManager* inNetworkManager, - KUInt32 inRAMSize = 0x00400000); + KUInt32 inRAMSize = 0x00400000, + TPrinterManager* inPrinterManager = nullptr); /// /// Constructor from a rom image buffer. @@ -289,6 +290,17 @@ class TEmulator return mInterruptManager; } + /// + /// Accessor on the printer manager interface. + /// + /// \return a pointer to the printer manager. + /// + TPrinterManager* + GetPrinterManager(void) + { + return mPrinterManager; + } + /// /// Accessor on the sound manager interface. /// @@ -473,6 +485,7 @@ class TEmulator TDMAManager* mDMAManager; ///< DMA manager. TPlatformManager* mPlatformManager; ///< Platform manager. TNetworkManager* mNetworkManager; ///< Network manager. + TPrinterManager* mPrinterManager; ///< Printer manager TSoundManager* mSoundManager; ///< Sound manager. TScreenManager* mScreenManager; ///< Screen manager. TFileManager* mFileManager; diff --git a/Emulator/TNativePrimitives.cpp b/Emulator/TNativePrimitives.cpp index 5918bdf3..fe46ed47 100644 --- a/Emulator/TNativePrimitives.cpp +++ b/Emulator/TNativePrimitives.cpp @@ -42,6 +42,7 @@ #include "Emulator/TMemory.h" #include "Emulator/Log/TLog.h" #include "Emulator/Network/TNetworkManager.h" +#include "Emulator/Printer/TPrinterManager.h" #include "Emulator/Screen/TScreenManager.h" #include "Emulator/Serial/TSerialHostPortDirect.h" #include "Emulator/Sound/TSoundManager.h" @@ -85,6 +86,7 @@ struct NewtonPixmap { #define ENABLE_LOG_HOSTCALL (1 << 0x9) #define ENABLE_LOG_NETWORKMANAGER (1 << 0xa) #define ENABLE_LOG_HOSTIOS_NATIVEIOS (1 << 0xb) +#define ENABLE_LOG_PRINTER (1 << 0xc) #define LOG_PLATFORM (mLog && (mLogMask & ENABLE_LOG_PLATFORM)) #define LOG_SOUND (mLog && (mLogMask & ENABLE_LOG_SOUND)) @@ -97,6 +99,7 @@ struct NewtonPixmap { #define LOG_HOSTCALL (mLog && (mLogMask & ENABLE_LOG_HOSTCALL)) #define LOG_NETWORKMANAGER (mLog && (mLogMask & ENABLE_LOG_NETWORKMANAGER)) #define LOG_HOSTIOS_NATIVEIOS (mLog && (mLogMask & ENABLE_LOG_HOSTIOS_NATIVEIOS)) +#define LOG_PRINTER (mLog && (mLogMask & ENABLE_LOG_PRINTER)) // -------------------------------------------------------------------------- // // Constantes @@ -154,6 +157,7 @@ TNativePrimitives::SetEmulator(TEmulator* inEmulator) if (inEmulator) { mNetworkManager = inEmulator->GetNetworkManager(); + mPrinterManager = inEmulator->GetPrinterManager(); mSoundManager = inEmulator->GetSoundManager(); mScreenManager = inEmulator->GetScreenManager(); mPlatformManager = inEmulator->GetPlatformManager(); @@ -162,6 +166,7 @@ TNativePrimitives::SetEmulator(TEmulator* inEmulator) } else { mNetworkManager = nil; + mPrinterManager = nil; mSoundManager = nil; mScreenManager = nil; mPlatformManager = nil; @@ -244,6 +249,10 @@ TNativePrimitives::ExecuteNative(KUInt32 inInstruction) break; #endif + case 0x00000C: + ExecutePrinterDriverNative(inInstruction); + break; + default: if (mLog) { @@ -3226,6 +3235,159 @@ TNativePrimitives::ExecuteHostiOSNativeiOS(KUInt32 inInstruction) } #endif +#ifdef TARGET_UI_FLTK +#include +// -------------------------------------------------------------------------- // +// * ExecutePrinterDriverNative( KUInt32 ) +// -------------------------------------------------------------------------- // +void +TNativePrimitives::ExecutePrinterDriverNative(KUInt32 inInstruction) +{ + KUInt32 ret = 0; + + switch (inInstruction & 0xFF) + { + case 0x01: // never called: void PDNew(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("void PDNew(DRIVERCLASSNAME *self);"); + } + break; + + case 0x02: // void PDDelete(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("void PDDelete(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + mPrinterManager->Delete(mProcessor->GetRegister(0)); + break; + + case 0x03: // NewtonErr PDOpen(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDOpen(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + ret = mPrinterManager->Open(mProcessor->GetRegister(0)); + mProcessor->SetRegister(0, ret); + break; + + case 0x04: // NewtonErr PDClose(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDClose(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + ret = mPrinterManager->Close(mProcessor->GetRegister(0)); + mProcessor->SetRegister(0, ret); + break; + + case 0x05: // NewtonErr PDOpenPage(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDOpenPage(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + ret = mPrinterManager->OpenPage(mProcessor->GetRegister(0)); + mProcessor->SetRegister(0, ret); + break; + + case 0x06: // NewtonErr PDClosePage(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDClosePage(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + ret = mPrinterManager->ClosePage(mProcessor->GetRegister(0)); + mProcessor->SetRegister(0, ret); + break; + + case 0x07: // NewtonErr PDImageBand(DRIVERCLASSNAME *self, PixelMap* theBand, const Rect* minRect); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDImageBand(DRIVERCLASSNAME *self, PixelMap* theBand, const Rect* minRect);"); + } + if (mPrinterManager) + ret = mPrinterManager->ImageBand( + mProcessor->GetRegister(0), + mProcessor->GetRegister(1), + mProcessor->GetRegister(2)); + mProcessor->SetRegister(0, ret); + break; + + case 0x08: // void PDCancelJob(DRIVERCLASSNAME *self, Boolean asyncCancel); + if (LOG_PRINTER) + { + mLog->LogLine("void PDCancelJob(DRIVERCLASSNAME *self, Boolean asyncCancel);"); + } + if (mPrinterManager) + mPrinterManager->CancelJob( + mProcessor->GetRegister(0), + mProcessor->GetRegister(1)); + break; + + case 0x09: // PrProblemResolution PDIsProblemResolved(DRIVERCLASSNAME *self); + if (LOG_PRINTER) + { + mLog->LogLine("PrProblemResolution PDIsProblemResolved(DRIVERCLASSNAME *self);"); + } + if (mPrinterManager) + ret = mPrinterManager->IsProblemResolved(mProcessor->GetRegister(0)); + mProcessor->SetRegister(0, ret); + break; + + case 0x0A: // void PDGetPageInfo(DRIVERCLASSNAME *self, PrPageInfo* info); + if (LOG_PRINTER) + { + mLog->LogLine("void PDGetPageInfo(DRIVERCLASSNAME *self, PrPageInfo* info);"); + } + if (mPrinterManager) + mPrinterManager->GetPageInfo( + mProcessor->GetRegister(0), + mProcessor->GetRegister(1)); + break; + + case 0x0B: // void PDGetBandPrefs(DRIVERCLASSNAME *self, DotPrinterPrefs* prefs); + if (LOG_PRINTER) + { + mLog->LogLine("void PDGetBandPrefs(DRIVERCLASSNAME *self, DotPrinterPrefs* prefs);"); + } + if (mPrinterManager) + mPrinterManager->GetBandPrefs( + mProcessor->GetRegister(0), + mProcessor->GetRegister(1)); + break; + + case 0x0C: // NewtonErr PDFaxEndPage(DRIVERCLASSNAME *self, long pageCount); + if (LOG_PRINTER) + { + mLog->LogLine("NewtonErr PDFaxEndPage(DRIVERCLASSNAME *self, long pageCount);"); + } + if (mPrinterManager) + ret = mPrinterManager->FaxEndPage( + mProcessor->GetRegister(0), + mProcessor->GetRegister(1)); + mProcessor->SetRegister(0, ret); + break; + + default: + if (LOG_PRINTER) + { + mLog->FLogLine("Unknown Printer Driver Call: 0x%08x\n", inInstruction); + } + KPrintf("Unknown Printer Driver Call: 0x%08x\n", inInstruction); + break; + } +} +#else +void +TNativePrimitives::ExecutePrinterDriverNative(KUInt32 inInstruction) +{ + KPrintf("Printer Driver Calls not supported on this platform.\n"); +} +#endif + // -------------------------------------------------------------------------- // // * TransferState( TStream* ) // -------------------------------------------------------------------------- // diff --git a/Emulator/TNativePrimitives.h b/Emulator/TNativePrimitives.h index f7013015..767d4223 100644 --- a/Emulator/TNativePrimitives.h +++ b/Emulator/TNativePrimitives.h @@ -34,6 +34,7 @@ class TEmulator; class TMemory; class TARMProcessor; class TNetworkManager; +class TPrinterManager; class TSoundManager; class TScreenManager; class TPlatformManager; @@ -224,6 +225,13 @@ class TNativePrimitives /// void ExecuteHostiOSNativeiOS(KUInt32 inInstruction); + /// + /// Execute a native instruction for printer drivers + /// + /// \param inInstruction opcode of the instruction to execute. + /// + void ExecutePrinterDriverNative(KUInt32 inInstruction); + /// \name Variables TARMProcessor* mProcessor; ///< Reference to the CPU. TLog* mLog; ///< Interface for logging. @@ -231,6 +239,7 @@ class TNativePrimitives TMemory* mMemory; ///< Interface to the memory. TEmulator* mEmulator; ///< Emulator (interface to hardware). TNetworkManager* mNetworkManager; ///< Network manager. + TPrinterManager* mPrinterManager; ///< Printer manager TSoundManager* mSoundManager; ///< Sound manager TScreenManager* mScreenManager; ///< Screen manager. TPlatformManager* mPlatformManager; ///< Platform manager. diff --git a/ReleaseText.md b/ReleaseText.md index a0f47824..9e6a1af7 100644 --- a/ReleaseText.md +++ b/ReleaseText.md @@ -1,4 +1,16 @@ +Binary Release v2022.4.19 +========================= + +User Release Notes +------------------ + - printer support, printer driver is built into REX + +Toolkit Release Notes +--------------------- + - NewtonScript host file access + + Binary Release v2022.4.18 ========================= diff --git a/Toolkit/TToolkitScriptExt.cpp b/Toolkit/TToolkitScriptExt.cpp index 10a3ad49..1dd13ed9 100644 --- a/Toolkit/TToolkitScriptExt.cpp +++ b/Toolkit/TToolkitScriptExt.cpp @@ -169,7 +169,7 @@ NewtMakeBinaryFromARMFile(const char* srcfilename, bool /*literal*/) char objfilename[FL_PATH_MAX + 1]; strncpy(objfilename, basename, FL_PATH_MAX); strncat(objfilename, "inline.o", FL_PATH_MAX); - char binfilename[FL_PATH_MAX]; + char binfilename[FL_PATH_MAX + 1]; strncpy(binfilename, basename, FL_PATH_MAX); strncat(binfilename, "inline", FL_PATH_MAX); char errfilename[FL_PATH_MAX + 1]; @@ -761,6 +761,23 @@ RegisterToolkitScriptExtensions() /* MakeIcon/ImagFormPNG: + Create an app icon from one or more GIF/PNG images. + + App icons can be 1 bit or 4 bit deep, have an alternative image when clicked + (highlighted), and have one 1-bit maks for normal and highlighted each. + There is an option to use no mask, a bitmap mask, or a calculated mask. + Iconsize is usually 26x25 pixels. + + (icon is also used in "viewclass: 76") + + We also want to create image and sound data for scripts. + + V1: icon { mask*, bits, bounds { left, top, right bottom } } + V2: icon, iconPro { unhilited { bounds, bits, mask, colorData [* { cbits, bitDepth } ]* } hilited { } } + V2c: icon { mask*, bits, bounds { left, top, right bottom } colorData { cbits, bitDepth } } + + + B/W image format: newt.app.parts[0].data.icon: { mask: MakeBinaryFromHex( diff --git a/_Data_/Einstein.rex b/_Data_/Einstein.rex index a7996acf..5db0c9e8 100644 Binary files a/_Data_/Einstein.rex and b/_Data_/Einstein.rex differ diff --git a/app/FLTK/TFLApp.cpp b/app/FLTK/TFLApp.cpp index 3dff297e..6e48d94c 100644 --- a/app/FLTK/TFLApp.cpp +++ b/app/FLTK/TFLApp.cpp @@ -220,6 +220,7 @@ Developer's Documentation: Basic Ideas, Basic Features, Detailed Class Reference #include "Emulator/Network/TUsermodeNetwork.h" #include "Emulator/PCMCIA/TLinearCard.h" #include "Emulator/Platform/TPlatformManager.h" +#include "Emulator/Printer/TFLPrinterManager.h" #include "Emulator/ROM/TAIFROMImageWithREXes.h" #include "Emulator/ROM/TFlatROMImageWithREX.h" #include "Emulator/ROM/TROMImage.h" @@ -357,12 +358,17 @@ TFLApp::Run(int argc, char* argv[]) InitNetwork(); + TFLPrinterManager* printerManager = new TFLPrinterManager(mLog); + // MP2000: 1MB Dynamic RAM, 4MB Flash RAM // MP2100: 4MB Dynamic RAM, 4MB Flash RAM // eMate: 1MB Dynamic RAM, 2MB Flash RAM mEmulator = new TEmulator(mLog, mROMImage, theFlashPath, - mSoundManager, mScreenManager, mNetworkManager, ramSize << 16); + mSoundManager, mScreenManager, mNetworkManager, + ramSize << 16, printerManager); + mPlatformManager = mEmulator->GetPlatformManager(); + printerManager->SetMemory(mEmulator->GetMemory()); // yes, this is valid C++ code; it tells the emulator to call us so we can tell FLTK to // call us again later from the main thread which then closes all windows, terminating diff --git a/app/FLTK/TFLApp.h b/app/FLTK/TFLApp.h index d070b183..121acd31 100644 --- a/app/FLTK/TFLApp.h +++ b/app/FLTK/TFLApp.h @@ -48,6 +48,7 @@ class TLog; class TBufferLog; class TPlatformManager; class TNetworkManager; +class TPrinterManager; class TMonitor; class TSymbolList; #if USE_TOOLKIT