;*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.;
;*****************************************************************************/

;/*****************************************************************************
;*
;* SOURCE FILE NAME = EDDCQERY
;*
;* DESCRIPTIVE NAME = Color Table Query functions
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION Provides information about current color
;*             status
;*
;*
;* FUNCTIONS   eddc_QueryRealColors
;*             eddc_QueryNearestColor
;*             eddc_QueryColorIndex
;*             eddc_QueryRGBColor
;*             save_lct
;*             deselect_lct
;*             OEMUpdateColors
;*             rgb_to_ipc
;*             ColorConvert
;*             ipc_to_index
;*             PropagateSysClrChange
;*
;* 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_46426
;*
;*****************************************************************************/

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

        .xlist

INCL_DDIMISC            equ                      1
INCL_GRE_BITMAPS        equ                      1
INCL_GPIBITMAPS         equ                      1
INCL_GPILOGCOLORTABLE   equ                      1
INCL_GRE_PALETTE        equ                      1
INCL_GRE_COLORTABLE     equ                      1
INCL_DEV                equ                      1
INCL_DDICOMFLAGS        equ                      1
INCL_WINPALETTE         equ                      1
INCL_WINSYS             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 assert.mac
        include palette.inc
        .list

QNC_ERROR       EQU     0ffffffffh      ;-1
QRC_ERROR       EQU     0ffffffffh      ;-1
ifndef IBMJ        ;IBMJ
.CODE
else  ;IBMJ        ;IBMJ
_PaletteSupport SEGMENT DWORD PUBLIC FLAT 'CODE'
endif ;IBMJ        ;IBMJ

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_QueryRealColors
;*
;* DESCRIPTION   = returns RGB values available on the current device.
;*
;* INPUT         = ArgOptions can specify:
;*                 LCOLOPT_REALIZED - the RGB values required are those available
;*                                    after the LCT has been realized.
;*                 LCOLOPT_INDEX    - the routine must return results in the form
;*                                    (index, RGB value). RGB values that are
;*                                    present on the device but have no logical
;*                                    index are given the special index
;*                                    CLR_NOINDEX.
;*                 ArgStart is the ordinal number of the first RGB value to be
;*                     returned. Note that this is NOT the logical index, and the
;*                     order in which the colors are returned is undefined. This
;*                     is therefore used as an index into the physical color
;*                     table.
;*                 ArgCount is the number of elements available in the results
;*                     array.
;*                 ArgArray is where the values are written to.
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_QueryRealColors PROC SYSCALL USES ESI EDI EBX,
        hdc             :HDC   ,
        ArgOptions      :ULONG ,
        ArgStart        :ULONG ,
        ArgCount        :ULONG ,
        ArgArray        :PULONG,
        hddc          :PDDC   ,
        FunN            :ULONG

LOCAL   ulLoop  :ULONG,         ;/* loop variable               */
        ulIndex :ULONG,         ;/* Index into return array     */
        ulRGB   :ULONG          ;/* value in RGB mode           */
;/*
;**    /******************************************************************/
;**    /* Get driver semaphore and perform entry checks                  */
;**    /******************************************************************/
;**    EnterDriver(hddc, FunN, EDF_STANDARD);
;*/

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,QNC_ERROR
        jc      qrc_exit_no_lock                 ;error logged
        mov     esi,edx
        mov     edx,[esi].ddc_pClrTbl
        ASSUME  esi:PDDC
;/*
;**    /******************************************************************/
;**    /* Check for an invalid start index.                              */
;**    /******************************************************************/
;**    if (ArgStart >= cPhysicalColors)
;*/

        mov     eax,PMERR_INV_COLOR_START_INDEX
        mov     ecx,ArgStart
        cmp     ecx,cPhysicalColors
        jae     qrc_exit_error
;/*
;**    {
;**        LOGERR(NULL, "Invalid start index", &ArgStart, 1,
;**                                          PMERR_INV_COLOR_START_INDEX);
;**        goto QRYREALCOLORS_ERR_EXIT;
;**    }
;**
;**    /******************************************************************/
;**    /* We don't specifically validate the count parameter.            */
;**    /* In theory at 16bpp we have 65536 valid items to return, and    */
;**    /* we basically return as much as we can.                         */
;**    /******************************************************************/
;**
;**    /******************************************************************/
;**    /* Check for illegal options. The only valid options are          */
;**    /* LCOLOPT_REALIZED and LCOLOPT_INDEX.                            */
;**    /******************************************************************/
;**    if ( ArgOptions & ~(ULONG)(LCOLOPT_REALIZED | LCOLOPT_INDEX) )
;*/

        mov     eax,PMERR_INV_COLOR_OPTIONS
        test    ArgOptions,NOT (LCOLOPT_REALIZED + LCOLOPT_INDEX)
        jnz     qrc_exit_error

;/*
;**    {
;**        /**************************************************************/
;**        /* At least one invalid option has been specified. Log an     */
;**        /* error and exit.                                            */
;**        /**************************************************************/
;**        LOGERR(NULL, "Invalid options", FNULL, 0,
;**                                               PMERR_INV_COLOR_OPTIONS);
;**        goto QRYREALCOLORS_ERR_EXIT;
;**    }
;**
;**    /******************************************************************/
;**    /* If we dont support realization, or the color table is not      */
;**    /* realizable then force the LCOLOPT_REALIZED option to be off.   */
;**    /******************************************************************/
;**    if ( !fRealizeSupported ||
;**         !(pdc->DCIColStatus & LCOL_REALIZABLE) )
;*/

        test    [esi].ddc_fbClrTbl,DDC_REALIZABLE
        jnz     @F

;/*
;**    {
;**        ArgOptions &= ~LCOLOPT_REALIZED;
;*/

        AND     ArgOptions,NOT LCOLOPT_REALIZED
@@:
;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Calculate Maximum count.                                       */
;**    /******************************************************************/
;**    if (ArgOptions & LCOLOPT_INDEX)
;*/

        test    ArgOptions,LCOLOPT_INDEX
        jz      @F

;/*
;**    {
;**        /**************************************************************/
;**        /* ArgCount must be even, as pairs of values are being        */
;**        /* returned.                                                  */
;**        /**************************************************************/
;**        ArgCount &= 0xFFFFFFFE;
;*/

        and     ArgCount,0FFFFFFFEh
@@:
;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Now enter a loop to pass back each item of data.               */
;**    /******************************************************************/
;**    for (ulLoop = ArgStart, ulIndex = 0;
;**         (ulLoop < cPhysicalColors) && (ulIndex < ArgCount);
;**         ulLoop++)
;*/

        mov     ecx,ArgArray
        mov     ebx,0           ;ulIndex
        mov     edi,ArgStart    ;ulLoop
loop_top:
        cmp     edi,cPhysicalColors
        jae     loop_exit
        cmp     ebx,ArgCount
        jae     loop_exit

;/*
;**    {
;**        /**********************************************************/
;**        /* We need the RGB value.                                 */
;**        /**********************************************************/
;**        if (DDT.BitCount == 16)
;**        {
;**            /**************************************************/
;**            /* 16bpp means we form the RGB value from the     */
;**            /* loop count.                                    */
;**            /**************************************************/
;**            ulRGB = ULONGFromRGB16(ulLoop);
;**        }
;**        else
;**        {
;**            /**********************************************************/
;**            /* If a color table is realized pick up the value from    */
;**            /* there, otherwise pick it up from the HWPalette table   */
;**            /* which all other situations use.                        */
;**            /*                                                        */
;**            /* This information may be out of date by the time an     */
;**            /* application gets to use it! (because palette manager   */
;**            /* and realizable color tables may get in and change the  */
;**            /* h/w palette).                                          */
;**            /**********************************************************/
;**            if (ColorTableRealized)
;*/

        cmp     ColorTableRealized,0
        je      else_1

;/*
;**            {
;**                ulRGB = URGB(RealizedLCTPalette[ulLoop]);
;*/

        mov     eax,RealizedLCTPalette[edi*4]
        jmp     endif_1

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

else_1:
;/*
;**            {
;**                ulRGB = URGB(HWPalette[ulLoop]);
;*/

        mov     eax,HWPalette[edi*4]

;/*
;**            }
;*/

endif_1:
        mov     ulRGB,eax

;/*
;**            ulRGB &= RGB_MASK;
;*/

        and     ulRGB,RGB_MASK

;/*
;**        }
;**        /**************************************************************/
;**        /* Check whether we need to return the index.                 */
;**        /**************************************************************/
;**        if (ArgOptions & LCOLOPT_INDEX)
;*/

        test    ArgOptions,LCOLOPT_INDEX
        je      endif_2

;/*
;**        {
;**            if (pdc->DCIColFormat == LCOLF_RGB)
;*/

        test    [esi].ddc_fbClrTbl,DDC_RGB_MODE
        jz      else_3

;/*
;**            {
;**                /******************************************************/
;**                /* Mode is RGB so there is no index -  write RGB      */
;**                /* value.                                             */
;**                /******************************************************/
;**                ArgArray[ulIndex++] = ulRGB;
;*/

        mov     eax,ulRGB
        mov     [ecx+ebx*4],eax
        inc     ebx

        jmp     endif_2

;/*
;**            }
;*/

else_3:
;/*
;**            else
;**            {
;**                /******************************************************/
;**                /* Mode is not RGB, so write logical index which      */
;**                /* gives the current physical index.                  */
;**                /******************************************************/
;**                ArgArray[ulIndex++] = PhyToLogIndex(ulLoop);
;*/

        INVOKE  PhyToLogIndex,
                hddc,
                edi

        mov     ecx,ArgArray

        mov     [ecx+ebx*4],eax
        inc     ebx
;/*
;**            }
;*/

endif_2:
;/*
;**        }
;**        /**************************************************************/
;**        /* Now we need to write the color value.                      */
;**        /**************************************************************/
;**        if ( (ArgOptions & LCOLOPT_REALIZED) &&
;**             (ulLoop <= pdc->DCIHighIndex) &&
;**             (pdc->DCIColorTable[ulLoop].PhyIndex != CLR_NOPHYINDEX))
;*/

        test    ArgOptions,LCOLOPT_REALIZED
        jz      else_4
        cmp     edi,[esi].ddc_ctMax
        ja      else_4
        .ERRNZ  COLORTABLETYPE-8
        cmp     [edx+edi*8].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        je      else_4

;/*
;**        {
;**            /**********************************************************/
;**            /* Return the RGB value that will be used when the LCT is */
;**            /* realized.                                              */
;**            /**********************************************************/
;**            ArgArray[ulIndex++] =
;**                    URGB(pdc->DCIColorTable[ulLoop].LogRGB) & RGB_MASK;
;*/

        mov     eax,[esi].ddc_pClrTbl
        mov     eax,[eax+edi*8].COLORTABLETYPE.LogRGB
        and     eax,RGB_MASK
        mov     [ecx+ebx*4],eax
        inc     ebx

        jmp     endif_4

;/*
;**        }
;*/

else_4:
;/*
;**        else
;**        {
;**            /**********************************************************/
;**            /* Return the RGB value used when the LCT has NOT been    */
;**            /* realized, or when the LCT has been realized and there  */
;**            /* is no valid entry. The value is returned from the      */
;**            /* default physical palette.                              */
;**            /**********************************************************/
;**            ArgArray[ulIndex++] = ulRGB;
;*/

        mov     eax,ulRGB
        mov     [ecx+ebx*4],eax
        inc     ebx
endif_4:
;/*
;**        }
;*/

        inc     edi
        jmp     loop_top
loop_exit:
        mov     eax,ebx
        jmp     qrc_exit

;/*
;**    }
;**
;**    /******************************************************************/
;**    /* Release driver semaphore                                       */
;**    /******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    /******************************************************************/
;**    /* Return the number of values written to the array               */
;**    /******************************************************************/
;**    return(ulIndex);
;**
;**
;**QRYREALCOLORS_ERR_EXIT:
;**    /******************************************************************/
;**    /* Release driver semaphore                                       */
;**    /******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    /******************************************************************/
;**    /* Return QRC_ERROR to indicate an error.                         */
;**    /******************************************************************/
;**    return(QRC_ERROR);
;*/

qrc_exit_error:
        mov     eax,QRC_ERROR
qrc_exit:
        INVOKE  leave_driver
qrc_exit_no_lock:
        ret
eddc_QueryRealColors ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = eddc_QueryNearestColor
;*
;* DESCRIPTION   = QueryNearestColor returns the nearest RGB color available
;*                 on the device to the specified RGB value.  Note that the
;*                 nearest RGB color is returned even if it is not available
;*                 using the current LCT.
;*
;*
;* INPUT         = ArgOptions can specify:
;*                 LCOLOPT_REALIZED - the RGB value required is that available
;*                                    after the LCT has been realized.
;*
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_QueryNearestColor PROC SYSCALL USES EBX ESI,
        hdc             :HDC  ,
        ArgOptions      :ULONG,
        ArgRGBColorIn   :ULONG,
        hddc            :PDDC  ,
        FunN            :ULONG


LOCAL   i           :ULONG,             ;/* loop variable               */
        RGBVal      :RGB2 ,             ;/* Stores current color        */
        PassedRGB   :RGB2 ,
        NearestRGB  :RGB2 ,             ;/* Stores nearest RGB          */
        Diff        :ULONG,             ;/* Stores color difference     */
        MinDiff     :ULONG              ;/* Stores minimum difference   */

;/*
;**    ;/******************************************************************/
;**    ;/* Get driver semaphore and perform entry checks                  */
;**    ;/******************************************************************/
;**    EnterDriver(hddc, FunN, EDF_STANDARD);
;*/

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,QNC_ERROR
        jc      qnc_exit_no_lock                 ;error logged
        mov     esi,edx
        ASSUME  esi:PDDC
;/*
;**    ;/******************************************************************/
;**    ;/* Check for illegal options. The only valid option is            */
;**    ;/* LCOLOPT_REALIZED.                                              */
;**    ;/******************************************************************/
;**    if ( ArgOptions & ~(LCOLOPT_REALIZED) )
;*/

        mov     eax,PMERR_INV_COLOR_OPTIONS
        test    ArgOptions,NOT LCOLOPT_REALIZED
        jnz     qnc_exit_error

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* At least one invalid option has been specified. Log an     */
;**        ;/* error and exit.                                            */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Invalid options", &ArgOptions, 1,
;**                                               PMERR_INV_COLOR_OPTIONS);
;**        goto QRYNEARESTCOLOR_ERR_EXIT;
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Check that the supplied RGB value is valid.                    */
;**    ;/******************************************************************/
;**    if (ArgRGBColorIn & 0xFF000000)
;*/

        mov     eax,PMERR_INV_RGBCOLOR
        test    ArgRGBColorIn,0FF000000h
        jnz     qnc_exit_error

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* The RGB value is invalid. Log an error and exit.           */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Invalid RGB color", &ArgRGBColor, 1,
;**                                                    PMERR_INV_RGBCOLOR);
;**        goto QRYNEARESTCOLOR_ERR_EXIT;
;**    }
;**
;**    ;/**************************************************************/
;**    ;/* Get the RGB we were given into an RGB2 structure.          */
;**    ;/**************************************************************/
;**    PassedRGB = *((PRGB2)&ArgRGBColorIn);
;*/

        mov     eax,ArgRGBColorIn
        mov     PassedRGB,eax

;/*
;**    ;/******************************************************************/
;**    ;/* Only process the LCOLOPT_REALIZED option if the color table    */
;**    ;/* is realizable, and the configuration supports realization.     */
;**    ;/******************************************************************/
;**    if ( fRealizeSupported                     &&
;**         (ArgOptions & LCOLOPT_REALIZED)       &&
;**         (pdc->DCIColStatus & LCOL_REALIZABLE) )
;*/

        test    ArgOptions,LCOLOPT_REALIZED
        jz      else_1
        test    [esi].ddc_fbClrTbl,DDC_REALIZABLE
        jz      else_1

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Return nearest color after LCT has been realized. Have to  */
;**        ;/* step through all the LCT entries comparing their RGB       */
;**        ;/* values with the given RGB value. The default color palette */
;**        ;/* supplies the RGB values for any invalid LCT entries.       */
;**        ;/**************************************************************/
;**
;**        ;/**************************************************************/
;**        ;/* Initialise MinDiff to be a jolly big number, bigger than   */
;**        ;/* any other MinDiff in the whole wide world.                 */
;**        ;/**************************************************************/
;**        MinDiff = 0xFFFFFFFFL;
;*/

        mov     MinDiff,0FFFFFFFFh
;/*
;**        ;/**************************************************************/
;**        ;/* Search through all entries in the color palette            */
;**        ;/**************************************************************/
;**        for (i = 0; i < SizeOfHWPalette; i++)
;*/

        mov     ecx,0
        mov     ebx,[esi].ddc_pClrTbl
top_loop1:
        cmp     ecx,SizeOfHWPalette
        jge     exit_loop1

;/*
;**        {
;**            if ( (i <= pdc->DCIHighIndex) &&
;**                 (pdc->DCIColorTable[i].PhyIndex != CLR_NOPHYINDEX))
;*/

        cmp     ecx,[esi].ddc_ctMax
        ja      else_3
        cmp     [ebx+ecx*8].COLORTABLETYPE.PhyIndex,CLR_NOPHYINDEX
        je      else_3

;/*
;**            {
;**                ;/******************************************************/
;**                ;/* Valid entry - use RGB entry in LCT                 */
;**                ;/******************************************************/
;**                RGBVal = pdc->DCIColorTable[i].LogRGB;
;*/

        mov     eax,[ebx+ecx*8].COLORTABLETYPE.LogRGB
        mov     RGBVal,eax
        jmp     endif_3

;/*
;**            }
;*/

else_3:
;/*
;**            else
;**            {
;**                ;/******************************************************/
;**                ;/* There is a gap in the color table, so pick up the  */
;**                ;/* value in the default 256 color palette.            */
;**                ;/* (this palette is always used in memory DC's)       */
;**                ;/******************************************************/
;**                RGBVal = MemoryDeviceDefaultPalette[i];
;*/

;PRK        mov     eax,MemoryDeviceDefaultPalette[ecx*4]
        mov     eax,MemoryDeviceDefaultPalette  ;PRK
        mov     eax,[eax+ecx*4]                 ;PRK
        mov     RGBVal,eax
endif_3:
;/*
;**            }
;**
;**            ;/**********************************************************/
;**            ;/* Calculate the difference between the two RGB values    */
;**            ;/**********************************************************/
;**            Diff = rgb2_diff(PassedRGB,RGBVal);
;*/

        push    ecx

        INVOKE  rgb2_diff,
                PassedRGB,
                RGBVal

        pop     ecx

        mov     Diff,eax

;/*
;**
;**            if (Diff == 0)
;*/

        cmp     eax,0
        jne     endif_4

;/*
;**            {
;**                ;/******************************************************/
;**                ;/* Exact match has been found - return RGB value      */
;**                ;/******************************************************/
;**                NearestRGB = RGBVal;
;*/

        mov     eax,RGBVal
        mov     NearestRGB,eax
        jmp     exit_loop1

;/*
;**                break;
;*/

endif_4:
;/*
;**            }
;**
;**            if (Diff < MinDiff)
;*/

        cmp     eax,MinDiff
        jae     endif_5

;/*
;**            {
;**                ;/******************************************************/
;**                ;/* This RGB value is the nearest to the desired RGB   */
;**                ;/* value so far. Store the difference and RGB value.  */
;**                ;/******************************************************/
;**                MinDiff = Diff;
;*/

        mov     MinDiff,eax

;/*
;**                NearestRGB = RGBVal;
;*/

        mov     eax,RGBVal
        mov     NearestRGB,eax
endif_5:
;/*
;**            }
;*/

        inc     ecx
        jmp     top_loop1
exit_loop1:
;/*
;**        }
;*/

        jmp     endif_1

;/*
;**    }
;**    else if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

else_1:
        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jz      else_2

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Use RGB values in current selected palette.                */
;**        ;/**************************************************************/
;**        NearestRGB = pdc->Palette->entries[NearestPaletteIndex(PassedRGB)].rgb;
;*/

        INVOKE  NearestPaletteIndex,
                esi,
                PassedRGB

        mov     ebx,[esi].ddc_npdevpal
        mov     eax,[ebx + eax * 8].DEVPAL.entries.rgb
        mov     NearestRGB,eax
;/*
;**        NearestRGB.fcOptions = 0;
;*/

        mov     NearestRGB.rgb2_fcOptions,0

        jmp     endif_1

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

else_2:
;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Use RGB values in the default color palette.               */
;**        ;/**************************************************************/
;**        NearestRGB = NearestDefaultPhysicalColor(PassedRGB);
;*/

        INVOKE  NearestDefaultPhysicalColor,
                esi,
                PassedRGB

        mov     NearestRGB,eax

endif_1:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(URGB(NearestRGB));
;**
;**
;*/

        mov     eax,NearestRGB
        jmp     qnc_exit

;/*
;**QRYNEARESTCOLOR_ERR_EXIT:
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(QNC_ERROR);
;**
;*/

qnc_exit_error:
        mov     eax,QNC_ERROR
qnc_exit:
        INVOKE  leave_driver
qnc_exit_no_lock:
        ret
eddc_QueryNearestColor ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = eddc_QueryColorIndex
;*
;* DESCRIPTION   = QueryColorIndex returns the index into the logical color
;*                 table which will generate the nearest color to
;*                 ArgRGBColor on the current device.  If the mode is RGB
;*                 then there is no LCT, so the RGB value is just returned.
;*
;* INPUT         = ArgOptions can specify:
;*                 LCOLOPT_REALIZED - the RGB values to be used are those
;*                                    available after the LCT has been realized.
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_QueryColorIndex PROC SYSCALL USES ESI,
        hdc             :HDC  ,
        ArgOptions      :ULONG,
        ArgRGBColor     :ULONG,
        hddc          :PDDC  ,
        FunN            :ULONG

LOCAL   ulLogIndex      :ULONG,    ;/* Logical index return value  */
        RGBValue        :RGB2

;/*
;**    ;/******************************************************************/
;**    ;/* Get driver semaphore and perform entry checks                  */
;**    ;/******************************************************************/
;**    EnterDriver(hddc, FunN, EDF_STANDARD);
;*/

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,QNC_ERROR
        jc      qci_exit_no_lock                 ;error logged
        mov     esi,edx
        ASSUME  esi:PDDC
;/*
;**    ;/******************************************************************/
;**    ;/* Check that the supplied RGB value is valid.                    */
;**    ;/******************************************************************/
;**    if (ArgRGBColor & 0xFF000000)
;*/

        mov     eax,PMERR_INV_RGBCOLOR
        test    ArgRGBColor,0FF000000h
        jnz     qci_exit_error

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* The RGB value is invalid. Log an error and exit.           */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Invalid options", &ArgRGBColor, 1,
;**                                                    PMERR_INV_RGBCOLOR);
;**        goto QRYCOLORINDEX_ERR_EXIT;
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Check for invalid options. The only valid option is            */
;**    ;/* LCOLOPT_REALIZED.                                              */
;**    ;/******************************************************************/
;**    if ( ArgOptions & ~(ULONG)(LCOLOPT_REALIZED) )
;*/

        mov     eax,PMERR_INV_COLOR_OPTIONS
        test    ArgOptions,NOT LCOLOPT_REALIZED
        jnz     qci_exit_error

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* At least one invalid option has been specified. Log an     */
;**        ;/* error and exit.                                            */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Invalid options", FNULL, 0,
;**                                               PMERR_INV_COLOR_OPTIONS);
;**        goto QRYCOLORINDEX_ERR_EXIT;
;**    }
;**
;**    if (pdc->DCIColFormat == LCOLF_RGB)
;*/

        mov     eax,ArgRGBColor
        test    [esi].ddc_fbClrTbl,DDC_RGB_MODE
        jz      not_rgb_mode

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Mode is RGB, so the return value is the RGB that was       */
;**        ;/* passed in.                                                 */
;**        ;/**************************************************************/
;**        ulLogIndex = ArgRGBColor;
;*/

        jmp     qci_exit_ok

;/*
;**    }
;**    else if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

not_rgb_mode:
        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jz      not_palette

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Mode is palette, so return the index of the nearest color  */
;**        ;/* in the palette.                                            */
;**        ;/**************************************************************/
;**        RGBValue   = *((PRGB2)&ArgRGBColor);
;*/


        mov     RGBValue,eax

;/*
;**        ulLogIndex = NearestPaletteIndex(RGBValue);
;*/

        INVOKE  NearestPaletteIndex,
                hddc,
                RGBValue

        jmp     qci_exit_ok

;/*
;**    }
;*/

not_palette:
;/*
;**    else
;**    {
;**        ;/**************************************************************/
;**        ;/* Mode is index. Search the LCT to find the nearest logical  */
;**        ;/* color.                                                     */
;**        ;/**************************************************************/
;**        RGBValue   = *((PRGB2)&ArgRGBColor);
;*/

        mov     RGBValue,eax

;/*
;**        ulLogIndex = NearestLogicalColor(ArgOptions,RGBValue);
;*/

        INVOKE  NearestLogicalColor,
                hddc,
                ArgOptions,
                RGBValue

;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(ulLogIndex);
;**
;**
;**QRYCOLORINDEX_ERR_EXIT:
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(QCI_ERROR);
;*/

qci_exit_ok:

        jmp     qci_exit
qci_exit_error:
        mov     eax,QRC_ERROR
qci_exit:
        INVOKE  leave_driver
qci_exit_no_lock:
        ret
eddc_QueryColorIndex ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = eddc_QueryRGBColor
;*
;* DESCRIPTION   = QueryRGBColor returns the actual RGB color that results
;*                 from using the specified color index on the display.
;*                 ArgColor may be an index into a logical color table or an
;*                 RGB value, according to the current index mode.  If the
;*                 index mode is RGB the nearest RGB color in the Physical
;*                 Color Table is returned, otherwise the RGB color (in the
;*                 Physical Color Table) which results from using the
;*                 specified logical index is returned.
;*
;*
;* INPUT         = ArgOptions can specify:
;*                 LCOLOPT_REALIZED - the RGB value required is that available
;*                                    after the LCT has been realized.
;*                 LCOLOPT_INDEX    - the routine must return the RGB color
;*                                    originally specified for this index,
;*                                    rather than the RGB value that actually
;*                                    results from drawing on the device.
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

eddc_QueryRGBColor PROC SYSCALL USES ESI,       ;          
        hdc             :HDC  ,
        ArgOptions      :ULONG,
        lLogIndex       :LONG ,
        hddc          :PDDC  ,
        FunN            :ULONG

;/*
;**    ;/******************************************************************/
;**    ;/* The action of this routine is very similar to the action of    */
;**    ;/* LogToPhyIndex, on which it is based.                           */
;**    ;/******************************************************************/
;*/

LOCAL   ulIndex :ULONG,
        ReqRGB  :RGB2

;/*
;**    ;/******************************************************************/
;**    ;/* Get driver semaphore and perform entry checks                  */
;**    ;/******************************************************************/
;**    EnterDriver(hddc, FunN, EDF_STANDARD);
;*/

        cld
        ddc?    hddc

        mov     edx,hddc
        INVOKE  enter_driver

        mov     eax,QNC_ERROR
        jc      qrc_exit_no_lock                 ;error logged
        mov     esi,edx
        ASSUME  esi:PDDC
;/*
;**    ;/******************************************************************/
;**    ;/* Check for illegal options. The only valid options are          */
;**    ;/* LCOLOPT_REALIZED and LCOLOPT_INDEX.                            */
;**    ;/******************************************************************/
;**    if ( ArgOptions & ~(ULONG)(LCOLOPT_REALIZED | LCOLOPT_INDEX) )
;*/

        mov     eax,PMERR_INV_COLOR_OPTIONS
        test    ArgOptions,NOT (LCOLOPT_REALIZED + LCOLOPT_INDEX)
        jnz     qrc_exit_error

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* At least one invalid option has been specified. Log an     */
;**        ;/* error and exit.                                            */
;**        ;/**************************************************************/
;**        LOGERR(NULL, "Invalid options", FNULL, 0,
;**                                               PMERR_INV_COLOR_OPTIONS);
;**        goto QRYRGBCOLOR_ERR_EXIT;
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* If the color table is not realizable then force the            */
;**    ;/* LCOLOPT_REALIZED option to be off.                             */
;**    ;/******************************************************************/
;**    if ( !(pdc->DCIColStatus & LCOL_REALIZABLE) )
;*/

        test    [esi].ddc_fbClrTbl,DDC_REALIZABLE
        jnz     @F

;/*
;**    {
;**        ArgOptions &= ~LCOLOPT_REALIZED;
;*/

        and     ArgOptions,NOT LCOLOPT_REALIZED
@@:
;/*
;**    }
;**
;**    ;/**************************************************************/
;**    ;/* Check for a system (negative) index                        */
;**    ;/**************************************************************/
;**    if ( lLogIndex < 0 )
;*/

        mov     eax,lLogIndex
        cmp     eax,0
        jge     is_positive

;/*
;**    {
;**        ;/**********************************************************/
;**        ;/* Index is negative - either a special colour or a       */
;**        ;/* system colour                                          */
;**        ;/**********************************************************/
;**        ;/**********************************************************/
;**        ;/* Negate LogIndex to get a positive index we can look    */
;**        ;/* it up in the table                                     */
;**        ;/**********************************************************/
;**        ulIndex = -lLogIndex;
;*/

        neg     eax

;/*
;**        if ( ulIndex < SPECIAL_COL_TAB_SIZE &&
;**             DirectSpecialColorTable[ulIndex].PhyIndex != CLR_NOPHYINDEX)
;*/

        cmp     eax,SPECIAL_COL_TAB_SIZE
        jae     invalid_negative_index
        cmp     DirectSpecialColorTable[eax*8].PhyIndex,CLR_NOPHYINDEX
        je      invalid_negative_index

;/*
;**        {
;**            ReqRGB   = DirectSpecialColorTable[ulIndex].LogRGB;
;*/

        mov     eax,DirectSpecialColorTable[eax*8].LogRGB
        mov     ReqRGB,eax
        jmp     end_else1

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

invalid_negative_index:
;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Invalid negative index                                 */
;**            ;/**********************************************************/
;**            LOGERR(NULL, "Invalid index", &lLogIndex, 1,
;**                                         PMERR_INV_COLOR_INDEX);
;**            goto QRYRGBCOLOR_ERR_EXIT;
;*/

        mov     eax,PMERR_INV_COLOR_INDEX
        jmp     qrc_exit_error

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

is_positive:
;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* Value was positive - a 'normal' logical colour.            */
;**        ;/**************************************************************/
;**        ;/**************************************************************/
;**        ;/* Find out what the current mode is.                         */
;**        ;/**************************************************************/
;**        if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jz      not_palette

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* we have a palette                                      */
;**            ;/**********************************************************/
;**            if (lLogIndex < (LONG)(pdc->Palette->usCountStored))
;** eax = lLogIndex
;*/

        mov     edx,[esi].ddc_npdevpal
        cmp     eax,[edx].DEVPAL.usCountStored
        jge     inv_pal_index

;/*
;**            {
;**                ;/******************************************************/
;**                ;/* This entry is valid so pick up the RGB from the    */
;**                ;/* palette.                                           */
;**                ;/******************************************************/
;**                ReqRGB = pdc->Palette->entries[lLogIndex].rgb;
;**                ReqRGB.fcOptions = 0;
;*/


        test    [edx].DEVPAL.entries[eax*8].rgb.rgb2_fcOptions,PC_EXPLICIT
        jnz     get_explicit

        mov     eax,[edx].DEVPAL.entries[eax*8].rgb
        and     eax,RGB_MASK
        mov     ReqRGB,eax
        jmp     end_else1

get_explicit:
        mov     eax,HWPalette[eax*sizeof RGB2]
        and     eax,RGB_MASK
        mov     ReqRGB,eax
        jmp     end_else1

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

inv_pal_index:
;/*
;**            {
;**                ;/******************************************************/
;**                ;/* The required index is outside the palette range    */
;**                ;/******************************************************/
;**                LOGERR(NULL, "Invalid index", &lLogIndex, 1,
;**                                             PMERR_INV_COLOR_INDEX);
;**                goto QRYRGBCOLOR_ERR_EXIT;
;*/

        mov     eax,PMERR_INV_COLOR_INDEX
        jmp     qrc_exit_error
;            }
;        }
;        else if (pdc->DCIColFormat != LCOLF_RGB)
not_palette:
        test    [esi].ddc_fbClrTbl,DDC_RGB_MODE
        jnz     its_rgb_mode

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Mode is index.                                         */
;**            ;/* Get the physical index directly from the LCT.          */
;**            ;/**********************************************************/
;**
;**            ;/**********************************************************/
;**            ;/* Index is positive                                      */
;**            ;/**********************************************************/
;**            if (lLogIndex <= (LONG)(pdc->DCIHighIndex))
;** eax = lLogIndex
;*/

        cmp     eax,[esi].ddc_ctMax
        jg      inv_log_index

;/*
;**            {
;**                ReqRGB   = pdc->DCIColorTable[lLogIndex].LogRGB;
;*/

        mov     edx,[esi].ddc_pClrTbl
        mov     eax,[edx+eax*8].COLORTABLETYPE.LogRGB
        mov     ReqRGB,eax
        jmp     end_else1

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

inv_log_index:
;/*
;**            {
;**                ;/******************************************************/
;**                ;/* Logical index is invalid.                          */
;**                ;/******************************************************/
;**                LOGERR(NULL, "Invalid index", &lLogIndex, 1,
;**                                             PMERR_INV_COLOR_INDEX);
;**                goto QRYRGBCOLOR_ERR_EXIT;
;*/

        mov     eax,PMERR_INV_COLOR_INDEX
        jmp     qrc_exit_error

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

its_rgb_mode:
;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Mode is RGB                                            */
;**            ;/**********************************************************/
;**            ReqRGB = *((PRGB2)&lLogIndex);
;*/

        mov     eax,lLogIndex
        mov     ReqRGB,eax

;/*
;**        }
;*/

end_else1:
;/*
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* now consider the options flags                                 */
;**    ;/******************************************************************/
;**    if (ArgOptions & LCOLOPT_INDEX)
;*/

        test    ArgOptions,LCOLOPT_INDEX
        jnz     qrc_exit_ok

;/*
;**    {
;**        ;/**************************************************************/
;**        ;/* We already have the RGB color originally specified         */
;**        ;/**************************************************************/
;**    }
;**    else
;**    {
;**        ;/**************************************************************/
;**        ;/* Find the nearest RGB actually supported                    */
;**        ;/**************************************************************/
;**        if (fRealizeSupported &&
;**            ArgOptions & LCOLOPT_REALIZED)
;**        cmp     fRealizeSupported,0
;**        jz      else_3
;*/

        test    ArgOptions,LCOLOPT_REALIZED
        jz      else_3

;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* We need the value when the color table is realized.    */
;**            ;/**********************************************************/
;**            ulIndex = NearestRealizableIndex(ReqRGB);
;*/

        INVOKE  NearestRealizableIndex,
                hddc,
                ReqRGB
        mov     ulIndex,eax

;/*
;**            ReqRGB = pdc->DCIColorTable[ulIndex].LogRGB;
;*/

        mov     edx,[esi].ddc_pClrTbl
        mov     eax,[edx+eax*8].COLORTABLETYPE.LogRGB
        mov     ReqRGB,eax
        jmp     qrc_exit_ok

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

else_3:
;/*
;**        {
;**            ;/**********************************************************/
;**            ;/* Use the nearest RGB in the default HW palette          */
;**            ;/**********************************************************/
;**            ReqRGB = NearestDefaultPhysicalColor(ReqRGB);
;*/

;/*
;**        }
;**    }
;**
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(URGB(ReqRGB));
;**
;**
;**QRYRGBCOLOR_ERR_EXIT:
;**    ;/******************************************************************/
;**    ;/* Release driver semaphore                                       */
;**    ;/******************************************************************/
;**    ExitDriver(hddc, FunN, EDF_STANDARD);
;**
;**    return(QRC_ERROR);
;*/

qrc_exit_ok:
        mov     eax,ReqRGB
        jmp     qrc_exit
qrc_exit_error:
        mov     eax,QRC_ERROR
qrc_exit:
        INVOKE  leave_driver
qrc_exit_no_lock:
        ret
eddc_QueryRGBColor ENDP

;/*
;** ENTRY:
;**  esi->DDC
;*/

save_lct PROC SYSCALL USES ESI EDI EBX

LOCAL   NewTable:PCOLORTABLE


;/*
;** If the color mode is not RGB then a logical color table will
;** be present and hence must be copied.
;*/

        ddc?    esi
        ASSUME  esi:PDDC

        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jz      @F
        mov     ebx,[esi].ddc_npdevpal
        assert  ebx,NE,0
        inc     [ebx].DEVPAL.cUsage
@@:

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

        test    [esi].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        jz      exit_ok

;/*
;**    {
;**        /**************************************************************/
;**        /* Allocate memory for logical color table                    */
;**        /**************************************************************/
;**        pdcSave->DCIColorTable =
;**            AllocateMemory( pdc->DCIColTabSize * sizeof(COLORTABLETYPE),
;**                            MT_COLORTABLE,
;**                            MO_PRIVATE );
;*/


        mov     eax,[esi].ddc_ctSize
        .ERRNZ  sizeof COLORTABLETYPE-8
        shl     eax,3

        LEA     ebx,NewTable
        INVOKE  private_alloc
        OR      ecx,ecx
        jnz     error_no_memory
        mov     edi,NewTable

;/*
;**
;**        if (pdcSave->DCIColorTable == NULL)
;**        {
;**            /**********************************************************/
;**            /* The allocation has failed.                             */
;**            /**********************************************************/
;**            goto SAVEDC_COLOR_EXIT;
;**        }
;**
;**        /**************************************************************/
;**        /* Initialise the color table                                 */
;**        /**************************************************************/
;**        memcpy (pdcSave->DCIColorTable,
;**                pdc->DCIColorTable,
;**                pdc->DCIColTabSize * sizeof(COLORTABLETYPE));
;*/

        mov     eax,[esi].ddc_pClrTbl   ;pold table
        mov     [esi].ddc_pClrTbl,edi   ;pnew table

        mov     ecx,[esi].ddc_ctSize
        .ERRNZ  sizeof COLORTABLETYPE-8
        add     ecx,ecx

        mov     esi,eax                 ;pold table

        rep     movsd
        jmp     exit_ok

error_no_memory:
        rip     text,<save_lct - no memory>
exit_ok:
        ret
save_lct ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = deselect_lct
;*
;* DESCRIPTION   = Frees a reference to a logical color table.  Decrements
;*                 the reference count and frees the memory if it hits zero.
;*
;*
;* INPUT         = ESI --> DDC
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

deselect_lct PROC SYSCALL USES EBX

        ddc?    ESI

;/*
;** Just return if there is no user color table.
;*/

        TEST    [ESI].ddc_fbClrTbl,DDC_LOG_CLR_TBL
        JZ      Deselect_LCT_done

;/*
;** Locate the table.
;*/

        MOV     ECX,[ESI].ddc_pClrTbl       ; EBX --> Color table

        INVOKE  private_free

;/*
;** Mark the flags to indicate there is no user table, since this might be part
;** of a ResetDC.
;*/


        AND     [ESI].ddc_fbClrTbl,not DDC_LOG_CLR_TBL
        MOV     [ESI].ddc_pClrTbl,0

Deselect_LCT_done:
        RET

deselect_lct ENDP

OEMUpdateColors PROC SYSCALL
        int 3
        ret
OEMUpdateColors ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = rgb_to_ipc
;*
;* DESCRIPTION   = Sets up the MyColor structure and calls
;*                 NearestDefaultPhysicalIndex
;*
;* INPUT         = EAX pointer to MyColor structure
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/
rgb_to_ipc PROC SYSCALL USES ECX EBX ESI
LOCAL MyColor:RGB2

        mov     MyColor,eax
        mov     MyColor.rgb2_bRed,dl
        mov     MyColor.rgb2_fcOptions,0
        INVOKE  NearestDefaultPhysicalIndex,
                pdcGlobal,
                MyColor


        ret
rgb_to_ipc ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = ColorConvert
;*
;* DESCRIPTION   = ColorConvert accepts a logical color and returns the
;*                 device dependent, physical representation of bits
;*                 necessary to display the color closest to the specified
;*                 color on the device.  This information will be used later
;*                 by other driver routines.
;*
;* INPUT         = ESI --> DDC
;*                 EAX  =  Logical color (special, index, or rgb)
;*                 CL   =  BA_CLR_DEF or BA_CLR_BACK_DEF from ba_fb
;*                           (only one may be set)
;*
;* OUTPUT        = EAX  = IPC
;*                 'S' clear
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = EAX = INVALID_IPC
;*                 'S' set
;*                 Error logged
;**************************************************************************/

ColorConvert PROC SYSCALL

        TEST    CL,BA_CLR_DEF or BA_CLR_BACK_DEF  ;@DMS
        JNZ     Have_a_def_color                                  ;@DMS

        INVOKE  LogToPhyIndex,  ;returns index or CLR_NOPHYINDEX
                esi,
                eax

        jmp     cconv_exit

Have_a_def_color:
        .ERRNZ  BA_CLR_DEF-00100000b
        .ERRNZ  BA_CLR_BACK_DEF-00010000b

        MOV     EAX,DEF_IPC_FORE_CLR                     ;@DMS
        TEST    CL,BA_CLR_DEF                                    ;@DMS
        JNZ     cconv_exit                                       ;@DMS
        MOV     EAX,DEF_IPC_BACK_CLR                     ;@DMS

cconv_exit:
        or      eax,eax
        ret

ColorConvert ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = ipc_to_index
;*
;* DESCRIPTION   = Converts an IPC to a valid color index.  Scans color
;*                 tables to find the index if needed.
;*
;*                 Registers modified:
;*                   ECX EDX
;*
;* INPUT         = EBX --> DDC
;*                 EAX  =  IPC
;*
;* OUTPUT        = EAX = Color index
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = EAX = CLR_NOINDEX if no index exists
;*
;**************************************************************************/

ipc_to_index PROC SYSCALL
        INVOKE  PhyToLogIndex,
                ebx,
                eax
        ret
ipc_to_index ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = PropagateSysClrChange
;*
;* DESCRIPTION   = Calls eddc_PropagateSysColorChanges.
;*
;* INPUT         = NONE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

PropagateSysClrChange PROC SYSCALL
        INVOKE  eddc_PropagateSysColorChanges,
                esi
        ret
PropagateSysClrChange ENDP
ifdef  IBMJ        ;IBMJ
_PaletteSupport ENDS
endif ;IBMJ        ;IBMJ
        END
