home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gondwana.ecr.mu.oz.au/pub/
/
Graphics.tar
/
Graphics
/
vogleplg.zip
/
DRIVERS
/
IBMPC
/
MSWINEXT.C
Wrap
C/C++ Source or Header
|
1994-07-17
|
20KB
|
875 lines
/****************************************************************************
PROGRAM: MSWINEXT.C
PURPOSE: MS-Windows driver for VOGLE/VOGL
For use with a window external to VOGLE
FUNCTIONS:
mswinext_cleanup() - frees objects created along the way in preparation for exit
mswinext_...() - VOGLE driver routines called by VOGLE
swap(() - swaps two integer values
****************************************************************************/
#include "windows.h" /* required for all Windows applications */
#include <stdio.h>
#include "vogle.h"
#define CMAPSIZE 256 /* max size of colour map */
#define MAX_INSTANCES 10 /* max # of instances of driver */
#define NO_INSTANCE -1 /* no current instance exists */
#define NO_WINDOW 0xffff /* no window info set before vinit() */
typedef COLORREF *PCOLORREF; /* pointer to a bunch of coloUr refs */
typedef struct _DRIVERINFO { /* info for driver operation */
int nId; /* id of this driver info structure */
HWND hWinder; /* handle of VOGLE's window */
HDC hMemoryDC; /* memory device context for hWinder */
HBITMAP hBitmap; /* bitmap compatible with hWinder */
unsigned int nCurColour; /* index of current colour in carray */
PCOLORREF carray; /* list of known colour values */
int bUseFrontBuf; /* FALSE if double buffering */
short int xChar; /* width of system font character */
short int yChar; /* height of system font character */
RECT BackRect; /* bitmap area to be swapped on next mswinext_swapbuf() call */
int nLWidth; /* line width */
} DRIVERINFO;
typedef struct _DEFERINFO { /* info for deferred creation of VOGLE instance */
HWND hWnd; /* window handle */
int w; /* window size... */
int h;
} DEFERINFO;
static DRIVERINFO InstanceTable[MAX_INSTANCES];
static DRIVERINFO Inst; /* save an indirection by storing the current instance info here */
static int nCurrentInstance = -1; /* no current instance */
static int bInited = FALSE; /* TRUE when init has been called at least once */
static DEFERINFO DeferInfo; /* info deferred to later creation of instance */
/* a couple of prototypes... */
static void InitInstances(void);
static int FindInstance(int);
static int mswinext_init(void);
static int mswinext_exit(void);
static void mswinext_cleanup(void);
static void mswinext_invalidate_rect(LPRECT);
static int mswinext_clear(void);
static int mswinext_draw(int, int);
static int mswinext_fill(int, int *, int *);
static int mswinext_color(int);
static int mswinext_mapcolor(int, int, int, int);
static int mswinext_char(char);
static int mswinext_string(char *);
static int mswinext_font(char *);
static int mswinext_frontbuf(void);
static int mswinext_backbuf(void);
static int mswinext_swapbuf(void);
static int mswinext_setlw(int);
static int noop(void);
extern int _mswinext_devcpy(void);
extern int mswin_verror(char *);
static int mswinext_SetupInstance(HWND, int, int);
extern int vo_mswinext_window(HWND, int, int);
extern int vo_mswinext_win_size(int, int);
extern int vo_mswinext_paint_window(HWND);
extern int vo_mswinext_paint_dc(HDC);
static void swap(int *, int *);
#ifdef MSC
#if (_MSC_VER >= 800)
#define strdup _strdup
#endif
#endif
char *strdup(char *);
static
void InitInstances()
{
int i;
for (i = 0; i < MAX_INSTANCES; i++) {
InstanceTable[i].nId = NO_INSTANCE;
InstanceTable[i].carray = NULL;
InstanceTable[i].hWinder = NULL;
}
nCurrentInstance = NO_INSTANCE;
}
static
int FindInstance(int nId)
{
int i;
for (i = 0; i < MAX_INSTANCES; i++) {
if (nId == InstanceTable[i].nId) {
/* found the required instance */
return i;
}
}
return NO_INSTANCE;
}
/*
* Save the state of an instance and return an instance
* identfier (for later restoration).
*/
int SaveInstance()
{
int n;
if ((n = nCurrentInstance) != NO_INSTANCE) {
/* save current instance in instance table */
InstanceTable[nCurrentInstance] = Inst;
/* now we have no current instance */
nCurrentInstance = NO_INSTANCE;
}
return n;
}
/*
* Restore an instance given a valid instance identifier.
* We won't restore an instance if there is a current one
* (call SaveInstance() first).
*/
int RestoreInstance(int nId)
{
if (nId < 0 || nId >= MAX_INSTANCES || nCurrentInstance != NO_INSTANCE) {
return NO_INSTANCE;
}
/* make sure we are using a valid instance id */
if (InstanceTable[nId].nId == NO_INSTANCE) return NO_INSTANCE;
/* restore the instance */
Inst = InstanceTable[nCurrentInstance = nId];
return nId;
}
static int mswinext_init()
{
HDC hDC;
PCOLORREF carray;
if (!bInited) {
/* do once off initialization */
InitInstances();
bInited = TRUE;
}
if (DeferInfo.hWnd == NO_WINDOW) {
/* we have no info for which to init VOGLE - cark */
return FALSE;
}
if (nCurrentInstance != NO_INSTANCE) {
/* zap current instance - too bad - user didn't save it */
mswinext_exit();
}
/* find a free instance */
nCurrentInstance = FindInstance(NO_INSTANCE);
if (nCurrentInstance == NO_INSTANCE) {
/* we've run out of available instances, cark it */
return FALSE;
}
Inst = InstanceTable[nCurrentInstance];
/* allocate the instance */
Inst.nId = nCurrentInstance;
/* find bit depth */
hDC = GetDC(GetDesktopWindow());
vdevice.depth = GetDeviceCaps(hDC, PLANES);
ReleaseDC(GetDesktopWindow(), hDC);
/* set up colour indices */
if (carray = (PCOLORREF)calloc(sizeof(COLORREF), CMAPSIZE)) {
carray[0] = RGB( 0, 0, 0);
carray[1] = RGB(255, 0, 0);
carray[2] = RGB( 0, 255, 0);
carray[3] = RGB(255, 255, 0);
carray[4] = RGB( 0, 0, 255);
carray[5] = RGB(255, 0, 255);
carray[6] = RGB( 0, 255, 255);
carray[7] = RGB(255, 255, 255);
}
/* zap current instance info*/
Inst.carray = carray;
Inst.hWinder = (HWND)NULL;
Inst.hMemoryDC = (HDC)NULL;
Inst.hBitmap = (HBITMAP)NULL;
Inst.nCurColour = 1;
Inst.bUseFrontBuf = TRUE;
Inst.xChar = 0;
Inst.yChar = 0;
Inst.nLWidth = 1;
InstanceTable[nCurrentInstance] = Inst;
mswinext_SetupInstance(DeferInfo.hWnd, DeferInfo.w, DeferInfo.h);
return TRUE;
}
static int mswinext_exit()
{
if (nCurrentInstance == NO_INSTANCE) return -1;
mswinext_cleanup();
/* deallocate the current instance */
if (Inst.carray) free(Inst.carray);
Inst.nId = NO_INSTANCE;
Inst.carray = NULL;
Inst.hWinder = NULL;
InstanceTable[nCurrentInstance] = Inst;
nCurrentInstance = NO_INSTANCE;
return 1;
}
static
void mswinext_cleanup()
{
if (nCurrentInstance == NO_INSTANCE) return;
if (Inst.hBitmap) {
DeleteObject(Inst.hBitmap);
Inst.hBitmap = (HBITMAP)NULL;
}
if (Inst.hMemoryDC) {
DeleteDC(Inst.hMemoryDC);
Inst.hMemoryDC = (HDC)NULL;
}
return;
}
static
void mswinext_invalidate_rect(LPRECT r)
{
if (r->left < Inst.BackRect.left) Inst.BackRect.left = r->left;
if (r->right > Inst.BackRect.right) Inst.BackRect.right = r->right;
if (r->top < Inst.BackRect.top) Inst.BackRect.top = r->top;
if (r->bottom > Inst.BackRect.bottom) Inst.BackRect.bottom = r->bottom;
}
#ifdef VOGLE
static
int mswinext_clear()
{
HDC hDC;
RECT r;
HBRUSH hBrush,
hOldBrush;
HBITMAP hOldBitmap;
if (nCurrentInstance == NO_INSTANCE) return -1;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
GetClientRect(Inst.hWinder, &r);
hBrush = CreateSolidBrush(Inst.carray[Inst.nCurColour]);
if (hBrush) {
hOldBrush = SelectObject(Inst.hMemoryDC, hBrush);
FillRect(Inst.hMemoryDC, &r, Inst.hBrush);
if (Inst.bUseFrontBuf) {
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
r.right - r.left,
r.bottom - r.top,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
mswinext_invalidate_rect(&r);
}
SelectObject(Inst.hMemoryDC, hOldBrush);
DeleteObject(hBrush);
}
SelectObject(Inst.hMemoryDC, Inst.hOldBitmap);
}
#else
/* VOGL */
static
int mswinext_clear()
{
HDC hDC;
RECT r;
HBRUSH hBrush,
hOldBrush;
HBITMAP hOldBitmap;
if (nCurrentInstance == NO_INSTANCE) return -1;
/* rectangle describing current viewport */
r.left = vdevice.minVx;
r.top = vdevice.sizeSy - vdevice.maxVy;
r.right = vdevice.maxVx - vdevice.minVx;
r.bottom = vdevice.maxVy - vdevice.minVy;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
hBrush = CreateSolidBrush(Inst.carray[Inst.nCurColour]);
if (hBrush) {
hOldBrush = SelectObject(Inst.hMemoryDC, hBrush);
FillRect(Inst.hMemoryDC, &r, hBrush);
if (Inst.bUseFrontBuf) {
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
r.right - r.left,
r.bottom - r.top,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
mswinext_invalidate_rect(&r);
}
SelectObject(Inst.hMemoryDC, hOldBrush);
DeleteObject(hBrush);
}
SelectObject(Inst.hMemoryDC, hOldBitmap);
}
#endif
static
int mswinext_draw(int x, int y)
{
HDC hDC;
HPEN hPen,
hOldPen;
HBITMAP hOldBitmap;
RECT r;
if (nCurrentInstance == NO_INSTANCE) return -1;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
hPen = CreatePen(PS_SOLID, Inst.nLWidth, Inst.carray[Inst.nCurColour]);
if (hPen) {
hOldPen = SelectObject(Inst.hMemoryDC, hPen);
MoveTo(Inst.hMemoryDC, r.left = vdevice.cpVx, r.top = vdevice.sizeSy - vdevice.cpVy);
LineTo(Inst.hMemoryDC, r.right = x, r.bottom = vdevice.sizeSy - y);
if (Inst.bUseFrontBuf) {
if (r.top > r.bottom) swap(&(r.top), &(r.bottom));
if (r.left > r.right) swap(&(r.left), &(r.right));
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
r.right - r.left + 1,
r.bottom - r.top + 1,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
mswinext_invalidate_rect(&r);
}
SelectObject(Inst.hMemoryDC, hOldPen);
DeleteObject(hPen);
}
hOldBitmap = SelectObject(Inst.hMemoryDC, hOldBitmap);
}
static
int mswinext_fill(int n, int *x, int *y)
{
HDC hDC;
LPPOINT lpPoint;
int OldPolyMode;
int i;
HBRUSH hBrush,
hOldBrush;
HBITMAP hOldBitmap;
RECT r;
if (nCurrentInstance == NO_INSTANCE) return -1;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
if (lpPoint = (LPPOINT) malloc(sizeof(POINT) * n)) {
hBrush = CreateSolidBrush(Inst.carray[Inst.nCurColour]);
if (hBrush) {
r.left = r.right = x[0];
r.top = r.bottom = y[0];
for (i = 0; i < n; i++) {
lpPoint[i].x = x[i];
if (lpPoint[i].x < r.left) r.left = lpPoint[i].x;
else if (lpPoint[i].x > r.right) r.right = lpPoint[i].x;
lpPoint[i].y = vdevice.sizeSy - y[i];
if (lpPoint[i].y < r.top) r.top = lpPoint[i].y;
else if (lpPoint[i].y > r.bottom) r.bottom = lpPoint[i].y;
}
hOldBrush = SelectObject(Inst.hMemoryDC, hBrush);
OldPolyMode = GetPolyFillMode(Inst.hMemoryDC);
SetPolyFillMode(Inst.hMemoryDC, WINDING);
Polygon(Inst.hMemoryDC, lpPoint, n);
if (Inst.bUseFrontBuf) {
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
r.right - r.left + 1,
r.bottom - r.top + 1,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
mswinext_invalidate_rect(&r);
}
SetPolyFillMode(Inst.hMemoryDC, OldPolyMode);
SelectObject(Inst.hMemoryDC, hOldBrush);
DeleteObject(hBrush);
}
free(lpPoint);
}
hOldBitmap = SelectObject(Inst.hMemoryDC, hOldBitmap);
vdevice.cpVx = x[n-1];
vdevice.cpVy = y[n-1];
}
static
int mswinext_color(int i)
{
if (nCurrentInstance == NO_INSTANCE) return -1;
Inst.nCurColour = (unsigned)i;
}
static
int mswinext_mapcolor(int i, int r, int g, int b)
{
if (nCurrentInstance == NO_INSTANCE) return -1;
if (i >= CMAPSIZE) return(-1);
Inst.carray[i] = RGB(r, g, b);
return -1;
}
static
int mswinext_char(char c)
{
HDC hDC;
char s[2];
HBITMAP hOldBitmap;
RECT r;
int OldBkMode;
DWORD OldTextColour;
if (nCurrentInstance == NO_INSTANCE) return -1;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
s[0] = c;
s[1] = '\0';
OldBkMode = SetBkMode(Inst.hMemoryDC, TRANSPARENT);
OldTextColour = SetTextColor(Inst.hMemoryDC, Inst.carray[Inst.nCurColour]);
TextOut(Inst.hMemoryDC, r.left = vdevice.cpVx, r.top = vdevice.sizeSy - vdevice.cpVy, s, 1);
SetTextColor(Inst.hMemoryDC, OldTextColour);
SetBkMode(Inst.hMemoryDC, OldBkMode);
if (Inst.bUseFrontBuf) {
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
Inst.xChar,
Inst.yChar,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
r.right = r.left + Inst.xChar;
r.bottom = r.top + Inst.yChar;
mswinext_invalidate_rect(&r);
}
hOldBitmap = SelectObject(Inst.hMemoryDC, hOldBitmap);
}
static
int mswinext_string(char *s)
{
HDC hDC;
HBITMAP hOldBitmap;
RECT r;
int n;
int OldBkMode;
DWORD OldTextColour;
if (nCurrentInstance == NO_INSTANCE) return -1;
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
OldBkMode = SetBkMode(Inst.hMemoryDC, TRANSPARENT);
OldTextColour = SetTextColor(Inst.hMemoryDC, Inst.carray[Inst.nCurColour]);
TextOut(Inst.hMemoryDC, r.left = vdevice.cpVx, r.top = vdevice.sizeSy - vdevice.cpVy, s, n = strlen(s));
SetTextColor(Inst.hMemoryDC, OldTextColour);
SetBkMode(Inst.hMemoryDC, OldBkMode);
if (Inst.bUseFrontBuf) {
hDC = GetDC(Inst.hWinder);
BitBlt(hDC,
r.left, r.top,
n * Inst.xChar,
Inst.yChar,
Inst.hMemoryDC,
r.left, r.top,
SRCCOPY);
ReleaseDC(Inst.hWinder, hDC);
}
else {
/* invalidate the region in front buffer */
r.right = r.left + n * Inst.xChar;
r.bottom = r.top + Inst.yChar;
mswinext_invalidate_rect(&r);
}
hOldBitmap = SelectObject(Inst.hMemoryDC, hOldBitmap);
}
static
int mswinext_font(char *font)
{
if (nCurrentInstance == NO_INSTANCE) return -1;
/* NOT IMPLEMENTED */
return 1;
}
static
int mswinext_frontbuf()
{
if (nCurrentInstance == NO_INSTANCE) return -1;
Inst.bUseFrontBuf = TRUE;
}
static
int mswinext_backbuf()
{
if (nCurrentInstance == NO_INSTANCE) return -1;
Inst.bUseFrontBuf = FALSE;
Inst.BackRect.left = Inst.BackRect.top = 32765;
Inst.BackRect.right = Inst.BackRect.bottom = -32765;
return 1;
}
static
int mswinext_swapbuf()
{
HDC hDC;
RECT r;
HBITMAP hOldBitmap;
if (nCurrentInstance == NO_INSTANCE) return -1;
hDC = GetDC(Inst.hWinder);
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
BitBlt(hDC,
Inst.BackRect.left, Inst.BackRect.top,
Inst.BackRect.right - Inst.BackRect.left,
Inst.BackRect.bottom - Inst.BackRect.top,
Inst.hMemoryDC,
Inst.BackRect.left, Inst.BackRect.top,
SRCCOPY);
Inst.BackRect.left = Inst.BackRect.top = 32765;
Inst.BackRect.right = Inst.BackRect.bottom = -32765;
ReleaseDC(Inst.hWinder, hDC);
SelectObject(Inst.hMemoryDC, hOldBitmap);
}
int mswin_verror(char *msg)
{
MessageBox(NULL, (LPSTR)msg, "A VOGLE error has occurred!", MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
}
static
int mswinext_setlw(int w)
{
if (nCurrentInstance == NO_INSTANCE) return -1;
if (w == 0) Inst.nLWidth = 1;
else Inst.nLWidth = 3;
}
/*
* Does nothing....
*/
static
noop()
{
return(-1);
}
/*
* the device entry
*/
static DevEntry mswinextdev = {
"mswinext",
"large",
"small",
mswinext_backbuf,
mswinext_char,
noop,
mswinext_clear,
mswinext_color,
mswinext_draw,
mswinext_exit,
mswinext_fill,
mswinext_font,
mswinext_frontbuf,
noop,
mswinext_init,
noop,
mswinext_mapcolor,
mswinext_setlw,
mswinext_string,
mswinext_swapbuf,
noop
};
/*
* _mswinext_devcpy
*
* copy the mswinext device into vdevice.dev.
*/
int _mswinext_devcpy()
{
vdevice.dev = mswinextdev;
}
/*
* Setup the window info for current instance.
*/
static
int mswinext_SetupInstance(HWND hWnd, int w, int h)
{
HDC hDC;
RECT r;
TEXTMETRIC tm;
HBRUSH hBrush,
hOldBrush;
HBITMAP hOldBitmap;
/* assign the window */
Inst.hWinder = hWnd;
/*
* Let VOGLE know about the dimensions of the window to be used.
* Make it square.
*/
r.top = r.left = 0;
r.right = w; r.bottom = h;
vdevice.sizeX = vdevice.sizeY = min(r.bottom, r.right);
vdevice.sizeSx = r.right;
vdevice.sizeSy = r.bottom;
/* determine size of default window font */
hDC = GetDC(Inst.hWinder);
GetTextMetrics(hDC, &tm);
Inst.xChar = tm.tmMaxCharWidth;
Inst.yChar = tm.tmHeight + tm.tmExternalLeading;
/* zap previous DC/bitmap */
mswinext_cleanup();
/* create a bitmap and memory context compatible with Inst.hWinder */
Inst.hMemoryDC = CreateCompatibleDC(hDC);
Inst.hBitmap = CreateCompatibleBitmap(hDC, vdevice.sizeSx, vdevice.sizeSy);
/* clear the bitmap */
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
hBrush = GetStockObject(BLACK_BRUSH);
if (hBrush) {
hOldBrush = SelectObject(Inst.hMemoryDC, hBrush);
r.top = r.left = 0;
r.right = vdevice.sizeSx;
r.bottom = vdevice.sizeSy;
FillRect(Inst.hMemoryDC, &r, hBrush);
SelectObject(Inst.hMemoryDC, hOldBrush);
}
SelectObject(Inst.hMemoryDC, hOldBitmap);
ReleaseDC(Inst.hWinder, hDC);
/* good return */
return TRUE;
}
/*
* vo_mswinext_window
*
* Assigns VOGL/VOGLE a window to use.
* You MUST use this routine before (and directly before)
* calling vinit().
*/
int vo_mswinext_window(HWND hWnd, int w, int h)
{
/* store window info until vinit() calls mswinext_init() */
DeferInfo.hWnd = hWnd;
DeferInfo.w = w;
DeferInfo.h = h;
return TRUE;
}
/*
* vo_mswinext_win_size
*
* If the user has resized the window, then
* you might wish to call this routine to tell VOGL/VOGLE about it.
*/
int vo_mswinext_win_size(int w, int h)
{
mswinext_SetupInstance(Inst.hWinder, w, h);
return TRUE;
}
/****
* Paint the client area of a (the) VOGL/VOGLE window.
* This should be called by the window's window procedure
* in response to a WM_PAINT message ONLY!
**/
int vo_mswinext_paint_window(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
HBITMAP hOldBitmap;
if (nCurrentInstance == NO_INSTANCE) return 0;
if (hWnd) {
BeginPaint(hWnd, &ps);
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
hDC = GetDC(hWnd);
BitBlt(hDC,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
Inst.hMemoryDC,
ps.rcPaint.left, ps.rcPaint.top,
SRCCOPY);
SelectObject(Inst.hMemoryDC, hOldBitmap);
ReleaseDC(hWnd, hDC);
EndPaint(hWnd, &ps);
}
return TRUE;
}
/****
* Paint the client area of a (the) VOGL/VOGLE window to
* a given device context.
* This should be called by the window's window procedure
* in response to a WM_PAINT message ONLY!
**/
int vo_mswinext_paint_dc(HDC hDC)
{
RECT rClip;
HBITMAP hOldBitmap;
if (nCurrentInstance == NO_INSTANCE) return 0;
if (Inst.hBitmap && Inst.hMemoryDC) {
hOldBitmap = SelectObject(Inst.hMemoryDC, Inst.hBitmap);
GetClipBox(hDC, &rClip);
BitBlt(hDC,
rClip.left, rClip.top,
rClip.right - rClip.left,
rClip.bottom - rClip.top,
Inst.hMemoryDC,
rClip.left, rClip.top,
SRCCOPY);
SelectObject(Inst.hMemoryDC, hOldBitmap);
}
return TRUE;
}
static
void swap(int *a, int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
}