Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
4.4KB

  1. // ----------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
  4. // Modified by falkTX on Jan-Apr 2015 for inclusion in Carla
  5. //
  6. // This program is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 2 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. //
  20. // ----------------------------------------------------------------------
  21. #include <cairo/cairo.h>
  22. #include <cairo/cairo-xlib.h>
  23. #include <math.h>
  24. #include "rotary.h"
  25. namespace BLS1 {
  26. cairo_t *RotaryCtl::_cairotype = 0;
  27. cairo_surface_t *RotaryCtl::_cairosurf = 0;
  28. int RotaryCtl::_wb_up = 4;
  29. int RotaryCtl::_wb_dn = 5;
  30. int RotaryCtl::_keymod = 0;
  31. int RotaryCtl::_button = 0;
  32. int RotaryCtl::_rcount = 0;
  33. int RotaryCtl::_rx = 0;
  34. int RotaryCtl::_ry = 0;
  35. RotaryCtl::RotaryCtl (X_window *parent,
  36. X_callback *cbobj,
  37. RotaryImg *image,
  38. int xp,
  39. int yp,
  40. int cbind) :
  41. X_window (parent,
  42. image->_x0 + xp, image->_y0 + yp,
  43. image->_dx, image->_dy,
  44. image->_backg->pixel),
  45. _cbobj (cbobj),
  46. _cbind (cbind),
  47. _image (image),
  48. _state (0),
  49. _count (0),
  50. _value (0),
  51. _angle (0)
  52. {
  53. x_add_events ( ExposureMask
  54. | Button1MotionMask | ButtonPressMask | ButtonReleaseMask);
  55. }
  56. RotaryCtl::~RotaryCtl (void)
  57. {
  58. }
  59. void RotaryCtl::init (X_display *disp)
  60. {
  61. _cairosurf = cairo_xlib_surface_create (disp->dpy (), 0, disp->dvi (), 50, 50);
  62. _cairotype = cairo_create (_cairosurf);
  63. }
  64. void RotaryCtl::fini (void)
  65. {
  66. cairo_destroy (_cairotype);
  67. cairo_surface_destroy (_cairosurf);
  68. }
  69. void RotaryCtl::handle_event (XEvent *E)
  70. {
  71. switch (E->type)
  72. {
  73. case Expose:
  74. render ();
  75. break;
  76. case ButtonPress:
  77. bpress ((XButtonEvent *) E);
  78. break;
  79. case ButtonRelease:
  80. brelse ((XButtonEvent *) E);
  81. break;
  82. case MotionNotify:
  83. motion ((XMotionEvent *) E);
  84. break;
  85. default:
  86. fprintf (stderr, "RotaryCtl: event %d\n", E->type );
  87. }
  88. }
  89. void RotaryCtl::bpress (XButtonEvent *E)
  90. {
  91. int r = 0;
  92. double d;
  93. d = hypot (E->x - _image->_xref, E->y - _image->_yref);
  94. if (d > _image->_rad + 3) return;
  95. _keymod = E->state;
  96. if (E->button < 4)
  97. {
  98. _rx = E->x;
  99. _ry = E->y;
  100. _button = E->button;
  101. r = handle_button ();
  102. _rcount = _count;
  103. }
  104. else if (_button) return;
  105. else if ((int)E->button == _wb_up)
  106. {
  107. r = handle_mwheel (1);
  108. }
  109. else if ((int)E->button == _wb_dn)
  110. {
  111. r = handle_mwheel (-1);
  112. }
  113. if (r)
  114. {
  115. callback (r);
  116. render ();
  117. }
  118. }
  119. void RotaryCtl::brelse (XButtonEvent *E)
  120. {
  121. if (_button == (int)E->button)
  122. {
  123. _button = 0;
  124. callback (RELSE);
  125. }
  126. }
  127. void RotaryCtl::motion (XMotionEvent *E)
  128. {
  129. int dx, dy, r;
  130. if (_button)
  131. {
  132. _keymod = E->state;
  133. dx = E->x - _rx;
  134. dy = E->y - _ry;
  135. r = handle_motion (dx, dy);
  136. if (r)
  137. {
  138. callback (r);
  139. render ();
  140. }
  141. }
  142. }
  143. void RotaryCtl::set_state (int s)
  144. {
  145. _state = s;
  146. render ();
  147. }
  148. void RotaryCtl::render (void)
  149. {
  150. XImage *I;
  151. double a, c, r, x, y;
  152. I = _image->_image [_state];
  153. XPutImage (dpy (), win (), dgc (), I,
  154. _image->_x0, _image->_y0, 0, 0, _image->_dx, _image->_dy);
  155. cairo_xlib_surface_set_drawable (_cairosurf, win(),
  156. _image->_dx, _image->_dy);
  157. c = _image->_lncol [_state] ? 1.0 : 0.0;
  158. a = _angle * M_PI / 180;
  159. r = _image->_rad;
  160. x = _image->_xref;
  161. y = _image->_yref;
  162. cairo_new_path (_cairotype);
  163. cairo_move_to (_cairotype, x, y);
  164. x += r * sin (a);
  165. y -= r * cos (a);
  166. cairo_line_to (_cairotype, x, y);
  167. cairo_set_source_rgb (_cairotype, c, c, c);
  168. cairo_set_line_width (_cairotype, 1.8);
  169. cairo_stroke (_cairotype);
  170. }
  171. }