|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1985 */
4:
5: #ifndef lint
6: static char *rcsid_pikapix_c = "$Header: pikapix.c,v 10.5 86/02/01 16:11:15 tony Rel $";
7: #endif lint
8:
9: #include <X/Xlib.h>
10: #include <stdio.h>
11: #include <strings.h>
12: #include "../cursors/target.cursor"
13: #include "../cursors/target_mask.cursor"
14: #include <sys/types.h>
15:
16: #define pik_width 15
17: #define pik_height 15
18: static short pik_bits[] = {
19: 0x8080, 0x8080, 0x81c0, 0x83e0,
20: 0x87f0, 0x8ff8, 0x9ffc, 0xbffe,
21: 0xbffe, 0xbffe, 0xbffe, 0xbffe,
22: 0xbffe, 0xbffe, 0x8000};
23: static short pik_mask_bits[] = {
24: 0x8080, 0x81c0, 0x83e0, 0x87f0,
25: 0x8ff8, 0x9ffc, 0xbffe, 0xffff,
26: 0xffff, 0xffff, 0xffff, 0xffff,
27: 0xffff, 0xffff, 0xffff};
28:
29: #define MIN(a,b) (((a) < (b)) ? (a) : (b))
30:
31: #define MAXIDX 200
32: #define PROMPT "#ffffff -> "
33: #define ASKSIZE (sizeof(PROMPT) + 25)
34:
35: #define RGBSIDE 50
36: #define RGBWIDTH (RGBSIDE * 3)
37: #define RGBHEIGHT (RGBSIDE * 2)
38:
39: #define BASEDELTA (1<<8)
40:
41: char *malloc();
42:
43: Window win;
44: u_char *buf;
45: u_char transbuf[256];
46: int width, height;
47: int pixels[5];
48: Color cdefs[2];
49: Color origdefs[256];
50: WindowInfo rinfo;
51: Font font;
52: Color rgbdefs[3];
53: Window rgb, redw, greenw, bluew;
54: int rgbx, rgby;
55: int shared = 0;
56:
57: main(argc, argv)
58: int argc;
59: char **argv;
60: {
61: Cursor cursor;
62: XEvent ev;
63: XExposeEvent *exp = (XExposeEvent *) &ev;
64: XMouseMovedEvent *mot = (XMouseMovedEvent *) &ev;
65: register XButtonPressedEvent *but = (XButtonPressedEvent *) &ev;
66: WindowInfo winfo;
67: Window ask;
68: int asking = 0;
69: int askwidth;
70: int askheight;
71: char colorbuf[MAXIDX + sizeof(PROMPT) + 1];
72: register char *colorname = &colorbuf[sizeof(PROMPT)];
73: int coloridx = 0;
74: int mixing = 0;
75: int mixtrack = 0;
76: char *string;
77: int nbytes;
78: int tpix, cnt;
79: unsigned char pixel;
80: Color cdef;
81: FontInfo finfo;
82: int xoff, yoff;
83: char *display = NULL;
84:
85: for (cnt = 1; cnt < argc; cnt++) {
86: if (!*argv[cnt]) continue;
87: if (strcmp(argv[cnt], "-s") == 0)
88: shared = 1;
89: else if (index(argv[cnt], ':'))
90: display = argv[cnt];
91: else {
92: fprintf(stderr, "usage: pikapix [-s] [host:display]\n");
93: (void) fflush(stderr);
94: exit(1);
95: }
96: }
97: if (!XOpenDisplay(display)) {
98: perror("pikapix");
99: exit(1);
100: }
101: if (DisplayPlanes() < 2 || DisplayPlanes() > 8)
102: Error("only works on displays with 2 to 8 planes");
103: cursor = XCreateCursor(target_width, target_height,
104: target_bits, target_mask_bits,
105: 8, 8, BlackPixel, WhitePixel, GXcopy);
106: while (!XGrabMouse(RootWindow, cursor, ButtonPressed))
107: sleep(1);
108: XNextEvent(&ev);
109: XUngrabMouse();
110: win = but->subwindow;
111: if (!win)
112: Error("no window selected");
113: xoff = 0;
114: yoff = 0;
115: switch (but->detail & ValueMask) {
116: case LeftButton:
117: case MiddleButton:
118: do {
119: XInterpretLocator(win, &but->x, &but->y, &but->subwindow,
120: but->location);
121: if (!but->subwindow)
122: break;
123: if (!XQueryWindow(win, &winfo))
124: Error("window disappeared");
125: xoff += winfo.x + winfo.bdrwidth;
126: yoff += winfo.y + winfo.bdrwidth;
127: but->window = win;
128: win = but->subwindow;
129: } while ((but->detail & ValueMask) == LeftButton);
130: }
131: XFreeCursor(cursor);
132: if (!XGetColorCells(0, 5, 0, &cnt, pixels))
133: Error("not enough color map entries");
134: cdefs[0].pixel = pixels[0];
135: cdefs[0].red = cdefs[0].green = cdefs[0].blue = ~0;
136: cdefs[1].pixel = pixels[1];
137: cdefs[1].red = cdefs[1].green = cdefs[1].blue = 0;
138: XStoreColors(2, cdefs);
139: cursor = XCreateCursor(pik_width, pik_height,
140: pik_bits, pik_mask_bits,
141: 7, 0, pixels[0], pixels[1], GXcopy);
142: if (!XQueryWindow(win, &winfo))
143: Error("window disappeared");
144: width = winfo.width + (winfo.bdrwidth << 1);
145: height = winfo.height + (winfo.bdrwidth << 1);
146: nbytes = BZPixmapSize(width, height);
147: buf = (u_char *) malloc(nbytes);
148: if (buf == NULL)
149: Error("window too large");
150: XPixmapGetZ(but->window, winfo.x, winfo.y, width, height, buf);
151: if (!shared) {
152: for (cnt = 256; --cnt >= 0; )
153: transbuf[cnt] = cnt;
154: while (--nbytes >= 0) {
155: pixel = buf[nbytes];
156: if (transbuf[pixel] != pixel)
157: continue;
158: cdef.pixel = pixel;
159: XQueryColor(&cdef);
160: if (!XGetColorCells(0, 1, 0, &cnt, &cdef.pixel))
161: Error("not enough color map entries, try -s option");
162: transbuf[pixel] = cdef.pixel;
163: origdefs[cdef.pixel] = cdef;
164: origdefs[pixel] = cdef;
165: origdefs[pixel].pixel = pixel;
166: XStoreColors(1, &cdef);
167: }
168: } else {
169: transbuf[0] = 1;
170: while (--nbytes >= 0) {
171: pixel = buf[nbytes];
172: if (transbuf[pixel] == pixel)
173: continue;
174: cdef.pixel = pixel;
175: XQueryColor(&cdef);
176: transbuf[pixel] = pixel;
177: origdefs[pixel] = cdef;
178: }
179: }
180: win = XCreateWindow(RootWindow, xoff + winfo.x, yoff + winfo.y,
181: width, height, 0, (Pixmap) 0, (Pixmap) 0);
182: XStoreName(win, "pikapix");
183: XDefineCursor(win, cursor);
184: XSelectInput(win, KeyPressed|ButtonPressed|ExposeRegion|MouseMoved);
185: XMapWindow(win);
186: font = XGetFont("6x10");
187: if (!font) Error("couldn't open font");
188: XQueryFont(font, &finfo);
189: askwidth = finfo.width * ASKSIZE + 2;
190: askheight = finfo.height + 2;
191: ask = XCreateWindow(RootWindow, 0, 0, askwidth, askheight,
192: 2, BlackPixmap, WhitePixmap);
193: askwidth += 4;
194: askheight += 4;
195: XSelectInput(ask, KeyPressed|ExposeWindow|ButtonPressed);
196: XDefineCursor(ask, cursor);
197: rgb = XCreateWindow(RootWindow, 0, 0, RGBWIDTH, RGBHEIGHT,
198: 2, XMakeTile(pixels[1]), XMakeTile(pixels[0]));
199: redw = XCreateWindow(rgb, 0, 0, RGBSIDE, RGBSIDE,
200: 0, (Pixmap) 0, XMakeTile(pixels[2]));
201: rgbdefs[0].pixel = pixels[2];
202: greenw = XCreateWindow(rgb, RGBSIDE, 0, RGBSIDE, RGBSIDE,
203: 0, (Pixmap) 0, XMakeTile(pixels[3]));
204: rgbdefs[1].pixel = pixels[3];
205: bluew = XCreateWindow(rgb, RGBSIDE * 2, 0, RGBSIDE, RGBSIDE,
206: 0, (Pixmap) 0, XMakeTile(pixels[4]));
207: rgbdefs[2].pixel = pixels[4];
208: rgbx = (RGBWIDTH - (finfo.width * 6)) >> 1;
209: rgby = RGBSIDE + ((RGBSIDE - finfo.height) >> 1);
210: XMapSubwindows(rgb);
211: XSelectInput(rgb, ButtonPressed|ExposeWindow);
212: XSelectInput(redw, ButtonPressed|ButtonReleased|MiddleDownMotion);
213: XSelectInput(greenw, ButtonPressed|ButtonReleased|MiddleDownMotion);
214: XSelectInput(bluew, ButtonPressed|ButtonReleased|MiddleDownMotion);
215: XDefineCursor(rgb, cursor);
216: XQueryWindow(RootWindow, &rinfo);
217: RedoCursor(1);
218: while (1) {
219: XNextEvent(&ev);
220: switch ((int)ev.type) {
221: case MouseMoved:
222: if (asking || (mixing && !mixtrack))
223: break;
224: if (mixtrack) {
225: XUpdateMouse(mot->window, &xoff, &yoff, &mot->subwindow);
226: CalcRGB(mot->window, pixel, yoff);
227: } else
228: RedoCursor(0);
229: break;
230: case KeyPressed:
231: string = XLookupMapping (&ev, &nbytes);
232: if (nbytes == 1 && (*string == '\003' || *string == '\004')) {
233: if (asking) {
234: coloridx = 0;
235: asking = 0;
236: XUnmapWindow(ask);
237: RedoCursor(0);
238: } else if (mixing) {
239: mixing = 0;
240: XUnmapWindow(rgb);
241: RedoCursor(1);
242: } else
243: exit(0);
244: } else if (asking && ev.window == ask) {
245: while (--nbytes >= 0)
246: colorname[coloridx++] = *string++;
247: if (colorname[coloridx - 1] == '\r') {
248: coloridx--;
249: asking = 0;
250: } else if (colorname[coloridx - 1] == '\177') {
251: if (--coloridx) {
252: --coloridx;
253: XClear(ask);
254: }
255: } else if (colorname[coloridx - 1] == '\025') {
256: if (--coloridx)
257: XClear(ask);
258: coloridx = 0;
259: }
260: XText(ask, 1, 1, colorbuf, sizeof (PROMPT) + coloridx, font,
261: BlackPixel, WhitePixel);
262: if (!asking) {
263: XUnmapWindow(ask);
264: if (coloridx) {
265: colorname[coloridx] = '\0';
266: if (XParseColor(colorname, &cdef)) {
267: if (!shared) {
268: cdef.pixel = transbuf[pixel];
269: XStoreColors(1, &cdef);
270: origdefs[cdef.pixel] = cdef;
271: RedoCursor(1);
272: } else if (XGetHardwareColor(&cdef)) {
273: if (transbuf[pixel] != pixel) {
274: tpix = transbuf[pixel];
275: XFreeColors(&tpix, 1, 0);
276: }
277: transbuf[pixel] = cdef.pixel;
278: origdefs[cdef.pixel] = cdef;
279: RedoCursor(1);
280: BitsPut(0, 0, width, height);
281: } else XFeep(0);
282: } else
283: XFeep(0);
284: coloridx = 0;
285: }
286: }
287: }
288: break;
289: case ButtonPressed:
290: if (asking) {
291: coloridx = 0;
292: asking = 0;
293: XUnmapWindow(ask);
294: RedoCursor(1);
295: break;
296: }
297: if (mixing && but->window == rgb) {
298: switch (but->detail & ValueMask) {
299: case LeftButton:
300: case MiddleButton:
301: if ((but->detail & ValueMask) == LeftButton)
302: cdefs[0] = origdefs[pixel];
303: else
304: cdefs[0] = cdef;
305: if (!shared) {
306: cdefs[0].pixel = transbuf[pixel];
307: origdefs[cdefs[0].pixel] = cdefs[0];
308: XStoreColors(1, &cdefs[0]);
309: }
310: cdefs[0].pixel = pixels[0];
311: rgbdefs[0].red = cdefs[0].red;
312: rgbdefs[1].green = cdefs[0].green;
313: rgbdefs[2].blue = cdefs[0].blue;
314: XStoreColors(3, rgbdefs);
315: ResetCursor();
316: PrintRGB();
317: break;
318: case RightButton:
319: XUnmapWindow(rgb);
320: if (cdef.red != cdefs[0].red ||
321: cdef.green != cdefs[0].green ||
322: cdef.blue != cdefs[0].blue) {
323: cdef = cdefs[0];
324: if (!shared) {
325: cdef.pixel = transbuf[pixel];
326: origdefs[cdef.pixel] = cdef;
327: XStoreColors(1, &cdef);
328: } else if (XGetHardwareColor(&cdef)) {
329: if (transbuf[pixel] != pixel) {
330: tpix = transbuf[pixel];
331: XFreeColors(&tpix, 1, 0);
332: }
333: transbuf[pixel] = cdef.pixel;
334: origdefs[cdef.pixel] = cdef;
335: RedoCursor(1);
336: BitsPut(0, 0, width, height);
337: } else
338: XFeep(0);
339: }
340: RedoCursor(1);
341: mixing = 0;
342: mixtrack = 0;
343: break;
344: }
345: break;
346: }
347: if (mixing && but->window == win)
348: break;
349: if (mixing) {
350: switch (but->detail & ValueMask) {
351: case MiddleButton:
352: mixtrack = 1;
353: CalcRGB(but->window, pixel, but->y);
354: break;
355: case LeftButton:
356: UpdateRGB(but->window, pixel, -BASEDELTA);
357: break;
358: case RightButton:
359: UpdateRGB(but->window, pixel, BASEDELTA);
360: break;
361: }
362: break;
363: }
364: pixel = buf[BZPixmapSize(width, but->y) + BZPixmapSize(but->x, 1)];
365: switch (but->detail & ValueMask) {
366: case LeftButton:
367: if (!shared) {
368: cdef = origdefs[pixel];
369: cdef.pixel = transbuf[pixel];
370: origdefs[cdef.pixel] = cdef;
371: XStoreColors(1, &cdef);
372: RedoCursor(1);
373: } else if (transbuf[pixel] != pixel) {
374: tpix = transbuf[pixel];
375: XFreeColors(&tpix, 1, 0);
376: transbuf[pixel] = pixel;
377: RedoCursor(1);
378: BitsPut(0, 0, width, height);
379: }
380: break;
381: case MiddleButton:
382: PopWindow(ask, but, askwidth, askheight);
383: (void)sprintf(colorbuf, "#%02x%02x%02x -> ", cdefs[0].red >> 8,
384: cdefs[0].green >> 8, cdefs[0].blue >> 8);
385: asking = 1;
386: break;
387: case RightButton:
388: mixing = 1;
389: cdef.red = rgbdefs[0].red = cdefs[0].red;
390: cdef.green = rgbdefs[1].green = cdefs[0].green;
391: cdef.blue = rgbdefs[2].blue = cdefs[0].blue;
392: XStoreColors(3, rgbdefs);
393: PopWindow(rgb, but, RGBWIDTH+4, RGBHEIGHT+4);
394: break;
395: }
396: break;
397: case ButtonReleased:
398: if (mixtrack && ((but->detail & ValueMask) == MiddleButton)) {
399: CalcRGB(but->window, pixel, but->y);
400: mixtrack = 0;
401: }
402: break;
403: case ExposeWindow:
404: case ExposeRegion:
405: if (exp->window == ask) {
406: XText(ask, 1, 1, colorbuf, sizeof (PROMPT) + coloridx, font,
407: BlackPixel, WhitePixel);
408: } else if (exp->window == rgb) {
409: if (exp->subwindow == NULL ) PrintRGB();
410: } else {
411: exp->width = MIN(exp->x + exp->width, width) - exp->x;
412: exp->height = MIN(exp->y + exp->height, height) - exp->y;
413: if (exp->width > 0 && exp->height > 0)
414: BitsPut(exp->x, exp->y, exp->width, exp->height);
415: }
416: break;
417: }
418: }
419: }
420:
421: PopWindow (pop, but, w, h)
422: Window pop;
423: XButtonPressedEvent *but;
424: int w, h;
425: {
426: int x, y;
427:
428: x = ((but->location >> 16) & 0xffff) - (w >> 1);
429: if (x < 0)
430: x = 0;
431: else if (x + w > rinfo.width)
432: x = rinfo.width - w;
433: y = (but->location & 0xffff) - (h >> 1) - 3;
434: if (y < 0)
435: y = 0;
436: else if (y + h > rinfo.height)
437: y = rinfo.height - h;
438: XMoveWindow(pop, x, y);
439: XMapWindow(pop);
440: }
441:
442: RedoCursor (force)
443: int force;
444: {
445: int x, y;
446: Window sub;
447: unsigned char pixel;
448: static unsigned short curspix = ~0;
449:
450: XUpdateMouse(win, &x, &y, &sub);
451: if (x < 0 || x >= width || y < 0 || y >= height)
452: return;
453: pixel = transbuf[buf[BZPixmapSize(width, y) + BZPixmapSize(x, 1)]];
454: if (!force && (pixel == curspix))
455: return;
456: curspix = pixel;
457: cdefs[0] = origdefs[pixel];
458: cdefs[0].pixel = pixels[0];
459: ResetCursor();
460: }
461:
462: ResetCursor()
463: {
464: if (cdefs[0].red <= 0x8000 &&
465: cdefs[0].green <= 0x8000 &&
466: cdefs[0].blue <= 0x8000)
467: cdefs[1].red = cdefs[1].green = cdefs[1].blue = ~0;
468: else
469: cdefs[1].red = cdefs[1].green = cdefs[1].blue = 0;
470: XStoreColors(2, cdefs);
471: }
472:
473: UpdateRGB (ew, pixel, value)
474: Window ew;
475: unsigned pixel;
476: int value;
477: {
478: Color cdef;
479:
480: if (ew == redw) {
481: value += rgbdefs[0].red;
482: if (value < 0)
483: value = 0;
484: else if (value > 0xffff)
485: value = 0xffff;
486: rgbdefs[0].red = value;
487: XStoreColors(1, &rgbdefs[0]);
488: } else if (ew == greenw) {
489: value += rgbdefs[1].green;
490: if (value < 0)
491: value = 0;
492: else if (value > 0xffff)
493: value = 0xffff;
494: rgbdefs[1].green = value;
495: XStoreColors(1, &rgbdefs[1]);
496: } else if (ew == bluew) {
497: value += rgbdefs[2].blue;
498: if (value < 0)
499: value = 0;
500: else if (value > 0xffff)
501: value = 0xffff;
502: rgbdefs[2].blue = value;
503: XStoreColors(1, &rgbdefs[2]);
504: } else
505: return;
506: cdefs[0].red = rgbdefs[0].red;
507: cdefs[0].green = rgbdefs[1].green;
508: cdefs[0].blue = rgbdefs[2].blue;
509: ResetCursor();
510: if (!shared) {
511: cdef = cdefs[0];
512: cdef.pixel = transbuf[pixel];
513: origdefs[cdef.pixel] = cdef;
514: XStoreColors(1, &cdef);
515: }
516: PrintRGB();
517: }
518:
519: CalcRGB (ew, pixel, value)
520: Window ew;
521: unsigned pixel;
522: int value;
523: {
524: Color cdef;
525:
526: if (value < 0)
527: value = 0;
528: else if (value >= RGBSIDE)
529: value = (RGBSIDE - 1);
530: value = (0xffff * value) / (RGBSIDE - 1);
531: if (ew == redw) {
532: rgbdefs[0].red = value;
533: XStoreColors(1, &rgbdefs[0]);
534: } else if (ew == greenw) {
535: rgbdefs[1].green = value;
536: XStoreColors(1, &rgbdefs[1]);
537: } else if (ew == bluew) {
538: rgbdefs[2].blue = value;
539: XStoreColors(1, &rgbdefs[2]);
540: } else
541: return;
542: cdefs[0].red = rgbdefs[0].red;
543: cdefs[0].green = rgbdefs[1].green;
544: cdefs[0].blue = rgbdefs[2].blue;
545: ResetCursor();
546: if (!shared) {
547: cdef = cdefs[0];
548: cdef.pixel = transbuf[pixel];
549: origdefs[cdef.pixel] = cdef;
550: XStoreColors(1, &cdef);
551: }
552: PrintRGB();
553: }
554:
555: PrintRGB ()
556: {
557: char rgbbuf[7];
558:
559: (void) sprintf(rgbbuf, "%02x%02x%02x", cdefs[0].red >> 8,
560: cdefs[0].green >> 8, cdefs[0].blue >> 8);
561: XText(rgb, rgbx, rgby, rgbbuf, 6, font, BlackPixel, WhitePixel);
562: }
563:
564: #define CHUNKSIZE 2048
565: u_char outbuf[CHUNKSIZE];
566:
567: BitsPut (x, y, w, h)
568: int x, y, w, h;
569: {
570: register u_char *data, *ptr, *trans;
571: register int i, j;
572: int per, delta, linesize;
573:
574: trans = transbuf;
575: linesize = BZPixmapSize(width, 1);
576: data = &buf[y * linesize + BZPixmapSize(x, 1)];
577:
578: per = BZPixmapSize(w, 1);
579: delta = CHUNKSIZE / per;
580: linesize -= per;
581:
582: while (h) {
583: if (h < delta)
584: delta = h;
585: for (ptr = outbuf, i = delta; --i >= 0; data += linesize) {
586: for (j = per; --j >= 0; )
587: *ptr++ = trans[*data++];
588: }
589: XPixmapBitsPutZ(win, x, y, w, delta, outbuf,
590: NULL, GXcopy, AllPlanes);
591: y += delta;
592: h -= delta;
593: }
594: }
595:
596: Error (why)
597: char *why;
598: {
599: fprintf(stderr, "pikapix: %s\n", why);
600: (void) fflush(stderr);
601: exit(1);
602: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.