wpi_os2.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,017 行 · 第 1/5 页

C
2,017
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WPI library core (OS/2 version).
*
****************************************************************************/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define INCL_PM
#define INCL_DOSPROCESS
#define INCL_SPL
#define INCL_SPLFSE
#define INCL_SPLDOSPRINT
#define INCL_BASE
#define INCL_DOSSEMAPHORES
#define INCL_DOSMISC
#define INCL_DOSDEVICES
#include <os2.h>
#include "wpi.h"

#define PATBRUSHID 200   /* This is the constant id for pattern brushes */
static char sys_font_facename[] = "System Proportional";
static BOOL GotSysFont = FALSE;
static FATTRS SysFont;
#define NUM_SYS_FONTS 5
#define IDEAL_SYSFONT_HEIGHT 10
static int SysFontHeight = 0;
static int SysFontWidth = 0;

        /*---------------------------------------------------------
         * The following functions are static.
         *---------------------------------------------------------*/
static HWND _wpi_getscrollhwnd( HWND parent, int scroll )
{
    HWND        scroll_bar;

    if( parent == (HWND)NULL ) {
        return( (HWND)NULL );
    }

    if( scroll == SB_HORZ ) {
        scroll_bar = WinWindowFromID( parent, FID_HORZSCROLL );
    } else {
        scroll_bar = WinWindowFromID( parent, FID_VERTSCROLL );
    }

    return( scroll_bar );
}

static BOOL _wpi_setmenuitemattr( HMENU hmenu, unsigned id,
                                  unsigned mask, unsigned attr )
{
    return( (BOOL) WinSendMsg( hmenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),
                               MPFROM2SHORT(mask,attr) ) );
}

void _wpi_menutext2win( char *text )
{
    if( text ) {
        while( *text ) {
            if( *text == '~' ) {
                *text = '&';
            }
            text++;
        }
    }
}

#if 0
static unsigned _wpi_getmenuitemposfromid( HMENU hmenu, unsigned id )
{
    MRESULT     result;

    result = WinSendMsg( hmenu, MM_ITEMPOSITIONFROMID,
                         MPFROM2SHORT(id, TRUE), NULL );
    if( result != MIT_NONE ) {
        return( (unsigned)result );
    }
    return( -1 );
}
#endif

static unsigned _wpi_getmenuitemidfrompos( HMENU hmenu, unsigned pos )
{
    MRESULT     result;

    result = WinSendMsg( hmenu, MM_ITEMIDFROMPOSITION, (WPI_PARAM1)pos, NULL );
    if( result != (MRESULT)MIT_ERROR ) {
        return( (unsigned)result );
    }
    return( -1 );
}

static BOOL _wpi_getmenuparentoffset( HMENU hmenu, unsigned id,
                                      HMENU *parent, unsigned *offset )
{
    int         num;
    int         i;
    unsigned    item_id;
    MENUITEM    mi;
    WPI_MRESULT result;

    if( hmenu == NULLHANDLE ) {
        return( FALSE );
    }

    num = (int) _wpi_getmenuitemcount( hmenu );
    for( i = 0; i < num; i++ ) {
        item_id = _wpi_getmenuitemidfrompos( hmenu, i );
        if( item_id == -1 ) {
            return( FALSE );
        }
        if( item_id == id ) {
            if( parent != NULL ) {
                *parent = hmenu;
            }
            if( offset != NULL ) {
                *offset = i;
            }
            return( TRUE );
        }
    }

    for( i = 0; i < num; i++ ) {
        item_id = _wpi_getmenuitemidfrompos( hmenu, i );
        if( item_id == -1 ) {
            return( FALSE );
        }
        result = WinSendMsg( hmenu, MM_QUERYITEM, MPFROM2SHORT(item_id, FALSE), MPFROMP(&mi) );
        if( (BOOL)result && (mi.afStyle & MF_POPUP) && (mi.hwndSubMenu != NULLHANDLE) ) {
            if( _wpi_getmenuparentoffset( mi.hwndSubMenu, id, parent, offset ) ) {
                return( TRUE );
            }
        }
    }

    return( FALSE );
}

static void _OldBrush( WPI_PRES pres, WPI_OBJECT* brush )
/**************************************/
/* The function is used to determine the type of and retrieve the
   old brush. */
{
    GpiQueryAttrs( pres, PRIM_AREA,
                   ABB_COLOR | ABB_SYMBOL | ABB_MIX_MODE | ABB_SET,
                   &(brush->brush.info) );

    if( brush->brush.info.usSet > 0 ) {
        /* if the pattern is not the default pattern
           then it is a pattern brush*/
        brush->type = WPI_PATBRUSH_OBJ;
    } else {
        /* Otherwise, it only a regular brush */
        brush->type = WPI_BRUSH_OBJ;
    }
}

        /*---------------------------------------------------------
         * The following functions have Windows equivalents
         *---------------------------------------------------------*/

void GetWindowRect( HWND hwnd, WPI_RECT *rect )
/**********************************************************************/
{
    WinQueryWindowRect( hwnd, rect );
    WinMapWindowPoints( hwnd, HWND_DESKTOP, (WPI_POINT *)rect, 2L );
} /* GetWindowRect */

void GetClientRect( HWND hwnd, WPI_RECT *prect )
{
    WPI_RECT    screen;
    BOOL        ret;

    WinQueryWindowRect( hwnd, prect );
    WinMapWindowPoints( hwnd, HWND_DESKTOP, (POINTL *)prect, 2 );
    screen = *prect;
    ret = WinCalcFrameRect( hwnd, prect, TRUE );
    prect->xRight   = prect->xRight - prect->xLeft;
    prect->yTop     = prect->yTop - prect->yBottom;
    if ( ret ) {
        prect->xLeft    = prect->xLeft - screen.xLeft;
        prect->yBottom  = prect->yBottom - screen.yBottom;
        prect->xRight  += prect->xLeft;
        prect->yTop    += prect->yBottom;
    } else {
        prect->xLeft    = 0;
        prect->yBottom  = 0;
    }

}

        /*---------------------------------------------------------
         * The following functions have the WPI naming convention.
         *---------------------------------------------------------*/

BOOL _wpi_showwindow( HWND hwnd, int state )
/******************************************/
{
    BOOL                ret = TRUE;
    if( state == SW_HIDE ) {
        ret = ret && WinShowWindow( hwnd, FALSE );
    } else {
        ret = ret && WinShowWindow( hwnd, TRUE );
    }
    return( ret && WinSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, state ) );
}

void _wpi_bitblt( WPI_PRES dest, int x_dest, int y_dest, int cx, int cy,
                        WPI_PRES source, int x_src, int y_src, LONG format )
/**********************************************************************/
/* The x and y values are platform dependent.  ie. (0,0) is top left  */
/* for windows and bottom left for PM.                                */
{
    POINTL      pts[3];

    pts[0].x = x_dest;
    pts[0].y = y_dest;
    pts[1].x = x_dest + cx;
    pts[1].y = y_dest + cy;
    pts[2].x = x_src;
    pts[2].y = y_src;
    GpiBitBlt( dest, source, 3, pts, format, BBO_IGNORE );
} /* _wpi_bitblt */

WPI_HANDLE _wpi_createcompatiblebitmap( WPI_PRES pres, int width, int height )
/**********************************************************************/
/* Note that the bitmap returned is of type WPI_OBJECT.  So we declare*/
/* the routine to be void*.                                           */
{
    WPI_BITMAP          bmih;
    LONG                formats[24];
    WPI_OBJECT          *obj;

    memset( &bmih, 0, sizeof(WPI_BITMAP) );
    GpiQueryDeviceBitmapFormats( pres, 24L, formats );
    bmih.cbFix = sizeof( WPI_BITMAP );
    bmih.cx = width;
    bmih.cy = height;
    bmih.cPlanes = (USHORT) formats[0];
    bmih.cBitCount = (USHORT) formats[1];

    obj = _wpi_malloc( sizeof(WPI_OBJECT) );
    obj->type = WPI_BITMAP_OBJ;
    obj->bitmap = GpiCreateBitmap( pres, &bmih, 0L, NULL, NULL );

    return( (WPI_HANDLE)obj );
}

WPI_PRES _wpi_createcompatiblepres( WPI_PRES pres, WPI_INST inst, HDC *hdc )
/**********************************************************************/
{
    WPI_PRES            mempres;
    SIZEL               sizl = { 0, 0 };
    DEVOPENSTRUC        dop = { 0L, "DISPLAY", NULL, 0L,
                                0L, 0L, 0L, 0L, 0L };

    pres = pres;                        // PM doesn't use this variable
    *hdc = DevOpenDC( inst.hab, OD_MEMORY, "*", 5L,
                                        (PDEVOPENDATA)&dop, NULLHANDLE );
    mempres = GpiCreatePS( inst.hab, *hdc, &sizl, PU_PELS | GPIA_ASSOC );
    return( mempres );
} /* _wpi_createcompatiblepres */

WPI_PRES _wpi_createos2normpres( WPI_INST inst, HWND hwnd )
/**********************************************************************/
{
    SIZEL               sizel = { 0, 0 };
    WPI_PRES            hps;

    hps = GpiCreatePS( inst.hab, WinOpenWindowDC( hwnd ), &sizel,
                            PU_PELS | GPIF_LONG | GPIT_NORMAL | GPIA_ASSOC );
    return( hps );
} /* _wpi_createos2normpres */

void _wpi_deletecompatiblepres( WPI_PRES pres, HDC hdc )
/**********************************************************************/
{
    GpiDestroyPS( pres );
    DevCloseDC( hdc );
} /* _wpi_deletecompatiblepres */

void _wpi_deleteos2normpres( WPI_PRES pres )
/**********************************************************************/
{
    GpiAssociate( pres, NULLHANDLE );
    GpiDestroyPS( pres );
} /* _wpi_deleteos2normpres */

void _wpi_deletepres( WPI_PRES pres, HDC hdc )
/**********************************************************************/
{
    GpiDestroyPS( pres );
    DevCloseDC( hdc );
} /* _wpi_deletepres */

int _wpi_dialogbox( HWND parent, WPI_PROC proc, WPI_INST inst, int res_id,
                                                                void *data )
/**********************************************************************/
{
    HWND                new_dlg;
    int                 ret;

    new_dlg = WinLoadDlg( HWND_DESKTOP, parent, proc, inst.mod_handle,
                                            (ULONG)res_id, (PVOID)data );
    if( new_dlg == (HWND)NULL ) {
        return( -1 );
    }
    ret = WinProcessDlg( new_dlg );
    WinDestroyWindow( new_dlg );
    return( ret );
}

void _wpi_drawfocusrect( WPI_PRES pres, WPI_RECT *rect )
/**********************************************************************/
{
    POINTL      pt;
    LONG        old_mix;
    LONG        old_back_mix;

    pt.x = rect->xLeft;
    pt.y = rect->yTop;

    GpiSetCurrentPosition( pres, &pt );
    pt.x = rect->xRight - 1;
    pt.y = rect->yBottom + 1;

    old_mix = GpiQueryMix( pres );
    old_back_mix = GpiQueryBackMix( pres );
    GpiSetMix( pres, FM_XOR );
    GpiSetBackMix( pres, FM_LEAVEALONE );
    GpiBox( pres, DRO_OUTLINEFILL, &pt, 0L, 0L );
    GpiSetMix( pres, old_mix );
    GpiSetBackMix( pres, old_back_mix );
} /* _wpi_drawfocusrect */

BOOL _wpi_ellipse( WPI_PRES pres, int left, int top, int right, int bottom )
/*******************************************************************/
{
    POINTL      pt;
    LONG        width;
    LONG        height;
    BOOL        ret = TRUE;

    width = abs(right - left);
    height = abs(top - bottom);
    pt.x = left;
    pt.y = top;
    if ( !GpiSetCurrentPosition(pres, &pt) ) ret = FALSE;
    pt.x = right - 1;
    pt.y = bottom + 1;

    if ( !GpiBox(pres, DRO_OUTLINEFILL, &pt, width, height) ) ret = FALSE;

    return( ret );
} /* _wpi_ellipse */

void _wpi_fillrect( WPI_PRES pres, WPI_RECT *rect, WPI_COLOUR colour, HBRUSH brush )
/*******************************************************************/
{
    RECTL       newrect;

    brush = brush;                      // PM doesn't use this
    newrect.xLeft = rect->xLeft;
    newrect.xRight = rect->xRight;
    newrect.yTop = rect->yTop;
    newrect.yBottom = rect->yBottom;
    WinFillRect( pres, (PRECTL)&newrect, colour );
} /* _wpi_fillrect */

void _wpi_getbitmapdim( WPI_HANDLE hbmp, int *pwidth, int *pheight )
/*******************************************************************/
{
    BITMAPINFOHEADER    bih;
    WPI_OBJECT          *obj;

    obj = (WPI_OBJECT *)hbmp;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?