/*
    PHWIF.C

Started by DavidW, 5/12/91

Printing extension to h layer of hwif

Help subsystem extension added 3/8/92

*/

#include <hwimman.g>
#include <hactive.g>
#include <p_gen.h>
#include <hwif.h>
#include <hwif.g>
#include <gate.g>

GLREF_D PR_WSERV *w_ws;
GLREF_D PR_HWIMMAN *w_am;
GLREF_D PR_GATE *DatGate;
GLREF_D UWORD DatLocked;

typedef struct
    {
    INT (*f)(WDR_PRINT *);
    } GATE_PRINTER;

typedef struct
    {
    HANDLE catHand;
    INT class;
    DL_DATA d;
    } GATE_OOD;

#define GATE_FORCE_WSERV_LEAVE   FALSE


#pragma save,ENTER_CALL

LOCAL_C INT EditPrintContext(VOID *junk)
    {
    p_send2(w_ws,O_WS_EDIT_PRINT_CONTEXT);
    return(0);
    }
    
LOCAL_C INT EditPrinterSetup(VOID *junk)
    {
    p_send2(w_ws,O_WS_EDIT_PDEV_SETUP);
    return(0);
    }

#define _phand ((PR_HPRINTER *)(w_ws->wserv.filelist))

LOCAL_C INT DoPrint(VOID *par)
    {
    _phand=p_new(CAT_HWIF_HWIF,C_HPRINTER);
    if (!_phand)
        return(E_GEN_NOMEMORY);
    _phand->hprinter.sense=((GATE_PRINTER *)par)->f;
    p_send2(_phand,O_LPR_INIT);
    return(0);
    }
    
LOCAL_C INT HelpSubSystem(VOID *par)
    {
    p_send3(w_ws,O_WS_DO_HELP,(INT)par);
    p_reclass(CAT_HWIF_HWIF,C_HHELPDLG,w_ws->wserv.dial);
    p_send2(w_am,O_AM_START);
    return(0);
    }

#define _dld ((GATE_OOD *)par)

LOCAL_C INT LaunchDialog(VOID *par)
    {
    p_send5(w_ws,O_WS_DO_DIAL,_dld->catHand,_dld->class,&_dld->d);
    return(0);
    }

#pragma restore

LOCAL_C UINT ConsoleOff(UWORD state,UINT leavestate)
/*
Set the console read off or on dependent on state
Also enable or disable leaves from the Window Server.
Return the old value of the disable leaves status.
*/
    {
    UINT func;

    func=P_SCR_DISABLE_READS;
    p_iow4(DatGate->gate.concb,P_FSET,&func,&state);
    return(wDisableLeaves(leavestate));
    }

LOCAL_C VOID ViaGate(
#pragma save,ENTER_CALL
                    INT func(VOID *),VOID *par)
#pragma restore
    {
    INT leavestate;
    INT ret;
    PR_WAOTSTAT *waotstat;

    leavestate=ConsoleOff(TRUE,GATE_FORCE_WSERV_LEAVE);
    w_ws->wserv.flags&=(~PR_WSERV_FROM_HWIF);
    DatLocked++;
    ret=p_enter2(func,par);
    DatLocked--;
    w_ws->wserv.flags|=PR_WSERV_FROM_HWIF;
    ConsoleOff(FALSE,leavestate);
    if (ret)
        uErrorValue(ret);
    waotstat=DatGate->gate.waotstat;
    while (waotstat->waotstat.count)
        {
        p_iosignal();
        (waotstat->waotstat.count)--;
        }
    }

LOCAL_C VOID ViaClearGate(
#pragma save,ENTER_CALL
                    INT func(VOID *),VOID *par)
#pragma restore
/* new function for 2.04, avoid trouble when HELP pressed */
    {
	INT old;
	
	old=w_ws->wserv.help_index_id;
	w_ws->wserv.help_index_id=0;
    ViaGate(func,par);
	w_ws->wserv.help_index_id=old;
    }

GLDEF_C VOID hPrintSetupDialog(VOID)
    {
	ViaClearGate(EditPrintContext,NULL);
    }

GLDEF_C VOID hPrint(INT sense(H_PRINT *))
    {
    GATE_PRINTER g;

    g.f=(INT (*)(WDR_PRINT *))sense;
    ViaClearGate(DoPrint,&g);
    if (_phand)
        {
        p_send2(_phand,O_DESTROY);
        _phand=NULL;
        }
    }

GLDEF_C VOID hPrinterSetupDialog(VOID)
    {
    ViaClearGate(EditPrinterSetup,NULL);
    }

GLDEF_C VOID hHelpSubSystem(INT startid,INT indexid)
    {
    INT old;

    old=w_ws->wserv.help_index_id;
    w_ws->wserv.help_index_id=indexid;
    ViaGate(HelpSubSystem,(VOID *)startid);
    w_ws->wserv.help_index_id=old;
    }

GLDEF_C VOID hOODialog(INT catHandle,INT class,INT resid,VOID *rbuf)
    {
    GATE_OOD dld;

    dld.catHand=catHandle;
    dld.class=class;
    dld.d.id=resid;
    dld.d.rbuf=rbuf;
    dld.d.pdlg=NULL;
    ViaClearGate(LaunchDialog,&dld);
    }

GLDEF_C VOID hPrintSetSI(UINT subsqind)
    {
    _phand->lprinter.subsqind=subsqind;
    }

GLDEF_C INT hPrintSensePageWidth(VOID)
    {
    return(_phand->lprinter.width);
    }

GLDEF_C INT hPrintSenseBufWidth(TEXT *buf,INT blen)
    {
    return(p_send4(_phand,O_LPR_SENSE_BUF_WIDTH,buf,blen));
    }

#define S_METHOD_CALL call(reg_param =>(bx,dx,si,di),reg_saved =>(ds))

#pragma S_METHOD_CALL

METHOD INT hprinter_lpr_sense_text(PR_HPRINTER *self,WDR_PRINT *pr)
    {
    return((self->hprinter.sense)(pr));
    }

METHOD VOID hprinter_lpr_read(PR_HPRINTER *self,INT x,WDR_PRINT *pr)
    {   /* added for Hwif 2.02 as workaround for lprinter bug */
    self->lprinter.defer.flags&=(~WDR_PRINT_PAGE);
    p_supersend4(self,O_LPR_READ,x,pr);
    }

METHOD VOID hhelpdlg_destroy(PR_HHELPDLG *self)
    {
    p_supersend2(self,O_DESTROY);
    p_send2(w_am,O_AM_STOP);
    }
