;*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 = EDDCCTAB
;*
;* DESCRIPTIVE NAME = Color Table functions
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  Create or alter a Logical Color Table.
;*              Load current logical colors into physical
;*              palette.
;*              Load default colors into physical palette.
;*
;*
;* FUNCTIONS    eddc_UpdateAttributes
;*              PropagateSysColorChanges
;*              eddc_PropagateSysColorChanges
;*              eddc_AlterSysColorTable
;*              eddc_ResetLogColorTable
;*              CreateLogColorTable
;*
;* 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
;*   03/03/93              62910  Set LogIndex correctly.
;*   03/08/93              62548  ResetLogColorTable() clearing too many flags.
;*   04/07/93                     Back out 62548. It hammered the default
;*                                palette.
;*   06/18/93              69006  Put 62548 back in.  The problem was that
;*                                we were dithering palette apps, giving the
;*                                appearance that the default palette was wrong.
;*
;*****************************************************************************/

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

        .xlist

INCL_DDIMISC            equ                      1
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

.CODE

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_UpdateAttributes
;*
;* DESCRIPTION   = updates the physical indices stored in the
;*                 attribute bundles to match the values in the LCT and the SCT.
;*
;* INPUT         = pddc    :PDDC
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_UpdateAttributes PROC SYSCALL USES ESI,
        pddc    :PDDC

LOCAL   PhyIndex        :ULONG    ;/* Physical index                   */

        mov     esi,pddc
        ddc?    esi
        ASSUME  esi:PDDC

;/*
;**    ;/******************************************************************/
;**    ;/* We can only update the physical indices if there is actually   */
;**    ;/* a bitmap selected into the dc.                                 */
;**    ;/* (Direct DCs always have a bitmap selected).                    */
;**    ;/******************************************************************/
;**    if (pdc->DCISelListEntry != NULL)
;*/

        cmp     [esi].ddc_npsd,INVALID_ADDRESS
        je      no_bitmap_selected

;/*
;**    {
;**        ;/******************************************************************/
;**        ;/* Character (text) attributes.                                   */
;**        ;/******************************************************************/
;**        PhyIndex = LogToPhyIndex(pdc->DCICurTxtAts.cbnd.lColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ca.ca_ba.ba_clr

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCICharColatts.ForeColor = PhyIndex;
;*/

                mov     [esi].ddc_ca.ca_ba.ba_ipc,ax
@@:
;/*
;**        }
;**
;**        PhyIndex = LogToPhyIndex(pdc->DCICurTxtAts.cbnd.lBackColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ca.ca_ba.ba_clrBack

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCICharColatts.BackColor = PhyIndex;
;*/

                mov     [esi].ddc_ca.ca_ba.ba_ipcBack,ax
@@:
;/*
;**        }
;**
;**        ;/******************************************************************/
;**       ;/* Line attributes.                                               */
;**        ;/******************************************************************/
;**        PhyIndex = LogToPhyIndex(pdc->DCICurLinAts.lbnd.lColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_la.la_ba.ba_clr

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCILineColatts.ForeColor = PhyIndex;
;*/

                mov     [esi].ddc_la.la_ba.ba_ipc,ax
@@:

;/*
;**        }
;**
;**        PhyIndex = LogToPhyIndex(pdc->DCICurLinAts.lbnd.lBackColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_la.la_ba.ba_clrBack

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCILineColatts.BackColor = PhyIndex;
;*/

                mov     [esi].ddc_la.la_ba.ba_ipcBack,ax
@@:
;/*
;**        }
;**
;**        ;/******************************************************************/
;**        ;/* Marker attributes.                                             */
;**        ;/******************************************************************/
;**        PhyIndex = LogToPhyIndex(pdc->DCICurMrkAts.mbnd.lColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ma.ma_ba.ba_clr

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCIMarkColatts.ForeColor = PhyIndex;
;*/

                mov     [esi].ddc_ma.ma_ba.ba_ipc,ax
@@:
;/*
;**        }
;**
;**        PhyIndex = LogToPhyIndex(pdc->DCICurMrkAts.mbnd.lBackColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ma.ma_ba.ba_clrBack
;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCIMarkColatts.BackColor = PhyIndex;
;*/

                mov     [esi].ddc_ma.ma_ba.ba_ipcBack,ax
@@:
;/*
;**        }
;**
;**        ;/******************************************************************/
;**        ;/* Pattern attributes.                                            */
;**        ;/******************************************************************/
;**        PhyIndex = LogToPhyIndex(pdc->DCICurPtnAts.abnd.lColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_pa.pa_ba.ba_clr

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCIPattColatts.ForeColor = PhyIndex;
;*/

                mov     [esi].ddc_pa.pa_ba.ba_ipc,ax
@@:
;/*
;**        }
;**
;**        PhyIndex = LogToPhyIndex(pdc->DCICurPtnAts.abnd.lBackColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_pa.pa_ba.ba_clrBack

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCIPattColatts.BackColor = PhyIndex;
;*/

                mov     [esi].ddc_pa.pa_ba.ba_ipcBack,ax
@@:
;/*
;**        }
;**
;**        ;/******************************************************************/
;**        ;/* Image attributes.                                              */
;**        ;/******************************************************************/
;**        PhyIndex = LogToPhyIndex(pdc->DCICurImgAts.ibnd.lColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ia.ia_ba.ba_clr

;/*
;**        if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**        {
;**            pdc->DCIImagColatts.ForeColor = PhyIndex;
;*/

                mov     [esi].ddc_ia.ia_ba.ba_ipc,ax
@@:
;/*
;**      }
;**
;**      PhyIndex = LogToPhyIndex(pdc->DCICurImgAts.ibnd.lBackColor);
;*/

        INVOKE  LogToPhyIndex,
                esi,
                [esi].ddc_ia.ia_ba.ba_clrBack

;/*
;**      if (PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,CLR_NOPHYINDEX
        je      @F

;/*
;**      {
;**          pdc->DCIImagColatts.BackColor = PhyIndex;
;*/

                mov     [esi].ddc_ia.ia_ba.ba_ipcBack,ax
@@:
;/*
;**      }
;*/

no_bitmap_selected:
;/*
;**  }
;*/

        ret
eddc_UpdateAttributes ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = PropagateSysColorChanges
;*                 eddc_PropagateSysColorChanges
;*
;* DESCRIPTION   = PropagateSysColorChanges is called by a DC when it
;*                 discovers that the system colors have changed.  The routine
;*                 updates the physical indices that are stored in the LCT and
;*                 all of the attribute bundles, because they may have been
;*                 invalidated by the system color change.
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

PropagateSysColorChanges PROC SYSCALL
        INVOKE  eddc_PropagateSysColorChanges,
                esi
        ret
PropagateSysColorChanges ENDP


eddc_PropagateSysColorChanges PROC SYSCALL USES ESI EBX,
        pddc    :PDDC

;/*
;**    ;/******************************************************************/
;**    ;/* Check whether the DC has a color table that needs updating.    */
;**    ;/******************************************************************/
;**    if (pdc->DCIColFormat == LCOLF_INDRGB ||
;**        pdc->DCIColFormat == LCOLF_DEFAULT)
;*/

        mov     esi,pddc
        ASSUME  esi:PDDC
        ddc?    esi

        mov     ebx,[esi].ddc_pClrTbl

        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jnz     has_color_table
        test    [esi].ddc_fbClrTbl,(DDC_LOG_CLR_TBL+DDC_PALETTE+DDC_RGB_MODE)
        jz      has_color_table
        jmp     no_color_table

;/*
;**    {
;*/

has_color_table:
;/*
;**        ;/**************************************************************/
;**        ;/* There is a color table.                                    */
;**        ;/* Check whether background and foreground have been defined. */
;**        ;/* If they have not, then copy the values from SYS_CLRWINDOW  */
;**        ;/* and SYS_CLRWINDOWTEXT respectively.                        */
;**        ;/**************************************************************/
;**        if (!pdc->DCIBackgndDefined)
;*/

        test    [esi].ddc_fbClrTbl,DDC_USER_CLR_0
        jz      endif_1

;/*
;**        {
;**            if (pdc->DCIDCType == OD_DIRECT)
;*/

        mov     edx,SYSCLR_WINDOW
        neg     edx
        test    [esi].ddc_fb,DDC_DEVICE
        jz      else_3

;/*
;**            {
;**                pdc->DCIColorTable[CLR_BACKGROUND] =
;**                              DirectSpecialColorTable[-(SYSCLR_WINDOW)];
;*/

                mov     eax,DirectSpecialColorTable[edx*8].LogRGB
                mov     [ebx+CLR_BACKGROUND*8].COLORTABLETYPE.LogRGB,eax

                mov     eax,DirectSpecialColorTable[edx*8].PhyIndex
                mov     [ebx+CLR_BACKGROUND*8].COLORTABLETYPE.PhyIndex,eax
                jmp     endif_3

;/*
;**            }
;*/

else_3:
;/*
;**            else
;**            {
;**                pdc->DCIColorTable[CLR_BACKGROUND] =
;**                              MemorySpecialColorTable[-(SYSCLR_WINDOW)];
;*/

                mov     eax,MemorySpecialColorTable[edx*8].LogRGB
                mov     [ebx+CLR_BACKGROUND*8].COLORTABLETYPE.LogRGB,eax

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

endif_1:
;/*
;**        }
;**
;**        if (!pdc->DCINeutralDefined)
;*/

        test    [esi].ddc_fbClrTbl,DDC_USER_CLR_7
        jz      endif_2

;/*
;**        {
;**            if (pdc->DCIDCType == OD_DIRECT)
;*/

        mov     edx,SYSCLR_WINDOWTEXT
        neg     edx
        test    [esi].ddc_fb,DDC_DEVICE
        jz      else_4

;/*
;**            {
;**                pdc->DCIColorTable[CLR_NEUTRAL] =
;**                          DirectSpecialColorTable[-(SYSCLR_WINDOWTEXT)];
;*/


                mov     eax,DirectSpecialColorTable[edx*8].LogRGB
                mov     [ebx+CLR_NEUTRAL*8].COLORTABLETYPE.LogRGB,eax

                mov     eax,DirectSpecialColorTable[edx*8].PhyIndex
                mov     [ebx+CLR_NEUTRAL*8].COLORTABLETYPE.PhyIndex,eax
                jmp     endif_4

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

else_4:
;/*
;**            {
;**                pdc->DCIColorTable[CLR_NEUTRAL] =
;**                          MemorySpecialColorTable[-(SYSCLR_WINDOWTEXT)];
;*/

                mov     eax,MemorySpecialColorTable[edx*8].LogRGB
                mov     [ebx+CLR_NEUTRAL*8].COLORTABLETYPE.LogRGB,eax

                mov     eax,MemorySpecialColorTable[edx*8].PhyIndex
                mov     [ebx+CLR_NEUTRAL*8].COLORTABLETYPE.PhyIndex,eax
endif_4:
;/*
;**            }
;*/

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

no_color_table:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Update all of the attribute bundles.                           */
;**    ;/******************************************************************/
;**    eddc_UpdateAttributes();
;*/

        INVOKE  eddc_UpdateAttributes,
                esi
;/*
;**    ;/******************************************************************/
;**    ;/* Update the count in pdc to indicate that the system colors  */
;**    ;/* have been propagated.                                          */
;**    ;/******************************************************************/
;**    pdc->DCISysColState = CurrentSysColState;
;*/

        mov     eax,ddcInit.ddc_iSysClr
        mov     [esi].ddc_iSysClr,eax
        ret
eddc_PropagateSysColorChanges ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_AlterSysColorTable
;*
;* DESCRIPTION   = AlterSysColorTable defines the entries in the System Color
;*                 Table (SCT).  The system color table is stored by the
;*                 driver in (part of) the SpecialColorTables.  There are
;*                 actually two versions of this table corresponding to
;*                 memory and direct DCs because the device default palette
;*                 used by direct DCs is not always the same as the device
;*                 default palette used by memory DCs (because HW slots are
;*                 allocated to palette manager palettes).
;*
;*                 This function is called by CreateLogColorTable when the
;*                 LCOL_SYSCOLORS bit in ulOptions is set.
;*
;*                 ulFormat can specify:
;*                 LCOLF_INDRGB     - The supplied data is an array of pairs,
;*                                    (logical index, RGB value)
;*                 LCOLF_CONSECRGB  - The supplied data is an array of RGB
;*                                    values which are the colors for the logical
;*                                    indices from lStart upwards.
;*
;*                 pData is where the input values are stored.
;*
;*                 ulCount is the number of elements supplied in pData. If the
;*                 mode is LCOLF_INDRGB then this must be even.
;*
;* INPUT         = pddc           :PDDC,
;*                 ulFormat       :ULONG,
;*                 lStart         :LONG,
;*                 ulCount        :ULONG,
;*                 pData          :PULONG
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_AlterSysColorTable PROC SYSCALL USES ESI EDI EBX,
        pddc           :PDDC,
        ulFormat       :ULONG,
        lStart         :LONG,
        ulCount        :ULONG,
        pData          :PULONG

LOCAL   LogIndex        :LONG,         ;/* Stores logical index        */
        i               :ULONG         ;/* Loop counter                */

;/*
;**
;**    if (ulFormat == LCOLF_CONSECRGB)
;*/

        cmp     ulFormat,LCOLF_CONSECRGB
        jne     not_consecrgb

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Format is LCOLF_CONSECRGB.                                 */
;**        ;/**************************************************************/
;**
;**        ;/**************************************************************/
;**        ;/* Check lStart is a valid value.                             */
;**        ;/* SYSCLR_HELPHILITE is the 'first' system color (negative    */
;**        ;/* number nearest to zero).                                   */
;**        ;/**************************************************************/
;**        if ((lStart > SYSCLR_HELPHILITE) ||
;**            (lStart <= (SYSCLR_HELPHILITE - SYSCLR_CSYSCOLORS) ) )
;*/

        mov     eax,PMERR_INV_COLOR_START_INDEX
        mov     ecx,lStart
        cmp     ecx,SYSCLR_HELPHILITE
        jg      asct_Error

        mov     edx,SYSCLR_HELPHILITE
        sub     edx,SYSCLR_CSYSCOLORS
        cmp     ecx,edx
        jle     asct_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Start index is invalid.                                */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid start index", &lStart, 1,
;**                                         PMERR_INV_COLOR_START_INDEX);
;**            return(ERROR_ZERO);
;**        }
;**
;**        if ( (lStart + ulCount - 1) > SYSCLR_HELPHILITE)
;*/

        mov     edx,ulCount
        add     edx,ecx
        dec     edx
        cmp     edx,SYSCLR_HELPHILITE
        jg      asct_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Count is invalid.                                      */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid count", &ulCount, 1,
;**                                             PMERR_INV_LENGTH_OR_COUNT);
;**            return(ERROR_ZERO);
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* Read values from pData                                     */
;**        ;/* The loop counts LogIndex down because what we were actually*/
;**        ;/* passed was a negative LogIndex to be counted up!           */
;**        ;/**************************************************************/
;**        for (i = 0, LogIndex = -lStart;
;**             i < ulCount;
;**             i++, LogIndex--)
;*/

        mov     ebx,pData
        mov     esi,ecx
        neg     esi     ;LogIndex
        mov     ecx,0   ;i
looptop_1:
        cmp     ecx,ulCount
        jae     endif_1

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Read logical RGB value.                                */
;**            ;/**********************************************************/
;**            DirectSpecialColorTable[LogIndex].LogRGB = ((PRGB2)pData)[i];
;*/

        mov     eax,DWORD PTR [ebx+ecx*4]
        mov     DirectSpecialColorTable[esi*8].LogRGB,eax
;/*
;**            MemorySpecialColorTable[LogIndex].LogRGB = ((PRGB2)pData)[i];
;*/

        mov     MemorySpecialColorTable[esi*8].LogRGB,eax

;/*
;** Calculate nearest physical indexes using the default
;** physical palettes for OD_MEMORY and OD_DIRECT DCs.
;*/

        push    ecx

;/*
;**            DirectSpecialColorTable[LogIndex].PhyIndex =
;**                        NearestDirectDefaultPhysicalIndex(
;**                              DirectSpecialColorTable[LogIndex].LogRGB);
;*/

        INVOKE  NearestDirectDefaultPhysicalIndex,
                DirectSpecialColorTable[esi*8].LogRGB

        mov     DirectSpecialColorTable[esi*8].PhyIndex,eax

;/*
;**
;**            MemorySpecialColorTable[LogIndex].PhyIndex =
;**                        NearestMemoryDefaultPhysicalIndex(
;**                              MemorySpecialColorTable[LogIndex].LogRGB);
;*/

        INVOKE  NearestMemoryDefaultPhysicalIndex,
                MemorySpecialColorTable[esi*8].LogRGB

        pop     ecx

        mov     MemorySpecialColorTable[esi*8].PhyIndex,eax

;/*
;**        }
;*/

        inc     ecx     ;i
        dec     esi     ;LogIndex
        jmp     looptop_1

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

not_consecrgb:

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Format is LCOLF_INDRGB.                                    */
;**        ;/**************************************************************/
;**        ;/**************************************************************/
;**        ;/* Check that ArgCount is even.                               */
;**        ;/**************************************************************/
;**        if (ulCount & 0x00000001)
;*/

        mov     eax,PMERR_INV_LENGTH_OR_COUNT
        mov     edi,ulCount
        shr     edi,1
        jc      asct_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* ArgCount is odd when it should be even.                */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid ArgCount", &ulCount, 1,
;**                                             PMERR_INV_LENGTH_OR_COUNT);
;**            return(ERROR_ZERO);
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* Divide ArgCount by two so that it contains the number      */
;**        ;/* of new RGB values being passed.                            */
;**        ;/**************************************************************/
;**        ulCount /= 2;
;**
;**        for (i = 0; i < ulCount; i++)
;*/

        mov     ecx,0           ;i
        mov     ebx,pData
looptop_2:
        cmp     ecx,edi         ;ulCount
        jae     loopexit_2
;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Read logical index.                                    */
;**            ;/**********************************************************/
;**            LogIndex = pData[i*2];
;*/

        mov     esi,DWORD PTR [ebx+ecx*8]

;/*
;**            if ((LogIndex > SYSCLR_HELPHILITE) ||
;**                (LogIndex <= (SYSCLR_HELPHILITE - SYSCLR_CSYSCOLORS)))
;*/

        mov     eax,PMERR_INV_COLOR_START_INDEX
        cmp     esi,SYSCLR_HELPHILITE
        jg      asct_Error
        cmp     esi,SYSCLR_HELPHILITE - SYSCLR_CSYSCOLORS
        jle     asct_Error
;/*
;**            {
;**                ;/******************************************************/
;**                ;/* System color index is invalid.                     */
;**                ;/******************************************************/
;**                LOGERR(NULL, "Invalid index", &LogIndex, 1,
;**                                           PMERR_INV_COLOR_START_INDEX);
;**                return(ERROR_ZERO);
;**            }
;**
;**            ;/**********************************************************/
;**            ;/* Negate the Logical index to get the SpecialColorTable  */
;**            ;/* index.                                                 */
;**            ;/**********************************************************/
;**            LogIndex = -LogIndex;
;*/

        neg     esi

;/*
;**
;**            ;/**********************************************************/
;**            ;/* Read logical RGB value.                                */
;**            ;/**********************************************************/
;**            DirectSpecialColorTable[LogIndex].LogRGB = ((PRGB2)pData)[i*2+1];
;*/

        mov     eax,DWORD PTR [ebx+ecx*8+4]
        mov     DirectSpecialColorTable[esi*8].LogRGB,eax

;/*
;**            MemorySpecialColorTable[LogIndex].LogRGB = ((PRGB2)pData)[i*2+1];
;*/

        mov     MemorySpecialColorTable[esi*8].LogRGB,eax

;/*
;**
;**            ;/**********************************************************/
;**            ;/* Calculate nearest physical indexes using the default   */
;**            ;/* physical palettes for OD_MEMORY and OD_DIRECT DCs.     */
;**            ;/**********************************************************/
;**            DirectSpecialColorTable[LogIndex].PhyIndex =
;**                        NearestDirectDefaultPhysicalIndex(
;**                              DirectSpecialColorTable[LogIndex].LogRGB);
;*/

        push    ecx
        INVOKE  NearestDirectDefaultPhysicalIndex,
                DirectSpecialColorTable[esi*8].LogRGB

        mov     DirectSpecialColorTable[esi*8].PhyIndex,eax

;/*
;**            MemorySpecialColorTable[LogIndex].PhyIndex =
;**                        NearestMemoryDefaultPhysicalIndex(
;**                              MemorySpecialColorTable[LogIndex].LogRGB);
;*/

        INVOKE  NearestDirectDefaultPhysicalIndex,
                MemorySpecialColorTable[esi*8].LogRGB
        pop     ecx

        mov     MemorySpecialColorTable[esi*8].PhyIndex,eax

;/*
;**        }
;*/

        inc     ecx
        jmp     looptop_2
loopexit_2:
endif_1:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Update the Default LCTs for OD_MEMORY and OD_DIRECT DCs so     */
;**    ;/* that entry 0 (CLR_BACKGROUND) and entry 7 (CLR_NEUTRAL) have   */
;**    ;/* the values of SYSCLR_WINDOW and SYSCLR_WINDOWTEXT              */
;**    ;/* respectively.  (Note: if we are at 8 bits per pel then palette */
;**    ;/* manager will be running so we must update all of the default   */
;**    ;/* logical color tables (corresponding to the five possible size  */
;**    ;/* of device default palette).  If we are not at 8 bits per pel   */
;**    ;/* then the default OD_DIRECT logical color table will be the     */
;**    ;/* same as the one for OD_MEMORY DCs.)                            */
;**    ;/******************************************************************/
;**    if (DDT.BitCount == 8)
;**    {
;*/

        mov     edx,SYSCLR_WINDOW
        neg     edx
        mov     eax,DirectSpecialColorTable[edx*8].LogRGB
        mov     edx,DirectSpecialColorTable[edx*8].PhyIndex

        mov     DefaultEightBppTable256[CLR_BACKGROUND*8].PhyIndex,edx
        mov     DefaultEightBppTable256[CLR_BACKGROUND*8].LogRGB,eax
        mov     DefaultEightBppTable128[CLR_BACKGROUND*8].PhyIndex,edx
        mov     DefaultEightBppTable128[CLR_BACKGROUND*8].LogRGB,eax
        mov     DefaultEightBppTable64[CLR_BACKGROUND*8].PhyIndex,edx
        mov     DefaultEightBppTable64[CLR_BACKGROUND*8].LogRGB,eax
        mov     DefaultEightBppTable32[CLR_BACKGROUND*8].PhyIndex,edx
        mov     DefaultEightBppTable32[CLR_BACKGROUND*8].LogRGB,eax
        mov     DefaultEightBppTable16[CLR_BACKGROUND*8].PhyIndex,edx
        mov     DefaultEightBppTable16[CLR_BACKGROUND*8].LogRGB,eax

        mov     edx,SYSCLR_WINDOWTEXT
        neg     edx
        mov     eax,DirectSpecialColorTable[edx*8].LogRGB
        mov     edx,DirectSpecialColorTable[edx*8].PhyIndex

        mov     DefaultEightBppTable256[CLR_NEUTRAL*8].PhyIndex,edx
        mov     DefaultEightBppTable256[CLR_NEUTRAL*8].LogRGB,eax
        mov     DefaultEightBppTable128[CLR_NEUTRAL*8].PhyIndex,edx
        mov     DefaultEightBppTable128[CLR_NEUTRAL*8].LogRGB,eax
        mov     DefaultEightBppTable64[CLR_NEUTRAL*8].PhyIndex,edx
        mov     DefaultEightBppTable64[CLR_NEUTRAL*8].LogRGB,eax
        mov     DefaultEightBppTable32[CLR_NEUTRAL*8].PhyIndex,edx
        mov     DefaultEightBppTable32[CLR_NEUTRAL*8].LogRGB,eax
        mov     DefaultEightBppTable16[CLR_NEUTRAL*8].PhyIndex,edx
        mov     DefaultEightBppTable16[CLR_NEUTRAL*8].LogRGB,eax
;/*
;**    }
;**
;**
;**    ;/******************************************************************/
;**    ;/* Update system color state.                                     */
;**    ;/* Each DC stores its own system color state. Whenever the driver */
;**    ;/* is entered, the DC's system color state is compared with the   */
;**    ;/* current global system color state. If they are different then  */
;**    ;/* the system colors have been altered and the DC has to go       */
;**    ;/* through all of its attribute bundles and update the physical   */
;**    ;/* indices that are stored there (because the system color change */
;**    ;/* may have altered them).                                        */
;**    ;/******************************************************************/
;**    CurrentSysColState++;
;*/

        inc     ddcInit.ddc_iSysClr
;/*
;**    ;/******************************************************************/
;**    ;/* Propagate the system color changes.                            */
;**    ;/******************************************************************/
;**    eddc_PropagateSysColorChanges();
;*/

        INVOKE  eddc_PropagateSysColorChanges,
                pddc

        jmp     asct_Ok

asct_Error:
        save_error_code
        xor     eax,eax
        jmp     asct_Exit
asct_Ok:
        mov     eax,1
asct_Exit:
        ret
eddc_AlterSysColorTable ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_ResetLogColorTable
;*
;* DESCRIPTION   = ResetLogColorTable resets the entries in the Logical Color
;*                 Table (LCT) to their default state.
;*
;* INPUT         = hddc :PDDC
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_ResetLogColorTable PROC SYSCALL USES ESI,
        hddc            :PDDC

        mov     esi,hddc
        ddc?    esi

;/*
;**    if (pdc->DCIColFormat == LCOLF_INDRGB)
;*/

        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jz      no_free

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* A color table currently exists so free its memory          */
;**        ;/**************************************************************/
;**        FreeMemory( pdc->DCIColorTable );
;*/

        mov     ecx,[esi].ddc_pClrTbl
        INVOKE  private_free
no_free:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Set the values in DCIData to their default values              */
;**    ;/******************************************************************/
;**    if (pdc->DCIDCType == OD_DIRECT)
;*/

        test    [esi].ddc_fb,DDC_DEVICE
        jz      not_direct

;/*
;**    {
;**        pdc->DCIColorTable = DefaultDirectLogicalColorTable;
;*/

        mov     eax,DefaultDirectLogicalColorTable
ifdef FIREWALLS
        or      eax,eax
        jnz     @F
        DebugMsg2       <ResetLog DefaultDirectLogicalColorTable = 0>
        int 3
@@:
endif
        mov     [esi].ddc_pClrTbl,eax

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

        mov     eax,DirectDeviceDefaultPalette
ifdef FIREWALLS
        or      eax,eax
        jnz     @F
        DebugMsg2       <ResetLog DirectDeviceDefaultPalette = 0>
        int 3
@@:
endif
        mov     [esi].ddc_pDefPal,eax
        jmp     done_pointers

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

not_direct:

;/*
;**    {
;**        pdc->DCIColorTable = DefaultMemoryLogicalColorTable;
;*/

        mov     eax,DefaultMemoryLogicalColorTable
ifdef FIREWALLS
        or      eax,eax
        jnz     @F
        DebugMsg2       <ResetLog DefaultMemoryLogicalColorTable = 0>
        int 3
@@:
endif
        mov     [esi].ddc_pClrTbl,eax

;/*
;**        pdc->DCIDeviceDefaultPalette = MemoryDeviceDefaultPalette;
;*/

        mov     eax,MemoryDeviceDefaultPalette
ifdef FIREWALLS
        or      eax,eax
        jnz     @F
        DebugMsg2       <ResetLog MemoryDeviceDefaultPalette = 0>
        int 3
@@:
endif
        mov     [esi].ddc_pDefPal,eax

;/*
;**    }
;*/

done_pointers:
;/*
;**    pdc->DCIColFormat      = LCOLF_DEFAULT;
;**    pdc->DCIColStatus      = 0;
;**    pdc->DCIBackgndDefined = FALSE;
;**    pdc->DCINeutralDefined = FALSE;
;*/

        ; RCW - Instead of clearing ALL the Color Table flags, simply clear the ones  ;           
        ;       specified above.                        ;           
        ;                                               ;           
;                   mov     [esi].ddc_fbClrTbl,0                    ;          
;        int     3 ;ekf
        and     [esi].ddc_fbClrTbl,NOT (DDC_RGB_MODE+DDC_LOG_CLR_TBL+DDC_USER_CLR_0+DDC_USER_CLR_7)

;/*
;**    pdc->DCIColTabSize     = DFLT_LOG_COL_TABLE_SIZE;
;**    pdc->DCILowIndex       = 0;
;**    pdc->DCIHighIndex      = DFLT_LOG_COL_TABLE_SIZE - 1;
;*/

        mov     eax,DFLT_LOG_COL_TABLE_SIZE
        mov     [esi].ddc_ctSize,eax
        mov     [esi].ddc_ctMin,0
        dec     eax
        mov     [esi].ddc_ctMax,eax
        ret
eddc_ResetLogColorTable ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = CreateLogColorTable
;*
;* DESCRIPTION   = CreateLogColorTable defines the entries in the Logical Color
;*                 Table (LCT).
;*
;* INPUT         = ArgOptions can specify:
;*                 LCOL_RESET       - the color table is reset to its default
;*                                    before processing the supplied values.
;*                                    If old mode was RGB then this option is
;*                                    forced.
;*                 LCOL_REALIZABLE  - indicates that the color table can be
;*                                    realized using RealizeColorTable. This
;*                                                                 affects the way in which the routine maps
;*                                    the logical color table onto the physical
;*                                    color table.
;*                 LCOL_PURECOLOR   - If set then only pure colors can be used
;*                                    i.e. dithering is not allowed.
;*
;*                 LCOL_SYSCOLORS   - The colors supplied are system colors
;*                                    i.e. the logical indices are negative and
;*                                    the colors must be updated in the global
;*                                    array SpecialColorTable.
;*
;*                 ArgFormat can specify:
;*                 LCOLF_INDRGB     - The supplied data is an array of pairs,
;*                                    (logical index, RGB value)
;*                 LCOLF_CONSECRGB  - The supplied data is an array of RGB values
;*                                    which are the colors for the logical
;*                                    indices from ArgStart upwards.
;*                 LCOLF_RGB        - Index mode is RGB, which does not use a
;*                                    color table
;*
;*                 ArgData is where the input values are stored.
;*
;*                 ArgCount is the number of elements supplied in ArgData. If
;*                 the mode is LCOLF_INDRGB then this must be even.
;*
;*
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

CreateLogColorTable PROC SYSCALL USES EBX EDI ESI,
        hdc          :HDC,
        flOptions    :ULONG,
        lFormat      :LONG,
        lStart       :LONG,
        cCount       :LONG,
        pData        :PLONG,
        pInstance    :PVOID,
        FunN         :ULONG

;/*
;** Local variables
;*/
        LOCAL   lSize    :ULONG,       ;/* Color Table Size             */
                LogIndex:ULONG,        ;/* Stores logical index         */
                i       :ULONG,        ;/* Loop counter                 */
                NewTable:PCOLORTABLE   ;/* Pointer to new color table   */

        LOCAL   plNewData:DWORD
        LOCAL   pClrTbl  :DWORD

;/*
;** Get driver semaphore and perform entry checks
;*/
        ddc?    pInstance
        CLD
        MOV     ESI,pInstance

        ASSUME  ESI:PDDC

        MOV     EDX,ESI
        INVOKE  enter_driver
        JC      CLCT_Exit_no_lock                ; EAX = 0 on error

ifdef PALMGR2
;/*
;**    ;/******************************************************************/
;**    ;/* this call cannot be used if there is a palette selected into   */
;**    ;/* this DC                                                        */
;**    ;/******************************************************************/
;**    if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

        mov     eax,PMERR_PALETTE_SELECTED
        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jnz     CLCT_Error

;/*
;**    {
;**        LOGERR(NULL, "palette error", 0L, 0 ,PMERR_PALETTE_SELECTED);
;**        goto CREATECOLTABLE_ERR_EXIT;
;**    }
;*/

endif ;/* PALMGR2 */

        no_path_area CLCT_Error,both,error
;/*
;**    if (lFormat == LCOLF_RGB)
;*/

        cmp     lFormat,LCOLF_RGB
        jne     end_rgb
;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* New mode is RGB                                            */
;**        ;/**************************************************************/
;**        ;/**************************************************************/
;**        ;/* Check options                                              */
;**        ;/**************************************************************/
;**        if (flOptions & LCOL_REALIZABLE)
;*/

        mov     eax,PMERR_INCOMPAT_COLOR_OPTIONS
        test    flOptions,LCOL_REALIZABLE
        jnz     CLCT_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Log an error and exit                                  */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid option", &flOptions, 1,
;**                                          PMERR_INCOMPAT_COLOR_OPTIONS);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;**        if (pdc->DCIColFormat == LCOLF_INDRGB)
;*/

        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jz      no_table

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* A color table currently exists so free its memory      */
;**            ;/**********************************************************/
;**            FreeMemory( pdc->DCIColorTable );
;*/

        mov     ecx,[esi].ddc_pClrTbl
        INVOKE  private_free
no_table:
;/*
;**        }
;**        pdc->DCIColFormat = (USHORT)LCOLF_RGB;
;*/

        mov      [esi].ddc_fbClrTbl,DDC_RGB_MODE

;/*
;**        pdc->DCIColStatus = (USHORT)flOptions;
;*/

        MOV     AL,[ESI].ddc_fbClrTbl
        ;AND     AL,not (DDC_DITHER or DDC_REALIZABLE)
        MOV     EBX,flOptions
        TEST    BL,LCOL_PURECOLOR
        JNZ     @F
        OR      AL,DDC_DITHER
@@:
        TEST    BL,LCOL_REALIZABLE
        JZ      @F
        OR      AL,DDC_REALIZABLE
@@:
        MOV     [ESI].ddc_fbClrTbl,AL

;/*
;**        pdc->DCIColTabSize = 0;
;*/

        mov     [esi].ddc_ctSize,0

;/*
;**        pdc->DCIHighIndex  = 0;
;*/

        mov     [esi].ddc_ctMax,0

;/*
;**
;**        goto CREATECOLTABLE_OK_EXIT;
;*/

        jmp     CLCT_Common_exit
end_rgb:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Check for an invalid lFormat                                 */
;**    ;/******************************************************************/
;**    if ( (lFormat != LCOLF_INDRGB) &&
;**         (lFormat != LCOLF_CONSECRGB) )
;*/

        cmp     lFormat,LCOLF_INDRGB
        je      format_valid
        cmp     lFormat,LCOLF_CONSECRGB
        je      format_valid

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Log an error and exit                                      */
;**        ;/**************************************************************/
;*/

        mov     eax,PMERR_INV_COLOR_FORMAT
        jmp     CLCT_Error

;/*
;**        LOGERR(NULL, "Invalid color format", &lFormat, 1,
;**                                                PMERR_INV_COLOR_FORMAT);
;**        goto CREATECOLTABLE_ERR_EXIT;
;*/

format_valid:
;/*
;**    }
;**
;**    if (flOptions & LCOL_SYSCOLORS)
;*/

        test    flOptions,LCOL_SYSCOLORS
        jz      not_syscolors

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Colors are system colors                                   */
;**        ;/**************************************************************/
;**        if (eddc_AlterSysColorTable(lFormat,
;**                                    lStart,
;**                                    cCount,
;**                                    pData))
;*/

        INVOKE  eddc_AlterSysColorTable,
                pInstance,
                lFormat,
                lStart,
                cCount,
                pData

        cmp     eax,0
        jne     CLCT_Exit_ok

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* The system colors were successfully updated so exit.   */
;**            ;/**********************************************************/
;**            goto CREATECOLTABLE_SYS_OK_EXIT;
;**        }
;**        else
;**        {
;**            ;/**********************************************************/
;**            ;/* An error occured during the system color update. An    */
;**            ;/* error will already have been logged so just exit.      */
;**            ;/**********************************************************/
;*/

        jmp     CLCT_Error

;/*
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;*/

not_syscolors:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* If current mode is LCOLF_RGB then force LCOL_RESET option.     */
;**    ;/******************************************************************/
;**    if (pdc->DCIColFormat == LCOLF_RGB)
;*/

        test    [esi].ddc_fbClrTbl,DDC_RGB_MODE
        jz      @F

;/*
;**    {
;**        flOptions |= LCOL_RESET;
;*/

        or      flOptions,LCOL_RESET
@@:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Check whether the LCT is being reset to the default.           */
;**    ;/******************************************************************/
;**    if ( (flOptions & LCOL_RESET) &&
;**         !(flOptions & LCOL_REALIZABLE) &&
;**         (cCount == 0) )
;*/

        test    flOptions,LCOL_RESET
        jz      no_reset
        test    flOptions,LCOL_REALIZABLE
        jnz     no_reset
        ;test    cCount,0
        cmp    cCount,0                 ; @DMS cmvc 51672
        jnz     no_reset

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Table will be the default.                                 */
;**        ;/**************************************************************/
;**        eddc_ResetLogColorTable();
;*/

        INVOKE  eddc_ResetLogColorTable,
                pInstance
;/*
;**        goto CREATECOLTABLE_OK_EXIT;
;*/

        jmp     CLCT_Common_exit
no_reset:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Initialise Size to the best value we know of so far...         */
;**    ;/******************************************************************/
;**    if (flOptions & LCOL_RESET)
;*/

        test    flOptions,LCOL_RESET
        jz      else_1

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Table is being reset so set size to that of default        */
;**        ;/* logical table.                                             */
;**        ;/**************************************************************/
;**        Size = DFLT_LOG_COL_TABLE_SIZE;
;*/

        mov     lSize,DFLT_LOG_COL_TABLE_SIZE
        jmp     @F                              ; @DMS

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

else_1:
;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Set size to the same as the current logical table          */
;**        ;/**************************************************************/
;**        Size = pdc->DCIColTabSize;
;*/
        mov     eax,[esi].ddc_ctSize
        mov     lSize,eax

;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Calculate size of new color table.                             */
;**    ;/******************************************************************/
;**    if (lFormat == LCOLF_CONSECRGB)
;*/

@@:                                     ;@DMS
        cmp     lFormat,LCOLF_CONSECRGB
        jne     else_2

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Format is LCOLF_CONSECRGB.                                 */
;**        ;/* Calculate size of color table given that the values passed */
;**        ;/* are all consecutive.                                       */
;**        ;/**************************************************************/
;**
;**        ;/**************************************************************/
;**        ;/* Check that start index is valid.                           */
;**        ;/**************************************************************/
;**        if (lStart > MaxLogColorIndex)
;*/

        mov     eax,PMERR_INV_COLOR_START_INDEX
        cmp     lStart,MaxLogColorIndex
        ja      CLCT_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Log an error and exit                                  */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid start index", &lStart, 1,
;**                                           PMERR_INV_COLOR_START_INDEX);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;**        ;/**************************************************************/
;**        ;/* Check that count is valid i.e. that it does not take us    */
;**        ;/* past the end of the color table.                           */
;**        ;/**************************************************************/
;**        if (lStart + cCount > (ULONG)(MaxLogColorIndex + 1))
;*/

        mov     eax,PMERR_INV_LENGTH_OR_COUNT
        mov     ecx,lStart
        add     ecx,cCount
        cmp     ecx,LOGICAL_COLOR_TABLE_SIZE
        ja      CLCT_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Log an error and exit                                  */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid count", &cCount, 1,
;**                                             PMERR_INV_LENGTH_OR_COUNT);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;**        ;/**************************************************************/
;**        ;/* Calculate the size                                         */
;**        ;/**************************************************************/
;**        Size = max( Size, (lStart + cCount) );
;*/

        cmp     lSize,ecx
        jg      @F
        mov     lSize,ecx
@@:
        jmp     endif_2

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

else_2:
;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Format is LCOLF_INDRGB.                                    */
;**        ;/* Calculate size of color table given that the indices of    */
;**        ;/* the RGB values are all individually specified.             */
;**        ;/**************************************************************/
;**
;**        ;/**************************************************************/
;**        ;/* Check cCount is even.                                    */
;**        ;/**************************************************************/
;**        if (cCount & 0x00000001)
;*/

        mov     eax,PMERR_INV_LENGTH_OR_COUNT
        mov     edx,cCount
        shr     edx,1
        mov     cCount,edx                                ;          
        jc      CLCT_Error

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* cCount is odd when it should be even.                */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid cCount", &cCount, 1,
;**                                             PMERR_INV_LENGTH_OR_COUNT);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* Divide cCount by two so that it contains the number of   */
;**        ;/* new RGB values being passed.                               */
;**        ;/**************************************************************/
;**        cCount /= 2;
;**
;**        ;/**************************************************************/
;**        ;/* Enter a loop which looks for the highest index being       */
;**        ;/* passed.                                                    */
;**        ;/**************************************************************/
;**        for (i = 0; i < cCount; i++)
;*/

        mov     edi,pData
        mov     ecx,0
loopstart_1:
        cmp     ecx,edx
        jae     loopexit_1

;/*
;**        {
;**            LogIndex = pData[i*2];
;*/

        mov     eax,DWORD PTR[edi+(ecx*8)]      ;get the index

;/*
;**            if (LogIndex >= Size)
;*/

        cmp     eax,lSize
        jb      @F

;/*
;**            {
;**                ;/******************************************************/
;**                ;/* Update Size. Size is set to (Index + 1) because    */
;**                ;/* the indices begin at zero                          */
;**                ;/******************************************************/
;**                Size = LogIndex + 1;
;*/

        inc     eax
        mov     lSize,eax
@@:
;/*
;**            }
;*/

        inc     ecx
        jmp     loopstart_1
loopexit_1:
;/*
;**        }
;**        ;/**************************************************************/
;**        ;/* Check that the maximum index is valid                      */
;**        ;/**************************************************************/
;**        if ( Size > (MaxLogColorIndex + 1) )
;*/

        mov     eax,PMERR_INV_LENGTH_OR_COUNT
        cmp     lSize,LOGICAL_COLOR_TABLE_SIZE
        ja      CLCT_Error

;/*
;**        {
;**            Size--;
;**
;**            LOGERR(NULL, "Invalid max index", &Size, 1,
;**                                             PMERR_INV_LENGTH_OR_COUNT);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;*/

endif_2:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Set NewTable to point to current table                         */
;**    ;/******************************************************************/
;**    NewTable = pdc->DCIColorTable;
;*/

        mov     eax,[esi].ddc_pClrTbl
        mov     NewTable,eax
;/*
;**    ;/******************************************************************/
;**    ;/* Check whether we need to acquire new storage.                  */
;**    ;/* New storage is fetched if the new table size is different to   */
;**    ;/* the current table size or if the current table is default (if  */
;**    ;/* we get this far the new table is not going to be the default). */
;**    ;/******************************************************************/
;**    if ( (Size != pdc->DCIColTabSize) ||
;**         (pdc->DCIColFormat == LCOLF_DEFAULT) )
;*/

        mov     eax,[esi].ddc_ctSize
        cmp     lSize,eax
        jne     get_new_storage
        test    [esi].ddc_fbClrTbl,(DDC_PALETTE+DDC_RGB_MODE+DDC_LOG_CLR_TBL)
        mov     edi,NewTable
        jnz     no_new_storage
get_new_storage:
;/*
;**    {
;**        NewTable = AllocateMemory( Size * sizeof(COLORTABLETYPE),
;**                                   MT_COLORTABLE,
;**                                   MO_SHARED );
;*/

        mov     eax,lSize
        shl     eax,3
        .ERRNZ  sizeof COLORTABLETYPE - 8
        LEA     ebx,NewTable
        INVOKE  private_alloc
        OR      ecx,ecx
        jnz     CLCT_Error_no_memory
        mov     edi,NewTable

;/*
;**        assert  NewTable,NE,0
;**        if (NewTable == NULL)
;**        {
;**            LOGERR(NULL, "No memory for colour table", NULL, 0,
;**                                             PMERR_INSUFFICIENT_MEMORY);
;**            goto CREATECOLTABLE_ERR_EXIT;
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* Set logical RGB values to the special value CLR_NOINDEX.   */
;**        ;/* (This is the value we must return to QueryLogColorTable).  */
;**        ;/*                                                            */
;**        ;/* For internal checks within the driver we check the         */
;**        ;/* PhyIndex field, so mark all these with CLR_NOPHYINDEX.     */
;**        ;/*                                                            */
;**        ;/* We only have to fill from index 16 upwards as indices 0-15 */
;**        ;/* always have defined values (due to the default color       */
;**        ;/* table).                                                    */
;**        ;/**************************************************************/
;**        for (i = DFLT_LOG_COL_TABLE_SIZE; i < Size; i++)
;*/

        mov     ecx,DFLT_LOG_COL_TABLE_SIZE
loopstart_2:
        cmp     ecx,lSize
        jae     loopdone_2

;/*
;**        {
;**            *(PULONG)(&NewTable[i].LogRGB) = CLR_NOINDEX;
;*/

        .ERRNZ  sizeof COLORTABLETYPE - 8
        mov     [edi+(ecx*8)].COLORTABLETYPE.LogRGB,CLR_NOINDEX

;/*
;**            NewTable[i].PhyIndex           = CLR_NOPHYINDEX;
;*/

        mov     [edi+(ecx*8)].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        inc     ecx
        jmp     loopstart_2
loopdone_2:
;/*
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* Copy old logical color table to new if required (if table  */
;**        ;/* is not being reset).                                       */
;**        ;/*                                                            */
;**        ;/* We only copy the RGB value because we always recalculate   */
;**        ;/* physical indices (because the realizable state may have    */
;**        ;/* changed).                                                  */
;**        ;/**************************************************************/
;**        if ( !(flOptions & LCOL_RESET) )
;**        assert  edi,E,NewTable
;**        assert  NewTable,NE,0
;*/


        test    flOptions,LCOL_RESET
        jnz     no_reset2

;/*
;**        {
;**            for (i = 0;
;**                 (i < pdc->DCIColTabSize) && (i < Size);
;**                 i++)
;*/

        mov     edx,[esi].ddc_ctSize
        mov     ecx,0
        mov     ebx,[esi].ddc_pClrTbl
looptop_3:
        cmp     ecx,edx
        jae     loopexit_3
        cmp     ecx,lSize
        jae     loopexit_3

;/*
;**            {
;**                NewTable[i].LogRGB = pdc->DCIColorTable[i].LogRGB;
;*/

        .errnz  sizeof COLORTABLETYPE - 8

        mov     eax,[ebx+ecx*8].COLORTABLETYPE.LogRGB
        mov     [edi+ecx*8].COLORTABLETYPE.LogRGB,eax

;/*
;**                ;/******************************************************/
;**                ;/* Make sure that this value is not thought to be     */
;**                ;/* invalid by making the PhyIndex 0 (any value which  */
;**                ;/* is not CLR_NOPHYINDEX would do!).  The true        */
;**                ;/* PhyIndex will be calculated later.                 */
;**                ;/******************************************************/
;**                NewTable[i].PhyIndex = 0;
;*/

        mov     [edi+ecx*8].COLORTABLETYPE.PhyIndex,0
        inc     ecx
        jmp     looptop_3
loopexit_3:
;/*
;**            }
;*/

no_reset2:
;/*
;**        }
;**
;**        ;/**************************************************************/
;**        ;/* If a table had previously been established then free       */
;**        ;/* its memory.                                                */
;**        ;/**************************************************************/
;**        if (pdc->DCIColFormat == LCOLF_INDRGB)
;*/

        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jz      no_free
;/*
;**        {
;**            FreeMemory( pdc->DCIColorTable );
;*/

        mov     ecx,[esi].ddc_pClrTbl
        INVOKE  private_free
no_free:
;/*
;**        }
;*/

no_new_storage:
;/*
;**        assert  edi,E,NewTable
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* If table is being reset                                        */
;**    ;/******************************************************************/
;**    if (flOptions & LCOL_RESET)
;*/

        test    flOptions,LCOL_RESET
        jz      no_reset4

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Copy default color table across                            */
;**        ;/**************************************************************/
;**        for (i = 0; i < DFLT_LOG_COL_TABLE_SIZE; i++)
;*/

        mov     ecx,0
looptop_4:
        cmp     ecx,DFLT_LOG_COL_TABLE_SIZE
        jae     loopexit_4

;/*
;**        {
;**            NewTable[i].LogRGB = DefaultDirectLogicalColorTable[i].LogRGB;
;*/

        .errnz  sizeof COLORTABLETYPE - 8
        mov     eax,DefaultDirectLogicalColorTable
        mov     eax,[eax+ecx*8].COLORTABLETYPE.LogRGB
        mov     [edi+ecx*8].COLORTABLETYPE.LogRGB,eax
;/*
;**            ;/******************************************************/
;**            ;/* Make sure that this value is not thought to be     */
;**            ;/* invalid by making the PhyIndex 0 (any value which  */
;**            ;/* is not CLR_NOPHYINDEX would do!).  The true        */
;**            ;/* PhyIndex will be calculated later.                 */
;**            ;/******************************************************/
;**            NewTable[i].PhyIndex = 0;
;*/

        mov     [edi+ecx*8].COLORTABLETYPE.PhyIndex,0

        inc     ecx
        jmp     looptop_4
loopexit_4:
;/*
;**        }
;**        ;/**************************************************************/
;**        ;/* Reset flags to say that application has not defined        */
;**        ;/* CLR_BACKGROUND and CLR_NEUTRAL.                            */
;**        ;/**************************************************************/
;**        pdc->DCIBackgndDefined = FALSE;
;*/

        and     [esi].ddc_fbClrTbl,NOT DDC_USER_CLR_0

;/*
;**        pdc->DCINeutralDefined = FALSE;
;*/

        and     [esi].ddc_fbClrTbl,NOT DDC_USER_CLR_7
no_reset4:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Update format.                                                 */
;**    ;/* Format will always be LCOLF_INDRGB by this stage.              */
;**    ;/******************************************************************/
;**    pdc->DCIColFormat = LCOLF_INDRGB;
;*/

        ;or      [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL     ;@DMS
        mov     [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL      ;@DMS

;/*
;**
;**    ;/******************************************************************/
;**    ;/* Update HighIndex to new value.                                 */
;**    ;/******************************************************************/
;**    pdc->DCIHighIndex = (USHORT)(Size - 1);
;*/

        mov     eax,lSize
        dec     eax
        mov     [esi].ddc_ctMax,eax
;/*
;**    ;/******************************************************************/
;**    ;/* Write new values into table.                                   */
;**    ;/******************************************************************/
;**    for (i = 0; i < cCount; i++)
;*/

        mov     ebx,pData

;/*
;**        assert  edi,E,NewTable
;**        assert  NewTable,NE,0
;**        assert  ebx,E,pData
;*/


        mov     ecx,0
looptop_5:
        cmp     ecx,cCount
        jae     loopexit_5

;/*
;**    {
;**        if (lFormat == LCOLF_INDRGB)
;*/

        cmp     lFormat,LCOLF_INDRGB
        jne     else_5

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Read index from pData                                */
;**            ;/**********************************************************/
;**            LogIndex = pData[i*2];
;*/

        mov     edx,DWORD PTR [ebx+ecx*8]
        mov     LogIndex,edx                    ;          

;/*
;**            NewTable[LogIndex].LogRGB = ((PRGB2)pData)[i*2+1];
;*/

        mov     eax,DWORD PTR [ebx+ecx*8+4]
        mov     [edi+edx*8].COLORTABLETYPE.LogRGB,eax

;/*
;**            ;/******************************************************/
;**            ;/* Make sure that this value is not thought to be     */
;**            ;/* invalid by making the PhyIndex 0 (any value which  */
;**            ;/* is not CLR_NOPHYINDEX would do!).  The true        */
;**            ;/* PhyIndex will be calculated later.                 */
;**            ;/******************************************************/
;**            NewTable[LogIndex].PhyIndex = 0;
;*/

        mov     [edi+edx*8].COLORTABLETYPE.PhyIndex,0

;/*
;**
;**            if (LogIndex == CLR_BACKGROUND)
;*/

        cmp     LogIndex,CLR_BACKGROUND
        jne     else_6

;/*
;**            {
;**                pdc->DCIBackgndDefined = TRUE;
;*/

        or      [esi].ddc_fbClrTbl,DDC_USER_CLR_0
        jmp     endif_6

;/*
;**            }
;**            else if (LogIndex == CLR_NEUTRAL)
;*/

        cmp     LogIndex,CLR_NEUTRAL
        jne     endif_6
else_6:
;/*
;**            {
;**                pdc->DCINeutralDefined = TRUE;
;*/

        or      [esi].ddc_fbClrTbl,DDC_USER_CLR_7
endif_6:
        jmp     endif_7

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

else_5:
;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Calculate index directly from loop count               */
;**            ;/**********************************************************/
;**            NewTable[lStart+i].LogRGB = ((PRGB2)pData)[i];
;*/

;/*
;** ecx = i
;** ebx = pData
;** edi = NewTable
;**
;**        assert  edi,E,NewTable
;**        assert  NewTable,NE,0
;**        assert  ebx,E,pData
;*/

        mov     eax,DWORD PTR [ebx+ecx*4]
        mov     edx,lStart      ; 
        add     edx,ecx         ; 
        mov     [edi+edx*8].COLORTABLETYPE.LogRGB,eax
;/*
;**            ;/******************************************************/
;**            ;/* Make sure that this value is not thought to be     */
;**            ;/* invalid by making the PhyIndex 0 (any value which  */
;**            ;/* is not CLR_NOPHYINDEX would do!).  The true        */
;**            ;/* PhyIndex will be calculated later.                 */
;**            ;/******************************************************/
;**            NewTable[lStart+i].PhyIndex = 0;
;*/

        mov     [edi+edx*8].COLORTABLETYPE.PhyIndex,0

;/*
;**            if (lStart+i == CLR_BACKGROUND)
;*/

        cmp     edx,CLR_BACKGROUND
        jne     else_7

;/*
;**            {
;**                pdc->DCIBackgndDefined = TRUE;
;*/

                or      [esi].ddc_fbClrTbl,DDC_USER_CLR_0
                jmp     endif_7

;/*
;**            }
;**            else if (lStart+i == CLR_NEUTRAL)
;*/

else_7:
        cmp     edx,CLR_NEUTRAL
        jne     endif_7

;/*
;**            {
;**                pdc->DCINeutralDefined = TRUE;
;*/

                or      [esi].ddc_fbClrTbl,DDC_USER_CLR_7
endif_7:
;/*
;**            }
;**        }
;*/

        inc     ecx
        jmp     looptop_5
loopexit_5:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Include new table in DC instance data                          */
;**    ;/******************************************************************/
;**    pdc->DCIColorTable = NewTable;
;*/

        mov     eax,NewTable
        mov     [esi].ddc_pClrTbl,eax

;/*
;**    pdc->DCIColTabSize = (USHORT)Size;
;*/

        mov     eax,lSize
        mov     [esi].ddc_ctSize,eax
;/*
;**    pdc->DCIColStatus  = (USHORT)flOptions;
;*/

        MOV     AL,[ESI].ddc_fbClrTbl
        AND     AL,not (DDC_DITHER or DDC_REALIZABLE)
        MOV     EBX,flOptions
        TEST    BL,LCOL_PURECOLOR
        JNZ     @F
        OR      AL,DDC_DITHER
@@:
        TEST    BL,LCOL_REALIZABLE
        JZ      @F
        OR      AL,DDC_REALIZABLE
@@:
        MOV     [ESI].ddc_fbClrTbl,AL

;/*
;**    ;/******************************************************************/
;**    ;/* Calculate physical indices                                     */
;**    ;/******************************************************************/
;**    CalculateColorTablePhysicalIndices();
;**        assert  esi,E,pInstance
;*/

        ddc?    esi

        INVOKE  CalculateColorTablePhysicalIndices,
                esi

CLCT_Common_exit:
        INVOKE  eddc_UpdateAttributes,
                esi

        OR      [ESI].ddc_ca.ca_ba.ba_fb,BA_CLR_INVALID or BA_CLR_BACK_INV or BA_REREALIZE
        OR      [ESI].ddc_pa.pa_ba.ba_fb,BA_CLR_INVALID or BA_CLR_BACK_INV or BA_REREALIZE
        OR      [ESI].ddc_la.la_ba.ba_fb,BA_CLR_INVALID or BA_CLR_BACK_INV or BA_REREALIZE
        OR      [ESI].ddc_ia.ia_ba.ba_fb,BA_CLR_INVALID or BA_CLR_BACK_INV or BA_REREALIZE
        OR      [ESI].ddc_ma.ma_ba.ba_fb,BA_CLR_INVALID or BA_CLR_BACK_INV or BA_REREALIZE

;/*
;** Caching causes a problem in that if the new IPCs match the old, and nothing
;** else changed, we won't pick up on the dithering flag changing.  We will
;** force a re-realization by indicating that the codepoint or font changed.
;*/

        jmp     CLCT_Exit_ok
CLCT_Error_no_memory:
        mov     eax,PMERR_INSUFFICIENT_MEMORY
CLCT_Error:
        save_error_code
        XOR     EAX,EAX
        JMP     CLCT_Exit
CLCT_Exit_ok:
        MOV     EAX,1

CLCT_Exit:
        INVOKE  leave_driver

CLCT_Exit_no_lock:

        RET
CreateLogColorTable ENDP
        END
