/*
TurboC, a library for porting Borland Turbo C to GNU gcc.
Copyright 2002 Ronald S. Burkey
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.1 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
Contact Ron Burkey at info@sandroid.org.
*/
#define TURBOC_VARIABLES_C
#include "x11-bgi.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
# include <stdio.h>
#endif
#define X11_BGI_USE_XKeycodeToKeysym 1
#define X11_BGI_USE_SELECT 1
#define X11_BGI_USE_PTHREADS 0
#define X11_BGI_INPUT_MASK \
ExposureMask | KeyPressMask | SubstructureNotifyMask | PointerMotionMask | \
ButtonPressMask | ButtonReleaseMask
/* unused */
#define X11_BGI_INPUT_MASK_2 NoEventMask \
+ KeyPressMask \
+ KeyReleaseMask \
+ ButtonPressMask \
+ ButtonReleaseMask \
+ EnterWindowMask \
+ LeaveWindowMask \
+ PointerMotionMask \
+ PointerMotionHintMask \
+ Button1MotionMask \
+ Button2MotionMask \
+ Button3MotionMask \
+ Button4MotionMask \
+ Button5MotionMask \
+ ButtonMotionMask \
+ KeymapStateMask \
+ ExposureMask \
+ VisibilityChangeMask \
+ StructureNotifyMask \
+ ResizeRedirectMask \
+ SubstructureNotifyMask \
+ SubstructureRedirectMask \
+ FocusChangeMask \
+ PropertyChangeMask \
+ ColormapChangeMask \
+ OwnerGrabButtonMask
#if defined(X11_BGI_USE_SELECT) && X11_BGI_USE_SELECT
# include <sys/select.h>
#else
# include <unistd.h>
#endif
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
# include <pthread.h>
# include <sys/types.h>
# include <signal.h>
static pthread_t ExposerThread;
static int ThreadsInitialized = 0;
#endif
static void *ExposerFunction(void *);
static void ExposerFunctionLoop(void);
void
X11_BGI_update_IO(void) /* {{{ */
{
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
/* do nothing */
#else
ExposerFunction(NULL);
#endif
} /* }}} */
/* TurboC-source/TurboX.c */
int
TurboX (int Forced) /* {{{ */
{
return 0;
} /* }}} */
/* TurboC-source/freeTurbo.c */
/* This is the stuff for the linked list of allocated memory blocks */
/* associated with Pixmaps. */
struct PixmappedBlock /* {{{ */
{
void *Object; /* Pointer created by malloc/calloc. */
Pixmap Pix; /* The Pixmap's handle. */
struct PixmappedBlock *Next;
}; /* }}} */
static struct PixmappedBlock *PixmappedRoot = NULL;
/* This is the function which is called by getimage to associate a Pixmap */
/* with an already-allocated memory block. If the block is not in the */
/* list already, it will be added. If the block *is* in the list, its old */
/* Pixmap will be freed and then the new one added. Returns 0 on success, */
/* non-zero if out of memory. */
extern int
AssociatePixmap (void *object, Pixmap handle) /* {{{ */
{
struct PixmappedBlock *Block, *LastBlock;
/* If the list is empty, just add the new block. */
if (PixmappedRoot == NULL)
{
PixmappedRoot =
(struct PixmappedBlock *) malloc (sizeof (struct PixmappedBlock));
if (PixmappedRoot == NULL)
return (1);
PixmappedRoot->Object = object;
PixmappedRoot->Pix = handle;
PixmappedRoot->Next = NULL;
return (0);
}
/* Navigate the linked list to see if this block is already in it! */
/* Note that this is guaranteed to iterate at least once, so if it falls */
/* through, we know that LastBlock has been initialized. */
for (Block = PixmappedRoot; Block != NULL;
LastBlock = Block, Block = Block->Next)
if (Block->Object == object)
{
if (Block->Pix != handle)
{
/* The block *is* already defined, but is associated with */
/* a different Pixmap. So free the old Pixmap and associate */
/* a new one! */
XFreePixmap (TcDisplay, Block->Pix);
Block->Pix = handle;
}
return (0);
}
/* The block wasn't in the list, so add it. */
Block = (struct PixmappedBlock *) malloc (sizeof (struct PixmappedBlock));
if (Block == NULL)
return (1);
Block->Object = object;
Block->Pix = handle;
Block->Next = NULL;
LastBlock->Next = Block;
return (0);
} /* }}} */
/* TurboC-source/Console-8.h */
const guchar TcConsole8Font[256][8] = { /* {{{ */
{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 },
{ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E },
{ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E },
{ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00 },
{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 },
{ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0xD6, 0x10, 0x38 },
{ 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x7C, 0x10, 0x38 },
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 },
{ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF },
{ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 },
{ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF },
{ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78 },
{ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 },
{ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0 },
{ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0 },
{ 0x18, 0xDB, 0x3C, 0xE7, 0xE7, 0x3C, 0xDB, 0x18 },
{ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00 },
{ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00 },
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18 },
{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 },
{ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00 },
{ 0x3E, 0x61, 0x3C, 0x66, 0x66, 0x3C, 0x86, 0x7C },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF },
{ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF },
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 },
{ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00 },
{ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00 },
{ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00 },
{ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00 },
{ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00 },
{ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00 },
{ 0 },
{ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00 },
{ 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 },
{ 0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0x00 },
{ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00 },
{ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00 },
{ 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00 },
{ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00 },
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 },
{ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30 },
{ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00 },
{ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 },
{ 0x38, 0x6C, 0xC6, 0xD6, 0xC6, 0x6C, 0x38, 0x00 },
{ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00 },
{ 0x7C, 0xC6, 0x06, 0x1C, 0x30, 0x66, 0xFE, 0x00 },
{ 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00 },
{ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00 },
{ 0xFE, 0xC0, 0xC0, 0xFC, 0x06, 0xC6, 0x7C, 0x00 },
{ 0x38, 0x60, 0xC0, 0xFC, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0xFE, 0xC6, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00 },
{ 0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x7C, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00 },
{ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00 },
{ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30 },
{ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00 },
{ 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00 },
{ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00 },
{ 0x7C, 0xC6, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00 },
{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 },
{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00 },
{ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00 },
{ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00 },
{ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00 },
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00 },
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00 },
{ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00 },
{ 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00 },
{ 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00 },
{ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00 },
{ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00 },
{ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00 },
{ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00 },
{ 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 },
{ 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xCE, 0x7C, 0x0E },
{ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00 },
{ 0x3C, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x3C, 0x00 },
{ 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 },
{ 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00 },
{ 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00 },
{ 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x00 },
{ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00 },
{ 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00 },
{ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00 },
{ 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00 },
{ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF },
{ 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0xE0, 0x60, 0x7C, 0x66, 0x66, 0x66, 0xDC, 0x00 },
{ 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00 },
{ 0x1C, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00 },
{ 0x3C, 0x66, 0x60, 0xF8, 0x60, 0x60, 0xF0, 0x00 },
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 },
{ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00 },
{ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0x06, 0x00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C },
{ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00 },
{ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0x00 },
{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x00 },
{ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0 },
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E },
{ 0x00, 0x00, 0xDC, 0x76, 0x60, 0x60, 0xF0, 0x00 },
{ 0x00, 0x00, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x00 },
{ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x36, 0x1C, 0x00 },
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 },
{ 0x00, 0x00, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00 },
{ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00 },
{ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0xFC },
{ 0x00, 0x00, 0x7E, 0x4C, 0x18, 0x32, 0x7E, 0x00 },
{ 0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 },
{ 0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0x00 },
{ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00 },
{ 0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x0C, 0x78 },
{ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0x0C, 0x18, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00 },
{ 0x7C, 0x82, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0xC6, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0x30, 0x18, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0x00, 0x00, 0x7E, 0xC0, 0xC0, 0x7E, 0x0C, 0x38 },
{ 0x7C, 0x82, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00 },
{ 0xC6, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00 },
{ 0x30, 0x18, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00 },
{ 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 },
{ 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00 },
{ 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 },
{ 0x38, 0x6C, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 },
{ 0x18, 0x30, 0xFE, 0xC0, 0xF8, 0xC0, 0xFE, 0x00 },
{ 0x00, 0x00, 0x7E, 0x18, 0x7E, 0xD8, 0x7E, 0x00 },
{ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00 },
{ 0x7C, 0x82, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x30, 0x18, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0x60, 0x30, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0xFC },
{ 0xC6, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x00 },
{ 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18 },
{ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x66, 0xFC, 0x00 },
{ 0x66, 0x66, 0x3C, 0x7E, 0x18, 0x7E, 0x18, 0x18 },
{ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7 },
{ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0xD8, 0x70, 0x00 },
{ 0x18, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 },
{ 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00 },
{ 0x0C, 0x18, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00 },
{ 0x18, 0x30, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 },
{ 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x00 },
{ 0x76, 0xDC, 0x00, 0xE6, 0xF6, 0xDE, 0xCE, 0x00 },
{ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00 },
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00 },
{ 0x18, 0x00, 0x18, 0x18, 0x30, 0x63, 0x3E, 0x00 },
{ 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x00, 0x00 },
{ 0x63, 0xE6, 0x6C, 0x7E, 0x33, 0x66, 0xCC, 0x0F },
{ 0x63, 0xE6, 0x6C, 0x7A, 0x36, 0x6A, 0xDF, 0x06 },
{ 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00 },
{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00 },
{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00 },
{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 },
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
{ 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36 },
{ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36 },
{ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18 },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 },
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00 },
{ 0x78, 0xCC, 0xCC, 0xD8, 0xCC, 0xC6, 0xCC, 0x00 },
{ 0xFE, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00 },
{ 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00 },
{ 0xFE, 0xC6, 0x60, 0x30, 0x60, 0xC6, 0xFE, 0x00 },
{ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00 },
{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0xC0 },
{ 0x00, 0x00, 0x7E, 0xD8, 0x18, 0x18, 0x1C, 0x00 },
{ 0x7E, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x7E },
{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00 },
{ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00 },
{ 0x0E, 0x18, 0x0C, 0x3E, 0x66, 0x66, 0x3C, 0x00 },
{ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00 },
{ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0 },
{ 0x1E, 0x30, 0x60, 0x7E, 0x60, 0x30, 0x1E, 0x00 },
{ 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00 },
{ 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00 },
{ 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00 },
{ 0x30, 0x18, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00 },
{ 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00 },
{ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70 },
{ 0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, 0x00 },
{ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00 },
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00 },
{ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C },
{ 0x6C, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00 },
{ 0x78, 0x0C, 0x18, 0x30, 0x7C, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 },
{ 0 }
}; /* }}} */
/* TurboC-source/bar.c */
void
bar (int x1, int y1, int x2, int y2) /* {{{ */
{
int i, j;
if (x1 > x2)
{
i = x1;
x1 = x2;
x2 = i;
}
if (y1 > y2)
{
i = y1;
y1 = y2;
y2 = i;
}
i = x2 - x1 + 1;
j = y2 - y1 + 1;
/* Convert to viewport coordinates. */
x1 += TcViewLeft;
y1 += TcViewTop;
XLockDisplay (TcDisplay);
XSetFillStyle (TcDisplay, TcGc, FillTiled);
XSetTile (TcDisplay, TcGc, TcTile);
/* Now do the actual drawing. */
XFillRectangle (TcDisplay, TcPixmaps[TcActivePage], TcGc, x1, y1, i, j);
if (TcActivePage == TcVisualPage)
{
XFillRectangle (TcDisplay, TcWindow, TcGc, x1, y1, i, j);
XSync (TcDisplay, False);
}
XSetFillStyle (TcDisplay, TcGc, FillSolid);
XUnlockDisplay (TcDisplay);
} /* }}} */
void
bar3d (int x1, int y1, int x2, int y2, int depth, int topflag) /* {{{ */
{
int dx, dy;
int i1, i2, j1, j2;
/* Order the coordinates correctly. */
if (x1 > x2)
{
i1 = x1;
x1 = x2;
x2 = i1;
}
if (y1 > y2)
{
j1 = y1;
y1 = y2;
y2 = j1;
}
/* Draw the innards of the bar. */
bar (x1, y1, x2, y2);
/* Put an outline around the bar. */
line (x1, y1, x2, y1);
line (x2, y1, x2, y2);
line (x2, y2, x1, y2);
line (x1, y2, x1, y1);
/* Calculate the x,y offsets associated with the depth. I assume */
/* a 60-degree angle. */
if (depth <= 0)
return;
dy = (depth + 1) / 2; /* dy = depth * sin(30) */
dx = (depth * 866 + 500) / 1000; /* dx = depth * cos(30); */
/* Draw the right-hand side. */
i1 = x1 + dx;
j1 = y1 - dy;
i2 = x2 + dx;
j2 = y2 - dy;
line (x2, y2, i2, j2);
line (i2, j2, i2, j1);
/* Draw the top. */
if (topflag)
{
line (x2, y1, i2, j1);
line (x1, y1, i1, j1);
line (i1, j1, i2, j1);
}
} /* }}} */
/* TurboC-source/clearXXXX.c */
void
cleardevice (void) /* {{{ */
{
int Left, Top, Right, Bottom, Clip;
Left = TcViewLeft;
Top = TcViewTop;
Right = TcViewRight;
Bottom = TcViewBottom;
Clip = TcViewClip;
setviewport (0, 0, TcXresolution - 1, TcYresolution - 1, 0);
clearviewport ();
setviewport (Left, Top, Right, Bottom, Clip);
} /* }}} */
void
clearviewport (void) /* {{{ */
{
int Mode;
Mode = TcWritemode;
setwritemode (COPY_PUT);
XSetForeground (TcDisplay, TcGc, TcXbackground.pixel);
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XFillRectangle (TcDisplay, TcPixmaps[TcActivePage], TcGc, TcViewLeft,
TcViewTop, TcViewRight - TcViewLeft + 1,
TcViewBottom - TcViewTop + 1);
if (TcActivePage == TcVisualPage)
{
XFillRectangle (TcDisplay, TcWindow, TcGc, TcViewLeft,
TcViewTop, TcViewRight - TcViewLeft + 1,
TcViewBottom - TcViewTop + 1);
XSync (TcDisplay, False);
}
XUnlockDisplay (TcDisplay);
XSetForeground (TcDisplay, TcGc, TcXforeground.pixel);
setwritemode (Mode);
} /* }}} */
/* TurboC-source/closegraph.c */
extern volatile int TcShutdownGraphics;
void
closegraph (void) /* {{{ */
{
if (TcGraphicsInitialized) {
register int i;
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
TcShutdownGraphics = 1;
while (TcShutdownGraphics || TcGraphicsInitialized);
#endif
#if 0
for (i = 0; i < MAX_TCIMAGEBUFS; i++)
if (TcPixmapPool[i].Allocated)
{
TcPixmapPool[i].Allocated = 0;
XFreePixmap (TcDisplay, TcPixmapPool[i].Region);
}
#endif /* 0 */
XFreePixmap (TcDisplay, TcTile);
XFreeGC (TcDisplay, TcGc);
XUnmapWindow (TcDisplay, TcWindow);
XUnmapWindow (TcDisplay, DefaultRootWindow (TcDisplay));
XDestroyWindow (TcDisplay, TcWindow);
for (i = 0; i < TcPageCount; i++)
XFreePixmap (TcDisplay, TcPixmaps[i]);
XFreeColormap (TcDisplay, TcColormap);
XCloseDisplay (TcDisplay);
TcGraphicsInitialized = 0;
}
} /* }}} */
/* restorecrtmode can be the same as closegraph because the textmode window */
/* never actually goes away, and therefore never needs to be restored. */
void
restorecrtmode (void) /* {{{ */
{
closegraph ();
} /* }}} */
/*TurboC-source/detectgraph.c */
/* We make the graphics screen this (integer) percentage of the full */
/* screen size, or less. */
#define SHRINK_PERCENT 90
void
detectgraph (int *graphdriver, int *graphmode) /* {{{ */
{
gint ScreenWidth, ScreenHeight;
ScreenWidth = 800;
ScreenHeight = 600;
if (TcGraphicsInitialized)
{
ScreenWidth = XDisplayWidth (TcDisplay, TcScreen);
ScreenHeight = XDisplayHeight (TcDisplay, TcScreen);
}
else
{
TcDisplay = XOpenDisplay (NULL);
if (TcDisplay != NULL)
{
TcScreen = DefaultScreen (TcDisplay);
ScreenWidth = XDisplayWidth (TcDisplay, TcScreen);
ScreenHeight = XDisplayHeight (TcDisplay, TcScreen);
XCloseDisplay (TcDisplay);
}
}
ScreenWidth = (SHRINK_PERCENT * ScreenWidth + 50) / 100;
ScreenHeight = (SHRINK_PERCENT * ScreenHeight + 50) / 100;
/* Now find the "best" mode that fits. Of course, what's "best" depends */
/* on your criteria ... */
if (ScreenWidth >= 1024 && ScreenHeight >= 768)
{
*graphdriver = IBM8514;
*graphmode = IBM8514HI;
}
else if (ScreenWidth >= 640 && ScreenHeight >= 480)
{
*graphdriver = IBM8514;
*graphmode = IBM8514LO;
}
else if (ScreenWidth >= 640 && ScreenHeight >= 350)
{
*graphdriver = VGA;
*graphmode = VGAMED;
}
else if (ScreenWidth >= 640 && ScreenHeight >= 200)
{
*graphdriver = EGA;
*graphmode = EGALO;
}
else
{
*graphdriver = CGA;
*graphmode = CGAC0;
}
} /* }}} */
/* TurboC-source/fillellipse.c */
void
fillellipse (int x, int y, int xradius, int yradius) /* {{{ */
{
/* Convert to viewport coordinates. */
x += TcViewLeft - xradius;
y += TcViewTop - yradius;
xradius *= 2;
yradius *= 2;
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XSetFillStyle (TcDisplay, TcGc, FillTiled);
XSetTile (TcDisplay, TcGc, TcTile);
XFillArc (TcDisplay, TcPixmaps[TcActivePage], TcGc, x, y, xradius, yradius,
0, 360 * 64);
if (TcActivePage == TcVisualPage)
{
XFillArc (TcDisplay, TcWindow, TcGc, x, y, xradius, yradius,
0, 360 * 64);
XSync (TcDisplay, False);
}
XSetFillStyle (TcDisplay, TcGc, FillSolid);
XUnlockDisplay (TcDisplay);
} /* }}} */
/* TurboC-source/getimage.c */
extern unsigned
imagesize (int left, int top, int right, int bottom) /* {{{ */
{
return (sizeof (struct TcImageBuffer));
} /* }}} */
extern void
getimage (int left, int top, int right, int bottom, void *bitmap) /* {{{ */
{
#define Buffer ((struct TcImageBuffer *) bitmap)
Pixmap Handle;
int OldWritemode;
int Left, Top, Right, Bottom, Clip;
Buffer->Width = right - left + 1;
Buffer->Height = bottom - top + 1;
Handle = XCreatePixmap (TcDisplay,
DefaultRootWindow (TcDisplay),
Buffer->Width, Buffer->Height,
DefaultDepth (TcDisplay, TcScreen));
AssociatePixmap (bitmap, Handle);
Buffer->Handle = Handle;
OldWritemode = TcWritemode;
if (OldWritemode != COPY_PUT)
setwritemode (COPY_PUT);
if (left > right)
{
Left = left;
left = right;
right = Left;
}
if (top > bottom)
{
Top = top;
top = bottom;
bottom = Top;
}
Left = TcViewLeft;
Top = TcViewTop;
Right = TcViewRight;
Bottom = TcViewBottom;
Clip = TcViewClip;
setviewport (0, 0, TcXresolution - 1, TcYresolution - 1, 0);
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XCopyArea (TcDisplay, TcWindow, Buffer->Handle,
TcGc, left, top, Buffer->Width, Buffer->Height, 0, 0);
XSync (TcDisplay, False);
XUnlockDisplay (TcDisplay);
setviewport (Left, Top, Right, Bottom, Clip);
if (OldWritemode != TcWritemode)
setwritemode (OldWritemode);
#undef Buffer
} /* }}} */
extern void
putimage (int left, int top, void *bitmap, int op) /* {{{ */
{
#define Buffer ((struct TcImageBuffer *) bitmap)
int OldWritemode;
int Left, Top, Right, Bottom, Clip;
if (bitmap == NULL)
return;
OldWritemode = TcWritemode;
if (OldWritemode != op)
setwritemode (op);
Left = TcViewLeft;
Top = TcViewTop;
Right = TcViewRight;
Bottom = TcViewBottom;
Clip = TcViewClip;
setviewport (0, 0, TcXresolution - 1, TcYresolution - 1, 0);
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XCopyArea (TcDisplay, Buffer->Handle, TcPixmaps[TcVisualPage],
TcGc, 0, 0, Buffer->Width, Buffer->Height, left, top);
XCopyArea (TcDisplay, Buffer->Handle, TcWindow,
TcGc, 0, 0, Buffer->Width, Buffer->Height, left, top);
XSync (TcDisplay, False);
XUnlockDisplay (TcDisplay);
setviewport (Left, Top, Right, Bottom, Clip);
if (OldWritemode != TcWritemode)
setwritemode (OldWritemode);
#undef Buffer
} /* }}} */
/* TurboC-source/getmaxcolor.c */
extern int
getmaxcolor (void) /* {{{ */
{
switch (TcPaletteNum)
{
case TC_PAL_2:
return (1);
case TC_PAL_4:
case TC_PAL_C0:
case TC_PAL_C1:
case TC_PAL_C2:
case TC_PAL_C3:
return (3);
case TC_PAL_16:
return (15);
case TC_PAL_256:
return (255);
default:
break;
}
/* Shouldn't be possible to get here, but still ... */
return (0);
} /* }}} */
extern int
getpalettesize (void) /* {{{ */
{
return (getmaxcolor () + 1);
} /* }}} */
/* TurboC-source/getmaxx.c */
int
getmaxx (void) /* {{{ */
{
return (TcXresolution - 1);
} /* }}} */
int
getmaxy (void) /* {{{ */
{
return (TcYresolution - 1);
} /* }}} */
/* TurboC-source/getpalette.c */
void
getpalette (struct palettetype *p) /* {{{ */
{
*p = TcCurrentPalette;
} /* }}} */
const struct palettetype *
getdefaultpalette (void) /* {{{ */
{
const struct palettetype *ret = NULL;
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
char *str = "NULL";
switch (TcPaletteNum)
{
case TC_PAL_2: str = "TC_PAL_2"; break;
case TC_PAL_4: str = "TC_PAL_4"; break;
case TC_PAL_C0: str = "TC_PAL_C0"; break;
case TC_PAL_C1: str = "TC_PAL_C1"; break;
case TC_PAL_C2: str = "TC_PAL_C2"; break;
case TC_PAL_C3: str = "TC_PAL_C3"; break;
case TC_PAL_16: str = "TC_PAL_16"; break;
}
fprintf(stderr, "getdefaultpalette(): returning %s (%d)",
str, TcPaletteNum);
#endif
switch (TcPaletteNum)
{
case TC_PAL_2: ret = &TcDefaultPalette2; break;
case TC_PAL_4: ret = &TcDefaultPalette4; break;
case TC_PAL_C0: ret = &TcDefaultPaletteC0; break;
case TC_PAL_C1: ret = &TcDefaultPaletteC1; break;
case TC_PAL_C2: ret = &TcDefaultPaletteC2; break;
case TC_PAL_C3: ret = &TcDefaultPaletteC3; break;
case TC_PAL_16: ret = &TcDefaultPalette16; break;
}
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, ", palette size %d\n", ret->size);
#endif
return ret;
} /* }}} */
/* TurboC-source/getpixel.c */
unsigned
getpixel (int x, int y) /* {{{ */
{
gint i, maxi, ClosestS, s;
XColor Color;
unsigned RetVal = 0;
XImage *Image;
/* Convert to viewport coordinates. */
x += TcViewLeft;
y += TcViewTop;
/* Now do the interrogating. */
XLockDisplay (TcDisplay);
Image = XGetImage (TcDisplay, TcPixmaps[TcVisualPage], x, y, 1, 1,
~0L, XYPixmap);
if (Image != NULL)
{
Color.pixel = XGetPixel (Image, 0, 0);
XDestroyImage (Image);
/* Look up the rgb components of the raw pixel we've read back. */
XQueryColor (TcDisplay, TcColormap, &Color);
XUnlockDisplay (TcDisplay);
/* Find the closest-match color in our current palette. Since the */
/* colors in our palette are generally so far apart from each other, */
/* we can save a lot of execution time by using a taxi-cab metric */
/* rather than a Euclidean metric. */
ClosestS = 1000000;
maxi = getmaxcolor ();
for (i = 0; i <= maxi; i++)
{
s = abs (Color.red - TcColors[i].r) + abs (Color.green - TcColors[i].g)
+ abs (Color.blue - TcColors[i].b);
if (s < ClosestS)
{
RetVal = i;
ClosestS = s;
}
if (s == 0)
break;
}
}
else
XUnlockDisplay (TcDisplay);
return (RetVal);
} /* }}} */
/* TurboC-source/gettextsettings.c */
void
gettextsettings (struct textsettingstype *info) /* {{{ */
{
info->font = TcTextFont;
info->direction = TcTextDirection;
info->charsize = TcTextCharsize;
info->horiz = TcTextHoriz;
info->vert = TcTextVert;
} /* }}} */
/* TurboC-source/graphdefaults.c */
void
graphdefaults (void) /* {{{ */
{
TcDefaultColors (TcPaletteNum);
TcGraphDefaults ();
} /* }}} */
void
TcGraphDefaults (void) /* {{{ */
{
setviewport (0, 0, getmaxx (), getmaxy (), 1);
setcolor (getmaxcolor ());
setlinestyle (SOLID_LINE, 0, NORM_WIDTH);
settextstyle (DEFAULT_FONT, HORIZ_DIR, 1);
settextjustify (LEFT_TEXT, TOP_TEXT);
setfillstyle (SOLID_FILL, getmaxcolor ());
setbkcolor (0);
setusercharsize (1, 1, 1, 1);
} /* }}} */
/* Sets the default colors for a given palette type. Returns 0 on success. */
int
TcDefaultColors (int Pal) /* {{{ */
{
int i;
switch (Pal)
{
case TC_PAL_2:
TcCurrentPalette = TcDefaultPalette2;
TcForegroundColor = 1;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColors2[i];
break;
case TC_PAL_C0:
TcCurrentPalette = TcDefaultPaletteC0;
TcForegroundColor = 3;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColorsC0[i];
break;
case TC_PAL_C1:
TcCurrentPalette = TcDefaultPaletteC1;
TcForegroundColor = 3;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColorsC1[i];
break;
case TC_PAL_C2:
TcCurrentPalette = TcDefaultPaletteC2;
TcForegroundColor = 3;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColorsC2[i];
break;
case TC_PAL_C3:
TcCurrentPalette = TcDefaultPaletteC3;
TcForegroundColor = 3;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColorsC3[i];
break;
case TC_PAL_4:
TcCurrentPalette = TcDefaultPalette4;
TcForegroundColor = 3;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColors4[i];
break;
case TC_PAL_16:
TcCurrentPalette = TcDefaultPalette16;
TcForegroundColor = 15;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColors16[i];
break;
case TC_PAL_256:
TcForegroundColor = 15;
for (i = 0; i <= TcForegroundColor; i++)
TcColors[i] = TcColors16[i];
for (; i < 256; i++)
TcColors[i] = TcColors16[0];
break;
default:
return (1);
}
return (0);
} /* }}} */
/* TurboC-source/grapherrormsg.c */
static const char *ErrorMessages[] = { /* {{{ */
"No error",
"(BGI) graphics not installed (use initgraph)",
"Graphics hardware not detected",
"Device driver file not found",
"Invalid device driver file",
"Not enough memory to load driver",
"Out of memory in scan fill",
"Out of memory in flood fill",
"Font file not found",
"Not enough memory to load font",
"Invalid graphics mode for selected driver",
"Graphics error",
"Graphics I/O error",
"Invalid font file",
"Invalid font number",
"Invalid device number",
"Unknown error",
"Unknown error",
"Invalid version of file"
}; /* }}} */
#define NUM_MESSAGES (sizeof (ErrorMessages) / sizeof (ErrorMessages[0]))
char *
grapherrormsg (int errorcode) /* {{{ */
{
static char ErrorMessage[61];
if (errorcode < 0 || errorcode >= NUM_MESSAGES)
strcpy(ErrorMessage, "Unknown error");
else
strcpy(ErrorMessage, ErrorMessages[errorcode]);
return ErrorMessage;
} /* }}} */
/* TurboC-source/graphresult.c */
int
graphresult (void) /* {{{ */
{
int i;
i = TcGraphResult;
TcGraphResult = grOk;
return (i);
} /* }}} */
/* TurboC-source/initgraph.c */
/*#include "graphics.h" */
/*#include "conio.h" */
extern void
setgraphmode (int mode) /* {{{ */
{
int graphdriver;
graphdriver = TcDriver;
initgraph (&graphdriver, &mode, "");
} /* }}} */
/* Borland Turbo C relies on loading a "graphics driver" ("*.BGI" files, */
/* which are like a plug-in) at runtime. The pathtodriver variable is */
/* supposed to specify the directory in which these driver files are located. */
/* The TurboC library, on the other hand, doesn't rely on the "driver" concept, */
/* and so the pathtodriver variables and graphdriver are unused. */
/* The TurboC library will allow any graphics mode (graphmode) to be applied */
/* to any "driver". */
extern void
initgraph (int *graphdriver, int *graphmode, char *pathtodriver) /* {{{ */
{
XSizeHints *SizeHints;
int i, Xres, Yres, Pcnt, Pal;
gulong White, Black;
Atom wm_delete_window;
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
if (!ThreadsInitialized)
{
XInitThreads ();
ThreadsInitialized = 1;
}
#endif
if (TcGraphicsInitialized)
closegraph ();
/* An alternate display name might allow the program to be run remotely. */
/* Since the conio.h functionality of the TurboC library (implemented */
/* in ncurses) is accessible remotely, it would be consistent to implement */
/* this. If/when I figure this out, I'll fix it up. */
if (*graphdriver == 0)
detectgraph (graphdriver, graphmode);
TcDisplay = XOpenDisplay (NULL);
if (TcDisplay == NULL)
{
TcGraphResult = *graphdriver = grNotDetected;
return;
}
TcScreen = DefaultScreen (TcDisplay);
switch ((*graphmode) % TCX)
{
case TC_X_320:
Xres = 320;
break;
case TC_X_640:
Xres = 640;
break;
case TC_X_720:
Xres = 720;
break;
case TC_X_800:
Xres = 800;
break;
case TC_X_1024:
Xres = 1024;
break;
case TC_X_1280:
Xres = 1280;
break;
default:
XCloseDisplay (TcDisplay);
TcGraphResult = *graphdriver = grInvalidMode;
return;
}
switch ((*graphmode / TCX) % TCY)
{
case TC_Y_200:
Yres = 200;
break;
case TC_Y_348:
Yres = 348;
break;
case TC_Y_350:
Yres = 350;
break;
case TC_Y_400:
Yres = 400;
break;
case TC_Y_480:
Yres = 480;
break;
case TC_Y_600:
Yres = 600;
break;
case TC_Y_768:
Yres = 768;
break;
case TC_Y_1024:
Yres = 1024;
break;
default:
XCloseDisplay (TcDisplay);
TcGraphResult = *graphdriver = grInvalidMode;
return;
}
switch ((*graphmode / TCXY) % TCG)
{
case TC_PG_1:
Pcnt = 1;
break;
case TC_PG_2:
Pcnt = 2;
break;
case TC_PG_4:
Pcnt = 4;
break;
default:
XCloseDisplay (TcDisplay);
TcGraphResult = *graphdriver = grInvalidMode;
return;
}
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "x11-bgi.c: initgraph(): Xres = %d, Yres = %d, Pcnt = %d\n",
Xres, Yres, Pcnt);
#endif
White = WhitePixel (TcDisplay, TcScreen);
Black = BlackPixel (TcDisplay, TcScreen);
SizeHints = XAllocSizeHints ();
SizeHints->flags = PMinSize | PMaxSize | PBaseSize;
SizeHints->min_width = Xres;
SizeHints->max_width = Xres;
SizeHints->base_width = Xres;
SizeHints->min_height = Yres;
SizeHints->max_height = Yres;
SizeHints->base_height = Yres;
TcWindow = XCreateSimpleWindow (TcDisplay,
DefaultRootWindow (TcDisplay),
0, 0, Xres, Yres, 0, White, Black);
/* Set up window title */
{
char *window_name = NULL;
#if defined(PACKAGE)
# if defined(VERSION)
window_name = strdup(PACKAGE " " VERSION);
if (window_name != NULL && strchr(VERSION, '-') != NULL)
*strrchr(window_name, '-') = '\0';
# else
window_name = strdup(PACKAGE);
# endif
if (window_name != NULL)
window_name[0] = toupper(window_name[0]);
#endif
XChangeProperty(TcDisplay, TcWindow, XA_WM_NAME, XA_STRING, 8,
PropModeReplace, window_name == NULL
? (unsigned char *) "X11 BGI"
: (unsigned char *) window_name, 50);
#if defined(PACKAGE)
if (window_name != NULL)
free(window_name);
#endif
}
/* Beg the window manager not to allow the window to be resized. */
XSetNormalHints (TcDisplay, TcWindow, SizeHints);
/* Tell the window manager we don't want the graphics window */
/* arbitrarily closed on us -- we want a signal instead. */
wm_delete_window = XInternAtom (TcDisplay, "WM_DELETE_WINDOW", False);
XSetWMProtocols (TcDisplay, TcWindow, &wm_delete_window, 1);
TcGc = XCreateGC (TcDisplay, TcWindow, 0, 0);
XSetArcMode (TcDisplay, TcGc, ArcPieSlice);
XSetForeground (TcDisplay, TcGc, Black);
for (i = 0; i < Pcnt; i++)
{
TcPixmaps[i] = XCreatePixmap (TcDisplay,
DefaultRootWindow (TcDisplay),
Xres, Yres,
DefaultDepth (TcDisplay, TcScreen));
XFillRectangle (TcDisplay, TcPixmaps[i], TcGc, 0, 0, Xres, Yres);
}
XFree (SizeHints);
/* Save what minimal info we need about the palette. */
Pal = (*graphmode / TCXYG) % TCP;
/* Set up the default colors in the palette. */
if (TcDefaultColors (Pal))
{
for (i = 0; i < Pcnt; i++)
XFreePixmap (TcDisplay, TcPixmaps[i]);
XDestroyWindow (TcDisplay, TcWindow);
XFreeGC (TcDisplay, TcGc);
XCloseDisplay (TcDisplay);
TcGraphResult = *graphdriver = grInvalidMode;
return;
}
TcColormap = DefaultColormap (TcDisplay, TcScreen);
XMapWindow (TcDisplay, TcWindow);
XSync (TcDisplay, False);
TcDriver = *graphdriver;
TcCurrentGraphMode = *graphmode;
TcXresolution = Xres;
TcYresolution = Yres;
TcPageCount = Pcnt;
TcVisualPage = TcActivePage = 0;
TcPaletteNum = Pal;
TcBackgroundColor = 0;
TcTile = XCreatePixmap (TcDisplay,
DefaultRootWindow (TcDisplay),
8, 8, DefaultDepth (TcDisplay, TcScreen));
TcGraphDefaults ();
TcGraphicsInitialized = 1;
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
if (ThreadsInitialized == 1)
{
ThreadsInitialized = 2;
if (pthread_create (&ExposerThread, NULL, ExposerFunction, NULL))
{
TcGraphResult = *graphdriver = grNoLoadMem;
return;
}
}
#endif
} /* }}} */
int volatile TcShutdownGraphics = 0;
static void *
ExposerFunction (void *DummyArg) /* {{{ */
{
XSelectInput(TcDisplay, TcWindow, X11_BGI_INPUT_MASK);
ExposerFunctionLoop();
return NULL;
} /* }}} */
static void
ExposerFunctionLoop(void) /* {{{ */
{
XEvent Event;
int i, j;
#if defined(X11_BGI_USE_XKeycodeToKeysym) && X11_BGI_USE_XKeycodeToKeysym
/* nothing needed */
#else
char Text[32];
KeySym Key;
#endif
#if defined(X11_BGI_USE_SELECT) && X11_BGI_USE_SELECT
struct timeval tval;
fd_set readfds;
#endif
do {
/* When the main thread wants to turn off graphics mode, it */
/* sets TcShutdownGraphics to 1 and waits until it turns */
/* back to 0 before proceeding. */
if (TcShutdownGraphics) {
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
ThreadsInitialized = 0;
#endif
TcShutdownGraphics = 0;
TcGraphicsInitialized = 0;
return;
}
#if defined(X11_BGI_USE_SELECT) && X11_BGI_USE_SELECT
/* Note: the select() call with nonzero timeout avoids CPU usage of nearly 100% */
i = ConnectionNumber(TcDisplay);
FD_ZERO(&readfds);
FD_SET(i, &readfds);
tval.tv_sec = 0;
tval.tv_usec = 1;
i = select(i + 1, &readfds, NULL, NULL, &tval);
#else
usleep(1);
#endif
XLockDisplay (TcDisplay);
if (XCheckWindowEvent(TcDisplay, TcWindow, X11_BGI_INPUT_MASK, &Event)) {
switch (Event.type)
{
default:
/* XPutBackEvent(TcDisplay, &Event); */
break;
case Expose:
/* Come here after something moves in front of our window */
/* so that we need to redraw it. */
XCopyArea(TcDisplay, TcPixmaps[TcVisualPage], TcWindow,
TcGc, Event.xexpose.x, Event.xexpose.y,
Event.xexpose.width, Event.xexpose.height,
Event.xexpose.x, Event.xexpose.y);
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): Expose\n");
#endif
break;
case KeyPress:
case KeyRelease:
if (KEYINFO_buffer != 0) {
XPutBackEvent(TcDisplay, &Event);
break;
}
#if defined(X11_BGI_USE_XKeycodeToKeysym) && X11_BGI_USE_XKeycodeToKeysym
i = XKeycodeToKeysym(TcDisplay, Event.xkey.keycode, 0);
KEYINFO_buffer = i;
# if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): Key%s %x (%d)",
Event.xkey.type == KeyPress ? "Press" : "Release", i, i);
if (i >= 0 && i <= 255 && isprint(i))
fprintf(stderr, " [%c]", i);
fputc('\n', stderr);
# endif
#else
/* This needs to be fixed up some to accomodate things */
/* like arrows and function keys, but it works okay for */
/* regular keys as-is. */
i = XLookupString(&Event.xkey, Text, sizeof(Text), &Key, NULL);
for (j = 0; j < i; j++) {
/* TODO: handle this
TcAddKeybuf(Text[j]) */
# if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): Key%s %x (%d) [%c]\n",
Event.xkey.type == KeyPress ? "Press" : "Release",
Text[j], Text[j], Text[j]);
# endif
}
#endif
break;
case NoExpose:
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): NoExpose\n");
#endif
break;
case ClientMessage:
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): ClientMessage\n");
#endif
/* Come here if the user tries to manually close the graphics */
/* window. We allow the programmer to decide what to do */
/* about it. The callback function TurboX can be provided */
/* by the programmer, but we also provide a default version that */
/* just returns 1. A return value of 0 means to continue */
/* executing, while a non-zero value means to close down the */
/* program. */
if (TurboX(0)) {
XUnlockDisplay(TcDisplay);
#if 0
closegraph ();
kill(0, SIGTERM);
#endif
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
ThreadsInitialized = 0;
#endif
TcGraphicsInitialized = 0;
/*return (NULL); */
exit(2);
}
break;
/* These event handler modifications regarding to mouse
handling was added by Nepto at 28th September 2003 */
case MotionNotify:
MOUINFO_xpos = Event.xmotion.x;
MOUINFO_ypos = Event.xmotion.y;
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): MotionNotify [%d,%d]\n",
MOUINFO_xpos, MOUINFO_ypos);
#endif
break;
case ButtonPress:
case ButtonRelease:
#if 0 /* This is orginal algorithm
DO NOT DELETE FROM SOURCE! */
unsigned int state = Event.state;
unsigned int mask = 0;
switch (Event.button) {
case Button1: mask = Button1Mask; break;
case Button2: mask = Button2Mask; break;
case Button3: mask = Button3Mask; break;
}
switch (Event.type) {
case ButtonPress: state |= mask; break;
case ButtonRelease: state &= ~mask; break;
}
return ( ((state & Button1Mask) ? GR_M_LEFT : 0)
| ((state & Button2Mask) ? GR_M_MIDDLE : 0)
| ((state & Button3Mask) ? GR_M_RIGHT : 0));
#endif
switch (Event.xbutton.button)
{
case Button1: i = Button1Mask; j = 0; break;
case Button2: i = Button2Mask; j = 1; break;
case Button3: i = Button3Mask; j = 2; break;
default: i = 0; j = -1; break;
}
switch (Event.xbutton.type)
{
case ButtonPress:
if (j >= 0 && j <= 2)
MOUINFO_pressed_count[j]++;
j = Event.xbutton.state | i;
break;
case ButtonRelease:
if (j >= 0 && j <= 2)
MOUINFO_released_count[j]++;
j = Event.xbutton.state & ~i;
break;
}
MOUINFO_bstat = 0
+ ((j & Button1Mask) ? 1 : 0)
+ ((j & Button2Mask) ? 0 : 0) /* Middle button disabled */
+ ((j & Button3Mask) ? 2 : 0);
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "ExposerFunctionLoop(): Button%s %d\n",
Event.xbutton.type == ButtonPress ? "Press" : "Release",
MOUINFO_bstat);
#endif
break;
}
}
XUnlockDisplay (TcDisplay);
}
#if defined(X11_BGI_USE_PTHREADS) && X11_BGI_USE_PTHREADS
while (1);
#else
while (0); /* exit when not in thread */
#endif
} /* }}} */
/* TurboC-source/line.c */
void
line (int x1, int y1, int x2, int y2) /* {{{ */
{
/* Convert to viewport coordinates. */
x1 += TcViewLeft;
x2 += TcViewLeft;
y1 += TcViewTop;
y2 += TcViewTop;
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XDrawLine (TcDisplay, TcPixmaps[TcActivePage], TcGc, x1, y1, x2, y2);
if (TcActivePage == TcVisualPage)
{
XDrawLine (TcDisplay, TcWindow, TcGc, x1, y1, x2, y2);
XSync (TcDisplay, False);
}
XUnlockDisplay (TcDisplay);
} /* }}} */
void
lineto (int x, int y) /* {{{ */
{
int x1, y1;
x1 = Tcx;
y1 = Tcy;
Tcx = x;
Tcy = y;
line (x1, y1, x, y);
} /* }}} */
void
linerel (int dx, int dy) /* {{{ */
{
lineto (Tcx + dx, Tcy + dy);
} /* }}} */
void
moveto (int x, int y) /* {{{ */
{
Tcx = x;
Tcy = y;
} /* }}} */
void
moverel (int dx, int dy) /* {{{ */
{
Tcx += dx;
Tcy += dy;
} /* }}} */
int
getx (void) /* {{{ */
{
return (Tcx);
} /* }}} */
int
gety (void) /* {{{ */
{
return (Tcy);
} /* }}} */
/* TurboC-source/outtextxy.c */
void
outtextxy (int x, int y, char * textstring) /* {{{ */
{
XPoint Points[64], DumPoints[64];
int NumPoints;
int CharX, CharY, DeltaCharX, DeltaCharY;
int RowX, RowY, DeltaRowX, DeltaRowY, DeltaX, DeltaY;
int OffX, OffY;
int i, j, Mask;
/* We need to convert x,y to where it is the upper-left corner of the */
/* first character of the string (if viewed comfortably for reading). */
if (TcTextDirection == HORIZ_DIR)
{
switch (TcTextHoriz)
{
case LEFT_TEXT:
break;
case CENTER_TEXT:
x -= textwidth (textstring) / 2;
break;
case RIGHT_TEXT:
x -= textwidth (textstring);
break;
}
switch (TcTextVert)
{
case BOTTOM_TEXT:
y -= textheight (textstring);
break;
case CENTER_TEXT:
y -= textheight (textstring) / 2;
break;
case TOP_TEXT:
break;
}
}
else /* VERT_DIR */
{
switch (TcTextHoriz)
{
case LEFT_TEXT:
/* This does not actually work in true Turbo C 2.x. */
/* The text ends up right-justified in my tests. */
/* I'm not sure if I should duplicate Borland's bug or not .... */
/* No, I guess I'll make it work the way it's documented, */
/* since Borland may have fixed it in later versions. */
break;
case CENTER_TEXT:
x -= textheight (textstring) / 2;
break;
case RIGHT_TEXT:
x -= textheight (textstring);
break;
}
switch (TcTextVert)
{
case BOTTOM_TEXT:
break;
case CENTER_TEXT:
y += textwidth (textstring) / 2;
break;
case TOP_TEXT:
y += textwidth (textstring);
break;
}
}
/* Convert to viewport coordinates. */
CharX = x + TcViewLeft;
CharY = y + TcViewTop;
XLockDisplay (TcDisplay);
/* The bitmapped font ... */
if (TcTextFont == DEFAULT_FONT)
{
if (TcTextDirection == HORIZ_DIR)
{
DeltaCharX = 8 * TcTextCharsize;
DeltaCharY = 0;
DeltaX = TcTextCharsize;
DeltaY = 0;
DeltaRowX = 0;
DeltaRowY = TcTextCharsize;
}
else
{
DeltaCharY = -8 * TcTextCharsize;
DeltaCharX = 0;
DeltaY = -TcTextCharsize;
DeltaX = 0;
DeltaRowY = 0;
DeltaRowX = TcTextCharsize;
}
for (; *textstring; textstring++)
{
/* Here's the basic idea. For each character, we set up the */
/* Points array to contain all of the visible pixels in the char. */
/* This entire set of pixels is drawn at once with XDrawPoints. */
/* If the chracter size has been magnified, so that each */
/* "pixel" is really an NxN block of pixels, we modify the */
/* coordinates in Points NxN times and use XDrawPoints NxN times. */
/* First, though, there is the initial setup of Points. */
NumPoints = 0;
i = (guchar) *textstring;
RowX = CharX;
RowY = CharY;
for (j = 0; j < 8; j++)
{
x = RowX;
y = RowY;
for (Mask = TcConsole8Font[i][j] ; Mask; Mask = Mask << 1)
{
if (0 != (Mask & 128))
{
/* Note that this CAN'T overflow the array. */
Points[NumPoints].x = x;
Points[NumPoints].y = y;
NumPoints++;
}
x += DeltaX;
y += DeltaY;
}
RowX += DeltaRowX;
RowY += DeltaRowY;
}
/* Now, draw the points */
if (TcTextCharsize == 1)
{
XDrawPoints (TcDisplay, TcPixmaps[TcActivePage], TcGc, Points, NumPoints, CoordModeOrigin);
if (TcActivePage == TcVisualPage)
XDrawPoints (TcDisplay, TcWindow, TcGc, Points, NumPoints, CoordModeOrigin);
}
else
{
for (x = 0; x < TcTextCharsize; x++)
{
for (y = 0; y < TcTextCharsize; y++)
{
if (TcTextDirection == HORIZ_DIR)
{
OffX = x;
OffY = y;
}
else
{
OffX = y;
OffY = -x;
}
for (i = 0; i < NumPoints; i++)
{
DumPoints[i].x = Points[i].x + OffX;
DumPoints[i].y = Points[i].y + OffY;
}
XDrawPoints (TcDisplay, TcPixmaps[TcActivePage], TcGc, DumPoints, NumPoints, CoordModeOrigin);
if (TcActivePage == TcVisualPage)
XDrawPoints (TcDisplay, TcWindow, TcGc, DumPoints, NumPoints, CoordModeOrigin);
}
}
}
CharX += DeltaCharX;
CharY += DeltaCharY;
}
}
if (TcActivePage == TcVisualPage)
XSync (TcDisplay, False);
XUnlockDisplay (TcDisplay);
} /* }}} */
void
outtext (char *textstring) /* {{{ */
{
outtextxy (Tcx, Tcy, textstring);
if (TcTextDirection == HORIZ_DIR && TcTextHoriz == LEFT_TEXT)
Tcx += textwidth (textstring);
} /* }}} */
/* TurboC-source/putpixel.c */
/* This is original putpixel() function from the TurboC library.
However it does not work well, because sometimes pixel are not printed. */
static void
putpixel_orig (int x, int y, int color) /* {{{ */
{
int OldColor;
OldColor = TcForegroundColor;
if (color != OldColor)
setcolor (color);
/* Convert to viewport coordinates. */
x += TcViewLeft;
y += TcViewTop;
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XDrawPoint (TcDisplay, TcPixmaps[TcActivePage], TcGc, x, y);
if (TcActivePage == TcVisualPage)
{
XDrawPoint (TcDisplay, TcWindow, TcGc, x, y);
XSync (TcDisplay, False);
}
XUnlockDisplay (TcDisplay);
if (color != OldColor)
setcolor (OldColor);
} /* }}} */
/* Safe variant of putpixel() function was created
by Ondrej Jombik <nepto@platon.sk> 2004-04-05 */
static void
putpixel_safe (int x, int y, int color) /* {{{ */
{
register int n_loops;
for (n_loops = 0; getpixel(x, y) != color; n_loops++)
putpixel_orig(x, y, color);
#if defined(X11_BGI_DEBUG) && X11_BGI_DEBUG
fprintf(stderr, "putpixel_safe(%d, %d, %d): n_loops = %d (%sCOMMON)\n",
x, y, color, n_loops, n_loops == 1 || n_loops == 0 ? "" : "UN");
#endif
} /* }}} */
void
putpixel(int x, int y, int color) /* {{{ */
{
putpixel_safe(x, y, color);
} /* }}} */
/* TurboC-source/rectangle.c */
void
rectangle (int x1, int y1, int x2, int y2) /* {{{ */
{
int i, j;
if (x1 > x2)
{
i = x1;
x1 = x2;
x2 = i;
}
if (y1 > y2)
{
i = y1;
y1 = y2;
y2 = i;
}
/* -1 hack by Nepto */
i = x2 - x1 + 1 - 1;
j = y2 - y1 + 1 - 1;
/* Convert to viewport coordinates. */
x1 += TcViewLeft;
y1 += TcViewTop;
/* Now do the actual drawing. */
XLockDisplay (TcDisplay);
XDrawRectangle (TcDisplay, TcPixmaps[TcActivePage], TcGc, x1, y1, i, j);
if (TcActivePage == TcVisualPage)
{
XDrawRectangle (TcDisplay, TcWindow, TcGc, x1, y1, i, j);
XSync (TcDisplay, False);
}
XUnlockDisplay (TcDisplay);
} /* }}} */
/* TurboC-source/setbkcolor.c */
void
setbkcolor (int color) /* {{{ */
{
XColor Color;
if (color < 0)
{
Error:
TcGraphResult = grError;
return;
}
Color.pixel = 0;
Color.flags = DoRed | DoGreen | DoBlue;
Color.pad = 0;
switch (TcPaletteNum)
{
case TC_PAL_2:
Color.red = 0;
Color.green = 0;
Color.blue = 0;
break;
case TC_PAL_4:
case TC_PAL_C0:
case TC_PAL_C1:
case TC_PAL_C2:
case TC_PAL_C3:
/* I treat these all similarly to CGA 4-color palettes. */
/* The Turbo C docs indicate somehow that in CGA "hi-res" */
/* mode, the background and foreground colors are reversed. */
/* I don't deal with this as of yet, because I don't grasp */
/* what it means. */
if (color >= 16)
goto Error;
Color.red = TcColors16[color].r;
Color.green = TcColors16[color].g;
Color.blue = TcColors16[color].b;
TcCurrentPalette.colors[0] = color;
break;
case TC_PAL_16:
/* I treat these all similarly to EGA 16-color palettes. */
if (color >= 16)
goto Error;
Color.red = TcColors[color].r;
Color.green = TcColors[color].g;
Color.blue = TcColors[color].b;
if (TcDriver == EGA || TcDriver == EGA64)
TcCurrentPalette.colors[0] = color;
break;
case TC_PAL_256:
if (color >= 256)
goto Error;
Color.red = TcColors[color].r;
Color.green = TcColors[color].g;
Color.blue = TcColors[color].b;
break;
}
XAllocColor (TcDisplay, TcColormap, &Color);
TcBackgroundColor = color;
TcXbackground = Color;
XSetBackground (TcDisplay, TcGc, Color.pixel);
/* The background color will now presumably be inconsistent with */
/* any tile that has previously been generated for fills. We therefore */
/* need to regenerate the tile. This same problem *does not* */
/* exist for setcolor, since fills don't use the foreground color. */
setfillstyle (TcFillStyle, TcFillColor);
} /* }}} */
int
getbkcolor (void) /* {{{ */
{
return (TcBackgroundColor);
} /* }}} */
/* TurboC-source/setcolor.c */
extern void
setcolor (int color) /* {{{ */
{
XColor Color;
if (color < 0)
{
Error:
TcGraphResult = grError;
return;
}
Color.pixel = 0;
Color.flags = DoRed | DoGreen | DoBlue;
Color.pad = 0;
switch (TcPaletteNum)
{
case TC_PAL_2:
if (color != 1)
goto Error;
break;
case TC_PAL_4:
case TC_PAL_C0:
case TC_PAL_C1:
case TC_PAL_C2:
case TC_PAL_C3:
if (color > 3)
goto Error;
break;
case TC_PAL_16:
if (color > 15)
goto Error;
break;
case TC_PAL_256:
if (color > 255)
goto Error;
break;
default:
goto Error;
}
Color.red = TcColors[color].r;
Color.green = TcColors[color].g;
Color.blue = TcColors[color].b;
XLockDisplay (TcDisplay);
XAllocColor (TcDisplay, TcColormap, &Color);
TcForegroundColor = color;
TcXforeground = Color;
XSetForeground (TcDisplay, TcGc, Color.pixel);
XUnlockDisplay (TcDisplay);
} /* }}} */
int
getcolor (void) /* {{{ */
{
return (TcForegroundColor);
} /* }}} */
/* TurboC-source/setfillXXXX.c */
static void
RawTile (char *pattern) /* {{{ */
{
int i, j, k, Match;
int OldColor;
OldColor = TcForegroundColor;
/* This loop draws all of the background-color pixels on the first */
/* pass, and all of the fill-color pixels on the second. */
for (Match = 0; Match < 0x100; Match += 0x80)
{
if (Match)
setcolor (TcFillColor);
else
setcolor (TcBackgroundColor);
for (i = 0; i < 8; i++)
{
k = pattern[i];
for (j = 0; j < 8; j++)
{
if (Match == (k & 0x80))
XDrawPoint (TcDisplay, TcTile, TcGc, j, i);
k = k << 1;
}
}
}
setcolor (OldColor);
} /* }}} */
void
setfillpattern (char *upattern, int color) /* {{{ */
{
int i;
for (i = 0; i < 8; i++)
TcUserFillPattern[i] = upattern[i];
TcFillColor = color;
TcFillStyle = USER_FILL;
RawTile (upattern);
} /* }}} */
void
getfillpattern (char *upattern) /* {{{ */
{
int i;
for (i = 0; i < 8; i++)
upattern[i] = TcUserFillPattern[i];
} /* }}} */
/* These are setfillpattern-compatible arrays for all of the tiling patterns. */
static guchar FillStyles[12][8] = { /* {{{ */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00},
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80},
{0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x81},
{0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x81},
{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01},
{0x22, 0x22, 0xff, 0x22, 0x22, 0x22, 0xff, 0x22},
{0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81},
{0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44},
{0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00},
{0x11, 0x00, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00}
}; /* }}} */
void
setfillstyle (int pattern, int color) /* {{{ */
{
/* An input value of USER_FILL isn't actually legal, but it's convenient */
/* for us to use it (in conjunction with setbkcolor). */
if (pattern < 0 || pattern > USER_FILL)
{
TcGraphResult = grError;
return;
}
TcFillColor = color;
TcFillStyle = pattern;
if (pattern == USER_FILL)
RawTile ((char *) TcUserFillPattern);
else
RawTile ((char *) &FillStyles[pattern][0]);
} /* }}} */
void
getfillsettings (struct fillsettingstype *fillinfo) /* {{{ */
{
fillinfo->pattern = TcFillStyle;
fillinfo->color = TcFillColor;
} /* }}} */
/* TurboC-source/setlinestyle.c */
void
setlinestyle (int linestyle, unsigned upattern, int thickness) /* {{{ */
{
gint line_style, dash_offset = 0, n = 0, i, j, k;
unsigned OrigUpattern;
char dash_list[18];
OrigUpattern = upattern;
switch (linestyle)
{
case SOLID_LINE:
line_style = LineSolid;
break;
case DOTTED_LINE:
line_style = LineOnOffDash;
n = 2;
dash_offset = 0;
dash_list[0] = thickness;
dash_list[1] = thickness * 3;
break;
case CENTER_LINE:
line_style = LineOnOffDash;
n = 4;
dash_offset = 0;
dash_list[0] = 6 * thickness;
dash_list[1] = 3 * thickness;
dash_list[2] = 3 * thickness;
dash_list[3] = 3 * thickness;
break;
case DASHED_LINE:
line_style = LineOnOffDash;
n = 2;
dash_offset = 0;
dash_list[0] = 5 * thickness;
dash_list[1] = 3 * thickness;
break;
case USERBIT_LINE:
line_style = LineOnOffDash;
dash_offset = 0;
if (upattern == 0)
{
n = 2;
dash_list[0] = 1;
dash_list[1] = 7;
}
else
{
while (0 == (upattern & 0x8000))
upattern = upattern << 1;
n = 0;
i = ((upattern & 0x8000) == 0);
if (i)
{
dash_list[0] = 0;
n++;
}
dash_list[n] = 0;
for (j = 0; j < 16; j++, upattern = upattern << 1)
{
k = ((upattern & 0x8000) == 0);
if (i == k)
dash_list[n]++;
else
{
i = k;
n++;
dash_list[n] = 1;
}
}
n++;
if ((n & 1) != 0)
dash_list[n++] = 1;
}
break;
default:
TcGraphResult = grError;
return;
}
TcLinestyle.linestyle = linestyle;
TcLinestyle.upattern = OrigUpattern;
TcLinestyle.thickness = thickness;
XLockDisplay (TcDisplay);
XSetLineAttributes (TcDisplay, TcGc, thickness, line_style, CapRound,
JoinRound);
if (line_style == LineOnOffDash)
XSetDashes (TcDisplay, TcGc, dash_offset, dash_list, n);
XUnlockDisplay (TcDisplay);
} /* }}}*/
void
getlinesettings (struct linesettingstype *lineinfo) /* {{{ */
{
*lineinfo = TcLinestyle;
} /* }}} */
/* TurboC-source/setpalette.c */
void
setpalette (int colornum, int color) /* {{{ */
{
int rawcolor;
unsigned Scale;
XColor Color;
rawcolor = color;
if (color < 0)
{
Error:
TcGraphResult = grError;
return;
}
Color.pixel = 0;
Color.flags = DoRed | DoGreen | DoBlue;
Color.pad = 0;
switch (TcPaletteNum)
{
case TC_PAL_2:
goto Error;
case TC_PAL_C0:
case TC_PAL_C1:
case TC_PAL_C2:
case TC_PAL_C3:
if (colornum != 0 || color > 15)
goto Error;
setbkcolor (color);
return;
case TC_PAL_4:
if (colornum < 0 || colornum > 3 || color > 63)
goto Error;
goto Palette16;
case TC_PAL_16:
if (colornum < 0 || colornum > 15 || color > 63)
goto Error;
Palette16:
/* We *assume* that the allowable colors (0-63) are just */
/* scaled versions of the usual 16 colors. */
Scale = 0x40 * (1 + (color / 16));
color = color % 16;
TcColors[colornum].r = (TcColors16[color].r / 0x100) * Scale;
TcColors[colornum].g = (TcColors16[color].g / 0x100) * Scale;
TcColors[colornum].b = (TcColors16[color].b / 0x100) * Scale;
if (colornum == 0)
{
Color.red = TcColors[0].r;
Color.green = TcColors[0].g;
Color.blue = TcColors[0].b;
XAllocColor (TcDisplay, TcColormap, &Color);
TcBackgroundColor = color;
XSetBackground (TcDisplay, TcGc, Color.pixel);
}
else
setcolor (colornum);
break;
case TC_PAL_256:
goto Error;
default:
goto Error;
}
TcCurrentPalette.colors[colornum] = rawcolor;
} /* }}} */
void
setallpalette (struct palettetype *palette) /* {{{ */
{
int i;
TcGraphResult = grOk;
for (i = 0; i < palette->size; i++)
{
setpalette (i, palette->colors[i]);
if (TcGraphResult != grOk)
return;
}
} /* }}} */
/* TurboC-source/settextstyle.c */
void
settextstyle (int font, int direction, int charsize) /* {{{ */
{
if (font < 0 || font >= MAX_FONT)
return;
if (direction < 0 || direction > 1)
return;
if (charsize < 0 || charsize > 10)
return;
TcTextFont = font;
TcTextDirection = direction;
TcTextCharsize = charsize;
} /* }}} */
void
setusercharsize (int multx, int divx, int multy, int divy) /* {{{ */
{
if (multx <= 0 || multy <= 0 || divx <= 0 || divy <= 0)
return;
TcTextMultX = multx;
TcTextDivX = divx;
TcTextMultY = multy;
TcTextDivY = divy;
} /* }}} */
void
settextjustify (int horiz, int vert) /* {{{ */
{
if (horiz < 0 || horiz > 2 || vert < 0 || vert > 2)
{
TcGraphResult = grError;
return;
}
TcTextHoriz = horiz;
TcTextVert = vert;
} /* }}} */
/* TurboC-source/setviewport.c */
void
setviewport (int left, int top, int right, int bottom, int clip) /* {{{ */
{
XRectangle Rectangle;
if (left < 0 || right > TcXresolution - 1 || left >= right ||
top < 0 || bottom > TcYresolution - 1 || top >= bottom)
{
TcGraphResult = grError;
return;
}
TcViewLeft = left;
TcViewTop = top;
TcViewRight = right;
TcViewBottom = bottom;
TcViewMaxx = right - left;
TcViewMaxy = bottom - top;
TcViewClip = clip;
Tcx = Tcy = 0;
/* Account for clipping. Fortunately, this can be done entirely */
/* within X, by setting the clipping region within the graphics */
/* context. */
if (clip)
{
Rectangle.x = left;
Rectangle.y = top;
Rectangle.width = TcViewMaxx + 1;
Rectangle.height = TcViewMaxy + 1;
XSetClipRectangles (TcDisplay, TcGc, 0, 0, &Rectangle, 1, Unsorted);
}
else
XSetClipMask (TcDisplay, TcGc, None);
} /* }}} */
/* TurboC-source/setwritemode.c */
void
setwritemode (int mode) /* {{{ */
{
XGCValues Values;
switch (mode)
{
case COPY_PUT:
Values.function = GXcopy;
break;
case XOR_PUT:
Values.function = GXxor;
break;
case OR_PUT:
Values.function = GXor;
break;
case AND_PUT:
Values.function = GXand;
break;
case NOT_PUT:
Values.function = GXinvert;
break;
default:
return;
}
TcWritemode = mode;
XLockDisplay (TcDisplay);
XChangeGC (TcDisplay, TcGc, GCFunction, &Values);
XUnlockDisplay (TcDisplay);
} /* }}} */
/* TurboC-source/textwidth.c */
int
textwidth (char * textstring) /* {{{ */
{
/* Handle the bitmapped font separately, since it's so easy. */
if (TcTextFont == DEFAULT_FONT)
return (8 * strlen (textstring) * TcTextCharsize);
/* Handle the stroke fonts here. */
/*#warning Stroke fonts not implemented yet. Ignore warnings about textwidth. */
return 0;
} /* }}} */
int
textheight (char * textstring) /* {{{ */
{
/* Handle the bitmapped font separately, since it's so easy. */
if (TcTextFont == DEFAULT_FONT)
return (8 * TcTextCharsize);
/* Handle the stroke fonts here. */
/*#warning Stroke fonts not implemented yet. Ignore warnings about textheight. */
return 0;
} /* }}} */
/* Modeline for ViM {{{
* vim: set ts=4:
* vim600: fdm=marker fdl=0 fdc=0:
* }}} */
Platon Group <platon@platon.sk> http://platon.sk/
|