/* 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 #include #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