home *** CD-ROM | disk | FTP | other *** search
- /*
- * VOGL/VOGLE driver for NeXTStep.
- * shamelessly hacked from X11 driver 9/91 by
- *
- * Patrick J. Flynn
- * School of EECS
- * Washington State University
- * Pullman, WA 99164-2752 USA cha cha cha
- * flynn@eecs.wsu.edu
- *
- * modified 9/22/91 to use NeXToid defaults (owner: "VOGL") for
- *
- * + preferred small & large font names/styles/sizes:
- * `SmallFont' `LargeFont'
- *
- * If no defaults are present, SmallFont is "Ohlfs 9.0" and
- * LargeFont is "Ohlfs 18.0"
- *
- * The space in the font string is significant (see NeXT_font below)
- *
- * + window size & placement: `WindowX' `WindowY'
- * `WindowW' `WindowH'
- *
- * If no defaults are present, the window is anchored (LL) at (10,10)
- * and is 792 pixels wide & high. If the user has set the preferred
- * position & size using the VOGL prefXXX() calls, they override the
- * defaults.
- *
- * THIS CODE HAS ONLY BEEN TESTED ON A DOUBLE-HEADED CUBE (2 bit + ND)
- * There are a couple of color-screen-centrisms and 24-bit-centrisms in
- * the code, but NextStep is pretty good about drawing as good as it
- * can on the available hardware.
- *
- */
-
- /*
- * set VOGLE if this is really for the VOGLE library.
- #define VOGLE 1
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <strings.h> /* strfoo() */
-
- #ifdef VOGLE
- #include "vogle.h"
- #else
- #include "vogl.h"
- #endif
-
- #import <appkit/Application.h> /* [NXApp colorScreen] */
- #import <appkit/Window.h>
- #import <appkit/View.h>
- #import <appkit/Font.h>
- #import <dpsclient/wraps.h>
- #import <dpsclient/event.h>
- #import <appkit/color.h>
- #import <appkit/graphics.h>
- #import <appkit/nextstd.h>
- #import <appkit/NXImage.h> /* double buffer */
- #import <appkit/afm.h> /* hack to get metrics */
- #import <appkit/defaults.h>
-
- #define CMAPSIZE 4096 /* perhaps we'll go RGBmode someday. */
-
- Window *winder;
- View *view;
- Font *phont;
- NXFontMetrics *fm;
- NXImage *backbuf = nil;
- NXColor colormap[CMAPSIZE]; /* yeah, I know it's ugly. */
- int back_used;
-
- id drawable; /* the thing we're drawing in (a View or an NXImage) */
-
- /*
- * NeXT_init()
- * initializes the NeXT display.
- */
- int NeXT_init(void)
- {
- int x0,y0,xs,ys;
- NXRect r;
- char name[80];
- const char *ptr;
-
- NXApp = [Application new];
- getprefposandsize(&x0,&y0,&xs,&ys);
-
- if (x0<0) {
- #ifdef VOGLE
- ptr=NXReadDefault("VOGLE","WindowX");
- #else
- ptr=NXReadDefault("VOGL","WindowX");
- #endif
- if (!ptr)
- x0=10;
- else
- if (sscanf(ptr,"%d",&x0) != 1) x0=10;
- };
-
- if (y0<0) {
- #ifdef VOGLE
- ptr=NXReadDefault("VOGLE","WindowY");
- #else
- ptr=NXReadDefault("VOGL","WindowY");
- #endif
- if (!ptr)
- y0=10;
- else
- if (sscanf(ptr,"%d",&y0) != 1) y0=10;
- };
-
- if (xs<0) {
- #ifdef VOGLE
- ptr=NXReadDefault("VOGLE","WindowW");
- #else
- ptr=NXReadDefault("VOGL","WindowW");
- #endif
- if (!ptr)
- xs=792;
- else
- if (sscanf(ptr,"%d",&xs) != 1) xs=792;
- };
-
- if (ys<0) {
- #ifdef VOGLE
- ptr=NXReadDefault("VOGLE","WindowH");
- #else
- ptr=NXReadDefault("VOGL","WindowH");
- #endif
- if (!ptr)
- ys=792;
- else
- if (sscanf(ptr,"%d",&ys) != 1) ys=792;
- };
-
- NXSetRect(&r,x0,y0,xs,ys);
- winder = [[Window alloc] initContent:&r
- style:NX_TITLEDSTYLE
- backing:NX_RETAINED
- buttonMask:0
- defer:NO
- screen:[NXApp colorScreen]];
- [winder setDepthLimit:NX_TwentyFourBitRGBDepth];
- vdevice.depth = 24;
- colormap[0]=NX_COLORBLACK;
- colormap[1]=NX_COLORRED;
- colormap[2]=NX_COLORGREEN;
- colormap[3]=NX_COLORYELLOW;
- colormap[4]=NX_COLORBLUE;
- colormap[5]=NX_COLORMAGENTA;
- colormap[6]=NX_COLORCYAN;
- colormap[7]=NX_COLORWHITE;
-
- #ifdef VOGLE
- sprintf(name, "vogle %d", getpid());
- [winder setTitle:name];
- #else
- if (!vdevice.wintitle) {
- sprintf(name, "vogl %d", getpid());
- [winder setTitle:name];
- }
- else {
- [winder setTitle:vdevice.wintitle];
- };
- #endif
-
- drawable = view = [winder contentView];
-
- phont = nil;
-
- vdevice.sizeX = vdevice.sizeY = MIN(xs,ys) - 1;
- vdevice.sizeSx = xs;
- vdevice.sizeSy = ys;
- back_used = 0;
- [[winder makeKeyAndOrderFront:0] display];
- [drawable lockFocus];
- return(1);
- }
-
- /*
- * NeXT_exit
- *
- * cleans up before returning the window to normal.
- */
- int NeXT_exit(void)
- {
- [winder free];
- if (backbuf) [backbuf free];
- [NXApp free];
- return(1);
- }
-
- /*
- * NeXT_draw
- *
- * draws a line from the current graphics position to (x, y).
- *
- */
- int NeXT_draw(
- int x,
- int y)
- {
- PSsetlinewidth(0.0);
- PSnewpath();
- PSmoveto(vdevice.cpVx,vdevice.cpVy);
- PSlineto(x,y);
- PSstroke();
- if (vdevice.sync)
- NXPing();
- }
-
- /*
- * NeXT_getkey
- *
- * grab a character from the keyboard - blocks until one is there.
- */
- int NeXT_getkey(void)
- {
- NXEvent e;
- NXEvent *ee = NXGetOrPeekEvent(DPSGetCurrentContext(),&e,
- NX_KEYDOWNMASK,NX_FOREVER,NX_BASETHRESHOLD,0);
- if (ee == NULL) fprintf(stderr,"error: NeXT_getKey failed.\n");
- return ee->data.key.charCode;
- }
-
- /*
- * NeXT_checkkey
- *
- * Check if there has been a keyboard key pressed.
- * and return it if so.
- */
- int NeXT_checkkey(void)
- {
- NXEvent e;
- NXEvent *ee = NXGetOrPeekEvent(DPSGetCurrentContext(),&e,
- NX_KEYDOWNMASK,0.0,NX_BASETHRESHOLD,0);
- if (ee == NULL) return 0;
- return ee->data.key.charCode;
- }
-
- /*
- * NeXT_locator
- *
- * return the window location of the cursor, plus which mouse button,
- * if any, is been pressed.
- *
- * the right mouse button is the LSB. There is no middle button on a NeXT
- * so the 2LSB is always 0. The left mouse button is the 3LSB.
- */
- int NeXT_locator(
- int *wx,
- int *wy)
- {
- int msk=0,flg;
- NXPoint p;
- [winder getMouseLocation:&p];
- [view convertPoint:&p fromView:nil];
- *wx = p.x;
- *wy = p.y;
- PSbuttondown(&flg);
- if (flg) msk=4;
- PSrightbuttondown(&flg);
- if (flg) msk+=1;
- return msk;
- }
-
- #ifdef VOGLE
- /*
- * NeXT_clear
- *
- * Clear the screen (or current buffer )to current colour
- */
- int NeXT_clear(void)
- {
- NXRect r;
- [view getBounds:&r];
- NXRectFill(&r);
- if (vdevice.sync)
- NXPing();
- }
-
- #else
-
- /*
- * NeXT_clear
- *
- * Clear the viewport (or current buffer )to current colour
- */
- int NeXT_clear(void)
- {
- NXRect r;
- float w=vdevice.maxVx - vdevice.minVx;
- float h=vdevice.maxVy - vdevice.minVy;
- NXSetRect(&r,vdevice.minVx,vdevice.minVy,w,h);
- [view getBounds:&r];
- NXRectFill(&r);
- if (vdevice.sync)
- NXPing();
- }
-
- #endif
-
- /*
- * NeXT_color
- *
- * set the current drawing color index.
- */
- int NeXT_color(int ind)
- {
- NXSetColor(colormap[ind]);
- }
-
- /*
- * NeXT_mapcolor
- *
- * change index i in the color map to the appropriate r, g, b, value.
- */
- int NeXT_mapcolor(
- int i,
- int r,
- int g,
- int b)
- {
- if (i >= CMAPSIZE) return(-1);
- colormap[i]=NXConvertRGBToColor(1.0*r/255.0,1.0*g/255.0,1.0*b/255.0);
- }
-
- /*
- * NeXT_font
- *
- * Set up a hardware font. Return 1 on success 0 otherwise.
- *
- * This is system-dependent. I assume that the fontfile parameter
- * has the font family name followed by a blank, followed by the size
- * in points, e.g. "Ohlfs 384.7", "Helvetica-BoldOblique 1.0".
- * Note that the size can be floating-point.
- *
- */
- /* c: ugly blech yech
- */
- char *strdup(const char *c)
- {
- char *d=malloc(1+strlen(c));
- bcopy(c,d,1+strlen(c));
- return d;
- }
-
- /* input: NS = "Name size", i.e. "Ohlfs 32.9".
- * output: *s = 32.9, return value = "Ohlfs";
- * returns NULL if string doesn't have both name and size.
- */
- char *_getFontNameNSize(
- const char *ns,
- float *s)
- {
- char *p,*q;
- if (!ns) return 0;
- p=strdup(ns); /* barf */
- q=index(p,' ');
- if (!q) return 0;
- *q++ = '\0'; /* null-terminate name */
- if (sscanf(q,"%f",s) != 1) { free(p); return 0;};
- return p;
- }
-
-
- int NeXT_font(char *fontfile)
- {
- char *name;
- float size;
- Font *newfont;
- if (!strcmp(fontfile,"small")) {
- #ifdef VOGLE
- name=_getFontNameNSize(NXReadDefault("VOGLE","SmallFont"),&size);
- #else
- name=_getFontNameNSize(NXReadDefault("VOGL","SmallFont"),&size);
- #endif
- if (!name) { name=strdup("Ohlfs"); size=9.0; };
- }
- else if (!strcmp(fontfile,"large")) {
- #ifdef VOGLE
- name=_getFontNameNSize(NXReadDefault("VOGLE","LargeFont"),&size);
- #else
- name=_getFontNameNSize(NXReadDefault("VOGL","LargeFont"),&size);
- #endif
- if (!name) { name=strdup("Ohlfs"); size=18.0; };
- }
- else {
- name=_getFontNameNSize((const char *)fontfile,&size);
- if (!name) { name=strdup("Ohlfs"); size=9.0; };
- };
- newfont = [Font newFont:name size:size matrix:NX_IDENTITYMATRIX];
- free(name);
- if (newfont) {
- NXFontMetrics *fm = [newfont metrics];
- int i;
- float wmax=0.0;
- [phont free];
- phont = newfont;
- [phont set];
-
- /* set hheight and hwidth for hardware fonts. The scale factor
- is apparently equal to the point size. It isn't well-documented. */
-
- vdevice.hheight=size*(fm->ascender-fm->descender);
-
- /* with this li'l loop we can handle var-width fonts but they look
- ugly. Stick to Courier & Ohlfs if you can. */
- for(i=0;i<MIN(fm->widthsLength,256);i++) {
- float w=fm->widths[i];
- if (w>wmax) wmax=w;
- };
- vdevice.hwidth=size*wmax;
- return 1;
- }
- else
- return 0;
- }
-
- /*
- * NeXT_char (outputs one char)
- */
- int NeXT_char(char c)
- {
- char s[2];
-
- s[0] = c; s[1]='\0';
- PSmoveto(vdevice.cpVx,vdevice.cpVy);
- PSshow(s);
- if (vdevice.sync)
- NXPing();
- }
-
- /*
- * NeXT_string
- *
- * Display a string at the current drawing position.
- */
- int NeXT_string(char s[])
- {
- PSmoveto(vdevice.cpVx,vdevice.cpVy);
- PSshow(s);
- NXPing();
- }
-
- /*
- * NeXT_fill
- *
- * fill a polygon
- */
- int NeXT_fill(
- int n,
- int x[],
- int y[])
- {
- int i;
- PSnewpath();
- PSmoveto(x[0],y[0]);
- for(i=1;i<n;i++) PSlineto(x[i],y[i]);
- PSclosepath();
- PSfill();
- if (vdevice.sync)
- NXPing();
- }
-
- /*
- * NeXT_backbuf
- *
- * Set up double buffering by allocating the back buffer and
- * setting drawing into it.
- */
- int NeXT_backbuf(void)
- {
- NXRect r;
- [drawable unlockFocus];
- [view getBounds:&r];
- backbuf = [[NXImage alloc] initSize:&r.size];
- if (![backbuf useCacheWithDepth:NX_TwentyFourBitRGBDepth]) {
- fprintf(stderr,"couldn't create backing buffer.\n");
- return 0;
- };
- drawable = backbuf;
- [drawable lockFocus];
- back_used = 1;
- return(1);
- }
-
- /*
- * NeXT_swapbuf
- *
- * Swap the back and front buffers. (Really, just copy the
- * back buffer to the screen).
- */
- int NeXT_swapbuf(void)
- {
- NXPoint origin = {0,0};
- [drawable unlockFocus];
- [view lockFocus];
- [backbuf composite:NX_COPY toPoint:&origin];
- [winder flushWindow];
- [view unlockFocus];
- [drawable lockFocus];
- }
-
- /*
- * NeXT_frontbuf
- *
- * Make sure we draw to the screen.
- */
- int NeXT_frontbuf(void)
- {
- [drawable unlockFocus];
- drawable = view;
- [drawable lockFocus];
- }
-
- /*
- * Syncronise the display with what we think has been sent to it...
- */
- int NeXT_sync(void)
- {
- NXPing();
- }
-
- int NeXT_setls(int ls)
- {
- }
-
- int NeXT_setlw(int w)
- {
- }
-
- /*
- * the device entry
- */
- static DevEntry NeXTdev = {
- "NeXT",
- "small",
- "large",
- NeXT_backbuf,
- NeXT_char,
- NeXT_checkkey,
- NeXT_clear,
- NeXT_color,
- NeXT_draw,
- NeXT_exit,
- NeXT_fill,
- NeXT_font,
- NeXT_frontbuf,
- NeXT_getkey,
- NeXT_init,
- NeXT_locator,
- NeXT_mapcolor,
- NeXT_setls,
- NeXT_setlw,
- NeXT_string,
- NeXT_swapbuf,
- NeXT_sync
- };
-
- /*
- * _NeXT_devcpy
- *
- * copy the NeXT device into vdevice.dev.
- */
- int _NeXT_devcpy(void)
- {
- vdevice.dev = NeXTdev;
- }
-