mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
676 lines
13 KiB
676 lines
13 KiB
;/* 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
|
|
|
|
;*/
|
|
|
|
|