colors.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <event.h>
  5. char *argv0;
  6. static void
  7. _sysfatalimpl(char *fmt, va_list arg)
  8. {
  9. char buf[1024];
  10. vseprint(buf, buf+sizeof(buf), fmt, arg);
  11. if(argv0)
  12. fprint(2, "%s: %s\n", argv0, buf);
  13. else
  14. fprint(2, "%s\n", buf);
  15. exits(buf);
  16. }
  17. void (*_sysfatal)(char *fmt, va_list arg) = _sysfatalimpl;
  18. void
  19. sysfatal(char *fmt, ...)
  20. {
  21. va_list arg;
  22. va_start(arg, fmt);
  23. (*_sysfatal)(fmt, arg);
  24. va_end(arg);
  25. }
  26. int nbit, npix;
  27. Image *pixel;
  28. Rectangle crect[256];
  29. Image *color[256];
  30. void
  31. eresized(int new)
  32. {
  33. int x, y, i, n, nx, ny;
  34. Rectangle r, b;
  35. if(new && getwindow(display, Refnone) < 0){
  36. fprint(2, "colors: can't reattach to window: %r\n");
  37. exits("resized");
  38. }
  39. if(screen->depth > 8){
  40. n = 256;
  41. nx = 16;
  42. }else{
  43. n = 1<<screen->depth;
  44. nx = 1<<(screen->depth/2);
  45. }
  46. ny = n/nx;
  47. draw(screen, screen->r, display->white, nil, ZP);
  48. r = insetrect(screen->r, 5);
  49. r.min.y+=20;
  50. b.max.y=r.min.y;
  51. for(i=n-1, y=0; y!=ny; y++){
  52. b.min.y=b.max.y;
  53. b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/ny;
  54. b.max.x=r.min.x;
  55. for(x=0; x!=nx; x++, --i){
  56. b.min.x=b.max.x;
  57. b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/nx;
  58. crect[i]=insetrect(b, 1);
  59. draw(screen, crect[i], color[i], nil, ZP);
  60. }
  61. }
  62. flushimage(display, 1);
  63. }
  64. char *buttons[] =
  65. {
  66. "exit",
  67. 0
  68. };
  69. ulong
  70. grey(int i)
  71. {
  72. if(i < 0)
  73. return grey(0);
  74. if(i > 255)
  75. return grey(255);
  76. return (i<<16)+(i<<8)+i;
  77. }
  78. Menu menu =
  79. {
  80. buttons
  81. };
  82. int
  83. dither[16] = {
  84. 0, 8, 2, 10,
  85. 12, 4, 14, 6,
  86. 3, 11, 1, 9,
  87. 15, 7, 13, 5
  88. };
  89. void
  90. main(int argc, char *argv[])
  91. {
  92. Point p;
  93. Mouse m;
  94. int i, j, k, l, n, ramp, prev;
  95. char buf[100];
  96. char *fmt;
  97. Image *dark;
  98. ulong rgb;
  99. ramp = 0;
  100. fmt = "index %3d r %3lud g %3lud b %3lud 0x%.8luX ";
  101. /*
  102. ARGBEGIN{
  103. default:
  104. goto Usage;
  105. case 'x':
  106. fmt = "index %2luX r %3luX g %3luX b %3luX 0x%.8luX ";
  107. break;
  108. case 'r':
  109. ramp = 1;
  110. break;
  111. }ARGEND
  112. */
  113. argv0 = argv[0];
  114. if(argc != 1){
  115. Usage:
  116. fprint(2, "Usage: %s [-rx]\n", argv0);
  117. exits("usage");
  118. }
  119. if(initdraw(nil, nil, "colors") < 0)
  120. sysfatal("initdraw failed: %r");
  121. einit(Emouse);
  122. for(i=0; i<256; i++){
  123. if(ramp){
  124. if(screen->chan == CMAP8){
  125. /* dither the fine grey */
  126. j = i-(i%17);
  127. dark = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(j)<<8)+0xFF);
  128. color[i] = allocimage(display, Rect(0,0,4,4), screen->chan, 1, (grey(j+17)<<8)+0xFF);
  129. for(j=0; j<16; j++){
  130. k = j%4;
  131. l = j/4;
  132. if(dither[j] > (i%17))
  133. draw(color[i], Rect(k, l, k+1, l+1), dark, nil, ZP);
  134. }
  135. freeimage(dark);
  136. }else
  137. color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (grey(i)<<8)+0xFF);
  138. }else
  139. color[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, (cmap2rgb(i)<<8)+0xFF);
  140. if(color[i] == nil)
  141. sysfatal("can't allocate image: %r");
  142. }
  143. eresized(0);
  144. prev = -1;
  145. for(;;){
  146. m = emouse();
  147. switch(m.buttons){
  148. case 1:
  149. while(m.buttons){
  150. if(screen->depth > 8)
  151. n = 256;
  152. else
  153. n = 1<<screen->depth;
  154. for(i=0; i!=n; i++)
  155. if(i!=prev && ptinrect(m.xy, crect[i])){
  156. if(ramp)
  157. rgb = grey(i);
  158. else
  159. rgb = cmap2rgb(i);
  160. sprint(buf, fmt,
  161. i,
  162. (rgb>>16)&0xFF,
  163. (rgb>>8)&0xFF,
  164. rgb&0xFF,
  165. (rgb<<8) | 0xFF);
  166. p = addpt(screen->r.min, Pt(2,2));
  167. draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p);
  168. string(screen, p, display->black, ZP, font, buf);
  169. prev=i;
  170. break;
  171. }
  172. m = emouse();
  173. }
  174. break;
  175. case 4:
  176. switch(emenuhit(3, &m, &menu)){
  177. case 0:
  178. exits(0);
  179. }
  180. }
  181. }
  182. }