egetrect.c 3.0 KB

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