colors.c 3.5 KB

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