320 lines
10 KiB
C
320 lines
10 KiB
C
|
/* OpenDoors Online Software Programming Toolkit
|
||
|
* (C) Copyright 1991 - 1999 by Brian Pirie.
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Lesser General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public
|
||
|
* License along with this library; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
*
|
||
|
* File: ODWin.c
|
||
|
*
|
||
|
* Description: Implements the od_window_...() functions for creating
|
||
|
* and removing text-mode windows.
|
||
|
*
|
||
|
* Revisions: Date Ver Who Change
|
||
|
* ---------------------------------------------------------------
|
||
|
* Oct 13, 1994 6.00 BP New file header format.
|
||
|
* Nov 01, 1994 6.00 BP Include stdlib.h for malloc prototype.
|
||
|
* Dec 09, 1994 6.00 BP Standardized coding style.
|
||
|
* Dec 12, 1994 6.00 BP Set od_error on window remove failure.
|
||
|
* Aug 19, 1995 6.00 BP 32-bit portability.
|
||
|
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
|
||
|
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
|
||
|
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
|
||
|
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
|
||
|
* Mar 03, 1996 6.10 BP Begin version 6.10.
|
||
|
* Aug 10, 2003 6.23 SH *nix support
|
||
|
*/
|
||
|
|
||
|
#define BUILDING_OPENDOORS
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "OpenDoor.h"
|
||
|
#include "ODGen.h"
|
||
|
#include "ODCore.h"
|
||
|
#include "ODKrnl.h"
|
||
|
|
||
|
|
||
|
/* ----------------------------------------------------------------------------
|
||
|
* od_window_create()
|
||
|
*
|
||
|
* Creates a window on the screen, storing information on the original screen
|
||
|
* contents "under" the window in order to restore the screen after the window
|
||
|
* is removed. A window that is created with this function must be destroyed
|
||
|
* by od_window_remove() in order to free up memory that is allocated by this
|
||
|
* function.
|
||
|
*
|
||
|
* Parameters: nLeft - 1-based column number of left edge of window.
|
||
|
*
|
||
|
* nTop - 1-based row number of top edge of window.
|
||
|
*
|
||
|
* nRight - 1-based column number of right edge of window.
|
||
|
*
|
||
|
* nBottom - 1-based row number of bottom edge of window.
|
||
|
*
|
||
|
* pszTitle - Pointer to a string containing title for window.
|
||
|
* If this string is empty, no title is displayed.
|
||
|
*
|
||
|
* btBoarderCol - Colour of window boarder.
|
||
|
*
|
||
|
* btTitleCol - Colour of window title.
|
||
|
*
|
||
|
* btInsideCol - Colour of rest of window.
|
||
|
*
|
||
|
* nReserved - Should always be 0 for this version.
|
||
|
*
|
||
|
* Return: Pointer to window description buffer (which must later be
|
||
|
* passed to od_window_remove(), or NULL on failure.
|
||
|
*/
|
||
|
ODAPIDEF void * ODCALL od_window_create(INT nLeft, INT nTop, INT nRight,
|
||
|
INT nBottom, char *pszTitle, BYTE btBorderCol, BYTE btTitleCol,
|
||
|
BYTE btInsideCol, INT nReserved)
|
||
|
{
|
||
|
BYTE btLine;
|
||
|
BYTE btBetweenSize;
|
||
|
void *pBuffer;
|
||
|
BYTE btTitleSize;
|
||
|
BYTE btRemaining;
|
||
|
|
||
|
/* Log function entry if running in trace mode. */
|
||
|
TRACE(TRACE_API, "od_window_create()");
|
||
|
|
||
|
/* Ensure that OpenDoors has been initialized */
|
||
|
if(!bODInitialized) od_init();
|
||
|
|
||
|
OD_API_ENTRY();
|
||
|
|
||
|
nReserved &= 0x00;
|
||
|
|
||
|
btBetweenSize = (nRight - nLeft) - 1;
|
||
|
|
||
|
/* Setup od_box_chars appropriately. */
|
||
|
if(od_control.od_box_chars[BOX_BOTTOM]==0)
|
||
|
{
|
||
|
od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
|
||
|
}
|
||
|
if(od_control.od_box_chars[BOX_RIGHT]==0)
|
||
|
{
|
||
|
od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
|
||
|
}
|
||
|
|
||
|
/* Ensure that the current display mode can support the capabilities */
|
||
|
/* required to display and remove windows. */
|
||
|
if(!(od_control.user_ansi || od_control.user_avatar))
|
||
|
{
|
||
|
od_control.od_error = ERR_NOGRAPHICS;
|
||
|
OD_API_EXIT();
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
/* Validate parameters. */
|
||
|
if(nLeft < 1 || nTop < 1 || nRight > 80 || nBottom > 25 || nRight-nLeft < 2
|
||
|
|| nBottom-nTop < 2)
|
||
|
{
|
||
|
od_control.od_error = ERR_PARAMETER;
|
||
|
OD_API_EXIT();
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
/* Allocate a buffer large enough to hold all window information. */
|
||
|
if((pBuffer = malloc((nRight - nLeft + 1) * 2 + (nBottom - nTop + 1) * 160
|
||
|
+ 4)) == NULL)
|
||
|
{
|
||
|
od_control.od_error = ERR_MEMORY;
|
||
|
OD_API_EXIT();
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
/* Store current contents of screen where window will be drawn. */
|
||
|
if(!od_gettext(nLeft, nTop, nRight, nBottom, (char *)pBuffer+4))
|
||
|
{
|
||
|
free(pBuffer);
|
||
|
|
||
|
/* Note: od_control.od_error code has been set by od_gettext(). */
|
||
|
|
||
|
OD_API_EXIT();
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
/* Store window information in buffer. */
|
||
|
((char *)pBuffer)[0]=nLeft;
|
||
|
((char *)pBuffer)[1]=nTop;
|
||
|
((char *)pBuffer)[2]=nRight;
|
||
|
((char *)pBuffer)[3]=nBottom;
|
||
|
|
||
|
/* Determine number of characters of title to display. */
|
||
|
if(pszTitle==NULL)
|
||
|
{
|
||
|
btTitleSize = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if((btTitleSize = strlen(pszTitle)) > (btBetweenSize - 4))
|
||
|
{
|
||
|
btTitleSize = btBetweenSize - 4;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Move to position of window's top corner, prepare to begin drawing the */
|
||
|
/* window. */
|
||
|
od_set_cursor(nTop,nLeft);
|
||
|
od_set_attrib(btBorderCol);
|
||
|
|
||
|
/* Display corner character. */
|
||
|
od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
|
||
|
|
||
|
/* If there is no title, display top line all in one piece. */
|
||
|
if(btTitleSize == 0)
|
||
|
{
|
||
|
/* Display top line. */
|
||
|
od_repeat(od_control.od_box_chars[BOX_TOP],btBetweenSize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* If there is a title, display the top line with a title centered in */
|
||
|
/* it. */
|
||
|
od_repeat(od_control.od_box_chars[BOX_TOP],btRemaining =
|
||
|
((btBetweenSize - btTitleSize - 2) / 2));
|
||
|
od_set_attrib(btTitleCol);
|
||
|
od_putch(' ');
|
||
|
od_disp(pszTitle,btTitleSize,TRUE);
|
||
|
od_putch(' ');
|
||
|
od_set_attrib(btBorderCol);
|
||
|
od_repeat(od_control.od_box_chars[BOX_TOP],
|
||
|
(BYTE)(btBetweenSize - btRemaining - btTitleSize - 2));
|
||
|
}
|
||
|
|
||
|
/* Display top right corner character. */
|
||
|
od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
|
||
|
|
||
|
/* If AVATAR mode is available. */
|
||
|
if(od_control.user_avatar)
|
||
|
{
|
||
|
/* Display first left verticle line. */
|
||
|
od_set_cursor(nTop + 1, nLeft);
|
||
|
od_putch(od_control.od_box_chars[BOX_LEFT]);
|
||
|
|
||
|
/* Fill in center of window with AVATAR clear area control sequence. */
|
||
|
od_emulate(22);
|
||
|
od_emulate(12);
|
||
|
od_emulate(btInsideCol);
|
||
|
od_emulate((BYTE)((nBottom - nTop) - 1));
|
||
|
od_emulate(btBetweenSize);
|
||
|
|
||
|
od_set_attrib(btBorderCol);
|
||
|
od_set_cursor(nTop + 1 , nRight);
|
||
|
|
||
|
/* Display first right verticle line. */
|
||
|
od_putch(od_control.od_box_chars[BOX_RIGHT]);
|
||
|
|
||
|
/* Display remaining verticle lines. */
|
||
|
for(btLine=nTop+2;btLine<nBottom;++btLine)
|
||
|
{
|
||
|
/* Move to line start and display left line character. */
|
||
|
od_set_cursor(btLine,nLeft);
|
||
|
od_putch(od_control.od_box_chars[BOX_LEFT]);
|
||
|
|
||
|
/* Move to line start and display right line character. */
|
||
|
od_set_cursor(btLine,nRight);
|
||
|
od_putch(od_control.od_box_chars[BOX_RIGHT]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If AVATAR mode is not available. */
|
||
|
else
|
||
|
{
|
||
|
/* Loop through middle lines of window. */
|
||
|
for(btLine=nTop+1;btLine<nBottom;++btLine)
|
||
|
{
|
||
|
/* Move to line start and display left line character. */
|
||
|
od_set_cursor(btLine,nLeft);
|
||
|
od_putch(od_control.od_box_chars[BOX_LEFT]);
|
||
|
|
||
|
/* Set window colour. */
|
||
|
od_set_attrib(btInsideCol);
|
||
|
|
||
|
/* display blank area between left and right vertical lines. */
|
||
|
od_repeat(' ',btBetweenSize);
|
||
|
|
||
|
/* Set border colour. */
|
||
|
od_set_attrib(btBorderCol);
|
||
|
|
||
|
/* Display right line. */
|
||
|
od_putch(od_control.od_box_chars[BOX_RIGHT]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Display bottom border of window */
|
||
|
od_set_cursor(nBottom,nLeft);
|
||
|
od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
|
||
|
od_repeat(od_control.od_box_chars[BOX_BOTTOM],btBetweenSize);
|
||
|
od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
|
||
|
|
||
|
/* Return a pointer to the window information buffer. */
|
||
|
OD_API_EXIT();
|
||
|
return(pBuffer);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* ----------------------------------------------------------------------------
|
||
|
* od_window_remove()
|
||
|
*
|
||
|
* Removes window from the screen, restoring the screen contents that where
|
||
|
* in the window area when the window was first created.
|
||
|
*
|
||
|
* Parameters: pWinInfo - Pointer to buffer returned by od_window_create().
|
||
|
* This buffer is deallocated before od_window_remove()
|
||
|
* returns.
|
||
|
*
|
||
|
* Return: TRUE on success, or FALSE on failure.
|
||
|
*/
|
||
|
ODAPIDEF BOOL ODCALL od_window_remove(void *pWinInfo)
|
||
|
{
|
||
|
/* Log function entry if running in trace mode */
|
||
|
TRACE(TRACE_API, "od_window_remove()");
|
||
|
|
||
|
/* Ensure that OpenDoors has been initialized */
|
||
|
if(!bODInitialized) od_init();
|
||
|
|
||
|
OD_API_ENTRY();
|
||
|
|
||
|
if(pWinInfo == NULL)
|
||
|
{
|
||
|
/* Set error code and return with failure. */
|
||
|
od_control.od_error = ERR_PARAMETER;
|
||
|
OD_API_EXIT();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if(!od_puttext(((char *)pWinInfo)[0], ((char *)pWinInfo)[1], ((char *)pWinInfo)[2], ((char *)pWinInfo)[3], (char *)pWinInfo + 4))
|
||
|
{
|
||
|
/* Deallocate memory assigned to window information structure. */
|
||
|
free(pWinInfo);
|
||
|
|
||
|
/* Note: od_control.od_error code has been set by od_puttext(). */
|
||
|
|
||
|
/* Return with failure. */
|
||
|
OD_API_EXIT();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
/* Deallocate memory assigned to window information structure. */
|
||
|
free(pWinInfo);
|
||
|
|
||
|
/* Return with success. */
|
||
|
OD_API_EXIT();
|
||
|
return(TRUE);
|
||
|
}
|