1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-16 00:04:59 +00:00
Interlisp.maiko/src/mnxmeth.c
2021-01-26 20:40:15 -08:00

3082 lines
114 KiB
C

/* $Id: mnxmeth.c,v 1.2 1999/01/03 02:07:25 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved
*/
/************************************************************************/
/* */
/* (C) Copyright 1989, 1990, 1990, 1991, 1992, 1993, 1994, 1995 Venue. */
/* All Rights Reserved. */
/* Manufactured in the United States of America. */
/* */
/************************************************************************/
#include "version.h"
#include <stdio.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string.h>
#include <alloca.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/IntrinsicP.h>
#include <X11/CoreP.h>
#include <X11/Xaw/BoxP.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include <X11/Xmu/Converters.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "lispemul.h"
#include "lspglob.h"
#include "cell.h"
#include "lsptypes.h"
#include "stream.h"
#include "array.h"
#include "dspdata.h"
#include "adr68k.h"
#include "mnxdefs.h"
#include "ScrollBoxP.h"
#include "ScrollBox.h"
#define BARTHICKNESS 10
#define BARFRAME 1
int MedleyWindowType, MedleyScreenType, MedleyBitmapType;
int gcfunction[4] = {GXcopy, GXor, GXxor, GXandInverted};
int bltshade_function[4] = {GXcopy, GXcopy, GXxor, GXcopy};
int xtinitialized = False;
extern DspInterfaceRec *FD_to_dspif[32]; /* map from FD # to display */
extern int LispReadFds;
extern int MNWReadFds;
extern char *sysout_name;
extern int save_argc;
extern char **save_argv;
extern DLword INVERT_atom;
extern DLword ERASE_atom;
extern DLword PAINT_atom;
extern DLword REPLACE_atom;
extern const unsigned char reversedbits[];
/**************************************************************/
/* Xerrhandler. */
/* Utility function to make URaid the error handler for X. */
/**************************************************************/
int Xerrhandler(Display *display, XErrorEvent *event)
{
char msg[80];
XGetErrorText(display, event->error_code, msg, 80);
error(msg);
}
void intersectregions(MRegion *reg1, MRegion *reg2, MRegion *result)
{
result->x = max(reg1->x, reg2->x);
result->y = max(reg1->y, reg2->y);
result->width = result->x - min(reg1->x + reg1->width, reg2->x + reg2->width);
result->height = result->y - min(reg1->y + reg1->height, reg2->y + reg2->height);
}
/**************************************************************/
/* getwhiteborder */
/* Utility function to calculate the white border of a window.*/
/* Takes a medley window as its argument. */
/**************************************************************/
int getwhiteborder(LispPTR medleywindow)
{
int border;
if (((MedleyWindow)Cptr(medleywindow))->WBORDER)
border = LispIntToCInt(((MedleyWindow)Cptr(medleywindow))->WBORDER);
else
border = 0;
if (border <= 1)
return (0);
else if (border <= 3)
return (1);
else
return (2);
}
/**************************************************************/
/* getblackborder */
/* Utility function to calculate the black border of a window.*/
/* Takes a medley window as its argument. */
/**************************************************************/
int getblackborder(LispPTR medleywindow)
{
int border;
if (((MedleyWindow)Cptr(medleywindow))->WBORDER)
border = LispIntToCInt(((MedleyWindow)Cptr(medleywindow))->WBORDER);
else
border = 0;
if (border <= 0)
return (0);
else if (border <= 2)
return (1);
else if (border <= 3)
return (2);
else
return (border - 2);
}
/**************************************************************/
/* gettitlestring */
/* Utility function to retrieve the titlestring from a window.*/
/* Takes a medley window as its argument. Returns a pointer to*/
/* a malloc'd c string or NULL if no string is present. */
/**************************************************************/
char *gettitlestring(LispPTR medleywin)
{
char *titlestring;
int strlen;
if (((MedleyWindow)Cptr(medleywin))->WTITLE == NIL)
titlestring = NULL;
else {
strlen = LispStringLength(((MedleyWindow)Cptr(medleywin))->WTITLE);
titlestring = (char *)malloc(strlen + 1);
LispStringToCStr(((MedleyWindow)Cptr(medleywin))->WTITLE, titlestring);
}
return (titlestring);
}
/**************************************************************/
/* gettitleheight */
/* Return the height of the title bar for this window. */
/* Pick the value from the TITLEDS of the screen. */
/**************************************************************/
int gettitleheight(LispPTR medleywin)
{
if (((MedleyWindow)Cptr(medleywin))->WTITLE == NIL)
return (0);
else {
DISPLAYDATA *dd;
dd = TitleDDFromMw(medleywin);
return (abs(LispIntToCInt(dd->ddlinefeed)));
}
}
/**************************************************************/
/* setlineattributes */
/* This function attempts to synchronize the line data in */
/* Lisp and X. */
/**************************************************************/
void setlineattributes(Display *display, DspInterface dspif, WindowInterface wif, DISPLAYDATA *dd,
LispPTR mwidth, LispPTR mdash)
{
int l, lw, ls;
unsigned char *dash_list;
lw = (mwidth == NIL) ? 0 : LispIntToCInt(mwidth);
ls = (mdash == NIL) ? LineSolid : LineOnOffDash;
if (dd->ddoperation == INVERT_atom) {
XSetLineAttributes(display, wif->InvertGC, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, dspif->PixIGC, lw, ls, CapRound, JoinBevel);
} else if (dd->ddoperation == ERASE_atom) {
XSetLineAttributes(display, wif->EraseGC1, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, wif->EraseGC2, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, dspif->PixEGC, lw, ls, CapRound, JoinBevel);
} else if (dd->ddoperation == PAINT_atom) {
XSetLineAttributes(display, wif->PaintGC1, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, wif->PaintGC2, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, dspif->PixPGC, lw, ls, CapRound, JoinBevel);
} else if (dd->ddoperation == REPLACE_atom) {
XSetLineAttributes(display, wif->ReplaceGC, lw, ls, CapRound, JoinBevel);
XSetLineAttributes(display, dspif->PixRGC, lw, ls, CapRound, JoinBevel);
}
if (mdash != NIL) {
l = LispStringLength(mdash);
dash_list = (unsigned char *)malloc(l + 1);
LispStringToCStr(mdash, dash_list);
if (dd->ddoperation == INVERT_atom) {
XSetDashes(display, wif->InvertGC, 0, dash_list, l);
XSetDashes(display, dspif->PixIGC, 0, dash_list, l);
} else if (dd->ddoperation == ERASE_atom) {
XSetDashes(display, wif->EraseGC1, 0, dash_list, l);
XSetDashes(display, wif->EraseGC2, 0, dash_list, l);
XSetDashes(display, dspif->PixEGC, 0, dash_list, l);
} else if (dd->ddoperation == PAINT_atom) {
XSetDashes(display, wif->PaintGC1, 0, dash_list, l);
XSetDashes(display, wif->PaintGC2, 0, dash_list, l);
XSetDashes(display, dspif->PixPGC, 0, dash_list, l);
} else if (dd->ddoperation == REPLACE_atom) {
XSetDashes(display, wif->ReplaceGC, 0, dash_list, l);
XSetDashes(display, dspif->PixRGC, 0, dash_list, l);
}
}
}
void settileorigin(LispPTR medleywin, LispPTR x, LispPTR y)
{
WindowInterface wif;
Display *display;
wif = WIfFromMw(medleywin);
display = XtDisplay(wif->windowwidget);
XSetTSOrigin(display, wif->InvertGC, x, y);
XSetTSOrigin(display, wif->EraseGC1, x, y);
XSetTSOrigin(display, wif->EraseGC2, x, y);
XSetTSOrigin(display, wif->PaintGC1, x, y);
XSetTSOrigin(display, wif->PaintGC2, x, y);
XSetTSOrigin(display, wif->ReplaceGC, x, y);
XSetTSOrigin(display, wif->dspif->PixIGC, x, y);
XSetTSOrigin(display, wif->dspif->PixEGC, x, y);
XSetTSOrigin(display, wif->dspif->PixPGC, x, y);
XSetTSOrigin(display, wif->dspif->PixRGC, x, y);
}
/**************************************************************/
/**************************************************************/
void calculateshape(WindowInterface wif, LispPTR x, LispPTR y, LispPTR width, LispPTR height, int topwidoffset, int tophgtoffset)
{
wif->windowreg.width = LispIntToCInt(width);
wif->windowreg.height = LispIntToCInt(height);
wif->windowreg.x = LispIntToCInt(x);
wif->windowreg.y = LispIntToCInt(y);
calcwif(wif, topwidoffset, tophgtoffset);
}
/**************************************************************/
/* calcwif */
/* layout the regions. All calculations based on the outer */
/* region. The rest of the widget moves around this region. */
/**************************************************************/
void calcwif(WindowInterface wif, int xoff, int yoff)
{
int whiteborder, blackborder, blackborder2, titleheight, border;
blackborder = getblackborder(wif->MedleyWindow);
blackborder2 = blackborder + blackborder;
whiteborder = getwhiteborder(wif->MedleyWindow);
/* Calculate the top & outer region */
wif->outerregion.y = 0;
wif->outerregion.x = 0;
wif->outerregion.width = wif->windowreg.width;
wif->topregion.width = wif->outerregion.width + /* wif->outerregion.x; */
xoff;
wif->outerregion.height = wif->windowreg.height;
wif->topregion.height = wif->outerregion.height + yoff;
wif->topregion.x = wif->windowreg.x - wif->outerregion.x;
wif->topregion.y = (HeightOfScreen(wif->screen) - wif->windowreg.y - wif->windowreg.height);
titleheight = gettitleheight(wif->MedleyWindow);
/* Calculate the inner region. */
border = 2 * (blackborder + whiteborder);
wif->innerregion.x = blackborder;
wif->innerregion.y = blackborder + titleheight;
wif->innerregion.width = wif->windowreg.width - border;
wif->innerregion.height = wif->windowreg.height - border - titleheight;
wif->whiteborder = whiteborder;
wif->blackborder2 = blackborder2;
sprintf(wif->gstring, "%dx%d+%d+%d", wif->topregion.width, wif->topregion.height,
wif->topregion.x, wif->topregion.y);
}
/**************************************************************/
/**************************************************************/
void refreshwindow(LispPTR medleywin)
{
WindowInterface wif;
DISPLAYDATA *dd;
float top, shown;
wif = WIfFromMw(medleywin);
dd = ImDataFromMw(medleywin);
calcwif(wif, wif->topregion.width - wif->outerregion.width,
wif->topregion.height - wif->outerregion.height);
XtVaSetValues(wif->formwidget, XtNclippX, dd->ddclippingleft, XtNclippY, dd->ddclippingbottom,
XtNclippWidth, dd->ddclippingright - dd->ddclippingleft, XtNclippHeight,
dd->ddclippingtop - dd->ddclippingbottom, NULL);
if (XtIsRealized(wif->topwidget)) {
XtConfigureWidget(wif->topwidget, wif->topregion.x, wif->topregion.y, wif->topregion.width,
wif->topregion.height, 0);
XtConfigureWidget(wif->framewidget, wif->outerregion.x, wif->outerregion.y,
wif->outerregion.width, wif->outerregion.height, 0);
XtConfigureWidget(wif->windowwidget, wif->innerregion.x, wif->innerregion.y,
wif->innerregion.width, wif->innerregion.height, wif->whiteborder);
}
}
/************************************************************************/
/* */
/* Translate X & Y window coords, allowing for offsets. */
/* */
/* XVAL & YVAL are already real integers. */
/* */
/************************************************************************/
int translate_x(WindowInterface wif, int xval)
{ return (xval + (wif->xoffset - wif->windowreg.x - (wif->blackborder2 >> 1) - wif->whiteborder)); }
int translate_y(WindowInterface wif, int yval)
{ return (yval + wif->yoffset - (wif->windowreg.y + (wif->blackborder2 >> 1) + wif->whiteborder)); }
extern void SignalVJmpScroll();
extern void SignalVScroll();
extern void SignalHJmpScroll();
extern void SignalHScroll();
extern void HandleBackgroundButton();
extern void HandleBackgroundCrossing();
extern void HandleButton();
extern void HandleMotion();
extern void HandleKey();
extern void HandleCrossing();
extern void HandleFocus();
extern void HandleStructure();
extern void HandleTitle();
extern void HandleExpose();
/**************************************************************/
/* InitScratchDepth */
/* Init the scratch image to fit the description of a bitmap */
/**************************************************************/
InitScratchDepth(image, MBM, scdepth) XImage *image;
BITMAP *MBM;
int scdepth;
{ /* Set up the scratch image for this operation */
image->width = MBM->bmwidth;
image->height = MBM->bmheight;
/* depth 1 implies that X should colorize */
if ((MBM->bmbitperpixel & 0xFFFF) == 1) {
image->depth = MBM->bmbitperpixel & 0xFFFF;
image->bits_per_pixel = 1;
image->bytes_per_line =
(((image->width + (BITSPER_DLWORD - 1)) / BITSPER_DLWORD) * (BITSPER_DLWORD / 8));
if (image->format != XYBitmap) {
image->format = XYBitmap;
_XInitImageFuncPtrs(image);
}
} else /* if(image->format != ZPixmap) */
{
image->depth = MBM->bmbitperpixel & 0xFFFF;
image->format = ZPixmap;
image->red_mask = (scdepth / 3);
image->green_mask = ((scdepth - image->red_mask) / 2);
image->blue_mask = (scdepth - image->red_mask - image->green_mask);
image->bits_per_pixel = image->depth;
_XInitImageFuncPtrs(image);
image->bytes_per_line =
((((image->width * image->depth) + (BITSPER_DLWORD - 1)) / BITSPER_DLWORD) *
(BITSPER_DLWORD / 8));
}
}
/**************************************************************/
/* MakeScratchImageFromBM */
/* Convert a Lisp BITMAP to fit in the scratch image in the */
/* dspif. Use the scratch image in subsequent computations. */
/**************************************************************/
MakeScratchImageFromBM(dspif, bitmap) DspInterface dspif;
BITMAP *bitmap;
{
InitScratchDepth(&dspif->image, bitmap, DefaultDepthOfScreen(dspif->xscreen));
dspif->image.data = (char *)Cptr((LispPTR)bitmap->bmbase);
}
/**************************************************************/
/* MakeScratchImageFromInt */
/* Convert a Lisp integer to be a bitmap in the scratch image */
/* in the dspif. Use the scratch image in subsequent */
/* computations. */
/* DANGER!! This function presumes that you have a valid data */
/* slot. ie. the caller have to make sure that the data area */
/* is allocated. */
/**************************************************************/
int revbits[16] = {15, 7, 11, 3, 13, 5, 9, 1, 14, 6, 10, 2, 12, 4, 8, 0};
MakeScratchImageFromInt(dspif, Texture) DspInterface dspif;
int Texture;
{
int width, height, pixpos, x, y;
unsigned char *bits = (unsigned char *)dspif->image.data;
unsigned int tbits;
width = height = 4;
pixpos = 0;
dspif->image.width = width;
dspif->image.height = height;
dspif->image.depth = 1;
dspif->image.format = XYBitmap;
dspif->image.bytes_per_line =
((width + (BITSPER_DLWORD - 1)) / BITSPER_DLWORD) * (BITSPER_DLWORD / 8);
tbits = revbits[Texture >> 12];
bits[0] = (tbits << 4) | tbits;
tbits = revbits[15 & (Texture >> 8)];
bits[1] = (tbits << 4) | tbits;
tbits = revbits[15 & (Texture >> 4)];
bits[2] = (tbits << 4) | tbits;
tbits = revbits[15 & (Texture)];
bits[3] = (tbits << 4) | tbits;
}
/**************************************************************/
/* settexture */
/* Argument is a Medleywindow. This function scans the texture*/
/* slot of the DISPLAYDATA structure. If that slot has a value*/
/* the Xwindow's background is updated to match that value. */
/* NOTE!!: Medley tiles from the lower left corner. X tiles */
/* the background from the upper left corner. This is not */
/* accounted for. */
/**************************************************************/
settexture(medleywin) LispPTR medleywin;
{
DspInterface dspif;
WindowInterface wif;
DISPLAYDATA *dd;
Pixmap bgpixmap;
Display *display;
dspif = DspIfFromMw(medleywin);
wif = WIfFromMw(medleywin);
dd = ImDataFromMw(medleywin);
display = dspif->handle;
if (dd->ddtexture != NIL) {
if (GetTypeNumber(dd->ddtexture) == TYPE_SMALLP)
if (LispIntToCInt(MScrFromMw(medleywin)->SCDEPTH) == 1) {
char id[64];
dspif->image.data = id; /* Danger zone! read comment for function in next call */
MakeScratchImageFromInt(dspif, LispIntToCInt(dd->ddtexture));
} else {
unsigned long pixval;
pixval = ~(unsigned long)LispIntToCInt(dd->ddtexture);
/* Set the background for pixel ops in this window */
XSetBackground(display, wif->InvertGC, pixval);
XSetBackground(display, wif->EraseGC1, pixval);
XSetBackground(display, wif->EraseGC2, pixval);
XSetBackground(display, wif->PaintGC1, pixval);
XSetBackground(display, wif->PaintGC2, pixval);
XSetBackground(display, wif->ReplaceGC, pixval);
XSetBackground(display, dspif->PixIGC, pixval);
XSetBackground(display, dspif->PixEGC, pixval);
XSetBackground(display, dspif->PixPGC, pixval);
XSetBackground(display, dspif->PixRGC, pixval);
XtVaSetValues(wif->windowwidget, XtNbackground, pixval, NULL);
return (NIL);
}
else { /* Its a bitmap */
MakeScratchImageFromBM(dspif, (BITMAP *)Cptr(dd->ddtexture));
}
} else { /* ddtexture is NIL */
char id[64];
dspif->image.data = id; /* Danger zone! read comment for function in next call */
MakeScratchImageFromInt(dspif, 0);
}
if (wif->bgpixmap) {
/* If we have an fgpixmap, junk it */
XFreePixmap(display, wif->bgpixmap);
wif->bgpixmap = 0;
}
bgpixmap = XCreatePixmapFromBitmapData(
display, dspif->root, dspif->image.data, dspif->image.width, dspif->image.height,
WhitePixelOfScreen(wif->screen), BlackPixelOfScreen(wif->screen),
DefaultDepthOfScreen(wif->screen));
XSetTile(display, wif->InvertGC, bgpixmap);
XSetTile(display, wif->EraseGC1, bgpixmap);
XSetTile(display, wif->EraseGC2, bgpixmap);
XSetTile(display, wif->PaintGC1, bgpixmap);
XSetTile(display, wif->PaintGC2, bgpixmap);
XSetTile(display, wif->ReplaceGC, bgpixmap);
/* XSetTile(display, dspif->PixIGC, bgpixmap);
XSetTile(display, dspif->PixEGC, bgpixmap);
XSetTile(display, dspif->PixPGC, bgpixmap);
XSetTile(display, dspif->PixRGC, bgpixmap); */
XtVaSetValues(wif->windowwidget, XtNbackgroundPixmap, bgpixmap, NULL);
wif->bgpixmap = bgpixmap;
return (NIL);
}
MBMToDrawable(MBM, dspif, wif, srcx, srcy, dstx, dsty, width, height, operation) BITMAP *MBM;
WindowInterface wif;
DspInterface dspif;
int srcx, srcy, dstx, dsty, width, height, operation;
{
Window window;
window = XtWindow(wif->windowwidget);
if ((MBM->bmbitperpixel == 1) || (MBM->bmbitperpixel == DefaultDepthOfScreen(wif->screen))) {
InitScratchDepth(&dspif->image, MBM, DefaultDepthOfScreen(wif->screen));
dspif->image.data = (char *)Cptr((LispPTR)MBM->bmbase);
switch (operation) {
case REPLACE:
if (window)
XPutImage(dspif->handle, window, wif->ReplaceGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
XPutImage(dspif->handle, wif->backing, dspif->PixRGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
break;
case INVERT:
if (window)
XPutImage(dspif->handle, window, wif->InvertGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
XPutImage(dspif->handle, wif->backing, dspif->PixIGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
break;
case PAINT:
if (window)
XPutImage(dspif->handle, window, wif->PaintGC1, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
if (window)
XPutImage(dspif->handle, window, wif->PaintGC2, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
XPutImage(dspif->handle, wif->backing, dspif->PixPGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
break;
case ERASE:
if (window)
XPutImage(dspif->handle, window, wif->EraseGC1, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
if (window)
XPutImage(dspif->handle, window, wif->EraseGC2, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
XPutImage(dspif->handle, wif->backing, dspif->PixEGC, &dspif->image, srcx, srcy, dstx, dsty,
width, height);
break;
}
} else {
/* JDS 2/22/94: I'm not sure this part is right; haven't thought about it. */
int x, y;
InitScratchDepth(&dspif->image, MBM, DefaultDepthOfScreen(wif->screen));
dspif->image.depth = DefaultDepthOfScreen(wif->screen);
dspif->image.data =
(char *)malloc(dspif->image.bytes_per_line * dspif->image.width * dspif->image.depth);
InitScratchDepth(&dspif->tmpimage, MBM, DefaultDepthOfScreen(wif->screen));
dspif->tmpimage.data = (char *)Cptr((LispPTR)MBM->bmbase);
for (x = 0; x < MBM->bmwidth; x++)
for (y = 0; y < MBM->bmheight; y++)
XPutPixel(&dspif->image, x, y, XGetPixel(&dspif->tmpimage, x, y));
if (operation == INVERT_atom) {
XPutImage(dspif->handle, window, wif->InvertGC, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
} else if (operation == ERASE_atom) {
XPutImage(dspif->handle, window, wif->EraseGC1, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
XPutImage(dspif->handle, window, wif->EraseGC2, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
} else if (operation == PAINT_atom) {
XPutImage(dspif->handle, window, wif->PaintGC1, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
XPutImage(dspif->handle, window, wif->PaintGC2, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
} else if (operation == REPLACE_atom) {
XPutImage(dspif->handle, window, wif->ReplaceGC, &dspif->image, srcx, srcy, dstx, dsty, width,
height);
}
free(dspif->image.data);
}
}
/************************************************************************/
/* DrawableToMBM */
/* Copy a drawable to a Medley bitmap. All coordinates are in X style. */
/* (i.e. y-coordinate assumed to be transformed) */
/* Since XGetSubImage will generate an error if the drawable is outside */
/* the rootwindow we have to get the geometry and clip it with the */
/* geometry of the root window. (Urk!) */
/* This offcause means that anything outside the screen will have to be */
/* ignored. (This has to be fixed. This sucks.). */
/************************************************************************/
DrawableToMBM(MBM, dspif, wif, xdrawable, xscreen, srcx, srcy, dstx, dsty, width, height,
op) BITMAP *MBM;
WindowInterface wif;
Screen *xscreen;
Drawable xdrawable;
DspInterface dspif;
int srcx, srcy, dstx, dsty, width, height, op;
{
#ifdef NEVER
if (MBM->bmbitperpixel == DefaultDepthOfScreen(xscreen)) {
InitScratchDepth(&dspif->image, MBM, DefaultDepthOfScreen(xscreen));
dspif->image.data = (char *)Cptr((LispPTR)MBM->bmbase);
XGetSubImage(dspif->handle, xdrawable, srcx, srcy, width, height, AllPlanes, ZPixmap,
&dspif->image, dstx, dsty);
} else {
int x, y, scdepth;
BITMAP tmp;
scdepth = DefaultDepthOfScreen(xscreen);
tmp.bmwidth = MBM->bmwidth;
tmp.bmheight = MBM->bmheight;
tmp.bmbitperpixel = scdepth;
InitScratchDepth(&dspif->tmpimage, &tmp, scdepth);
dspif->tmpimage.depth = scdepth;
dspif->tmpimage.data = (char *)malloc(dspif->tmpimage.bytes_per_line * dspif->tmpimage.width *
dspif->tmpimage.depth);
XGetSubImage(dspif->handle, xdrawable, srcx, srcy, width, height, AllPlanes, ZPixmap,
&dspif->tmpimage, dstx, dsty);
InitScratchDepth(&dspif->image, MBM, MBM->bmbitperpixel);
dspif->image.data = (char *)Cptr((LispPTR)MBM->bmbase);
for (x = 0; x < MBM->bmwidth; x++)
for (y = 0; y < MBM->bmheight; y++)
XPutPixel(&dspif->image, x, y, !XGetPixel(&dspif->tmpimage, x, y));
free(dspif->tmpimage.data);
}
#else /* NEVER */
InitScratchDepth(&dspif->image, MBM, 1);
dspif->image.data = (char *)Cptr((LispPTR)MBM->bmbase);
XGetSubImage(dspif->handle, xdrawable, srcx, srcy, width, height, AllPlanes, ZPixmap,
&dspif->image, dstx, dsty);
#endif /* Never */
}
MNXBBTToXWindow(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to src BITMAP */
/* args[2] = scr_x */
/* args[3] = scr_y */
/* args[4] = dst WINDOW */
/* args[5] = dst_x */
/* args[6] = dst_y */
/* args[7] = width */
/* args[8] = height */
/* args[9] = operation */
{
WindowInterface wif;
DspInterface dspif;
Display *display;
BITMAP *bitmap;
int width, height, depth, srcy, dsty;
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
bitmap = (BITMAP *)Cptr(args[1]);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
/* Transform the coordinates */
width = LispIntToCInt(args[7]);
height = LispIntToCInt(args[8]);
dsty = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[6])) - height;
srcy = (bitmap->bmheight & 0xFFFF) - LispIntToCInt(args[3]) - height;
MBMToDrawable(bitmap, dspif, wif, LispIntToCInt(args[2]), /* src x */
srcy, translate_x(wif, LispIntToCInt(args[5])), /* dst x */
dsty, width, height, args[9] & 0xF);
XFlush(display);
}
MNXBBTFromXWindow(LispArgs args) /* args[0] = LispPTR to src WINDOW */
/* args[1] = scr_x */
/* args[2] = scr_y */
/* args[3] = LispPTR to dst BITMAP */
/* args[4] = dst_x */
/* args[5] = dst_y */
/* args[6] = width */
/* args[7] = height */
/* args[8] = operation */
/* Things to remember: This function does not handle integer-textures */
/* The handling of the OPERATION argument is done in lisp */
{
WindowInterface wif;
DspInterface dspif;
Display *display;
BITMAP *bitmap;
int width, height, depth, srcx, srcy, dstx, dsty;
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
bitmap = (BITMAP *)Cptr(args[3]);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
/* Transform the coordinates */
srcx = max(0, translate_x(wif, LispIntToCInt(args[1])));
dstx = LispIntToCInt(args[4]);
width = min(LispIntToCInt(args[6]), wif->innerregion.width - max(0, srcx));
;
height = min(LispIntToCInt(args[7]), wif->innerregion.height - LispIntToCInt(args[2]));
;
srcy = max(0, wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2])) - height);
dsty = (bitmap->bmheight & 0xFFFF) - LispIntToCInt(args[5]) - height;
DrawableToMBM(bitmap, dspif, wif, wif->backing, wif->screen, srcx, srcy, dstx, dsty, width,
height, args[8] & 0xF);
XFlush(display);
return (ATOM_T);
}
MNXBBTWinWin(LispArgs args) /* args[0] = LispPTR to src WINDOW */
/* args[1] = scr_x */
/* args[2] = scr_y */
/* args[3] = LispPTR to dst WINDOW */
/* args[4] = dst_x */
/* args[5] = dst_y */
/* args[6] = width */
/* args[7] = height */
/* args[8] = operation */
/* Things to remember: This function does not handle integer-textures */
{
WindowInterface srcwif, dstwif;
DspInterface dspif;
Display *display;
Window swin, dwin;
BITMAP *bitmap;
DISPLAYDATA *dd;
int width, height, depth, srcy, dsty, srcx, dstx;
srcwif = WIfFromMw(args[0]);
dstwif = WIfFromMw(args[3]);
dspif = DspIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
display = XtDisplay(srcwif->windowwidget);
swin = XtWindow(srcwif->windowwidget);
dwin = XtWindow(dstwif->windowwidget);
if (!srcwif->open) return (NIL); /* If window not open, don't do anything. */
if (!dstwif->open) return (NIL); /* If window not open, don't do anything. */
/* Transform the coordinates */
width = LispIntToCInt(args[6]);
height = LispIntToCInt(args[7]);
dsty = dstwif->innerregion.height - translate_y(dstwif, LispIntToCInt(args[5])) - height;
srcy = srcwif->innerregion.height - translate_y(srcwif, LispIntToCInt(args[2])) - height;
srcx = translate_x(srcwif, LispIntToCInt(args[1]));
dstx = translate_x(dstwif, LispIntToCInt(args[4]));
switch (args[8] & 0xF) {
case INVERT:
XCopyArea(display, swin, dwin, srcwif->InvertGC, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, srcwif->backing, dstwif->backing, dspif->PixIGC, srcx, srcy, width, height,
dstx, dsty);
break;
case ERASE:
XCopyArea(display, swin, dwin, srcwif->EraseGC1, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, swin, dwin, srcwif->EraseGC2, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, srcwif->backing, dstwif->backing, dspif->PixEGC, srcx, srcy, width, height,
dstx, dsty);
break;
case PAINT:
XCopyArea(display, swin, dwin, srcwif->PaintGC1, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, swin, dwin, srcwif->PaintGC2, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, srcwif->backing, dstwif->backing, dspif->PixPGC, srcx, srcy, width, height,
dstx, dsty);
break;
case REPLACE:
XCopyArea(display, swin, dwin, srcwif->ReplaceGC, srcx, srcy, width, height, dstx, dsty);
XCopyArea(display, srcwif->backing, dstwif->backing, dspif->PixRGC, srcx, srcy, width, height,
dstx, dsty);
break;
}
XFlush(display);
return (ATOM_T);
}
/************************************************************************/
/* MNXcloseW */
/* Close a window and save the inner region of the window. */
/* NOTE! we don't save the whiteframe, blackframe or the title. This is */
/* contrary to Medleys own window system. If you do tricks with the */
/* SAVE field of the window, reconsider your evil ways. */
/************************************************************************/
MNXcloseW(LispArgs args)
{
Display *display;
WindowInterface wif;
DspInterface dspif;
BITMAP *bitmap;
display = XDisplayFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) return (NIL); /* If window not open, don't close it. */
wif->open = 0; /* If it is, tell others it's closed. */
bitmap = (BITMAP *)Cptr(((MedleyWindow)Cptr(args[0]))->SAVE);
DrawableToMBM(bitmap, dspif, wif, wif->backing, wif->screen, 0, 0,
/* wif->innerregion.x, wif->innerregion.y, */ 0, 0, wif->innerregion.width,
wif->innerregion.height, REPLACE);
XtUnrealizeWidget(wif->topwidget);
XtRemoveEventHandler(wif->framewidget, ButtonPressMask | ButtonReleaseMask, False, HandleButton,
wif);
XtRemoveEventHandler(wif->framewidget, PointerMotionMask, False, HandleMotion, wif);
XtRemoveEventHandler(wif->framewidget, KeyPressMask | KeyReleaseMask, False, HandleKey, wif);
XtRemoveEventHandler(wif->framewidget, EnterWindowMask | LeaveWindowMask, False, HandleCrossing,
wif);
XtRemoveEventHandler(wif->framewidget, FocusChangeMask, False, HandleFocus, wif);
XtRemoveEventHandler(wif->framewidget, ExposureMask, False, HandleTitle, wif);
XtRemoveEventHandler(wif->windowwidget, ExposureMask, False, HandleExpose, wif);
XtRemoveEventHandler(wif->topwidget, StructureNotifyMask, False, HandleStructure, wif);
wif->not_exposed = 1; /* next time we open this, display it */
XFlush(display);
return (ATOM_T);
}
WindowInterface removewif(chain, wif) WindowInterface chain, wif;
{
/* Recursive unlink off the wif from chain */
if (chain == (WindowInterface)NULL)
return (NULL);
else if (chain == wif)
return (chain->next);
else {
chain->next = removewif(chain->next, wif);
return (chain);
}
}
/************************************************************************/
/* bubblewif */
/* Make sure that the wif is the first wif in the chain of wifs on the */
/* dspif. If not, make it so. */
/* Return wif if we find wif. Return NIL if we don't find wif. */
/* */
/************************************************************************/
WindowInterface bubblewif(dspif, wif) DspInterface dspif;
WindowInterface wif;
{
WindowInterface curr, prev;
if (dspif->CreatedWifs == (WindowInterface)NULL) return (NIL);
if (dspif->CreatedWifs == wif) return (wif);
/* Find the wif we are interested in. */
for (prev = dspif->CreatedWifs, curr = prev->next;
((curr != (WindowInterface)NULL) && (curr != wif)); curr = curr->next, prev = prev->next)
;
if (curr == (WindowInterface)NULL) return (NIL); /* wif not found */
/* Bubble curr to the head of the list */
prev->next = curr->next;
curr->next = dspif->CreatedWifs;
dspif->CreatedWifs = curr;
return (wif);
}
/************************************************************************/
/* destroyw/Xdestroyw */
/* Destroy a window by freeing all structures associated with it. */
/* */
/************************************************************************/
destroyw(dspif, wif, medleyw) WindowInterface wif;
DspInterface dspif;
MedleyWindow medleyw;
{ /* Tell X to destroy its part. */
if (wif->topwidget) XtDestroyWidget(wif->topwidget);
if (wif->InvertGC) XFreeGC(dspif->handle, wif->InvertGC);
if (wif->EraseGC1) XFreeGC(dspif->handle, wif->EraseGC1);
if (wif->EraseGC2) XFreeGC(dspif->handle, wif->EraseGC2);
if (wif->PaintGC1) XFreeGC(dspif->handle, wif->PaintGC1);
if (wif->PaintGC2) XFreeGC(dspif->handle, wif->PaintGC2);
if (wif->ReplaceGC) XFreeGC(dspif->handle, wif->ReplaceGC);
XFreePixmap(dspif->handle, wif->backing);
dspif->CreatedWifs = removewif(dspif->CreatedWifs, wif);
/* Throw away the window and free the space. */
(void)free(wif);
medleyw->NativeIf = 0;
}
MNXdestroyW(LispArgs args)
{
/* Medley interface to destroyw */
destroyw(DspIfFromMw(args[0]), WIfFromMw(args[0]), Cptr(args[0]));
return (ATOM_T);
}
/************************************************************************/
/* MNXdestroyDisplay */
/* Closing down the screen means that we have to invalidate all window */
/* handles. When a window is opened (in Medley) we test the windows */
/* handle. If it is NIL we have to reexternalize it before we open it. */
/* */
/************************************************************************/
MNXdestroyDisplay(LispArgs args) /* args[0] = LispPTR to MedleyScreen */
{
DspInterface dspif;
WindowInterface i;
MedleyScreen MScreen;
int Xfd;
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = MScreen->NativeIf;
Xfd = ConnectionNumber(dspif->handle);
FD_to_dspif[Xfd] = 0;
LispReadFds &= ~(1 << Xfd);
MNWReadFds &= ~(1 << Xfd);
if (dspif->cursor) XFreeCursor(dspif->handle, dspif->cursor);
dspif->cursor = 0;
/* Smash the handles of all the created wifs. */
if (dspif != NULL) {
for (i = dspif->CreatedWifs; i != NULL; i = dspif->CreatedWifs)
destroyw(dspif, i, (MedleyWindow)Cptr(i->MedleyWindow));
if (dspif->legatewidget) XtDestroyWidget(dspif->legatewidget);
XtCloseDisplay(dspif->handle);
(void)free(dspif);
}
}
MNXmoveW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = left */
/* args[2] = bottom */
/* args[3] = non-NIL => skip actually moving it */
{
Display *dsp;
WindowInterface wif;
dsp = XDisplayFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif) return (NIL); /* no real window, no action. */
wif->moving = 1; /* tell event handler to expect an event */
wif->windowreg.x = LispIntToCInt(args[1]);
wif->windowreg.y = LispIntToCInt(args[2]);
calcwif(wif, wif->topregion.width - wif->outerregion.width,
wif->topregion.height - wif->outerregion.height);
/* stolen from calculateshape */
/* printf("MOVEW to %d, %d.\n", wif->windowreg.x, wif->windowreg.y); */
if (!args[3]) {
if (wif->open)
XtMoveWidget(wif->topwidget, wif->topregion.x, wif->topregion.y, 0);
else {
wif->move_pend = 1; /* Save the move for when we open it. */
}
XFlush(dsp);
}
return (ATOM_T);
}
MNXshapeW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = left */
/* args[2] = bottom */
/* args[3] = width */
/* args[4] = height */
{
Display *dsp;
WindowInterface wif;
XtWidgetGeometry geom;
wif = WIfFromMw(args[0]);
if (!wif) return (NIL); /* no real window, no action. */
wif->reshaping = 1; /* tell event handler to expect an event */
dsp = XDisplayFromMw(args[0]);
calculateshape(wif, args[1], args[2], args[3], args[4],
wif->topregion.width - wif->outerregion.width,
wif->topregion.height - wif->outerregion.height);
/* printf("SHAPEW to %d, %d, %d, %d.\n", args[1]&0xFFFF, args[2]&0xFFFF,
args[3]&0xFFFF, args[4]&0xFFFF); */
if (wif->open) {
refreshwindow(args[0]);
XtVaSetValues(wif->formwidget, XtNextentX, 0, XtNextentY, 0, XtNextentWidth, args[3] & 0xFFFF,
XtNextentHeight, args[4] & 0xFFFF, NULL);
XtMoveWidget(wif->topwidget, args[1] & 0xFFFF,
HeightOfScreen(wif->screen) - (args[2] & 0xFFFF) - wif->topregion.height);
} else {
wif->shape_pend = 1;
}
XFreePixmap(wif->dspif->handle, wif->backing);
wif->backing = XCreatePixmap(dsp, wif->dspif->root, args[3] & 0xFFFF, args[4] & 0xFFFF, 1);
XFlush(dsp);
return (ATOM_T);
}
MNXtotopW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
{
Display *dsp;
WindowInterface wif;
dsp = XDisplayFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
XRaiseWindow(dsp, XtWindow(wif->topwidget));
XFlush(dsp);
return (ATOM_T);
}
MNXburyW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
{
Display *dsp;
WindowInterface wif;
dsp = XDisplayFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
XLowerWindow(dsp, XtWindow(wif->topwidget));
XFlush(dsp);
return (ATOM_T);
}
MNXshrinkW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to icon MedleyWindow. */
/* args[2] = Iconwindow x */
/* args[3] = Iconwindow y */
/* args[4] = Iconwindow width */
/* args[5] = Iconwindow height */
{
Screen *screen;
Display *display;
XImage Xbm;
XWMHints Lisp_WMhints;
BITMAP *bitmap;
WindowInterface wif, iconwif;
DspInterface dspif;
int depth;
dspif = DspIfFromMw(args[0]);
display = dspif->handle;
bitmap = (BITMAP *)Cptr(((MedleyWindow)Cptr(args[0]))->SAVE);
wif = WIfFromMw(args[0]);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
iconwif = WIfFromMw(args[1]);
XtVaSetValues(wif->topwidget, XtNiconWindow, iconwif->blackframe, NULL);
DrawableToMBM(bitmap, dspif, wif, wif->backing, XtScreen(wif->topwidget), 0, 0, 0, 0,
wif->innerregion.width, wif->innerregion.height, REPLACE);
XIconifyWindow(XtDisplay(wif->topwidget), XtWindow(wif->topwidget), DefaultScreen(display));
XFlush(display);
return (ATOM_T);
}
MNXexpandW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
{
DspInterface dspif;
WindowInterface wif;
BITMAP *bitmap;
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
if (!args[0]) return (NIL);
if (!wif->open) return (NIL); /* If window not open, don't do anything. */
XMapWindow(XtDisplay(wif->topwidget), XtWindow(wif->topwidget));
showtitle(args[0]);
bitmap = (BITMAP *)Cptr(((MedleyWindow)Cptr(args[0]))->SAVE);
MBMToDrawable(bitmap, dspif, wif, 0, 0, 0, 0, wif->innerregion.width, wif->innerregion.height,
REPLACE);
XFlush(XtDisplay(wif->topwidget));
return (ATOM_T);
}
MNXcreateW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = left */
/* args[2] = bottom */
/* args[3] = width */
/* args[4] = height */
{
XGCValues gcv;
XVisualInfo vinfo, *vinfo2;
XSizeHints sizehints;
Screen *screen;
Display *display;
Window *window;
MedleyScreenRec *mscreen;
WindowInterface wif;
DspInterface dspif;
int width, height, border, whiteborder, blackborder, titleheight;
int strlen, scrno, vcount;
char *tmpstring;
BITMAP *bitmap;
DISPLAYDATA *dd;
/***********************************/
/* Initialize the window structure */
/***********************************/
wif = (WindowInterface)malloc(sizeof(WindowInterfaceRec));
WIfFromMw(args[0]) = wif;
mscreen = ScrnFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
scrno = DefaultScreen(display);
wif->screen = ScreenOfDisplay(display, scrno);
wif->Dispatch = &(dspif->ImageOp);
wif->MedleyWindow = args[0]; /* so we know what WINDOW this corresponds to */
/* Cache the MScreen for the benefit of the signals. */
wif->MedleyScreen = ((MedleyWindow)Cptr(args[0]))->SCREEN;
wif->dspif = dspif;
wif->fgpixmap = 0; /* Cache for the foreground pixmap. */
wif->bgpixmap = 0; /* Cache for the foreground pixmap. */
whiteborder = getwhiteborder(args[0]);
blackborder = getblackborder(args[0]);
tmpstring = gettitlestring(args[0]);
dd = ImDataFromMw(args[0]);
wif->xoffset = LispIntToCInt(dd->ddxoffset);
wif->yoffset = LispIntToCInt(dd->ddyoffset);
/* Special case for Icons and windows with no content and only a titlebar */
if (wif->innerregion.height == 0) whiteborder = 0;
calculateshape(wif, args[1], args[2], args[3], args[4], 0, 0);
/********************************/
/* Create the X window instance */
/********************************/
wif->topwidget = XtVaAppCreateShell(tmpstring, tmpstring, applicationShellWidgetClass, display,
XtNgeometry, wif->gstring, XtNargc, save_argc, XtNargv,
save_argv, XtNborderWidth, 0, NULL);
wif->formwidget =
XtCreateManagedWidget("scrollBox", scrollBoxWidgetClass, wif->topwidget, NULL, 0);
wif->framewidget = XtVaCreateManagedWidget(
"frame", boxWidgetClass, wif->formwidget, XtNheight, wif->outerregion.height, XtNwidth,
wif->outerregion.width, XtNborderWidth, blackborder, XtNbackground,
BlackPixelOfScreen(wif->screen), XtNvSpace, 0, XtNdefaultDistance, 0, XtNhorizDistance, 0,
XtNvertDistance, 0, NULL);
boxClassRec.core_class.compress_motion = False;
wif->windowwidget = XtVaCreateManagedWidget(
"window", boxWidgetClass, wif->framewidget, XtNheight, wif->innerregion.height, XtNwidth,
wif->innerregion.width, XtNx, wif->innerregion.x, XtNy, wif->innerregion.y, XtNborderColor,
WhitePixelOfScreen(wif->screen), XtNborderWidth, whiteborder, XtNvSpace, 0,
XtNdefaultDistance, 0, XtNhorizDistance, 0, XtNvertDistance, 0, XtNbottom, XtChainBottom,
XtNleft, XtChainLeft, NULL);
gcv.function = GXcopy;
gcv.foreground = dspif->black;
gcv.background = dspif->white;
wif->ReplaceGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXxor;
gcv.foreground = (dspif->black) ^ (dspif->white);
gcv.background = 0;
wif->InvertGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXor;
gcv.foreground = dspif->black & (~dspif->white);
gcv.background = 0;
wif->PaintGC1 = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXandInverted;
gcv.foreground = dspif->white & (~dspif->black);
gcv.background = 0;
wif->PaintGC2 = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXor;
gcv.foreground = dspif->white & (~dspif->black);
gcv.background = 0;
wif->EraseGC1 = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXandInverted;
gcv.foreground = dspif->black & (~dspif->white);
gcv.background = 0;
wif->EraseGC2 = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXandInverted;
gcv.foreground = dspif->black & (~dspif->white);
gcv.background = 0;
wif->gc = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
/* Push this wif onto the list of created wifs. */
wif->next = dspif->CreatedWifs;
dspif->CreatedWifs = wif;
wif->backing = XCreatePixmap(display, dspif->root, args[3] & 0xFFFF, args[4] & 0xFFFF, 1);
bitmap = (BITMAP *)Cptr(((MedleyWindow)Cptr(args[0]))->SAVE);
MBMToDrawable(bitmap, dspif, wif, 0, 0, wif->innerregion.x, wif->innerregion.y,
wif->innerregion.width, wif->innerregion.height, REPLACE);
free(tmpstring);
return (ATOM_T);
}
/**************************************************************/
/* showtitle */
/* Update the title frame of the window. It is assumed that */
/* the titlehight is the same as the abs(linefeed) height for */
/* the displaydata of the screen. */
/**************************************************************/
showtitle(win) LispPTR win;
{
BITMAP *bitmap;
DISPLAYDATA *dd;
WindowInterface wif;
DspInterface dspif;
char *tmpstring;
int xpos, dsty, i, width, stringlen, titleheight;
wif = WIfFromMw(win);
dspif = DspIfFromMw(win);
dd = TitleDDFromMw(win);
tmpstring = gettitlestring(win);
titleheight = gettitleheight(win);
if (tmpstring == NULL) return (ATOM_T);
stringlen = strlen(tmpstring);
bitmap = (BITMAP *)Cptr(dd->ddpilotbbt);
MakeScratchImageFromBM(dspif, bitmap);
/* Clear the window of previous gunk. */
XClearWindow(dspif->handle, wif->blackframe);
/* Start text flush to the border */
xpos = LispIntToCInt(((MedleyWindow)Cptr(win))->WBORDER);
dsty = titleheight - bitmap->bmheight + 2; /* The +2 is ad hoc */
/* Set the name property in the server */
XtVaSetValues(wif->topwidget, XtNtitle, tmpstring, NULL);
/* Add character set switching code... */
if ((bitmap->bmbitperpixel == 1) || (bitmap->bmbitperpixel == DefaultDepthOfScreen(wif->screen)))
for (i = 0; i < stringlen; i++) {
width = GETWORD((DLword *)Cptr(dd->ddwidthscache + tmpstring[i]));
XPutImage(dspif->handle, wif->blackframe, dspif->TitleGC, &dspif->image,
GETWORD(Cptr(dd->ddoffsetscache + tmpstring[i])), /* src x */
0, /* src y */
xpos, /* dst x */
dsty, /* ??? dst y */
width, bitmap->bmheight /* height */
);
xpos += width;
}
else {
/* Take the long way out. Make an image of the cached bitmap and */
/* convert it to the depth of the screen. Then dump it to the server */
int x, y;
dspif->image.width = bitmap->bmwidth;
dspif->image.height = bitmap->bmheight;
dspif->image.bytes_per_line =
((bitmap->bmwidth + (BITSPER_DLWORD - 1)) / BITSPER_DLWORD) * (BITSPER_DLWORD / 8);
dspif->image.depth = DefaultDepthOfScreen(wif->screen);
dspif->image.data =
(char *)malloc(dspif->image.bytes_per_line * dspif->image.width * dspif->image.depth);
dspif->tmpimage.width = bitmap->bmwidth;
dspif->tmpimage.height = bitmap->bmheight;
dspif->tmpimage.depth = bitmap->bmbitperpixel & 0xFFFF;
dspif->tmpimage.data = (char *)Cptr((LispPTR)bitmap->bmbase);
dspif->tmpimage.bytes_per_line =
((bitmap->bmwidth + (BITSPER_DLWORD - 1)) / BITSPER_DLWORD) * (BITSPER_DLWORD / 8);
for (x = 0; x < bitmap->bmwidth; x++)
for (y = 0; y < bitmap->bmheight; y++)
XPutPixel(&dspif->image, x, y, XGetPixel(&dspif->tmpimage, x, y));
for (i = 0; i < stringlen; i++) {
width = GETWORD((DLword *)Cptr(dd->ddwidthscache + tmpstring[i]));
XPutImage(dspif->handle, wif->blackframe, dspif->TitleGC, &dspif->image,
GETWORD(Cptr(dd->ddoffsetscache + tmpstring[i])), /* src x */
0, /* src y */
xpos, /* dst x */
dsty, /* ??? dst y */
width, bitmap->bmheight /* height */
);
xpos += width;
}
free(dspif->image.data);
}
free(tmpstring);
return (ATOM_T);
}
/************************************************************************/
/* MNXopenW */
/* Open a window and get the inner region of the window from the SAVE */
/* slot on the MedWindow */
/* NOTE! we don't get whiteframe, blackframe or the title. See MNXcloseW. */
/************************************************************************/
MNXopenW(LispArgs args)
{
Display *display;
WindowInterface wif;
DspInterface dspif;
char *tmpstring;
BITMAP *bitmap;
XGCValues gcv;
Window window, root, parent, *children;
int nch;
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = dspif->handle;
XtAddEventHandler(wif->framewidget, ButtonPressMask | ButtonReleaseMask, False, HandleButton,
wif);
XtAddEventHandler(wif->framewidget, PointerMotionMask, False, HandleMotion, wif);
XtAddEventHandler(wif->framewidget, KeyPressMask | KeyReleaseMask, False, HandleKey, wif);
XtAddEventHandler(wif->framewidget, EnterWindowMask | LeaveWindowMask, False, HandleCrossing,
wif);
XtAddEventHandler(wif->framewidget, FocusChangeMask, False, HandleFocus, wif);
XtAddEventHandler(wif->framewidget, ExposureMask, False, HandleTitle, wif);
XtAddEventHandler(wif->windowwidget, ExposureMask, False, HandleExpose, wif);
XtAddEventHandler(wif->topwidget, StructureNotifyMask, False, HandleStructure, wif);
XtRealizeWidget(wif->topwidget);
#ifdef NEVER
if (wif->shape_pend) /* We reshaped while closed; do it for real here */
{
refreshwindow(args[0]);
XtVaSetValues(wif->formwidget, XtNextentX, 0, XtNextentY, 0, XtNextentWidth,
wif->windowreg.width, XtNextentHeight, wif->windowreg.height, NULL);
XtMoveWidget(wif->topwidget, wif->topregion.x, wif->topregion.y);
wif->move_pend = wif->shape_pend = 0;
} else if (wif->move_pend) /* We moved while closed; do the move here. */
{
wif->move_pend = 0;
XtMoveWidget(wif->topwidget, wif->topregion.x, wif->topregion.y, 0);
}
#endif
wif->blackframe = XtWindow(wif->framewidget);
wif->handle = window = XtWindow(wif->windowwidget);
/* wif->parent = XtWindow(wif->topwidget); */
XQueryTree(display, XtWindow(wif->topwidget), &root, &parent, &children, &nch);
wif->parent = parent;
XFree(children);
refreshwindow(args[0]);
settileorigin(args[0], 0, wif->innerregion.height);
settexture(args[0]);
showtitle(args[0]);
XtSetSensitive(wif->framewidget, True);
XtSetSensitive(wif->windowwidget, True);
if (!wif->backing) {
wif->backing =
XCreatePixmap(display, window, wif->outerregion.width, wif->outerregion.height, 1);
}
bitmap = (BITMAP *)Cptr(((MedleyWindow)Cptr(args[0]))->SAVE);
MBMToDrawable(bitmap, dspif, wif, 0, 0,
/* wif->innerregion.x, wif->innerregion.y, */ 0, 0, wif->innerregion.width,
wif->innerregion.height, REPLACE);
XRaiseWindow(display, XtWindow(wif->topwidget));
XFlush(display);
wif->open = 1; /* mark the window open. */
return (ATOM_T);
}
MNXresetW(LispArgs args)
{
Display *display;
WindowInterface wif;
DISPLAYDATA *dd;
display = XDisplayFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) return (NIL); /* if the window is closed, do nothing */
if (XtIsRealized(wif->topwidget)) {
#ifdef NEVER
showtitle(args[0]);
settexture(args[0]);
XClearWindow(display, XtWindow(wif->windowwidget));
#else
bltshade_internal(display, 0, dd->ddtexture, 0, 0, wif->innerregion.width,
wif->innerregion.height, wif, wif->dspif);
#endif /* NEVER */
}
XFlush(display);
return (ATOM_T);
}
MNXSetOffsets(LispArgs args) /* args[0] = window XOFFSET/YOFFSET changed in */
/* args[1] = new XOFFSET */
/* args[2] = new YOFFSET */
{
Display *display;
WindowInterface wif;
wif = WIfFromMw(args[0]);
wif->xoffset = LispIntToCInt(args[1]);
wif->yoffset = LispIntToCInt(args[2]);
}
/*********************/
/* Imageop Methods. */
/*********************/
MNXdrawpoint(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = x */
/* args[2] = y */
/* args[3] = brush */
{
Display *display;
Window window;
DspInterface dspif;
WindowInterface wif;
int width, x, y;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
dd = ImDataFromMw(args[0]);
display = dspif->handle;
window = XtWindow(wif->windowwidget);
if (args[3] == NIL)
width = 0;
else
width = LispIntToCInt(args[3]);
x = translate_x(wif, LispIntToCInt(args[1]));
y = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2]));
/** Handle the four operation cases **/
if (dd->ddoperation == INVERT_atom) {
XDrawPoint(display, window, wif->InvertGC, x, y);
XDrawPoint(display, wif->backing, dspif->PixIGC, x, y);
} else if (dd->ddoperation == ERASE_atom) {
XDrawPoint(display, window, wif->EraseGC1, x, y);
XDrawPoint(display, window, wif->EraseGC2, x, y);
XDrawPoint(display, wif->backing, dspif->PixEGC, x, y);
} else if (dd->ddoperation == PAINT_atom) {
XDrawPoint(display, window, wif->PaintGC1, x, y);
XDrawPoint(display, window, wif->PaintGC2, x, y);
XDrawPoint(display, wif->backing, dspif->PixPGC, x, y);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawPoint(display, window, wif->ReplaceGC, x, y);
XDrawPoint(display, wif->backing, dspif->PixRGC, x, y);
}
XFlush(display);
return (NIL);
}
/**************************************************************/
/* MNXdrawline */
/* color not yet implemented */
/* Medleys Drawline can't handle dashing. */
/* Thick lines in Medley are handled as parallelograms */
/* instead of rectangles. */
/* Remember that this method has an OPERATION argument in */
/* Lisp so we have to fix that there. */
/**************************************************************/
MNXdrawline(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = x1 */
/* args[2] = y1 */
/* args[3] = x2 */
/* args[4] = y2 */
/* args[5] = width */
/* Args[6] = dashing */
{
WindowInterface wif;
Display *display;
Window window;
DspInterface dspif;
int y1, y2, x1, x2;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
dd = ImDataFromMw(args[0]);
display = dspif->handle;
window = XtWindow(wif->windowwidget);
/* Transform the Y coordinates */
y1 = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2]));
y2 = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[4]));
x1 = translate_x(wif, LispIntToCInt(args[1]));
x2 = translate_x(wif, LispIntToCInt(args[3]));
setlineattributes(display, dspif, wif, dd, args[5], args[6]);
if (dd->ddoperation == INVERT_atom) {
XDrawLine(display, window, wif->InvertGC, x1, y1, x2, y2);
XDrawLine(display, wif->backing, dspif->PixIGC, x1, y1, x2, y2);
} else if (dd->ddoperation == ERASE_atom) {
XDrawLine(display, window, wif->EraseGC1, x1, y1, x2, y2);
XDrawLine(display, window, wif->EraseGC2, x1, y1, x2, y2);
XDrawLine(display, wif->backing, dspif->PixEGC, x1, y1, x2, y2);
} else if (dd->ddoperation == PAINT_atom) {
XDrawLine(display, window, wif->PaintGC1, x1, y1, x2, y2);
XDrawLine(display, window, wif->PaintGC2, x1, y1, x2, y2);
XDrawLine(display, wif->backing, dspif->PixPGC, x1, y1, x2, y2);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawLine(display, window, wif->ReplaceGC, x1, y1, x2, y2);
XDrawLine(display, wif->backing, dspif->PixRGC, x1, y1, x2, y2);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdrawcircle */
/* Note: 23040 is 360 * 64 sixtyfourth degrees */
/* It is assumed that the BRUSH argument is a fixp that */
/* represents a ROUND brush. */
/**************************************************************/
MNXdrawcircle(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = centerX */
/* args[2] = centerY */
/* args[3] = radius */
/* args[4] = brush */
/* args[5] = dashing */
{
int radius, d, x, y;
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
radius = LispIntToCInt(args[3]);
d = radius << 1;
y = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2])) - radius;
x = translate_x(wif, LispIntToCInt(args[1])) - radius;
setlineattributes(display, dspif, wif, dd, args[4], args[5]);
if (dd->ddoperation == INVERT_atom) {
XDrawArc(display, window, wif->InvertGC, x, y, d, d, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixIGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == ERASE_atom) {
XDrawArc(display, window, wif->EraseGC1, x, y, d, d, 0, 23040);
XDrawArc(display, window, wif->EraseGC2, x, y, d, d, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixEGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == PAINT_atom) {
XDrawArc(display, window, wif->PaintGC1, x, y, d, d, 0, 23040);
XDrawArc(display, window, wif->PaintGC2, x, y, d, d, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixPGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawArc(display, window, wif->ReplaceGC, x, y, d, d, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixRGC, x, y, d, d, 0, 23040);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdrawarc */
/* It is assumed that the BRUSH argument is a fixp that */
/* represents a ROUND brush. */
/**************************************************************/
MNXdrawarc(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = centerX */
/* args[2] = centerY */
/* args[3] = radius */
/* args[4] = startangle in 64'ths degrees */
/* args[5] = ndegrees in 64'ths degrees */
/* args[6] = brush */
/* args[7] = dashing */
/* Brush and dashing args are ignored for the moment. */
{
int radius, d, x, y, start, ndeg;
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
radius = LispIntToCInt(args[3]);
d = radius << 1;
x = translate_x(wif, LispIntToCInt(args[1])) - radius;
y = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2])) - radius;
start = LispIntToCInt(args[4]);
ndeg = LispIntToCInt(args[5]);
setlineattributes(display, dspif, wif, dd, args[6], args[7]);
if (dd->ddoperation == INVERT_atom) {
XDrawArc(display, window, wif->InvertGC, x, y, d, d, start, ndeg);
XDrawArc(display, wif->backing, dspif->PixIGC, x, y, d, d, start, ndeg);
} else if (dd->ddoperation == ERASE_atom) {
XDrawArc(display, window, wif->EraseGC1, x, y, d, d, start, ndeg);
XDrawArc(display, window, wif->EraseGC2, x, y, d, d, start, ndeg);
XDrawArc(display, wif->backing, dspif->PixEGC, x, y, d, d, start, ndeg);
} else if (dd->ddoperation == PAINT_atom) {
XDrawArc(display, window, wif->PaintGC1, x, y, d, d, start, ndeg);
XDrawArc(display, window, wif->PaintGC2, x, y, d, d, start, ndeg);
XDrawArc(display, wif->backing, dspif->PixPGC, x, y, d, d, start, ndeg);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawArc(display, window, wif->ReplaceGC, x, y, d, d, start, ndeg);
XDrawArc(display, wif->backing, dspif->PixRGC, x, y, d, d, start, ndeg);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdrawelipse */
/* Note: 23040 is 360 * 64 sixtyfourth degrees */
/* It is assumed that the BRUSH argument is a fixp that */
/* represents a ROUND brush. */
/**************************************************************/
MNXdrawelipse(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = centerX */
/* args[2] = centerY */
/* args[3] = semiminorradius */
/* args[4] = semimajorradius */
/* args[5] = orientation */
/* args[6] = brush */
/* args[7] = dashing */
{
int radius, d1, d2, x, y;
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
x = translate_x(wif, LispIntToCInt(args[1])) - radius;
y = wif->innerregion.height - translate_x(wif, LispIntToCInt(args[2])) - radius;
d1 = LispIntToCInt(args[3]);
d2 = LispIntToCInt(args[4]);
setlineattributes(display, dspif, wif, dd, args[6], args[7]);
if (dd->ddoperation == INVERT_atom) {
XDrawArc(display, window, wif->InvertGC, x, y, d1, d2, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixIGC, x, y, d1, d2, 0, 23040);
} else if (dd->ddoperation == ERASE_atom) {
XDrawArc(display, window, wif->EraseGC1, x, y, d1, d2, 0, 23040);
XDrawArc(display, window, wif->EraseGC2, x, y, d1, d2, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixEGC, x, y, d1, d2, 0, 23040);
} else if (dd->ddoperation == PAINT_atom) {
XDrawArc(display, window, wif->PaintGC1, x, y, d1, d2, 0, 23040);
XDrawArc(display, window, wif->PaintGC2, x, y, d1, d2, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixPGC, x, y, d1, d2, 0, 23040);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawArc(display, window, wif->ReplaceGC, x, y, d1, d2, 0, 23040);
XDrawArc(display, wif->backing, dspif->PixRGC, x, y, d1, d2, 0, 23040);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXfillcircle */
/* Note: 23040 is 360 * 64 sixtyfourth degrees */
/**************************************************************/
MNXfillcircle(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = centerX */
/* args[2] = centerY */
/* args[3] = radius */
/* Brush and dashing args are ignored for the moment. */
{
int radius, d, x, y;
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
radius = LispIntToCInt(args[3]);
d = radius << 1;
x = translate_x(wif, LispIntToCInt(args[1])) - radius;
y = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2])) - radius;
if (dd->ddoperation == INVERT_atom) {
XFillArc(display, window, wif->InvertGC, x, y, d, d, 0, 23040);
XFillArc(display, wif->backing, dspif->PixIGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == ERASE_atom) {
XFillArc(display, window, wif->EraseGC1, x, y, d, d, 0, 23040);
XFillArc(display, window, wif->EraseGC2, x, y, d, d, 0, 23040);
XFillArc(display, wif->backing, dspif->PixEGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == PAINT_atom) {
XFillArc(display, window, wif->PaintGC1, x, y, d, d, 0, 23040);
XFillArc(display, window, wif->PaintGC2, x, y, d, d, 0, 23040);
XFillArc(display, wif->backing, dspif->PixPGC, x, y, d, d, 0, 23040);
} else if (dd->ddoperation == REPLACE_atom) {
XFillArc(display, window, wif->ReplaceGC, x, y, d, d, 0, 23040);
XFillArc(display, wif->backing, dspif->PixRGC, x, y, d, d, 0, 23040);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXwritepixel */
/**************************************************************/
MNXwritepixel(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = x */
/* args[2] = y */
{
int x, y;
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
x = translate_x(wif, LispIntToCInt(args[1]));
y = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2]));
if (dd->ddoperation == INVERT_atom) {
XDrawPoint(display, window, wif->InvertGC, x, y);
XDrawPoint(display, wif->backing, dspif->PixIGC, x, y);
} else if (dd->ddoperation == ERASE_atom) {
XDrawPoint(display, window, wif->EraseGC1, x, y);
XDrawPoint(display, window, wif->EraseGC2, x, y);
XDrawPoint(display, wif->backing, dspif->PixEGC, x, y);
} else if (dd->ddoperation == PAINT_atom) {
XDrawPoint(display, window, wif->PaintGC1, x, y);
XDrawPoint(display, window, wif->PaintGC2, x, y);
XDrawPoint(display, wif->backing, dspif->PixPGC, x, y);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawPoint(display, window, wif->ReplaceGC, x, y);
XDrawPoint(display, wif->backing, dspif->PixRGC, x, y);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdrawpolygon */
/* Lisp sends down a pointer to a vector of points. The vector*/
/* is organized as [x1,y1,x2,y2,...] MNXdrawpolygon smashes this*/
/* vector with the integer values converted to C integers. */
/**************************************************************/
MNXdrawpolygon(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to Pointvector */
/* args[2] = Closedp */
{
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
int i;
Arrayp *pv;
short *xpt, y;
long *Mpt;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
pv = (Arrayp *)Cptr(args[1]);
Mpt = (long *)Cptr(pv->base);
xpt = (short *)Cptr(pv->base);
/* XPoint is defined as shorts, base is defined as longs. */
/* Pack the vector. */
for (i = 0; i < pv->length; i++) xpt[i] = (short)Mpt[i];
/* Transmogrify the y coordinates */
y = (short)wif->innerregion.height;
for (i = 1; i < pv->length; i += 2) {
xpt[i] = y - translate_y(wif, xpt[i]);
xpt[i - 1] = translate_x(wif, xpt[i - 1]);
}
/* If CLOSED then set last point are eq to the first. */
if (args[2] != NIL) {
xpt[pv->length++] = xpt[0];
xpt[pv->length++] = xpt[1];
}
if (dd->ddoperation == INVERT_atom) {
XDrawLines(display, window, wif->InvertGC, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixIGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == ERASE_atom) {
XDrawLines(display, window, wif->EraseGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, window, wif->EraseGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixEGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == PAINT_atom) {
XDrawLines(display, window, wif->PaintGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, window, wif->PaintGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixPGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawLines(display, window, wif->ReplaceGC, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixRGC, xpt, (pv->length >> 1), CoordModeOrigin);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
MNXfillpolygon(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to Pointvector */
/* args[2] = Closedp */
{
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
int i;
Arrayp *pv;
short *xpt, y;
long *Mpt;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
pv = (Arrayp *)Cptr(args[1]);
Mpt = (long *)Cptr(pv->base);
xpt = (short *)Cptr(pv->base);
/* XPoint is defined as shorts, base is defined as longs. */
/* Pack the vector. */
for (i = 0; i < pv->length; i++) xpt[i] = (short)Mpt[i];
/* Transmogrify the y coordinates */
y = (short)wif->innerregion.height;
for (i = 1; i < pv->length; i += 2) {
xpt[i] = y - translate_y(wif, xpt[i]);
xpt[i - 1] = translate_x(wif, xpt[i - 1]);
}
/* If CLOSED then set last point are eq to the first. */
if (args[2] != NIL) {
xpt[pv->length++] = xpt[0];
xpt[pv->length++] = xpt[1];
}
if (dd->ddoperation == INVERT_atom) {
XFillPolygon(display, window, wif->InvertGC, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, wif->backing, dspif->PixIGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == ERASE_atom) {
XFillPolygon(display, window, wif->EraseGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, window, wif->EraseGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, wif->backing, dspif->PixEGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == PAINT_atom) {
XFillPolygon(display, window, wif->PaintGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, window, wif->PaintGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, wif->backing, dspif->PixPGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == REPLACE_atom) {
XFillPolygon(display, window, wif->ReplaceGC, xpt, (pv->length >> 1), CoordModeOrigin);
XFillPolygon(display, wif->backing, dspif->PixRGC, xpt, (pv->length >> 1), CoordModeOrigin);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdrawcurve */
/* NOTE: Not yet implemented. Works like MNXdrawpolygon!!!!! */
/* Lisp sends down a pointer to a vector of points. The vector*/
/* is organized as [x1,y1,x2,y2,...] MNXdrawpolygon smashes this*/
/* vector with the integer values converted to C integers. */
/**************************************************************/
MNXdrawcurve(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to Pointvector */
/* args[2] = Closedp */
{
WindowInterface wif;
Window window;
Display *display;
DspInterface dspif;
int i;
Arrayp *pv;
short *xpt, y;
long *Mpt;
DISPLAYDATA *dd;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
pv = (Arrayp *)Cptr(args[1]);
Mpt = (long *)Cptr(pv->base);
xpt = (short *)Cptr(pv->base);
/* XPoint is defined as shorts, base is defined as longs. */
/* Pack the vector. */
for (i = 0; i < pv->length; i++) xpt[i] = (short)Mpt[i];
/* Transmogrify the y coordinates */
y = (short)wif->innerregion.height;
for (i = 1; i < pv->length; i += 2) {
xpt[i] = y - translate_y(wif, xpt[i]);
xpt[i - 1] = translate_x(wif, xpt[i - 1]);
}
/* If CLOSED then set last point are eq to the first. */
if (args[2] != NIL) {
xpt[pv->length++] = xpt[0];
xpt[pv->length++] = xpt[1];
}
if (dd->ddoperation == INVERT_atom) {
XDrawLines(display, window, wif->InvertGC, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixIGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == ERASE_atom) {
XDrawLines(display, window, wif->EraseGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, window, wif->EraseGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixEGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == PAINT_atom) {
XDrawLines(display, window, wif->PaintGC1, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, window, wif->PaintGC2, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixPGC, xpt, (pv->length >> 1), CoordModeOrigin);
} else if (dd->ddoperation == REPLACE_atom) {
XDrawLines(display, window, wif->ReplaceGC, xpt, (pv->length >> 1), CoordModeOrigin);
XDrawLines(display, wif->backing, dspif->PixRGC, xpt, (pv->length >> 1), CoordModeOrigin);
}
XFlush(display);
return (NIL); /* Report that all is ok. */
}
/************************************************************/
/* MNXclippingregion */
/************************************************************/
MNXclippingregion(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = left */
/* args[2] = bottom */
/* args[3] = width */
/* args[4] = height */
{
WindowInterface wif;
Window window;
DspInterface dspif;
Display *display;
XRectangle rect;
DISPLAYDATA *dd;
/* This is a noop. We read the region straight from the displaydata slots. */
return (ATOM_T);
}
/**************************************************************/
/* MNXoperation */
/* Sets the GC for the window according to the following: */
/* 0=replace, 1=paint, 2=invert, 3=erase */
/* Remember that some functions have operation as argument and*/
/* Thus have to call this function explicitly twice. Once to */
/* set the new state and once to put the old state back. */
/**************************************************************/
MNXoperation(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = Smallp for function. */
{
WindowInterface wif;
Window window;
DspInterface dspif;
Display *display;
DISPLAYDATA *dd;
wif = WIfFromMw(args[0]);
window = XWindowFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
dd = ImDataFromMw(args[0]);
/* This is a noop. We manipulate the GC from the displaydata slots. */
if (dd->ddoperation == REPLACE_atom)
wif->op = 0;
else if (dd->ddoperation == PAINT_atom)
wif->op = 1;
else if (dd->ddoperation == INVERT_atom)
wif->op = 2;
else if (dd->ddoperation == ERASE_atom)
wif->op = 3;
return (NIL);
}
/**************************************************************/
/* MNXdspcolor */
/* */
/* */
/* */
/* */
/**************************************************************/
MNXdspcolor(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to FIXP or BITMAPP */
{
WindowInterface wif;
DspInterface dspif;
Display *display;
DISPLAYDATA *dd;
int fgcol;
char id[64];
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
dd = ImDataFromMw(args[0]);
if (wif->fgpixmap) {
/* If we have an fgpixmap, junk it */
XFreePixmap(display, wif->fgpixmap);
wif->fgpixmap = 0;
}
if (TYPE_SMALLP == GetTypeNumber(args[1]))
if (LispIntToCInt(MScrFromMw(args[0])->SCDEPTH) == 1) {
/* A fixp on a BW screen: make a texture of this */
dspif->image.data = id;
MakeScratchImageFromInt(dspif, LispIntToCInt(args[1]));
} else { /* A fixp on a color screen: color the foreground */
fgcol = ~LispIntToCInt(args[1]);
XSetForeground(display, wif->InvertGC, fgcol);
XSetForeground(display, wif->EraseGC1, fgcol);
XSetForeground(display, wif->EraseGC2, fgcol);
XSetForeground(display, wif->PaintGC1, fgcol);
XSetForeground(display, wif->PaintGC2, fgcol);
XSetForeground(display, wif->ReplaceGC, fgcol);
return (NIL);
}
else {
BITMAP *bitmap;
bitmap = (BITMAP *)Cptr(args[1]);
MakeScratchImageFromBM(dspif, bitmap);
}
if (dspif->image.depth == 1) {
wif->fgpixmap = XCreatePixmapFromBitmapData(dspif->handle, XtWindow(wif->windowwidget),
dspif->image.data, dspif->image.width,
dspif->image.height, 0, 1, dspif->image.depth);
XSetStipple(display, wif->InvertGC, wif->fgpixmap);
XSetStipple(display, wif->EraseGC1, wif->fgpixmap);
XSetStipple(display, wif->EraseGC2, wif->fgpixmap);
XSetStipple(display, wif->PaintGC1, wif->fgpixmap);
XSetStipple(display, wif->PaintGC2, wif->fgpixmap);
XSetStipple(display, wif->ReplaceGC, wif->fgpixmap);
} else {
wif->fgpixmap = XCreatePixmapFromBitmapData(
dspif->handle, XtWindow(wif->windowwidget), dspif->image.data, dspif->image.width,
dspif->image.height, BlackPixelOfScreen(wif->screen), WhitePixelOfScreen(wif->screen),
dspif->image.depth);
XSetTile(display, wif->InvertGC, wif->fgpixmap);
XSetTile(display, wif->EraseGC1, wif->fgpixmap);
XSetTile(display, wif->EraseGC2, wif->fgpixmap);
XSetTile(display, wif->PaintGC1, wif->fgpixmap);
XSetTile(display, wif->PaintGC2, wif->fgpixmap);
XSetTile(display, wif->ReplaceGC, wif->fgpixmap);
}
return (NIL); /* Report that all is ok. */
}
/**************************************************************/
/* MNXdspbackcolor */
/* */
/* */
/* */
/* */
/**************************************************************/
MNXdspbackcolor(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = background type 0=fixp for color 1=bitmap for stiple. */
/* args[2] = background, fixp or bitmap */
{ settexture(args[0]); }
/************************************************************/
/* MNXBitblt - can only copy from bitmap to window. we need */
/* to make it do WINDOW -> BITMAP and WINDOW -> WINDOW */
/************************************************************/
MNXBitBltBW() { error("Call to MNXBitBltBW. This function is not in use anymore."); }
MNXbltshadeBW(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = LispPTR to TEXTURE */
/* args[2] = dst_x */
/* args[3] = dst_y */
/* args[4] = width */
/* args[5] = height */
/* args[6] = operation */
/* args[7] = background, fixp or bitmap */
{
WindowInterface wif;
DspInterface dspif;
Display *display;
Screen *screen;
int width, height, depth, regheight, dstx, dsty;
char tmpstring[128], *data;
int op = args[6] & 0xFFFF;
wif = WIfFromMw(args[0]);
dspif = DspIfFromMw(args[0]);
display = XDisplayFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
regheight = LispIntToCInt(args[5]);
width = LispIntToCInt(args[4]);
dstx = translate_x(wif, LispIntToCInt(args[2]));
dsty = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[3])) - regheight;
bltshade_internal(display, op, args[1], dstx, dsty, width, regheight, wif, dspif);
}
bltshade_internal(display, op, texture, dstx, dsty, width, regheight, wif, dspif) Display *display;
LispPTR texture;
int op, dstx, dsty, width, regheight;
WindowInterface wif;
DspInterface dspif;
{
Pixmap bgpixmap;
char id[64];
if (TYPE_SMALLP == GetTypeNumber(texture)) {
#ifdef NEVER
if (dspif->depth == 1) {
#endif /* NEVER */
dspif->image.data = id;
MakeScratchImageFromInt(dspif, texture & 0xFFFF);
#ifdef NEVER
} else { /* Medley sez' color the foreground */
XSetForeground(display, wif->gc, ~LispIntToCInt(texture));
XFillRectangle(display, XtWindow(wif->windowwidget), wif->gc, dstx, dsty, width, regheight);
XFlush(display);
return (ATOM_T);
}
#endif /* NEVER */
} else { /* Its a bitmap. Medley sez' make a texture of this */
BITMAP *bitmap;
bitmap = (BITMAP *)Cptr(texture);
MakeScratchImageFromBM(dspif, bitmap);
}
#ifdef NEVER
if (dspif->image.depth == 1) {
#endif /* NEVER */
bgpixmap = XCreatePixmapFromBitmapData(dspif->handle, XtWindow(wif->windowwidget),
dspif->image.data, dspif->image.width,
dspif->image.height, 0, 1, dspif->image.depth);
XSetStipple(display, wif->gc, bgpixmap);
#ifdef NEVER
} else {
bgpixmap = XCreatePixmapFromBitmapData(dspif->handle, XtWindow(wif->windowwidget),
dspif->image.data, dspif->image.width,
dspif->image.height, BlackPixelOfScreen(wif->screen),
WhitePixelOfScreen(wif->screen), dspif->image.depth);
XSetTile(display, wif->gc, bgpixmap);
}
#endif /* NEVER */
XSetFunction(display, wif->gc, bltshade_function[op % 4]);
switch (op) {
case 0:
/* XSetFillStyle(display, wif->gc, FillOpaqueStippled); */
XSetFillStyle(display, dspif->PixRGC, FillOpaqueStippled);
XSetStipple(display, dspif->PixRGC, bgpixmap);
XSetTSOrigin(display, dspif->PixRGC, dstx, dsty);
XFillRectangle(display, wif->backing, dspif->PixRGC, dstx, dsty, width, regheight);
break;
case 1:
XSetFillStyle(display, wif->gc, FillStippled);
XSetFillStyle(display, dspif->PixRGC, FillStippled);
XSetStipple(display, dspif->PixRGC, bgpixmap);
XSetTSOrigin(display, dspif->PixRGC, dstx, dsty);
XFillRectangle(display, wif->backing, dspif->PixRGC, dstx, dsty, width, regheight);
break;
case 2:
XSetForeground(display, wif->gc, dspif->white ^ dspif->black);
XSetFillStyle(display, wif->gc, FillStippled);
XSetFillStyle(display, dspif->PixIGC, FillStippled);
XSetStipple(display, dspif->PixIGC, bgpixmap);
XSetTSOrigin(display, dspif->PixIGC, dstx, dsty);
XFillRectangle(display, wif->backing, dspif->PixIGC, dstx, dsty, width, regheight);
break;
case 3:
XSetForeground(display, wif->gc, dspif->white);
XSetFillStyle(display, wif->gc, FillStippled);
XSetFillStyle(display, dspif->PixEGC, FillStippled);
XSetStipple(display, dspif->PixEGC, bgpixmap);
XSetTSOrigin(display, dspif->PixEGC, dstx, dsty);
XFillRectangle(display, wif->backing, dspif->PixEGC, dstx, dsty, width, regheight);
break;
}
/* XSetTSOrigin(display, wif->gc, dstx, dsty);
XFillRectangle(display, XtWindow(wif->windowwidget), wif->gc,
dstx, dsty, width, regheight); */
XCopyPlane(display, wif->backing, XtWindow(wif->windowwidget), wif->ReplaceGC, dstx, dsty, width,
regheight, dstx, dsty, 1);
XFreePixmap(display, bgpixmap);
switch (op) /* undo the changing of foreground color above */
{
case 0:
case 1: XSetFillStyle(display, dspif->PixRGC, FillSolid); break;
case 2:
XSetForeground(display, wif->gc, dspif->black);
XSetFillStyle(display, dspif->PixIGC, FillSolid);
break;
case 3:
XSetForeground(display, wif->gc, dspif->black);
XSetFillStyle(display, dspif->PixEGC, FillSolid);
break;
}
/* XSetFunction(display, wif->gc, gcfunction[wif->op % 4]); */
XFlush(display);
}
XClearToEOL(LispArgs args) /* args[0] = MedleyWindow */
{
Display *display;
Window window;
WindowInterface wif;
DISPLAYDATA *dd;
int dsty, dstx, height;
dd = ImDataFromMw(args[0]);
display = XDisplayFromMw(args[0]);
window = XWindowFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
height = abs(dd->ddlinefeed);
dstx = translate_x(wif, LispIntToCInt(args[1]));
dsty = wif->innerregion.height - translate_y(wif, LispIntToCInt(args[2])) - height;
XClearArea(display, window, dstx, dsty, 0, /* Out to the end */
height, /* The height */
False /* Don't generate exposure events */
);
XFlush(display);
}
MNXNewPage(LispArgs args) /* args[0] = MedleyWindow */
{
Display *display;
Window window;
display = XDisplayFromMw(args[0]);
window = XWindowFromMw(args[0]);
/* ... */
XFlush(display);
}
/************************************************************/
/* MNXOutchar */
/* NOTE this function returns NIL if we succeed and T if we */
/* bump into the right margin. */
/************************************************************/
MNXOutchar(LispArgs args) /* args[0] = MedleyWindow */
/* args[1] = Charcode */
/* args[2] = Stream */
/* args[3] = DD */
/* DSPXOFFSET and DSPYOFFSET are ignored here. */
{
/* Doesn't switch charsets. */
Display *display;
Window window;
char tmpstring[2];
DspInterface dspif;
WindowInterface wif;
Stream *s;
DISPLAYDATA *dd;
BITMAP *bitmap;
int cx, cy, char8code, right, rmargin, lmargin, newpos;
int w, height, sx, sy;
dspif = DspIfFromMw(args[0]);
wif = WIfFromMw(args[0]);
if (!wif->open) MNXopenW(args); /* if window is closed, open it. */
display = dspif->handle;
window = XtWindow(wif->windowwidget);
if (!window) return (NIL); /* No window, pretend we succeeded. */
s = ((Stream *)Cptr(args[2]));
dd = ((DISPLAYDATA *)Cptr(args[3]));
char8code = LispIntToCInt(args[1]) & 255;
/* Get the current position */
cx = translate_x(wif, LispIntToCInt(dd->ddxposition));
rmargin = LispIntToCInt(dd->ddrightmargin);
lmargin = LispIntToCInt(dd->ddleftmargin);
w = GETWORD((DLword *)Cptr(dd->ddcharimagewidths + char8code));
right = cx + w;
if ((right > rmargin) && (cx > lmargin)) /* a linebreak. Punt. */
return (ATOM_T);
newpos = cx + GETWORD((DLword *)Cptr(dd->ddwidthscache + char8code));
dd->ddxposition = CIntToLispInt(newpos);
/* Y transform. Ypos is the baseline, it is adjusted by ascent */
cy = translate_y(wif, LispIntToCInt(dd->ddyposition));
cy = wif->innerregion.height - cy - dd->ddcharsetascent;
/* This bitmap should be cached on the server! */
/* Do this in the CHANGECHARSET code. */
bitmap = (BITMAP *)Cptr(dd->ddpilotbbt);
MakeScratchImageFromBM(dspif, bitmap);
sx = GETWORD(Cptr(dd->ddoffsetscache + char8code));
sy = 0;
if (dd->ddoperation == INVERT_atom) {
XPutImage(display, window, wif->InvertGC, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, wif->backing, dspif->PixIGC, &dspif->image, sx, sy, cx, cy, w,
bitmap->bmheight);
} else if (dd->ddoperation == ERASE_atom) {
XPutImage(display, window, wif->EraseGC1, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, window, wif->EraseGC2, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, wif->backing, dspif->PixEGC, &dspif->image, sx, sy, cx, cy, w,
bitmap->bmheight);
} else if (dd->ddoperation == PAINT_atom) {
XPutImage(display, window, wif->PaintGC1, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, window, wif->PaintGC2, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, wif->backing, dspif->PixPGC, &dspif->image, sx, sy, cx, cy, w,
bitmap->bmheight);
} else if (dd->ddoperation == REPLACE_atom) {
XPutImage(display, window, wif->ReplaceGC, &dspif->image, sx, sy, cx, cy, w, bitmap->bmheight);
XPutImage(display, wif->backing, dspif->PixRGC, &dspif->image, sx, sy, cx, cy, w,
bitmap->bmheight);
}
/* Increment the CHARPOSITION of the stream with 1 */
s->CHARPOSITION++;
XFlush(display);
return (NIL);
}
/************************************************************/
/* The WINDOWPROP interface */
/************************************************************/
MNXgetwindowprop(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
{}
MNXputwindowprop(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
/* args[1] = Lispint to dispatch on. */
/* args[n] = args for the method. */
{
int method;
Window window;
XWindowAttributes attr;
WindowInterface wif;
method = LispIntToCInt(args[1]);
wif = WIfFromMw(args[0]);
/* Discard the dispatching lispint and */
/* make the argvector be on the form */
/* <medleywindow> <methodarg1> <methodarg2> ... */
args[1] = args[0];
args++;
switch (method) {
case MNWTitle: showtitle(args[0]); break;
case MNWScrollFn:
XtVaSetValues(WIfFromMw(args[0])->formwidget, XtNbarOnOff, (args[1] != NIL), XtNmedleyWindow,
wif, XtNhScroll, &SignalHScroll, XtNhJmpScroll, &SignalHJmpScroll, XtNvScroll,
&SignalVScroll, XtNvJmpScroll, &SignalVJmpScroll, NULL);
if (XtWindow(wif->topwidget)) {
XGetWindowAttributes(wif->dspif->handle, XtWindow(wif->topwidget), &attr);
wif->topregion.width = attr.width;
wif->topregion.height = attr.height;
}
break;
case MNWNoScrollbars:
XtVaSetValues(WIfFromMw(args[0])->formwidget, XtNbarOnOff, (args[1] == NIL), NULL);
if (XtWindow(wif->topwidget)) {
XGetWindowAttributes(wif->dspif->handle, XtWindow(wif->topwidget), &attr);
wif->topregion.width = attr.width;
wif->topregion.height = attr.height;
}
break;
case MNWScrollExtent:
XtVaSetValues(WIfFromMw(args[0])->formwidget, XtNextentX, LispIntToCInt(args[1]), XtNextentY,
LispIntToCInt(args[2]), XtNextentWidth, LispIntToCInt(args[3]), XtNextentHeight,
LispIntToCInt(args[4]), NULL);
break;
case MNWScrollExtentUse: break;
case MNWBorder: refreshwindow(args[0]); break;
default: break;
}
}
/************************************************************/
/* Mouse position and friends. Have to be vectored through */
/* the screen. */
/************************************************************/
static Cursor grab_cursor = 0; /* Cursor in effect while pointer is grabbed */
/************************************************************************/
/* */
/* G r a b P o i n t e r */
/* args[0] = screen to do it on */
/* args[1] = cursor to use (?) */
/* args[2] = cursor hotspot x */
/* args[3] = cursor hotspot y */
/* */
/* */
/************************************************************************/
MNXGrabPointer(LispArgs args)
/* args[0] = medley screen */
/* args[1] = cursor to use, or NIL */
{
Display *display;
WindowInterface wif;
DspInterface dspif;
char *tmpstring;
BITMAP *bitmap;
XGCValues gcv;
MedleyScreen MScreen;
Pixmap bits;
Window promptw;
int res, i;
unsigned char *src;
unsigned char srcbits[32]; /* holds the reversed bits for cursor */
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = MScreen->NativeIf;
display = dspif->handle;
wif = dspif->promptw; /* handle on the prompt window */
promptw = XtWindow(wif->framewidget);
if (args[1]) {
src = (unsigned char *)Cptr(args[1]);
for (i = 0; i < 32; i++) srcbits[i] = reversedbits[src[i]];
bits = XCreatePixmapFromBitmapData(display, dspif->root, srcbits, 16, 16, 1, 0, 1);
grab_cursor = XCreatePixmapCursor(display, bits, bits, &dspif->black, &dspif->white,
args[2] & 0xFFFF, 16 - (args[3] & 0xFFFF));
} else {
grab_cursor = None;
}
res =
XGrabPointer(display, promptw, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None, grab_cursor, CurrentTime);
if (grab_cursor != None) { XFreePixmap(display, bits); }
if (res == GrabSuccess)
return (ATOM_T);
else
return (NIL);
}
MNXUngrabPointer(LispArgs args)
{
Display *display;
WindowInterface wif;
DspInterface dspif;
char *tmpstring;
BITMAP *bitmap;
XGCValues gcv;
MedleyScreen MScreen;
int res;
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = MScreen->NativeIf;
display = dspif->handle;
/* wif = WIfFromMw(args[0]); */
res = XUngrabPointer(display, CurrentTime);
if (grab_cursor != None) XFreeCursor(display, grab_cursor);
grab_cursor = None;
return (ATOM_T);
}
static int box_drawn = 0; /* T if there's a box on already */
MNXDrawBox(LispArgs args) /* args[0] = Medley SCREEN to draw box on */
/* args[1] = Left of box */
/* args[2] = bottom of box */
/* args[3] = width of box */
/* args[4] = height of box */
/* args[5] = T to force turning box off iff it's on */
{
Display *display;
WindowInterface wif;
DspInterface dspif;
MedleyScreen MScreen;
int res, l, b, w, h;
GC gc;
Window root;
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = MScreen->NativeIf;
display = dspif->handle;
gc = dspif->BoxingGC;
root = dspif->root;
l = LispIntToCInt(args[1]);
b = LispIntToCInt(args[2]);
w = LispIntToCInt(args[3]);
h = LispIntToCInt(args[4]);
if (w < 0) /* Negative width, change X coord and make it positive */
{
l += w;
w = -w;
}
if (h < 0) /* Negative height, change Y coord and make it positive */
{
b += h;
h = -h;
}
b = HeightOfScreen(dspif->xscreen) - b - h; /* convert to X's Y-coord */
if (args[5]) {
if (box_drawn) XDrawRectangle(display, root, gc, l, b, w, h);
box_drawn = 0;
} else {
XDrawRectangle(display, root, gc, l, b, w, h);
box_drawn = !box_drawn;
}
}
MNXMovePointer(LispArgs args) /* args[0] = LispPTR to SCREEN */
/* args[1] = new pointer X */
/* args[2] = new pointer Y */
{
Display *display;
WindowInterface wif;
DspInterface dspif;
MedleyScreen MScreen;
int res, l, b, w, h;
GC gc;
Window root;
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = MScreen->NativeIf;
display = dspif->handle;
gc = dspif->BoxingGC;
root = dspif->root;
XWarpPointer(display, None, root, 0, 0, 0, 0, args[1] & 0xFFFF, args[2] & 0xFFFF);
return (ATOM_T);
}
MNXmouseconfirm(LispArgs args) /* args[0] = LispPTR to MedleyWindow */
{ /* Use a DIALOG WIDGET here. */ }
MNXgarb(LispArgs args) /* args[0] = LispPTR to MedleyScreen */
/* args[1] = NIL for GC off, non-NIL for GC on */
{
DspInterface dspif;
dspif = DspIfFromMscr(args[0]);
if (dspif->gcindicator)
if (XtIsRealized(dspif->gcindicator))
if (args[1] == NIL)
XClearWindow(XtDisplay(dspif->gcindicator), XtWindow(dspif->gcindicator));
else
XFillRectangle(XtDisplay(dspif->gcindicator), XtWindow(dspif->gcindicator),
DefaultGCOfScreen(XtScreen(dspif->gcindicator)), 0, 0, 8, 8);
}
MNXMakePromptWindow(LispArgs args) /* args[0] = Lisp window, the prompt window */
{
Widget form, menu;
DspInterface dspif;
WindowInterface wif;
wif = WIfFromMw(args[0]);
dspif = wif->dspif;
dspif->promptw = wif; /* Save prompt window, for grabbing pointer events */
dspif->legatewidget = XtVaAppCreateShell(
"Medley Status", "Medley Status", applicationShellWidgetClass, XDisplayFromMw(args[0]),
XtNargc, save_argc, XtNargv, save_argv, XtNborderWidth, 0, NULL);
form = XtVaCreateManagedWidget("bar", boxWidgetClass, dspif->legatewidget, NULL);
dspif->gcindicator =
XtVaCreateManagedWidget("gcindicator", boxWidgetClass, form, XtNwidth, 8, XtNheight, 8, NULL);
menu = XtVaCreateManagedWidget("Background", commandWidgetClass, form, NULL);
XtAddEventHandler(menu, ButtonPressMask | ButtonReleaseMask, False, HandleBackgroundButton,
dspif->screen);
XtAddEventHandler(dspif->legatewidget, PointerMotionMask, False, HandleMotion, 0);
XtAddEventHandler(dspif->legatewidget, EnterWindowMask | LeaveWindowMask, False,
HandleBackgroundCrossing, dspif);
XtAddEventHandler(dspif->legatewidget, KeyPressMask | KeyReleaseMask, False, HandleKey, dspif);
XtRealizeWidget(dspif->legatewidget);
XtSetSensitive(dspif->legatewidget, True);
XtSetSensitive(form, True);
return (ATOM_T);
}
/************************************************************/
/* */
/* M N X S e t C u r s o r */
/* */
/* Set the cursor for all windows on a given screen. */
/* */
/************************************************************/
static Cursor MNX_cursor = NULL; /* Cursor in active use */
MNXSetCursor(LispArgs args) /* args[0] = Medley screen */
/* args[1] = bits for new cursor */
/* args[2] = hot-spot x */
/* args[3] = hot-spot y */
{
Display *display;
WindowInterface wif;
DspInterface dspif;
char *tmpstring;
BITMAP *bitmap;
XGCValues gcv;
MedleyScreen MScreen;
Pixmap bits;
Cursor new_cursor;
Window win;
unsigned char srcbits[32]; /* hold the reversed-bits for cursor */
unsigned char *src;
int i;
MScreen = (MedleyScreen)Cptr(args[0]);
dspif = DspIfFromMscr(args[0]);
display = dspif->handle;
src = (unsigned char *)Cptr(args[1]);
for (i = 0; i < 32; i++) srcbits[i] = reversedbits[src[i]];
bits = XCreatePixmapFromBitmapData(display, dspif->root, srcbits, 16, 16, 1, 0, 1);
new_cursor = XCreatePixmapCursor(display, bits, bits, &dspif->black, &dspif->white,
args[2] & 0xFFFF, args[3] & 0xFFFF);
for (wif = dspif->CreatedWifs; wif; wif = wif->next)
if (win = XtWindow(wif->windowwidget)) XDefineCursor(display, win, new_cursor);
XFreePixmap(display, bits);
if (dspif->cursor) { XFreeCursor(display, dspif->cursor); }
dspif->cursor = new_cursor;
return (NIL);
}
/************************************************************/
/* I n i t D s p */
/* */
/* The slots for identifier, object type and window system */
/* has to be filled in. */
/************************************************************/
InitDsp(LispArgs args) /* arg[0] = LispPTR to MedleyScreen */
{
DspInterface dspif;
MedleyScreen SCREEN;
char *tmpstring, *defaulthost;
int strlen;
Display *display;
Screen *screen;
XGCValues gcv;
int black, white; /* Pixel values for this display */
int mask, diff, inverted; /* For finding a plane where they differ */
Pixmap tpx; /* temp pixmap of depth 1 for creating GCs */
int Xfd;
SCREEN = (MedleyScreen)Cptr(args[0]);
dspif = (DspInterface)malloc(sizeof(DspInterfaceRec));
SCREEN->NativeIf = dspif;
if (!xtinitialized) {
XtToolkitInitialize();
xtinitialized = True;
}
dspif->xtcontext = XtCreateApplicationContext();
/* if NATIVE_INFO has a string use it for the hostname */
/* else use the environment var DISPLAY or "unix:0.0" */
if (LispStringP(SCREEN->NATIVE_INFO)) {
strlen = LispStringLength(SCREEN->NATIVE_INFO);
tmpstring = (char *)alloca(strlen + 1);
LispStringToCStr(SCREEN->NATIVE_INFO, tmpstring);
dspif->handle =
XtOpenDisplay(dspif->xtcontext, tmpstring, NULL, "window", NULL, 0, &save_argc, save_argv);
} else
dspif->handle =
XtOpenDisplay(dspif->xtcontext, NULL, NULL, "window", NULL, 0, &save_argc, save_argv);
/* Set up the native structure here */
if (dspif->handle == NULL) return (CIntToLispInt(2));
XSetErrorHandler(Xerrhandler);
display = dspif->handle;
dspif->xscreen = screen = DefaultScreenOfDisplay(display);
Xfd = ConnectionNumber(display);
FD_to_dspif[Xfd] = dspif;
LispReadFds |= (1 << Xfd);
MNWReadFds |= (1 << Xfd);
fcntl(Xfd, F_SETOWN, getpid());
dspif->screen = args[0]; /* So we know which SCREEN this display is */
dspif->root = RootWindowOfScreen(screen); /* And the root window for the screen */
dspif->gcindicator = 0;
dspif->legatewidget = 0;
dspif->cursor = 0;
gcv.function = GXcopy;
gcv.foreground = dspif->white = WhitePixelOfScreen(screen);
gcv.background = dspif->black = BlackPixelOfScreen(screen);
dspif->TitleGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
tpx = XCreatePixmap(display, dspif->root, 10, 10, 1);
gcv.function = GXcopy;
gcv.foreground = 1;
gcv.background = 0;
dspif->PixRGC = XCreateGC(display, tpx, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXor;
gcv.foreground = 1;
gcv.background = 0;
dspif->PixPGC = XCreateGC(display, tpx, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXxor;
gcv.foreground = 1;
gcv.background = 0;
dspif->PixIGC = XCreateGC(display, tpx, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXandInverted;
gcv.foreground = 1;
gcv.background = 0;
dspif->PixEGC = XCreateGC(display, tpx, GCForeground | GCBackground | GCFunction, &gcv);
XFreePixmap(display, tpx);
dspif->image.format = XYBitmap;
dspif->image.xoffset = 0;
#if (defined(BYTESWAP))
dspif->image.byte_order = LSBFirst;
#else /* BYTESWAP */
dspif->image.byte_order = MSBFirst;
#endif /* BYTESWAP */
dspif->image.bitmap_unit = 16 /*BitmapUnit( dspif->handle )*/;
dspif->image.bitmap_bit_order = MSBFirst;
dspif->image.bitmap_pad = 16 /* 32 */;
_XInitImageFuncPtrs(&dspif->image);
dspif->tmpimage.format = XYBitmap;
dspif->tmpimage.xoffset = 0;
#if (defined(BYTESWAP))
dspif->tmpimage.byte_order = LSBFirst;
#else /* BYTESWAP */
dspif->tmpimage.byte_order = MSBFirst;
#endif /* BYTESWAP */
dspif->tmpimage.bitmap_unit = 16 /*BitmapUnit( dspif->handle )*/;
dspif->tmpimage.bitmap_bit_order = MSBFirst;
dspif->tmpimage.bitmap_pad = 16 /* 32 */;
_XInitImageFuncPtrs(&dspif->tmpimage);
dspif->CreatedWifs = NULL; /* List of created wif. */
/* Fill in the screen dimensions too! */
SCREEN->SCWIDTH = CIntToLispInt(WidthOfScreen(screen));
SCREEN->SCHEIGHT = CIntToLispInt(HeightOfScreen(screen));
#ifndef NEVER
SCREEN->SCDEPTH = CIntToLispInt(PlanesOfScreen(screen));
#endif
/* Methods for the display */
dspif->Dispatch.Method.InitW = MNXcreateW;
dspif->Dispatch.Method.Openw = MNXopenW;
dspif->Dispatch.Method.Closew = MNXcloseW;
dspif->Dispatch.Method.MoveW = MNXmoveW;
dspif->Dispatch.Method.ShapeW = MNXshapeW;
dspif->Dispatch.Method.TotopW = MNXtotopW;
dspif->Dispatch.Method.BuryW = MNXburyW;
dspif->Dispatch.Method.ShrinkW = MNXshrinkW;
dspif->Dispatch.Method.ExpandW = MNXexpandW;
dspif->Dispatch.Method.DestroyW = MNXdestroyW;
dspif->Dispatch.Method.MakePromptW = MNXMakePromptWindow;
dspif->Dispatch.Method.DestroyMe = MNXdestroyDisplay;
dspif->Dispatch.Method.BBTtoWin = MNXBBTToXWindow;
dspif->Dispatch.Method.BBTfromWin = MNXBBTFromXWindow;
dspif->Dispatch.Method.BBTWinWin = MNXBBTWinWin;
dspif->Dispatch.Method.GetWindowProp = MNXgetwindowprop;
dspif->Dispatch.Method.PutWindowProp = MNXputwindowprop;
dspif->Dispatch.Method.GrabPointer = MNXGrabPointer;
dspif->Dispatch.Method.UngrabPointer = MNXUngrabPointer;
dspif->Dispatch.Method.DrawBox = MNXDrawBox;
dspif->Dispatch.Method.MovePointer = MNXMovePointer;
dspif->Dispatch.Method.MouseConfirm = MNXmouseconfirm;
dspif->Dispatch.Method.GCIndicator = MNXgarb;
dspif->Dispatch.Method.SetCursor = MNXSetCursor;
/* ImageOp methods */
dspif->ImageOp.Method.BitBlt = MNXBitBltBW;
dspif->ImageOp.Method.BltShade = MNXbltshadeBW;
dspif->ImageOp.Method.DrawPoint = MNXdrawpoint;
dspif->ImageOp.Method.DrawLine = MNXdrawline;
dspif->ImageOp.Method.DrawCurve = MNXdrawcurve;
dspif->ImageOp.Method.DrawCircle = MNXdrawcircle;
dspif->ImageOp.Method.FillCircle = MNXfillcircle;
dspif->ImageOp.Method.DrawCurve = MNXdrawcurve;
dspif->ImageOp.Method.DrawPolygon = MNXdrawpolygon;
dspif->ImageOp.Method.FillPolygon = MNXfillpolygon;
dspif->ImageOp.Method.DrawElips = MNXdrawelipse;
dspif->ImageOp.Method.WritePixel = MNXwritepixel;
dspif->ImageOp.Method.DrawArc = MNXdrawarc;
dspif->ImageOp.Method.OutcharFn = MNXOutchar;
dspif->ImageOp.Method.NewPage = MNXNewPage;
dspif->ImageOp.Method.ClippingRegion = MNXclippingregion;
dspif->ImageOp.Method.Operation = MNXoperation;
dspif->ImageOp.Method.Color = MNXdspcolor;
dspif->ImageOp.Method.BackColor = MNXdspbackcolor;
dspif->ImageOp.Method.Reset = MNXresetW;
dspif->ImageOp.Method.Offsets = MNXSetOffsets;
XSynchronize(display, True);
/**************************************************/
/* Create GCs for BITBLTs from window to bitmap */
/**************************************************/
diff = black & (~white);
inverted = 0;
if (diff)
for (mask = 1; mask; mask <<= 1) {
if (mask & diff) break;
}
else {
mask = 1;
inverted = 1;
for (diff = white & (~black); mask; mask <<= 1) {
if (mask & diff) break;
}
}
#ifdef NEVER
gcv.function = GXcopy;
gcv.foreground = !inverted;
gcv.background = inverted;
dspif->GetRGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXxor;
dspif->GetIGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXor;
dspif->GetPGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
gcv.function = GXandInverted;
dspif->GetEGC = XCreateGC(display, dspif->root, GCForeground | GCBackground | GCFunction, &gcv);
dspif->bw_plane = mask;
dspif->bw_inverted = inverted;
#endif /* NEVER */
gcv.function = GXxor;
gcv.line_style = LineSolid;
gcv.line_width = 0;
gcv.foreground = 255;
gcv.background = 0;
dspif->BoxingGC =
XCreateGC(display, dspif->root,
GCForeground | GCBackground | GCFunction | GCLineWidth | GCLineStyle, &gcv);
XSetSubwindowMode(display, dspif->BoxingGC, IncludeInferiors);
/* Check the requested depth against possibilities */
if (SCREEN->SCDEPTH) {
int i;
int *dlist;
int dcount;
dlist = XListDepths(display, XScreenNumberOfScreen(screen), &dcount);
for (i = 0; i < dcount; i++)
if (dlist[i] == (SCREEN->SCDEPTH & 0xFFFF)) return (NIL);
return (CIntToLispInt(1)); /* Can't find depth */
} else {
SCREEN->SCDEPTH = CIntToLispInt(PlanesOfScreen(screen));
}
return (NIL);
}
/************************************************************/
/* */
/* i n i t _ m n w _ i n s t a n c e */
/* */
/* */
/************************************************************/
init_mnw_instance(args) LispPTR *args;
{
int type;
/* HACK !! HACK !! make this better later!! */
MedleyWindowType = GetTypeNumber(*GetVALCELL68k(MAKEATOM("PROMPTWINDOW")));
MedleyScreenType = GetTypeNumber(*GetVALCELL68k(MAKEATOM("LASTSCREEN")));
MedleyBitmapType = 0;
type = GetTypeNumber(args[0]);
if (type == MedleyScreenType) {
return (InitDsp(args));
} else
error("Bogus type\n");
return (ATOM_T);
}
/**************************************************************/
/* d i s p a t c h _ m n w _ m e t h o d */
/* */
/* The arguments to the dispatcher are as follows */
/* args[0] = methodindex, the index into the dispatch vector */
/* args[1] = self, the object to dispatch from */
/* args[n] = the misc arguments. */
/* */
/* The dispatcher finds the method dispatch table for the */
/* object and dispatches the method. The method is called */
/* with the methodindex removed. */
/**************************************************************/
dispatch_mnw_method(args) LispPTR *args;
{
int type;
int index;
index = LispIntToCInt(args[0]);
type = GetTypeNumber(args[1]);
if (args[1] == NULL) error("No object to dispatch from\n");
if (type == MedleyWindowType) {
WindowInterface wif;
wif = WIfFromMw(args[1]);
if (wif == NULL) {
/* error("Attempt to dispatch on a non-native window.\n"); */
return (NIL);
}
if ((wif->Dispatch->vector[index]) == NULL) {
error("Display method not defined.\n");
return (NIL);
}
/* Now, dispatch with the selector (first) arg shave off */
return ((wif->Dispatch->vector[index])(&args[1]));
} else if (type == MedleyScreenType) {
DspInterface dspif;
dspif = DspIfFromMscr(args[1]);
if (dspif == NULL) {
error("Attempt to dispatch on a non-native screen.\n");
return (NIL);
}
if ((dspif->Dispatch.vector[index]) == NULL) {
error("Display method not defined.\n");
return (NIL);
}
/* Dispatch with selector and screen popped off */
return ((dspif->Dispatch.vector[index])(&args[2]));
} else {
error("Bogus type\n");
return (NIL);
}
}