From: engber@ils.nwu.edu (Mike Engber)
Subject: Re: Software control of landscape/not landscape
Organization: The Institute for the Learning Sciences
Date: Tue, 22 Dec 1992 14:51:06 GMT


Attached is the relevant code extracted from SaveATree. It's THINK C code.

Basically, there is no official way to get a landscape print record,
but it's somewhat common knowledge that the orientation is controlled
by single bit in the print record (once source for this info is
MacRevealed vol 3). This bit is used for Apple printers and deskwriters
- don't have access to other types of printers to check it out.

My conservative approach is to:
 1) flip the bit
 2) use PrValidate to make sure I didn't trash the print record - i.e.
    this driver can't handle this bit being flipped.
 3) use PrGeneral to make sure flipping the bit put the print record
    into landscape mode (instead of doing something else)
 4) if 1-3 didn't work, I prompt the user to pick a landscape record
    from the PrStlDialog I subsequently display. This is sure to work
    unless the user screws up (I display the landscape Icon in the dialog
    in an attempt to make it more foolproof).
 5) Once I get a landscape record I save it away so I'll never have
    to do this again. 

This should work pretty well. I don't think it violate any guidlines
(too badly). And I've never had and problems reported wrt to SaveATree
doing it. Some cavats:

1) the printer must have PrGeneral implemented along with the getRotnOp
   opcode (I assume most do nowadays)

2) Older HP deswriter drivers have PrGeneral & getRotnOp implementd, but
   don't return a success error code from PrGeneral. So flipping the bit
   works, but since PrGeneral says it's didn't - I end up prompting the
   user anyway. This bug has been fixed in the more recent drivers.

-ME

---

void PrintPromptedStyle(THPrint printRecH, Boolean landscape){
    Alert(DU_CenterALRT(landscape ? L_SETUP_ALERT_ID : P_SETUP_ALERT_ID),0L);
    PrOpen();
    PrStlDialog(printRecH);
    PrClose();
}
 
static Boolean PrRotn(THPrint printRecH, Boolean* landscape){
    TGetRotnBlk rotnBlk;
    
    rotnBlk.iOpCode = getRotnOp;
    rotnBlk.hPrint  = printRecH;
    PrGeneral((Ptr)&rotnBlk);
    
    if(rotnBlk.iError == noErr){
        *landscape = rotnBlk.fLandscape ? true : false;
        return true;
    }else{
        return false;
    }
}
 
void PrintDefaultRotn(THPrint printRecH, Boolean landscape){
    Boolean         is_landscape;
    static TPrint   landscapeTPrint;
    static TPrint   portraitTPrint;
    static Boolean  landscapeStored = false;
    static Boolean  portraitStored = false;
    
    PrOpen();
    if(PrintError("\pprint.c: PrintDefaultRotn()","\pPrOpen") != noErr){
        PrClose();
        return;
    }
    
    PrValidate(printRecH);
    
    if(PrRotn(printRecH,&is_landscape)){
        if(is_landscape != landscape){
            /* toggle the bit */
            (*printRecH)->prStl.wDev ^= 0x02;
            /* make sure it worked */
            PrValidate(printRecH);
            if(PrRotn(printRecH,&is_landscape) && is_landscape==landscape){
                PrClose();
                return;
            }
        }else{
            /* it was ok to begin with */
            PrClose();
            return;
        }
    }
    
    /*
        If we reach this point either PrGeneral/getRotnOp or the
        bit toggling won't work on this printer. So we'll prompt
        the user & display a style dlog (ugh!).
    */
        PrClose();
        
        if(landscape){
            if(landscapeStored){
                **printRecH = landscapeTPrint;
            }else{
                PrintPromptedStyle(printRecH,landscape);
                landscapeStored = true;
                landscapeTPrint = **printRecH;
            }
        }else{
            if(portraitStored){
                **printRecH = portraitTPrint;
            }else{
                PrintPromptedStyle(printRecH,landscape);
                portraitStored = true;
                portraitTPrint = **printRecH;
            }
        }
}

Newsgroups: comp.sys.mac.programmer