|
|
;/* GDIMACRO.INC - GDI macros
LMHLockCnt equ byte ptr 3 wptr equ word ptr bptr equ byte ptr
PtoLMH macro r1,r2 ifnb <r2> mov r1,[r2 - 2] else mov r1,[r1 - 2] endif endm
LMHtoP macro r1,r2 ;; Local Movable Handle to pointer ifnb <r2> mov r1,[r2] else mov r1,[r1] endif endm
LMHtoPES macro r1,r2 ;; Local Movable Handle to ptr, deref vi ES ifnb <r2> mov r1,es:[r2] else mov r1,es:[r1] endif endm
LMPsize macro r1,r2 ;; Local Movable pointer size mov r1,-4[r2] endm
LockDataSegment macro endm
UnlockDataSegment macro endm
farLockDataSegment macro endm
farUnlockDataSegment macro endm
; NOTE: The lock/unlock macros are not going to check ; for under/overflow. Its highly unlikely that ; it will occur, and if it does, we'll be hosed ; anyway....
LLock macro r inc LMHLockCnt[r] ;;Increment ref count endm
LUnlock macro r dec LMHLockCnt[r] ;;Decrement reference count endm
LLocked? macro r cmp LMHLockCnt[r],0 ;; is the handle locked? endm
LLockES macro r inc es:LMHLockCnt[r] ;;Increment ref count endm
LUnlockES macro r dec es:LMHLockCnt[r] ;;Decrement reference count endm
LLockedES? macro r cmp es:LMHLockCnt[r],0 ;; is the handle locked? endm
; The jmpnext macro and associated symbols are used to generate ; the fall-through chain and generate the labels required for ; error checking.
??ji = 0 ;;Initial index value
jmpnext macro e jn %??ji,%(??ji+1),e ;;Set next label endm
jn macro i,j,e .sall ??ji&i: .xall ifb <e> ;;If not the end of the chain db 03dh ;;mov bx, next two bytes errn$ ??ji&j,+2 ;;mext lable must be two bytes away endif ??ji=j ;;increment counter endm
ifdef DEBUG ifndef ?HELPER ExternFP ValidateHandle endif endif
;* ;* Valid? macro Handle,Error_exit,LowLimit,UpLimit ;* ;* Validate an object handle. A valid handle must 1)not be NULL 2)be for ;* an object of the specified type. ;* ;* ;* Macro Arguments: ;* ;* Handle - object handle ;* Error_exit - the next instruction to execute if an invalid obj ;* LowLimit, UpLimit - Range of the possible object type ;* ;* Return: ;* DS:BX - pointer to the object ;* ;* Trashes: ;* AX,BX,CX,DX ;*
Valid? macro Handle,Error_exit,LowLimit,UpLimit local ValidHandle,Invalidexit
ifdef DISABLE ifdef DEBUG
;****************************************************************************** ; ; Object handle validation in a debug version ; ;******************************************************************************
push dx mov bx, LowLimit ifnb <UpLimit> mov dx, UpLimit else mov dx, LowLimit endif
cCall <far ptr ValidateHandle>,<Handle,bx,dx> pop dx or ax,ax jnz ValidHandle jmp Error_exit else
;****************************************************************************** ; ; Object handle validation in a retail version ; ;******************************************************************************
mov bx,Handle ; NULL handle validation or bx,bx jz Invalidexit
LMHtoP bx ; dereference for object pointer
mov ax,ilObjType[bx] ; Validate the object type
irp stock_type,<OBJ_PEN,OBJ_BRUSH,OBJ_FONT,OBJ_BITMAP,OBJ_PALETTE> ife stock_type-LowLimit and ax,NOT OBJ_FLAGS ; mask only for possible stock obj endif endm
ifnb <UpLimit> cmp ax,LowLimit ; Check object type range jl Invalidexit cmp ax,UpLimit jle ValidHandle else cmp ax,LowLimit ; Check a particular object type je ValidHandle endif
Invalidexit: xor ax,ax jmp Error_exit ; it is not a valid handle
endif
ValidHandle:
else ; !DISABLE
mov bx,Handle LMHtoP bx
endif ; !DISABLE endm
ValidDebug? macro Handle,LowLimit,UpLimit
ifdef DEBUG
push bx push dx mov bx, LowLimit ifnb <UpLimit> mov dx, UpLimit else mov dx, LowLimit endif
cCall <far ptr ValidateHandle>,<Handle,bx,dx> pop dx pop bx
endif endm
;* ;* Notify? macro ;* ;* Tests if the given dc is hooked, and if it is, calls off to ;* send a notification to whomever is hooked into the dc notification ;* hook. ;* ;* Macro Arguments: ;* ;* hDC - the actual DC handle ;* lParam - the notification code to send via the hook ;* errLbl - optional parameter, which gives label to ;* jump to if notification returns 0 ;* ;* Trashes: ;* AX,BX,flags ;* ifdef LATER ifndef ?LVB ExternFP SendDCNotify ExternFP SendInvalidVisRgn endif Notify? macro hDC,code,param1,param2,errLbl mov bx,hDC mov bx,[bx] mov ax,word ptr lpNotifyProc[bx] or ax,word ptr lpNotifyProc+2[bx] jz @F push hDC mov ax,code push ax mov ax,param1 push ax mov ax,param2 push ax cCall <far ptr SendDCNotify> ifnb <errLbl> or ax,ax endif ifnb <errLbl> jnz @F jmp errLbl endif @@: endm
;* VNotify? ;* ;* Tests if the given dc is hooked and has an invalid visrgn. If ;* it does, then a notification is sent to the dc hook. ;* ;* Warning: ;* if we call the call-back, the gdi heap can be compacted, ;* so no dereferenced handles can be relied on after making ;* this call. ;* ;* Entry: ;* hDC - handle to dc to check and send notifications ;* reg - scratch register to use ;* ;* Exit: ;* reg - trashed ;* flags - trashed ;* VNotify? macro hDC,reg mov reg,hDC LMHtoP reg test byte ptr DCFlags[reg],BadVisRgn jz @F cCall <far ptr SendInvalidVisRgn>,<hDC> @@: endm
VNotifyPtr? macro reg,hDC test byte ptr DCFlags[reg],BadVisRgn jz @F cCall <far ptr SendInvalidVisRgn>,<hDC> @@: endm endif
;----------------------------------------------------------------------- ; cProcVDO - cProc "Validate Debug Only" ; ; Same as cProc, except used for "Validate in Debug Only" entry points. ; Declares Iname if debug, name if retail. ; cProcVDO macro name,opts,savelist ifdef DEBUG cProc <I&name>,<opts>,<savelist> else LabelFP <PUBLIC, I&name> cProc <name>,<opts>,<savelist> endif endm
GDIGLOBALLOCK macro Handle,segRegister,offsetRegister .lall ifndef GlobalLock ExternFP GlobalLock endif cCall <far ptr GlobalLock>,<Handle> ifnb <segRegister> mov segRegister,dx endif ifnb <offsetRegister> mov offsetRegister,ax endif .sall endm
GDIGLOBALUNLOCK macro Handle ifndef GlobalUnlock ExternFP GlobalUnlock endif cCall <far ptr GlobalUnlock>,<Handle> endm
GDIRequestSem macro endm
GDIClearSem macro endm
; setlbl generates a macro which will declare labels public ; if "debug" has been defined. The symbol generated will ; be of the form: ; ; filename_label ; ; where ; ; filename is the parameter given to the setlbl macro, ; and label is the first parameter given to the lbl macro ; which is generated by setlbl. ; ; ; lbl is the macro which will define the given label and ; if "debug" is defined, declare it public. ; ; ; lbl foo,<opt1>,opt2 ; ; where ; ; foo is the name of the label ; opt1 is an optional second parameter. If present, ; it must be some combination of ; proc, label, near, far, byte, word, dword ; opt2 is an optional third parameter which if present ; must be "public". It forces the declaration of ; "foo" to be public.
setlbl macro filename lbl ¯o n,opt1,opt2 .sall ifnb <opt1> n opt1 ifdef debug filename&&_&&n equ n public filename&&_&&n endif else n: ifdef debug filename&&_&&n: public filename&&_&&n endif endif ifnb <opt2> public n endif .xall &endm endm
smov macro segreg1,segreg2 push segreg2 pop segreg1 endm
jmps macro there jmp short there endm
; structure to allow easy access to components of DWORD.
HILO struc lo dw ? hi dw ? HILO ends
; structure to allow easy access to components of LP.
OFFSEL struc off dw ? sel dw ? OFFSEL ends
;--------------------------------------------------------------------------; ; ABS ; Maps the signed integer in AX to a positive signed integer to be ; returned in AX. If FOO is blank then 8000h is mapped to 7fffh. ; Since GDI defines MININT as 8000h, we should deal with this case. ; If FOO is non-blank, 8000h is mapped to 8000h. (Usually bad!) ; All other integers behave as one would expect with Absolute Value. ; Entry: ; AX = signed integer (8000h to 7fffh) ; Returns: ; AX = ABS(AX) ; Trashes: ; DX, FLAGS ; ; History: ; Tue 29 October 1991 -by- Raymond E. Endres [rayen] ; Wrote it. ;--------------------------------------------------------------------------;
ABS macro FOO ;NOTE: default FOO is blank! cwd xor ax,dx sub ax,dx ifb <FOO> ;if FOO is blank cwd ;remove the 8000h case xor ax,dx endif endm
;--------------------------------------------------------------------------; ; min_ax ; returns min of AX and REG ; Entry: ; AX = integer ; REG = general purpose register containing an integer ; Returns: ; AX = min(AX,REG) ; Error Returns: ; none ; Registers Destroyed: ; DX,FLAGS ; Registers Preserved: ; BX,CX,SI,DI,DS,ES,BP ; Calls: ; none ; History: ; Sat Mar 07, 1987 08:39:04p -by- Tony Pisculli [tonyp] ; wrote it ;--------------------------------------------------------------------------;
min_ax macro REG sub ax,REG cwd and ax,dx add ax,REG endm
;--------------------------------------------------------------------------; ; max_ax ; returns max of AX and REG ; Entry: ; AX = integer ; REG = general purpose register containing an integer ; Returns: ; AX = max(AX, REG) ; Error Returns: ; none ; Registers Destroyed: ; DX,FLAGS ; Registers Preserved: ; BX,CX,SI,DI,DS,ES,BP ; Calls: ; none ; History: ; Sat Mar 07, 1987 08:41:38p -by- Tony Pisculli [tonyp] ; wrote it ;--------------------------------------------------------------------------;
maxintoax macro mem1,mem2 mov ax,mem1 max_ax mem2 endm
max_ax macro REG sub ax,REG cwd not dx and ax,dx add ax,REG endm
; The following equates are used for defining the target ; processor to the shift macros.
GENERIC equ 0
;CPU equ GENERIC ;CPU equ 88 ;CPU equ 86 ;CPU equ 186 CPU equ 286 ;CPU equ 386
;--------------------------------------------------------------------------; ; shiftl ; ; shiftl is used to implement the advanced shift left immediate ; (SHL dest,count) functionality of the 286 and 386. ; ; Entry: ; DEST = var to shift ; COUNT = number to shift by ; Returns: ; DEST = DEST shl COUNT ; Error Returns: ; none ; Registers Destroyed: ; none ; Registers Preserved: ; all ; Calls: ; none ; History: ; Sat Mar 07, 1987 08:44:30p -by- Tony Pisculli [tonyp] ; wrote it ;--------------------------------------------------------------------------;
shiftl macro DEST,COUNT if (CPU eq 286) or (CPU eq 386) shl DEST,COUNT else REPT COUNT shl DEST,1 ENDM endif endm
;--------------------------------------------------------------------------; ; shiftr ; ; shiftr is used to implement the advanced shift right immediate ; (SHR dest,count) functionality of the 286 and 386. ; ; Entry: ; DEST = var to shift ; COUNT = number to shift by ; Returns: ; DEST = DEST shr COUNT ; Error Returns: ; none ; Registers Destroyed: ; none ; Registers Preserved: ; all ; Calls: ; none ; History: ; Sat Mar 07, 1987 08:44:52p -by- Tony Pisculli [tonyp] ; wrote it ;--------------------------------------------------------------------------;
shiftr macro DEST,COUNT if (CPU eq 286) or (CPU eq 386) shr DEST,COUNT else REPT COUNT shr DEST,1 ENDM endif endm
;--------------------------------------------------------------------------; ; nop32 ; ; compensate for bug in the 386 chip and 32-bit string operations. ; ;--------------------------------------------------------------------------; nop32 macro db 067h nop endm
if 0 */
#ifndef DEBUG #include "igdi.inc" #endif
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<=(b)?(a):(b)) #define ABS(x) (((x) >= 0) ? (x) : (-(x))) #define LBYTE(x) ((BYTE)((x)&0xFF)) #define HBYTE(y) ((BYTE)(((y)>>8)&0xFF)) #define LWORD(x) ((short)((x)&0xFFFF)) #define HWORD(y) ((short)(((y)>>16)&0xFFFF)) #define MAKELONG(h,l) ((long)(((WORD)l)|(((long)h)<<16)))
extern far PASCAL ValidateHandle(HANDLE, short, short); #ifdef DISABLE #define Valid(Handle, Low, High) ValidateHandle(Handle, Low, High) #else #define Valid(Handle, Low, High) TRUE #endif
#ifdef DEBUG #define ValidDebug(Handle, Low, High) {if(!ValidateHandle(Handle, Low, High)) return(NULL);} #else #define ValidDebug(Handle, Low, High) TRUE #endif
#define GDIGLOBALLOCK(x) GlobalLock(x) #define GDIGLOBALUNLOCK(x) GlobalUnlock(x) #define GDILOCKRESOURCE(x) LockResource(x) #define GDIENTERCRITSEC() #define GDIEXITCRITSEC() #define LockDataSegment() #define UnlockDataSegment() #define farLockDataSegment() #define farUnlockDataSegment() #define GDIRequestSem() #define GDIClearSem()
#define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) #define SELECTOROF(lp) HIWORD(lp) #define OFFSETOF(lp) LOWORD(lp)
/* endif
;*/
|