|
|
1.1 root 1: #include "jerq.h"
2:
3: #ifdef BSD
4: #include <fcntl.h>
5: #else /* V9 */
6: #include <sys/filio.h>
7: #endif BSD
8: #ifdef SUNTOOLS
9: #include <signal.h>
10: #include <sys/ioctl.h>
11: #include <suntool/fullscreen.h>
12: #endif SUNTOOLS
13:
14: Rectangle Drect;
15: Bitmap display, Jfscreen;
16: Point Joffset;
17: struct Mouse mouse;
18: static struct JProc sP;
19: struct JProc *P;
20: Font defont;
21: int mouse_alive = 0;
22: int jerqrcvmask = 1;
23: int displayfd;
24: Cursor normalcursor;
25: static int hintwidth, hintheight, hintflags;
26: static Jlocklevel;
27:
28: #ifdef X11
29: GC gc;
30: Display *dpy;
31: int fgpix, bgpix;
32: Colormap colormap;
33: XColor fgcolor, bgcolor;
34: static unsigned long inputmask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|
35: StructureNotifyMask|ExposureMask|KeyPressMask|
36: PointerMotionHintMask;
37: #endif X11
38: #ifdef SUNTOOLS
39: Pixwin *displaypw;
40: int damagedone;
41: static struct fullscreen *Jfscp;
42: static int screendepth;
43: #endif SUNTOOLS
44:
45: static short arrow_bits[] = {
46: 0x0000, 0x0008, 0x001c, 0x003e,
47: 0x007c, 0x00f8, 0x41f0, 0x43e0,
48: 0x67c0, 0x6f80, 0x7f00, 0x7e00,
49: 0x7c00, 0x7f00, 0x7fc0, 0x0000
50: };
51:
52: static short arrow_mask_bits[] = {
53: 0x0008, 0x001c, 0x003e, 0x007f,
54: 0x00fe, 0x41fc, 0xe3f8, 0xe7f0,
55: 0xffe0, 0xffc0, 0xff80, 0xff00,
56: 0xff00, 0xffc0, 0xffe0, 0xffc0
57: };
58:
59: /* This must be called before initdisplay */
60: mousemotion ()
61: {
62: mouse_alive = 1;
63: #ifdef X11
64: inputmask |= PointerMotionMask;
65: #endif X11
66: }
67:
68: #ifdef X11
69: initdisplay(argc, argv)
70: int argc;
71: char *argv[];
72: {
73: int i;
74: XSetWindowAttributes xswa;
75: XSizeHints sizehints;
76: XWindowAttributes xwa;
77: char *font;
78: char *geom = 0;
79: int flags;
80: int width, height, x, y;
81: char **ap;
82:
83: if(!(dpy= XOpenDisplay(NULL))){
84: perror("Cannot open display\n");
85: exit(-1);
86: }
87: displayfd = dpy->fd;
88:
89: if (jerqrcvmask)
90: #ifdef BSD
91: fcntl(1, F_SETFL, FNDELAY);;
92: #else
93: ioctl(1, FIOWNBLK, 0);
94: #endif
95: font = XGetDefault(dpy, argv[0], "JerqFont");
96: if(font == NULL)
97: font = "fixed";
98: bzero(&sizehints, sizeof(sizehints));
99: ap = argv;
100: i = argc;
101: while(i-- > 0){
102: if(!strcmp("-fn", ap[0])){
103: font = ap[1];
104: i--; ap++;
105: }
106: else if(ap[0][0] == '='){
107: geom = ap[0];
108: flags = XParseGeometry(ap[0],&x,&y,&width,&height);
109: if(WidthValue & flags){
110: sizehints.flags |= USSize;
111: sizehints.width = width;
112: }
113: if(HeightValue & flags){
114: sizehints.flags |= USSize;
115: sizehints.height = height;
116: }
117: if(XValue & flags){
118: if(XNegative & flags)
119: x=DisplayWidth(dpy,DefaultScreen(dpy))+x
120: - sizehints.width;
121: sizehints.flags |= USPosition;
122: sizehints.x = x;
123: }
124: if(YValue & flags){
125: if(YNegative & flags)
126: y=DisplayHeight(dpy,DefaultScreen(dpy))+y
127: -sizehints.height;
128: sizehints.flags |= USPosition;
129: sizehints.y = y;
130: }
131: }
132: ap++;
133: }
134: defont = getfont(font);
135: P = &sP;
136: sizehints.width_inc = sizehints.height_inc = 1;
137: sizehints.min_width = sizehints.min_height = 20;
138: sizehints.flags |= PResizeInc|PMinSize;
139: if(!geom){
140: sizehints.width = defont.max_bounds.width * 80;
141: sizehints.height = (defont.max_bounds.ascent +
142: defont.max_bounds.descent) * 24;
143: sizehints.flags |= PSize;
144: jerqsizehints();
145: if (hintwidth)
146: sizehints.width = hintwidth;
147: if (hintheight)
148: sizehints.height = hintheight;
149: if (hintflags) {
150: sizehints.min_width = hintwidth;
151: sizehints.min_height = hintheight;
152: }
153: }
154: xswa.event_mask = 0;
155: bgpix = xswa.background_pixel = WhitePixel(dpy, 0);
156: fgpix = xswa.border_pixel = BlackPixel(dpy, 0);
157: display.dr = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
158: sizehints.x,sizehints.y, sizehints.width, sizehints.height,
159: 2,0,InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
160: CWEventMask | CWBackPixel | CWBorderPixel, &xswa);
161: XSetStandardProperties(dpy, display.dr, argv[0], argv[0],
162: None, argv, argc, &sizehints);
163: XMapWindow(dpy, display.dr);
164: colormap = XDefaultColormap(dpy, 0);
165: fgcolor.pixel = fgpix;
166: bgcolor.pixel = bgpix;
167: XQueryColor(dpy, colormap, &fgcolor);
168: XQueryColor(dpy, colormap, &bgcolor);
169: gc = XCreateGC(dpy, display.dr, 0, NULL);
170: XSetForeground(dpy, gc, fgpix);
171: XSetBackground(dpy, gc, bgpix);
172: XSetFont(dpy, gc, defont.fid);
173: XSetLineAttributes(dpy, gc, 0, LineSolid, CapNotLast, JoinMiter);
174: Drect.origin.x = 0;
175: Drect.origin.y = 0;
176: Drect.corner.x = sizehints.width;
177: Drect.corner.y = sizehints.height;
178: display.rect = Drect;
179: #ifdef XBUG
180: Jfscreen = display;
181: #else
182: Jfscreen.dr = RootWindow(dpy, DefaultScreen(dpy));
183: Jfscreen.rect.origin.x = 0;
184: Jfscreen.rect.origin.y = 0;
185: Jfscreen.rect.corner.x = DisplayWidth(dpy, DefaultScreen(dpy));
186: Jfscreen.rect.corner.y = DisplayHeight(dpy, DefaultScreen(dpy));
187: #endif XBUG
188: normalcursor = ToCursor(arrow_bits, arrow_mask_bits, 1, 15);
189: cursswitch(&normalcursor);
190: XSelectInput(dpy, display.dr, inputmask);
191: for(;;) {
192: if (sizehints.flags & USPosition) {
193: XGetWindowAttributes(dpy, display.dr, &xwa);
194: if (xwa.map_state != IsUnmapped) {
195: #ifndef XBUG
196: Joffset.x = xwa.x;
197: Joffset.y = xwa.y;
198: #endif XBUG
199: break;
200: }
201: } else if (P->state & RESHAPED)
202: break;
203: while (XPending(dpy))
204: handleinput();
205: }
206: }
207:
208: Font
209: getfont(s)
210: char *s;
211: {
212: static Font f;
213: Font *fp;
214:
215: fp = XLoadQueryFont(dpy, s);
216: return fp ? *fp : f;
217: }
218: #endif X11
219:
220: #ifdef SUNTOOLS
221: initdisplay (argc, argv)
222: int argc;
223: char **argv;
224: {
225: extern char *getenv();
226: extern struct pixrectops mem_ops;
227: int gfx;
228: int designee;
229: struct inputmask mask;
230: struct rect gfxrect;
231: static winch_catcher();
232:
233: fcntl(1, F_SETFL, FNDELAY);
234: signal(SIGWINCH, winch_catcher);
235: gfx = open(getenv("WINDOW_GFX"), 0);
236: if(gfx < 0){
237: perror("cannot get graphics window");
238: exit(1);
239: }
240: designee = win_nametonumber(getenv("WINDOW_GFX"));
241: displayfd = win_getnewwindow();
242: win_insertblanket(displayfd, gfx);
243: close(gfx);
244: defont = pf_default();
245: displaypw = pw_open(displayfd);
246: win_getrect(displayfd, &gfxrect);
247: screendepth = displaypw->pw_pixrect->pr_depth;
248: if(!(displaypw->pw_prretained =
249: mem_create(gfxrect.r_width, gfxrect.r_height, 1)))
250: perror("initdisplay: mem_create");
251: display.dr = (char *)displaypw;
252: Drect.origin.x = Drect.origin.y = 0;
253: Drect.corner.x = gfxrect.r_width;
254: Drect.corner.y = gfxrect.r_height;
255: display.rect = Drect;
256: P = &sP;
257: input_imnull(&mask);
258: if(mouse_alive)
259: win_setinputcodebit(&mask, LOC_MOVE);
260: win_setinputcodebit(&mask, MS_LEFT);
261: win_setinputcodebit(&mask, MS_MIDDLE);
262: win_setinputcodebit(&mask, MS_RIGHT);
263: win_setinputcodebit(&mask, LOC_DRAG);
264: mask.im_flags |= IM_NEGEVENT;
265: mask.im_flags |= IM_ASCII;
266: win_setinputmask(displayfd, &mask, 0, designee);
267: normalcursor = ToCursor(arrow_bits, arrow_mask_bits, 1, 15);
268: cursswitch(&normalcursor);
269: rectf(&display, Drect, F_CLR);
270: Joffset.x = 0;
271: Joffset.y = 0;
272: P->state |= RESHAPED;
273: if (damagedone)
274: fixdamage();
275: }
276:
277: /*
278: * Catch SIGWINCH signal when window is damaged
279: */
280: static
281: winch_catcher ()
282: {
283: damagedone = 1;
284: }
285:
286: fixdamage()
287: {
288: struct rect gfxrect;
289: int x, y;
290:
291: damagedone = 0;
292: pw_damaged(displaypw);
293: win_getrect(displayfd, &gfxrect);
294: if (Drect.corner.x != gfxrect.r_width ||
295: Drect.corner.y != gfxrect.r_height) {
296: Drect.corner.x = gfxrect.r_width;
297: Drect.corner.y = gfxrect.r_height;
298: display.rect = Drect;
299: P->state |= RESHAPED;
300: pw_donedamaged(displaypw);
301: pr_destroy(displaypw->pw_prretained);
302: displaypw->pw_prretained = 0;
303: rectf(&display, Drect, F_CLR);
304: displaypw->pw_prretained =
305: mem_create(gfxrect.r_width, gfxrect.r_height, 1);
306: }
307: else {
308: pw_repairretained(displaypw);
309: pw_donedamaged(displaypw);
310: }
311: }
312:
313: Font
314: getfont(s)
315: char *s;
316: {
317: return(pf_open(s));
318: }
319: #endif SUNTOOLS
320:
321: request(what)
322: int what;
323: {
324: if (!(what & RCV)) {
325: jerqrcvmask = 0;
326: close(0);
327: close(1);
328: }
329: }
330:
331: Bitmap *
332: balloc (r)
333: Rectangle r;
334: {
335: Bitmap *b;
336:
337: b = (Bitmap *)malloc(sizeof (struct Bitmap));
338: #ifdef X11
339: b->dr = XCreatePixmap(dpy, display.dr, r.cor.x-r.org.x,
340: r.cor.y-r.org.y, DefaultDepth(dpy, 0));
341: #endif X11
342: #ifdef SUNTOOLS
343: b->dr = (char *)mem_create(r.cor.x - r.org.x, r.cor.y - r.org.y, 1);
344: #endif SUNTOOLS
345: b->flag = BI_OFFSCREEN;
346: b->rect=r;
347: return b;
348: }
349:
350: void
351: bfree(b)
352: Bitmap *b;
353: {
354: if(b){
355: #ifdef X11
356: XFreePixmap(dpy, b->dr);
357: #endif X11
358: #ifdef SUNTOOLS
359: pr_destroy((Pixrect *)b->dr);
360: #endif SUNTOOLS
361: free((char *)b);
362: }
363: }
364:
365: Point
366: string (f, s, b, p, c)
367: Font *f;
368: char *s;
369: Bitmap *b;
370: Point p;
371: Code c;
372: {
373: if(b->flag & BI_OFFSCREEN)
374: p = sub(p, b->rect.origin);
375: #ifdef X11
376: XSetFunction(dpy, gc, c);
377: XDrawString(dpy, b->dr, gc, p.x, p.y + f->max_bounds.ascent, s, strlen(s));
378: #endif X11
379: #ifdef SUNTOOLS
380: if(b->flag & BI_OFFSCREEN){
381: struct pr_prpos where;
382: where.pr = (Pixrect *)b->dr;
383: where.pos.x = p.x;
384: where.pos.y = p.y - (*f)->pf_char['A'].pc_home.y;
385: pf_text(where, c, *f, s);
386: }
387: else
388: pw_text((Pixwin *)b->dr, p.x,
389: p.y - (*f)->pf_char['A'].pc_home.y,
390: c, *f, s);
391: #endif SUNTOOLS
392: return(add(p, Pt(strwidth(f,s),0)));
393: }
394:
395: int
396: strwidth (f, s)
397: Font *f;
398: register char *s;
399: {
400: #ifdef X11
401: return XTextWidth(f, s, strlen(s));
402: #endif X11
403: #ifdef SUNTOOLS
404: struct pr_size size;
405: size = pf_textwidth(strlen(s), *f, s);
406: return(size.x);
407: #endif SUNTOOLS
408: }
409:
410: #ifdef X11
411: /*
412: * Convert a blit style texture to a pixmap which can be used in tiling
413: * or cursor operations.
414: */
415: Texture
416: ToTexture(bits)
417: short bits[];
418: {
419: static XImage *im;
420: Pixmap pm;
421:
422: if (!im)
423: im = XCreateImage(dpy, XDefaultVisual(dpy, 0), 1,
424: XYBitmap, 0, (char *)bits, 16, 16, 8, 2);
425: else
426: im->data = (char *)bits;
427: XSetForeground(dpy, gc, fgpix);
428: XSetBackground(dpy, gc, bgpix);
429: XSetFunction(dpy, gc, GXcopy);
430: pm = XCreatePixmap(dpy, display.dr, 16, 16, 1);
431: XPutImage(dpy, pm, gc, im, 0, 0, 0, 0, 16, 16);
432: return pm;
433: }
434:
435: Cursor
436: ToCursor (source, mask, hotx, hoty)
437: short source[], mask[];
438: {
439: Texture sp, mp;
440: Cursor c;
441:
442: sp = ToTexture(source);
443: mp = ToTexture(mask);
444: c = XCreatePixmapCursor(dpy, sp,mp, &fgcolor,&bgcolor, hotx,hoty);
445: XFreePixmap(dpy, sp);
446: XFreePixmap(dpy, mp);
447: return(c);
448: }
449: #endif X11
450:
451: #ifdef SUNTOOLS
452: Cursor
453: ToCursor (source, mask, hotx, hoty)
454: short source[], mask[];
455: {
456: Cursor c;
457:
458: c.bits = source;
459: c.hotx = hotx;
460: c.hoty = hoty;
461: return(c);
462: }
463: #endif SUNTOOLS
464:
465: char *
466: gcalloc (nbytes, where)
467: unsigned long nbytes;
468: char **where;
469: {
470: *where=(char *)alloc(nbytes);
471: return *where;
472: }
473:
474: void
475: gcfree (s)
476: char *s;
477: {
478: free(s);
479: }
480:
481: #ifdef X11
482: #undef button
483: handleinput ()
484: {
485: XEvent ev;
486: KeySym key;
487: unsigned char s[16], *cp;
488: int n;
489: Window rw, cw;
490: int xr, yr, xw, yw;
491: unsigned bstate;
492:
493: for(;;){
494: XNextEvent(dpy, &ev);
495: switch (ev.type) {
496: case ButtonPress:
497: mouse.buttons |= (8 >> ev.xbutton.button);
498: mouse.xy.x = ev.xbutton.x;
499: mouse.xy.y = ev.xbutton.y;
500: mouse.time = ev.xbutton.time;
501: break;
502: case ButtonRelease:
503: mouse.buttons &= ~(8 >> ev.xbutton.button);
504: mouse.xy.x = ev.xbutton.x;
505: mouse.xy.y = ev.xbutton.y;
506: mouse.time = ev.xbutton.time;
507: break;
508: case MotionNotify:
509: XQueryPointer(dpy, display.dr,
510: &rw, &cw, &xr, &yr, &xw, &yw, &bstate);
511: if(button123() && bstate==0)
512: continue;
513: mouse.xy.x = xw;
514: mouse.xy.y = yw;
515: break;
516: case MapNotify:
517: case NoExpose:
518: break;
519: case ConfigureNotify:
520: #ifndef XBUG
521: Joffset.x = ev.xconfigure.x;
522: Joffset.y = ev.xconfigure.y;
523: #endif XBUG
524: if (display.rect.corner.x != ev.xconfigure.width ||
525: display.rect.corner.y != ev.xconfigure.height) {
526: display.rect.corner.x = ev.xconfigure.width;
527: display.rect.corner.y = ev.xconfigure.height;
528: Drect = display.rect;
529: #ifdef XBUG
530: Jfscreen = display;
531: #endif
532: }
533: break;
534: case Expose:
535: if (ev.xexpose.count == 0) {
536: rectf(&display, Drect, F_CLR);
537: P->state |= RESHAPED;
538: }
539: break;
540: case KeyPress:
541: mouse.xy.x = ev.xkey.x;
542: mouse.xy.y = ev.xkey.y;
543: mouse.time = ev.xkey.time;
544: n = XLookupString(&ev, s, sizeof(s), NULL, NULL);
545: if(n > 0){
546: cp = s;
547: P->state |= KBD;
548: do{
549: kbdread(cp);
550: } while (--n);
551: }
552: break;
553: default:
554: break;
555: }
556: return;
557: }
558: }
559: #endif X11
560:
561: #ifdef SUNTOOLS
562: #define BUTTON1 0x4
563: #define BUTTON2 0x2
564: #define BUTTON3 0x1
565: handleinput ()
566: {
567: struct inputevent ie;
568: long readbytes;
569: static grabbed = 0;
570: unsigned char c;
571:
572: for(;;){
573: if(input_readevent(displayfd, &ie) == -1){
574: perror("input_readevent: ");
575: break;
576: }
577: mouse.xy.x = ie.ie_locx;
578: mouse.xy.y = ie.ie_locy;
579: mouse.time = ie.ie_time.tv_sec*1000 + ie.ie_time.tv_usec/1000;
580: if(event_is_ascii(&ie)){
581: c = ie.ie_code;
582: kbdread(&c);
583: P->state |= KBD;
584: }
585: else if(event_is_button(&ie)){
586: switch(ie.ie_code){
587: case MS_LEFT:
588: if(win_inputnegevent(&ie)){
589: mouse.buttons &= ~BUTTON1;
590: }
591: else{
592: mouse.buttons |= BUTTON1;
593: if(!grabbed){
594: win_grabio(displayfd);
595: grabbed = 1;
596: }
597: }
598: break;
599: case MS_MIDDLE:
600: if(win_inputnegevent(&ie)){
601: mouse.buttons &= ~BUTTON2;
602: }
603: else{
604: mouse.buttons |= BUTTON2;
605: if(!grabbed){
606: win_grabio(displayfd);
607: grabbed = 1;
608: }
609: }
610: break;
611: case MS_RIGHT:
612: if(win_inputnegevent(&ie)){
613: mouse.buttons &= ~BUTTON3;
614: }
615: else{
616: mouse.buttons |= BUTTON3;
617: if(!grabbed){
618: win_grabio(displayfd);
619: grabbed = 1;
620: }
621: }
622: break;
623: }
624: if(!button123() && grabbed){
625: win_releaseio(displayfd);
626: grabbed = 0;
627: }
628: }
629: /* break if there is nothing to read */
630: if(ioctl(displayfd, FIONREAD, &readbytes) == -1){
631: perror("handleinput:");
632: break;
633: }
634: if(readbytes == 0)
635: break;
636: }
637: }
638: #endif SUNTOOLS
639:
640: Jscreengrab()
641: {
642: if (!Jlocklevel) {
643: #ifdef X11
644: while (XGrabPointer(dpy, display.dr, False,
645: inputmask, GrabModeAsync, GrabModeAsync,
646: None, *P->cursor, CurrentTime) != GrabSuccess)
647: sleep(6);
648: XSetSubwindowMode(dpy, gc, IncludeInferiors);
649: #endif X11
650: #ifdef SUNTOOLS
651: if (screendepth == 1) {
652: Jfscp = fullscreen_init(displayfd);
653: Jfscreen.dr = (char *)Jfscp->fs_pixwin;
654: Jfscreen.rect.origin.x = Jfscp->fs_screenrect.r_left;
655: Jfscreen.rect.origin.y = Jfscp->fs_screenrect.r_top;
656: Jfscreen.rect.corner.x = Jfscp->fs_screenrect.r_left +
657: Jfscp->fs_screenrect.r_width;
658: Jfscreen.rect.corner.y = Jfscp->fs_screenrect.r_top +
659: Jfscp->fs_screenrect.r_height;
660: } else
661: Jfscreen = display;
662: #endif SUNTOOLS
663: }
664: Jlocklevel++;
665: }
666:
667: Jscreenrelease()
668: {
669: if (--Jlocklevel <= 0) {
670: Jlocklevel = 0;
671: #ifdef X11
672: XUngrabPointer(dpy, CurrentTime);
673: XSetSubwindowMode(dpy, gc, ClipByChildren);
674: #endif X11
675: #ifdef SUNTOOLS
676: if (screendepth == 1)
677: fullscreen_destroy(Jfscp);
678: #endif SUNTOOLS
679: }
680: }
681:
682: /* Compatability functions */
683:
684: ringbell ()
685: {}
686:
687: cursinhibit ()
688: {
689: }
690:
691: cursallow ()
692: {
693: }
694:
695: /* misc functions */
696: border (b,r,i,f)
697: Bitmap *b;
698: Rectangle r;
699: int i;
700: Code f;
701: {
702: rectf(b, Rect(r.origin.x, r.origin.y, r.corner.x, r.origin.y+i), f);
703: rectf(b, Rect(r.origin.x, r.corner.y-i, r.corner.x, r.corner.y), f);
704: rectf(b, Rect(r.origin.x, r.origin.y+i, r.origin.x+i, r.corner.y-i), f);
705: rectf(b, Rect(r.corner.x-i, r.origin.y+i, r.corner.x, r.corner.y-i), f);
706: }
707:
708: setsizehints (width, height, flags)
709: {
710: hintwidth = width;
711: hintheight = height;
712: hintflags = flags;
713: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.