;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; 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.;
;*****************************************************************************/
        page    ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = CTAB2.ASM
;*
;* DESCRIPTIVE NAME = Display Device Driver minor function handler
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Display Device Driver minor function handler
;*              Create or alter a Logical Color Table.  Load current logical
;*              colors into physical palette.  Load default colors into
;*              physical palette.
;*
;* FUNCTIONS    CalculateColorTablePhysicalIndices
;*              eddc_RealizeColorTable
;*              eddc_UnrealizeColorTable
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   ??/??/92                     Paul King CMVC_52845
;*
;*****************************************************************************/

        .386
        .MODEL FLAT,SYSCALL
        ASSUME  SS:FLAT, DS:FLAT, CS:FLAT, ES:FLAT

        .xlist

INCL_GRE_PALETTE        equ                      1
INCL_DDICOMFLAGS        equ                      1
INCL_WINPALETTE         equ                      1
INCL_WINSYS             equ                      1
INCL_GPIPRIMITIVES      equ                      1
INCL_GPIERRORS          equ     1
INCL_GPILOGCOLORTABLE   equ                      1
        include pmgre.inc
DINCL_ENABLE    equ     1
DINCL_BITMAP            equ                      1
DINCL_CLR_TBL           equ                      1
        include driver.inc
        include extern.inc
        include protos.inc
        include palette.inc
        .list

eddc_UpdateAttributes PROTO SYSCALL,
        pddc    :PDDC

eddc_AlterSysColorTable PROTO SYSCALL,
        pddc           :PDDC,
        ulFormat       :ULONG,
        lStart         :LONG,
        ulCount        :ULONG,
        pData          :PULONG

eddc_ResetLogColorTable PROTO SYSCALL,
        hddc            :PDDC

eddc_RealizeColorTable PROTO SYSCALL,
        hdc             :HDC,
        hddc            :PDDC,
        FunN            :ULONG

eddc_UnrealizeColorTable PROTO SYSCALL,
        hdc             :HDC,
        hddc            :PDDC,
        FunN            :ULONG

ifndef IBMJ        ;IBMJ
.CODE
else  ;IBMJ        ;IBMJ
_PaletteSupport SEGMENT DWORD PUBLIC FLAT 'CODE'
endif ;IBMJ        ;IBMJ

;/***************************************************************************
;*
;* FUNCTION NAME = CalculateColorTablePhysicalIndices
;*
;* DESCRIPTION   = Calculate physical indices using the current device default
;*                 palette.
;*
;* INPUT         = pddc
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/
CalculateColorTablePhysicalIndices PROC SYSCALL USES ESI EDI EBX,
        pddc    :PDDC

        LOCAL   ulLogIndex:ULONG

        mov     esi,pddc
        ASSUME  ESI:PDDC
ifdef FIREWALLS
;/*
;**    /******************************************************************/
;**    /* This function should only be called if the color table is in   */
;**    /* rgb-index pair format.                                         */
;**    /******************************************************************/
;**    if (pdc->DCIColFormat != LCOLF_INDRGB)
;*/


        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jnz     @F

;/*
;**    {
;**        haltproc();
;*/

        int 3
@@:

;/*
;**    }
;*/

endif ;/* FIREWALLS */

;/*
;**    /******************************************************************/
;**    /* We are about to change the physical indexes used by the color  */
;**    /* table. We must call ChangedColorTable so that the current      */
;**    /* "palette to palette" mapping will be invalidated if necessary. */
;**    /******************************************************************/
;**    ChangedColorTable (pdc->DCIColorTable);
;*/

        INVOKE  ChangedColorTable,
                [esi].ddc_pClrTbl


;/*
;**    /******************************************************************/
;**    /* Update the DCs device default palette so that we will          */
;**    /* calculate the correct physical indices when we call off to     */
;**    /* NearestDefaultPhysicalIndex.                                   */
;**    /******************************************************************/
;**    if (pdc->DCIDCType == OD_DIRECT)
;*/

        test    [esi].ddc_fb,DDC_DEVICE
        jz      else_1

;/*
;**    {
;**        pdc->DCIDeviceDefaultPalette = DirectDeviceDefaultPalette;
;*/

        mov     eax,DirectDeviceDefaultPalette
        mov     [esi].ddc_pDefPal,eax
        jmp     endif_1

;/*
;**    }
;**    else
;*/

else_1:
;/*
;**    {
;**        pdc->DCIDeviceDefaultPalette = MemoryDeviceDefaultPalette;
;*/

        mov     eax,MemoryDeviceDefaultPalette
        mov     [esi].ddc_pDefPal,eax
endif_1:

;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Calculate physical indices using the current device default    */
;**    /* palette.                                                       */
;**    /******************************************************************/
;**    for (ulLogIndex = pdc->DCILowIndex;
;**         ulLogIndex <= pdc->DCIHighIndex;
;**         ulLogIndex++)
;**    {
;*/

        mov     ecx,[esi].ddc_ctMin
        mov     edx,[esi].ddc_ctMax
        mov     ebx,[esi].ddc_pClrTbl
        .ERRNZ  sizeof COLORTABLETYPE - 8
        jmp     loop_entry
loop_start:
;/*
;**        if (pdc->DCIColorTable[ulLogIndex].PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     [ebx+ecx*8].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        je      endif_2

;/*
;**        {
;**            if (fRealizeSupported && (pdc->DCIColStatus & LCOL_REALIZABLE))
;*/

                test    [esi].ddc_fbClrTbl,DDC_REALIZABLE
                jz      else_2

;/*
;**            {
;**                /******************************************************/
;**                /* Realizable was specified and we actually support it*/
;**                /* Thus physical index is the same as logical index.  */
;**                /******************************************************/
;**                pdc->DCIColorTable[ulLogIndex].PhyIndex = ulLogIndex;
;*/

                mov     [ebx+ecx*8].COLORTABLETYPE.PhyIndex,ecx
                jmp     endif_3

;/*
;**            }
;**            else
;*/

else_2:
;/*
;**            {
;**                /******************************************************/
;**                /* Find physical index which will give nearest RGB    */
;**                /* value to specified RGB using the current device    */
;**                /* default palette.                                   */
;**                /******************************************************/
;**                pdc->DCIColorTable[ulLogIndex].PhyIndex =
;**                              NearestDefaultPhysicalIndex(
;**                                        pdc->DCIColorTable[ulLogIndex].LogRGB);
;*/

                push    ecx
                push    edx

                INVOKE  NearestDefaultPhysicalIndex,
                        pddc,
                        [ebx+ecx*8].COLORTABLETYPE.LogRGB

                pop     edx
                pop     ecx
                mov     [ebx+ecx*8].COLORTABLETYPE.PhyIndex,eax
endif_3:
;/*
;**            }
;*/

endif_2:
;/*
;**        }
;*/

        inc     ecx
loop_entry:
        cmp     ecx,edx
        jbe     loop_start

;/*
;**    }
;**}
;*/

        ret
CalculateColorTablePhysicalIndices ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_RealizeColorTable
;*
;* DESCRIPTION   = RealizeColorTable ensures that the physical color table is set
;*                 to the closest possible match to the logical color table.
;*
;* INPUT         = hdc
;*                 hddc
;*                 FunN
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_RealizeColorTable PROC SYSCALL USES ESI EDI,
        hdc             :HDC,
        hddc            :PDDC,
        FunN            :ULONG
;/*
;**    ;/******************************************************************/
;**    ;/* Local variables                                                */
;**    ;/******************************************************************/
;**    ULONG          i;              ;/* Loop counter                    */
;**
;*/

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,ERROR_ZERO
        jc      rct_exit_no_lock                 ;error logged

ifdef FIREWALLS
;/*
;**    /******************************************************************/
;**    /* this test is firewalled since the 8514 driver claims that the  */
;**    /* engine will have already done the test                         */
;**    /******************************************************************/
;**
;**    /******************************************************************/
;**    /* If the function is being called within an area or path         */
;**    /* definition then we raise an error and leave immediately.       */
;**    /******************************************************************/
;**        ;/**************************************************************/
;**        ;/* We have been called within an area definition              */
;**        ;/**************************************************************/
;*/

        no_path_area    rct_exit_error,both
endif ;;/* FIREWALLS */
;/*
;**
;**    ;/******************************************************************/
;**    ;/* Check whether color table can be realized.                     */
;**    ;/******************************************************************/
;**    if ( !(pdc->DCIColStatus & LCOL_REALIZABLE) )
;*/

        test    [edx].DDC.ddc_fbClrTbl,DDC_REALIZABLE
        jnz     @F

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* If it cannot, log an error and return                      */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Unrealizable", FNULL, 0,
;**                                        PMERR_COL_TABLE_NOT_REALIZABLE);
;**        goto REALIZECOLTABLE_ERR_EXIT;
;*/

        mov     eax,PMERR_COL_TABLE_NOT_REALIZABLE
        save_error_code
        DebugMsg2       <Unrealizable>
        jmp     rct_exit_error
@@:
;/*
;**    }
;**
;**    if (!fRealizeSupported)
;**    {
;**        ;/**************************************************************/
;**        ;/* We dont support realizable color tables at all bits per    */
;**        ;/* pel.  If this is one where we dont support them, we log a  */
;**        ;/* warning but return success.                                */
;**        ;/**************************************************************/
;**        LOGWARNING(NULL, "Not supported", FNULL, 0,
;**                                           PMERR_REALIZE_NOT_SUPPORTED);
;**        goto REALIZECOLTABLE_OK_EXIT;
;**    }
;**
;*/

ifdef FIREWALLS
;/*
;**#pragma message( __FILE__"(1052) : Warning: Can a LCT in a non direct DC be realized ?")
;**    if (pdc->DCIDCType != OD_DIRECT)
;*/

        test    [edx].DDC.ddc_fb,DDC_DEVICE
        jz      not_device
        test    [edx].DDC.ddc_fbAbove,DDC_INFO_DC
        jz      is_device
not_device:
;/*
;**    {
;**        DebugOutput("RealizeColorTable: DC is not direct\n\r");
;*/

        DebugMsg2       <RealizeColorTable: DC is not direct>
is_device:
;/*
;**    }
;*/

endif ;;/* FIREWALLS */

;/*
;**    ;/******************************************************************/
;**    ;/* Check whether the currently loaded palette is not the default  */
;**    ;/******************************************************************/
;**    if (ColorTableRealized != 0)
;*/

        cmp     ColorTableRealized,0
        je      @F

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Load the default palette                                   */
;**        ;/* We pick this up from the memory version, because this      */
;**        ;/* will always be the full size that the device supports.     */
;**        ;/**************************************************************/
;**        for (i = 0; i < SizeOfHWPalette; i++)
;*/


        .ERRNZ  4-sizeof RGB2

        mov     ecx,SizeOfHWPalette
        lea     edi,RealizedLCTPalette
        mov     esi,MemoryDeviceDefaultPalette
        rep     movsd

;/*
;**        {
;**            RealizedLCTPalette[i] = MemoryDeviceDefaultPalette[i];
;**        }
;*/

@@:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Copy RGB values from logical color table to physical color     */
;**    ;/* table                                                          */
;**    ;/******************************************************************/
;**
;**    for (i = pdc->DCILowIndex;
;**         i <= min(pdc->DCIHighIndex, (USHORT)(SizeOfHWPalette - 1));
;**         i++)
;*/


        mov     esi,[edx].DDC.ddc_pClrTbl
        mov     ecx,[edx].DDC.ddc_ctMin
        mov     edx,[edx].DDC.ddc_ctMax

        lea     edi,RealizedLCTPalette          ;          

        mov     eax,SizeOfHWPalette
        dec     eax
        cmp     edx,eax
        jb      @F
        mov     edx,eax
@@:
        jmp     enter_for1
top_for1:
;/*
;**    {
;**        if (pdc->DCIColorTable[i].PhyIndex != CLR_NOPHYINDEX )
;*/

        cmp     [edi].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Copy over the RGB value                                */
;**            ;/**********************************************************/
;**            RealizedLCTPalette[i] = pdc->DCIColorTable[i].LogRGB;
;*/

                .errnz  sizeof RGB2-4
ASSUME  ESI:NOTHING
                mov     eax,[esi].COLORTABLETYPE.LogRGB
                mov     DWORD PTR [edi],eax
@@:
;/*
;**        }
;*/

        add     esi,sizeof COLORTABLETYPE
        add     edi,sizeof RGB2
        inc     ecx
enter_for1:
        cmp     ecx,edx
        jbe     top_for1
end_for1:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Realize it !                                                   */
;**    ;/******************************************************************/
;**    ColorTableRealized = hdc;
;*/

        mov     eax,hdc
        mov     ColorTableRealized,eax
;/*
;**    LoadPaletteEntries(0,
;**                       SizeOfHWPalette,
;**                       RealizedLCTPalette);
;*/

        INVOKE  LoadPaletteEntries,
                0,
                SizeOfHWPalette,
                ADDR RealizedLCTPalette

;/*
;**    ;/******************************************************************/
;**    ;/* Set up the realized indices for black and white now, because   */
;**    ;/* from experience we know these are common colors !              */
;**    ;/******************************************************************/
;**    RealizedWhiteIndex = InnerSearchRealizedLCTPalette(RGBWhite);
;*/

        INVOKE  InnerSearchRealizedLCTPalette,
                RGBWhite

        mov     RealizedWhiteIndex,eax
;/*
;**    RealizedBlackIndex = InnerSearchRealizedLCTPalette(RGBBlack);
;*/

        INVOKE  InnerSearchRealizedLCTPalette,
                RGBBlack

        mov     RealizedBlackIndex,eax
;/*
;**REALIZECOLTABLE_OK_EXIT:
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**    return(OK);
;*/

rct_exit_ok:
        mov     eax,OK
        jmp     rct_exit


;/*
;**REALIZECOLTABLE_ERR_EXIT:
;*/

rct_exit_error:

;/*
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**    return(ERROR_ZERO);
;*/

        mov     eax,ERROR_ZERO
rct_exit:
        INVOKE  leave_driver
rct_exit_no_lock:
        ret
eddc_RealizeColorTable ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_UnrealizeColorTable
;*
;* DESCRIPTION   =  UnrealizeColorTable reverses RealizeColorTable by causing
;*                  the default color table to be reinstated.
;*
;* INPUT         = hdc
;*                 hddc
;*                 FunN
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_UnrealizeColorTable PROC SYSCALL,
        hdc             :HDC,
        hddc            :PDDC,
        FunN            :ULONG

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,ERROR_ZERO
        jc      uct_exit_no_lock                 ;error logged

ifdef FIREWALLS
;/*
;** this test is firewalled since the 8514 driver claims that the
;** engine will have already done the test
;** If the function is being called within an area or path
;** definition then we raise an error and leave immediately.
;** We have been called within an area definition
;*/

        no_path_area    uct_exit_error,both
endif ;;/* FIREWALLS */

;/*
;**    ;/******************************************************************/
;**    ;/* Only execute the code if there is a realized color table       */
;**    ;/******************************************************************/
;**    if (ColorTableRealized)
;*/

        cmp     ColorTableRealized,0
        je      @F

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Since we are unrealizing a logical color table, we are     */
;**        ;/* basically stepping back into the 2.0 world of Palette      */
;**        ;/* Manager palettes, and (unrealizable) color tables.  Thus   */
;**        ;/* we simply restore the HWPalette contents in to the         */
;**        ;/* hardware.                                                  */
;**        ;/**************************************************************/
;**
;**        ;/**************************************************************/
;**        ;/* Unrealize it !                                             */
;**        ;/**************************************************************/
;**        ColorTableRealized = NULL;
;*/

                mov     ColorTableRealized,0
;/*
;**        LoadPaletteEntries(0,
;**                           SizeOfHWPalette,
;**                           HWPalette);
;*/

                INVOKE  LoadPaletteEntries,
                        0,
                        SizeOfHWPalette,
                        ADDR HWPalette
@@:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**    return(OK);
;*/

uct_exit_ok:
        mov     eax,OK
        jmp     uct_exit
;/*
;**UNREALIZECOLTABLE_ERR_EXIT:
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**    return(ERROR_ZERO);
;*/


uct_exit_error:

;/*
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**    return(ERROR_ZERO);
;*/

        mov     eax,ERROR_ZERO
uct_exit:
        INVOKE  leave_driver
uct_exit_no_lock:
        ret
eddc_UnrealizeColorTable ENDP

ifdef  IBMJ        ;IBMJ
_PaletteSupport ENDS
endif ;IBMJ        ;IBMJ
END
