windows-nt/Source/XPSP1/NT/base/mvdm/wow16/gdi/gdimacro.inc
2020-09-26 16:20:57 +08:00

676 lines
13 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/* 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 &macro 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
;*/