setvideo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 865 行 · 第 1/2 页
C
865 行
/****************************************************************************
*
* 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: Video mode set processing.
*
****************************************************************************/
#include <conio.h>
#include "gdefn.h"
#include "gbios.h"
#include "montypes.h"
#ifdef __QNX__
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/console.h>
#include <sys/dev.h>
#include <sys/kernel.h>
static struct _console_ctrl *ConCtrl;
static unsigned old_hscroll;
static void HScrollOff()
{
int h;
if( ConCtrl == NULL ) {
h = open( "//0/dev/con1", O_RDONLY );
if( h != -1 ) {
ConCtrl = console_open( h, O_RDWR );
close( h );
}
}
if( ConCtrl != NULL ) {
old_hscroll = console_ctrl( ConCtrl, -1, CONSOLE_NOHSCROLL, CONSOLE_NOHSCROLL );
}
}
static void HScrollRestore()
{
if( ConCtrl != NULL ) {
console_ctrl( ConCtrl, -1, old_hscroll, CONSOLE_NOHSCROLL );
}
}
#endif // __QNX__
#if defined( _DEFAULT_WINDOWS )
#undef HANDLE // already defined by WPI
#undef GLOBALHANDLE
#include "win.h"
#include <stdarg.h>
#if defined( __OS2__ )
#include "pmmenu.h"
#endif
WPI_PRES _Mem_dc = NULL;
HDC _Hdc;
HBITMAP _Mem_bmp = NULL;
HWND _CurrWin = NULL;
extern HWND _MainWindow;
#if !defined( __OS2__ )
extern HMENU _SubMenuWindows;
#else
extern HWND _GetWinMenuHandle();
#endif
extern void _GetWindowNameAndCoords( char*, char*, int*, int*, int*, int* );
static LPWDATA _NewGphWindow( HWND hwnd, ... );
static short _registergphclass( WPI_INST );
#else
extern gr_device _FARD _TextDevice, _GrCGA_4, _GrCGA_6, _GrHGC_11,
_GrEGA_13, _GrEGA_14, _GrEGA_15, _GrEGA_16,
_GrVGA_17, _GrVGA_18, _GrVGA_19;
#if defined( _SUPERVGA )
extern gr_device _FARD _GrSVGA_100, _GrSVGA_102, _GrSVGA_103,
_GrSVGA_104, _GrSVGA_105;
#endif
typedef struct supported_video_mode {
short mode;
gr_device _FARD *dev;
} SUPP_MODE;
static SUPP_MODE VideoModes[] = {
_TEXTBW40, &_TextDevice,
_TEXTC40, &_TextDevice,
_TEXTBW80, &_TextDevice,
_TEXTC80, &_TextDevice,
_MRES4COLOR, &_GrCGA_4,
_MRESNOCOLOR, &_GrCGA_4,
_HRESBW, &_GrCGA_6,
_TEXTMONO, &_TextDevice,
_HERCMONO, &_GrHGC_11,
_MRES16COLOR, &_GrEGA_13,
_HRES16COLOR, &_GrEGA_14,
_ERESNOCOLOR, &_GrEGA_15,
_ERESCOLOR, &_GrEGA_16,
_VRES2COLOR, &_GrVGA_17,
_VRES16COLOR, &_GrVGA_18,
_MRES256COLOR, &_GrVGA_19,
#if defined( _SUPERVGA )
0x100, &_GrSVGA_100,
0x101, &_GrSVGA_100,
0x102, &_GrSVGA_102,
0x103, &_GrSVGA_103,
0x104, &_GrSVGA_104,
0x105, &_GrSVGA_105,
#endif
-1, NULL
};
static short SelectMode( short );
#endif
static void SetTextInfo( void )
/*=======================
This routine initializes the graphics text defaults. */
{
short height;
short width;
/* Make the graphics text look the same on all devices. Take the
width to height visual ratio to be 5:8 and assume that the
width to height ratio of the physical dimensions of the screen
is 4 : 3. The size is about 1.5 the size of BIOS text. */
height = ( _CurrState->vc.numypixels * 3 ) /
( _CurrState->vc.numtextrows * 2 );
width = ( (long) height * _CurrState->vc.numxpixels * 15 ) / // 3 * 5
( (long) _CurrState->vc.numypixels * 32 ); // 4 * 8
_setcharsize( height, width );
_settextorient( 1, 0 );
_settextpath( _PATH_RIGHT );
_setcharspacing( 0 );
_settextalign( _NORMAL, _NORMAL );
}
static void _InitVariables( void )
/*================================
This routine initializes all of the global variables used by the
graphics functions. */
{
_CurrPos.xcoord = 0; /* initial position */
_CurrPos.ycoord = 0;
_LogOrg.xcoord = _CurrPos.xcoord;
_LogOrg.ycoord = _CurrPos.ycoord;
_CurrPos_w.wx = 0.0;
_CurrPos_w.wy = 0.0;
_Window.invert = TRUE; /* window coordinates defaults */
_Window.xleft = 0.0;
_Window.ybottom = 0.0;
_Window.xright = 1.0;
_Window.ytop = 1.0;
_CurrState->clip_def.xmin = 0; /* graphics window */
_CurrState->clip_def.xmax = _CurrState->vc.numxpixels - 1;
_CurrState->clip_def.ymin = 0;
_CurrState->clip_def.ymax = _CurrState->vc.numypixels - 1;
_setclip( _GCLIPON );
_TextPos.row = 0; /* BIOS text cursor position */
_TextPos.col = 0;
_Tx_Row_Min = 0; /* text window */
_Tx_Row_Max = _CurrState->vc.numtextrows - 1;
_Tx_Col_Min = 0;
_Tx_Col_Max = _CurrState->vc.numtextcols - 1;
if( _GrMode ) {
SetTextInfo();
}
memcpy( _FillMask, _DefMask, MASK_LEN ); /* solid fill */
_HaveMask = 0; /* no fill mask set */
_PaRf_x = 0; /* fill pattern */
_PaRf_y = 0; /* reference point */
_CharAttr = _DEFAULT_ATTR;
_CurrColor = ( _CurrState->vc.numcolors - 1 ) & 15;
_CurrBkColor = 0;
_CurrActivePage = _CurrVisualPage = 0;
_CurrState->screen_seg = _CurrState->screen_seg_base;/* pg 0 scrn segment */
_CurrState->screen_off = _CurrState->screen_off_base;/* pg 0 scrn offset */
_LineStyle = 0xFFFF; /* solid line */
_StyleWrap = 0; /* line style continuation */
_PlotAct = 0; /* replace mode */
_Transparent = 1; /* transparent mode */
_Wrap = 1; /* wrapping on */
}
short _WCI86FAR _CGRAPH _setvideomode( short req_mode )
/*================================================
This routine sets the video mode if it is supported by the current
hardware configuration. It returns the number of text rows if
successful, otherwise it returns 0. */
{
#if defined( _DEFAULT_WINDOWS )
WPI_INST Inst;
HWND Win;
WPI_PRES Win_DC;
WPI_RECT rect;
WPI_TEXTMETRIC fntinfo;
HMENU menu;
HFONT old_font;
LPWDATA w;
char* name = "\0";
char dest[80];
long x, y;
int x1, y1, x2, y2;
short clipy1, clipy2;
WPI_RECTDIM right, bottom, height;
#if defined( __OS2__ )
ULONG style;
HWND frame;
MENUITEM gphmenu;
#endif
#else
short mode;
short prev_mode;
#ifdef __QNX__
int wasTextMode;
#endif
SUPP_MODE *tab;
gr_device _FARD *prev_dev;
gr_device _FARD *dev_ptr;
#endif
_ErrorStatus = _GROK;
_InitState();
#if defined( _DEFAULT_WINDOWS )
Win = 0;
#if defined( __OS2__ )
Inst.hab = WinQueryAnchorBlock( _MainWindow );
Inst.mod_handle = NULL;
#else
Inst = GetWindowWord( _MainWindow, GWW_HINSTANCE );
#endif
_SetInst( &Inst );
if( !_registergphclass( Inst ) ) {
_ErrorStatus = _GRMODENOTSUPPORTED;
return( 0 );
}
x = _wpi_getsystemmetrics( SM_CXSCREEN );
y = _wpi_getsystemmetrics( SM_CYSCREEN );
_SetPresHeight( y );
if( req_mode == 0 ) {
_ErrorStatus = _GRMODENOTSUPPORTED;
return( 0 );
} else if( _CurrWin ){
// Make sure we don't create more than 1 window, and know when to close it
if( req_mode == _DEFAULTMODE ) {
#if defined( __OS2__ )
w = _GetWindowData( _CurrWin );
Win = w->frame;
#else
Win = _CurrWin;
#endif
_wpi_destroywindow( Win );
return( _CurrState->vc.numtextrows );
} else {
// if we are only changing moods, we will reinitialize everything
_clearscreen( _GCLEARSCREEN );
init_memdc_bk( x, y );
init_all();
_wpi_updatewindow( Win );
return( _CurrState->vc.numtextrows );
}
}
// Create a new window
// Get the name and coordinates of the window
name = "Graphics";
_GetWindowNameAndCoords( name, dest, &x1, &x2, &y1, &y2 );
#if defined( __OS2__ )
style = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MINMAX |
FCF_VERTSCROLL | FCF_HORZSCROLL;
frame = WinCreateStdWindow( _MainWindow,
WS_VISIBLE | WS_CLIPSIBLINGS,
&style, "GraphWndClass", dest, 0, NULL, 0, &Win );
if( frame == 0 ) return( FALSE );
WinSetOwner( Win, _MainWindow );
_OldFrameProc = WinSubclassWindow( frame, GraphFrameProc );
#else
Win = CreateWindow( "GraphWndClass", dest,
WS_CHILD |
WS_CAPTION | WS_THICKFRAME |
WS_CLIPSIBLINGS | WS_SYSMENU |
WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
0, 0,
0, 0,
_MainWindow, NULL,
Inst, NULL );
if( !Win ) return( FALSE );
#endif
_CurrWin = Win;
Win_DC = _wpi_getpres( Win );
// Create the memory dc
_Mem_dc = _wpi_createcompatiblepres( Win_DC, Inst, &_Hdc );
if( !_Mem_dc ){
_ErrorStatus = _GRMODENOTSUPPORTED;
_wpi_destroywindow( _CurrWin );
return( 0 );
}
// Create the bitmap to draw on
_Mem_bmp = _wpi_createcompatiblebitmap( Win_DC, x,y );
if( !_Mem_bmp ){
_ErrorStatus = _GRMODENOTSUPPORTED;
_wpi_destroywindow( _CurrWin );
return( 0 );
}
_wpi_torgbmode( _Mem_dc );
_wpi_torgbmode( Win_DC );
_wpi_selectbitmap( _Mem_dc, _Mem_bmp );
_wpi_releasepres( Win, Win_DC );
_CurrState->vc.mode = Win;
w = _NewGphWindow( Win, 9999, -1 );
// initialize variables, memory device, etc.
if( !_CreateSysMonoFnt( _Mem_dc ) ) {
_ErrorStatus = _GRMODENOTSUPPORTED;
return( 0 );
}
init_memdc_bk( x, y );
init_all();
/* Initialize clipping regions */
clipy1 = _wpi_cvth_y( _CurrState->clip_def.ymin, _GetPresHeight() );
clipy2 = _wpi_cvth_y( _CurrState->clip_def.ymax, _GetPresHeight() );
_wpi_setintwrectvalues( &rect, _CurrState->clip_def.xmin,
clipy1,
_CurrState->clip_def.xmax,
clipy2 );
_ClipRgn = _wpi_createrectrgn( _Mem_dc, &rect );
_wpi_selectcliprgn( _Mem_dc, _ClipRgn );
#if defined( __OS2__ )
GpiDeleteSetId( _Mem_dc, LCID_DEFAULT );
_CurFnt = LCID_DEFAULT;
#else
_CurFnt = GetStockObject( SYSTEM_FONT );
#endif
old_font = _MySelectFont( _Mem_dc, _CurFnt );
_wpi_gettextmetrics( _Mem_dc, &fntinfo );
#if defined( __OS2__ )
w->frame = frame;
menu = _GetWinMenuHandle();
#else
w->inst = Inst;
menu = _SubMenuWindows;
#endif
_wpi_getclientrect( _MainWindow, &rect );
height = _wpi_getheightrect( rect );
// Calculate where to put the window and how big it should be
x2 -= x1;
y2 -= y1;
x1 *= _wpi_metricmaxcharwidth( fntinfo );
y1 *= _wpi_metricheight( fntinfo );
x2 *= _wpi_metricmaxcharwidth( fntinfo );
y2 *= _wpi_metricheight( fntinfo );
w->xchar = _wpi_metricmaxcharwidth( fntinfo );
w->ychar = _wpi_metricheight( fntinfo );
_wpi_getrectvalues( rect, NULL, NULL, &right, &bottom );
if( ( x1 < 0 ) || ( x1 >= right ) ) {
x1 = 0;
}
if( ( y1 < 0 ) || ( y1 >= bottom ) ) {
y1 = 0;
}
if( ( x2 <= 0 ) || ( x2 >= right ) ) {
x2 = right - x1;
}
if( ( y2 <= 0 ) || ( y2 >= bottom ) ) {
y2 = bottom - y1;
}
#if defined( __OS2__ )
WinSendMsg( frame, WM_SETICON,
MPFROMLONG( WinQuerySysPointer( HWND_DESKTOP, SPTR_APPICON, TRUE ) ), 0 );
WinSetWindowPos( frame,
HWND_TOP,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?