egetrect.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <cursor.h>
  5. #include <event.h>
  6. #define W Borderwidth
  7. static Image *tmp[4];
  8. static Image *red;
  9. static Cursor sweep={
  10. {-7, -7},
  11. {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
  12. 0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
  13. 0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
  14. 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
  15. {0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
  16. 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
  17. 0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
  18. 0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
  19. };
  20. static
  21. void
  22. brects(Rectangle r, Rectangle rp[4])
  23. {
  24. if(Dx(r) < 2*W)
  25. r.max.x = r.min.x+2*W;
  26. if(Dy(r) < 2*W)
  27. r.max.y = r.min.y+2*W;
  28. rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
  29. rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
  30. rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
  31. rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
  32. }
  33. Rectangle
  34. egetrect(int but, Mouse *m)
  35. {
  36. Rectangle r, rc;
  37. but = 1<<(but-1);
  38. esetcursor(&sweep);
  39. while(m->buttons)
  40. *m = emouse();
  41. while(!(m->buttons & but)){
  42. *m = emouse();
  43. if(m->buttons & (7^but))
  44. goto Return;
  45. }
  46. r.min = m->xy;
  47. r.max = m->xy;
  48. do{
  49. rc = canonrect(r);
  50. edrawgetrect(rc, 1);
  51. *m = emouse();
  52. edrawgetrect(rc, 0);
  53. r.max = m->xy;
  54. }while(m->buttons == but);
  55. Return:
  56. esetcursor(0);
  57. if(m->buttons & (7^but)){
  58. rc.min.x = rc.max.x = 0;
  59. rc.min.y = rc.max.y = 0;
  60. while(m->buttons)
  61. *m = emouse();
  62. }
  63. return rc;
  64. }
  65. static
  66. void
  67. freetmp(void)
  68. {
  69. freeimage(tmp[0]);
  70. freeimage(tmp[1]);
  71. freeimage(tmp[2]);
  72. freeimage(tmp[3]);
  73. freeimage(red);
  74. tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
  75. }
  76. void
  77. edrawgetrect(Rectangle rc, int up)
  78. {
  79. int i;
  80. Rectangle r, rects[4];
  81. if(up && tmp[0]!=nil)
  82. if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
  83. freetmp();
  84. if(tmp[0] == 0){
  85. r = Rect(0, 0, Dx(screen->r), W);
  86. tmp[0] = allocimage(display, r, screen->chan, 0, -1);
  87. tmp[1] = allocimage(display, r, screen->chan, 0, -1);
  88. r = Rect(0, 0, W, Dy(screen->r));
  89. tmp[2] = allocimage(display, r, screen->chan, 0, -1);
  90. tmp[3] = allocimage(display, r, screen->chan, 0, -1);
  91. red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
  92. if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0)
  93. drawerror(display, "getrect: allocimage failed");
  94. }
  95. brects(rc, rects);
  96. if(!up){
  97. for(i=0; i<4; i++)
  98. draw(screen, rects[i], tmp[i], nil, ZP);
  99. return;
  100. }
  101. for(i=0; i<4; i++){
  102. draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
  103. draw(screen, rects[i], red, nil, ZP);
  104. }
  105. }