/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = EDDMACRO                                       */
/*                                                                    */
/*   Description     = Display Device Driver macros                   */
/*                                                                    */
/*   Function        = Include file defining C macros                 */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                                                                    */
/*                                                                    */
/**********************************************************************/

/**********************************************************************/
/* abs(x) : returns the absolute value of x (x must be signed)        */
/**********************************************************************/
#define abs(x) ((x)<0?(-(x)):(x))

/**********************************************************************/
/* max(x,y) : returns whichever of x and y has the higher value       */
/**********************************************************************/
#define max(x,y) (((x)>(y))?(x):(y))

/**********************************************************************/
/* min(x,y) : returns whichever of x and y has the lower value        */
/**********************************************************************/
#define min(x,y) (((x)<(y))?(x):(y))

/**********************************************************************/
/* Macro to get the command bits from the FunN parameter (the upper   */
/* 16 bits of a 32 bit word.                                          */
/**********************************************************************/
#define COMMANDBITS(x) ( ((PUSHORT)&(x))[1] )

/**********************************************************************/
/* Macro to test the FunN parameter                                   */
/**********************************************************************/
#define FunNTest(command) (FunN & (command))

/**********************************************************************/
/* Macro to avoid a compiler warning, because we deliberately don't   */
/* use a passed parameter.                                            */
/* Any reasonable compiler will optimize this away!                   */
/**********************************************************************/
#define IgnoreParam(x) (x)

/**********************************************************************/
/* Error logging macros                                               */
/**********************************************************************/
#define LOGERR(FunName,Text,num1,num2,error)       LogError(error)
#define LOGWARNING(FunName,Text,num1,num2,warning) LogWarning(warning)
#define LOGDOSERR(FunName,Text,num1,num2,doserror) LogDosError(doserror)

#define LogError(error)                                                \
      WinSetErrorInfo(MAKEERRORID(SEVERITY_ERROR,error),               \
                      SEI_NOBEEP | SEI_NOPROMPT)

#define LogWarning(warning)                                            \
      WinSetErrorInfo(MAKEERRORID(SEVERITY_WARNING,warning),           \
                      SEI_NOBEEP | SEI_NOPROMPT)

#define LogDosError(doserror)                                          \
      WinSetErrorInfo(MAKEERRORID(SEVERITY_ERROR,PMERR_BASE_ERROR),    \
                      SEI_NOBEEP | SEI_NOPROMPT )

// We would like to actually log the Dos error, but the thunk provided
// by the engine only thunks a fixed set of 2 parameters
// #define LogDosError(doserror)                                       \
//    WinSetErrorInfo(MAKEERRORID(SEVERITY_ERROR,PMERR_BASE_ERROR),    \
//                    SEI_NOBEEP | SEI_NOPROMPT | SEI_DOSERROR,        \
//                    doserror)

/**********************************************************************/
/* Option Flags for EnterDriver and ExitDriver:                       */
/*                                                                    */
/*      EDF_EXCLUSIVE       -   Exclusive driver access required      */
/*      EDF_DC_NULL         -   The DC is invalid (NULL)              */
/*      EDF_DONT_CLEAN      -   Don't clean the DC if it is dirty.    */
/*                                                                    */
/*      EDF_NONE            -   No extra options, just set up the     */
/*                              pdc.                                  */
/*      EDF_STANDARD        -   The 'usual' combination of flags      */
/*                                                                    */
/* An extra flag exists for the ExitDriver Macro.                     */
/*      EDF_IGNORE_TIME     -   To tell performance routines to ignore*/
/*                              the call just made (usually when we   */
/*                              are about to pass back to the engine  */
/*                              for simulation)                       */
/*                                                                    */
/* There are some cases where EnterDriver and ExitDriver are called   */
/* when there is no function number(usually in the enable routines)   */
/* a value of FUNN_UNKNOWN can be used for these cases.               */
/**********************************************************************/
#define     EDF_EXCLUSIVE           0x00000001
#define     EDF_DC_NULL             0x00000002
#define     EDF_DONT_CLEAN          0x00000004

#define     EDF_IGNORE_TIME         0x00000008

#define     EDF_NONE                0x00000000
#define     EDF_STANDARD            EDF_EXCLUSIVE

#define     FUNN_UNKNOWN            0xffffffff

/**********************************************************************/
/* The Enter and Exit driver macors                                   */
/**********************************************************************/
#define EnterDriver(pdc, FunN, flags) XGA_EnterDriver(pdc, FunN, flags)
#define ExitDriver(pdc, FunN, flags)  XGA_ExitDriver(pdc, FunN, flags)

/**********************************************************************/
/* This macro is used to fix up the drawing to use the hardware or    */
/* the software.  There are several things it must do if it finds a   */
/* switch is necessary..                                              */
/*                                                                    */
/* Alter pXGARegs                                                     */
/* Alter LinePatternCur, MarkerCur                                    */
/* Alter softDrawInUse                                                */
/* Alter pointer to drawFunctions table                               */
/**********************************************************************/
#ifndef   _8514
#define SetDrawModeSoft                                                \
{                                                                      \
    if (!softDrawInUse)                                                \
    {                                                                  \
        pXGARegs          = (pMMReg)&ShadowXGARegs;                    \
        LinePatternCur    = LinePatternSys;                            \
        MarkerCur         = MarkerSys;                                 \
        pDrawFunctions    = (pDrawFunctionsTable)softDrawTable;        \
        softDrawInUse     = TRUE;                                      \
    }                                                                  \
}

#define SetDrawModeHard                                                \
{                                                                      \
    if (softDrawInUse && foregroundSession)                            \
    {                                                                  \
        pXGARegs          = pRealXGARegs;                              \
        LinePatternCur    = LinePatternPhys;                           \
        MarkerCur         = MarkerPhys;                                \
        pDrawFunctions    = (pDrawFunctionsTable)hardDrawTable;        \
        softDrawInUse     = FALSE;                                     \
    }                                                                  \
}

/**********************************************************************/
/* Macro to change FlatLock into the appropriate IOCtl call.          */
/**********************************************************************/
typedef struct _FLATLOCKDATA
{
    PVOID       VirtualAddress;
    ULONG       PhysicalAddress;
    ULONG       cMemorySize;
    ULONG       ActionFlags;
    ULONG       LockHandle[3];
} FLATLOCKDATA;

#define FlatLock(data)                                                 \
{                                                                      \
    ULONG       fn_id = IO_FLAT_LOCK;                                  \
                                                                       \
    DosDevIOCtl( ring0_handle,                                         \
                 XGA_CATEGORY,                                         \
                 GEN_FUNCTION,                                         \
                 (PVOID)&fn_id,                                        \
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */\
                 NULL,           /* not passed to level 1 ring0 code */\
                 (PVOID)data,                                          \
                 sizeof(FLATLOCKDATA),                                 \
                                 /* not passed to level 1 ring0 code */\
                 NULL            /* not passed to level 1 ring0 code */\
               );                                                      \
}

#else
#define SetDrawModeSoft                                                \
{                                                                      \
    if (!softDrawInUse)                                                \
    {                                                                  \
        LinePatternCur    = LinePatternSys;                            \
        MarkerCur         = MarkerSys;                                 \
        pDrawFunctions    = (pDrawFunctionsTable)softDrawTable;        \
        softDrawInUse     = TRUE;                                      \
    }                                                                  \
}

#define SetDrawModeHard                                                \
{                                                                      \
    if (softDrawInUse && foregroundSession)                            \
    {                                                                  \
        LinePatternCur    = LinePatternPhys;                           \
        MarkerCur         = MarkerPhys;                                \
        pDrawFunctions    = (pDrawFunctionsTable)hardDrawTable;        \
        softDrawInUse     = FALSE;                                     \
    }                                                                  \
}
#endif

/**********************************************************************/
/* Macro to compare a passed in FunN with a defined NGre... number    */
/* Equates to TRUE if they are the same.                              */
/* Only checks least significant 10 bits as others are flags and can  */
/* change from version to version.                                    */
/**********************************************************************/
#define FUNCTIONIS(FunN, Ngre)  ((LOUSHORT(FunN) & 0x3ff) == (Ngre & 0x3ff))

/**********************************************************************/
/* Macros to remove any previous profiling statements.                */
/**********************************************************************/
#define PROFILE_ENTER(D)
#define PROFILE_EXIT(D)
