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.

212 lines
4.5KB

  1. // ----------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2010-2012 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 AT1 {
  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. int cbind,
  38. RotaryGeom *rgeom,
  39. int xp,
  40. int yp) :
  41. X_window (parent,
  42. rgeom->_x0 + xp, rgeom->_y0 + yp,
  43. rgeom->_dx, rgeom->_dy,
  44. rgeom->_backg->pixel),
  45. _cbobj (cbobj),
  46. _cbind (cbind),
  47. _rgeom (rgeom),
  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 - _rgeom->_xref, E->y - _rgeom->_yref);
  94. if (d > _rgeom->_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. if (_state != s)
  146. {
  147. _state = s;
  148. render ();
  149. }
  150. }
  151. void RotaryCtl::render (void)
  152. {
  153. XImage *I;
  154. double a, c, r, x, y;
  155. I = _rgeom->_image [_state];
  156. XPutImage (dpy (), win (), dgc (), I,
  157. _rgeom->_x0, _rgeom->_y0, 0, 0, _rgeom->_dx, _rgeom->_dy);
  158. cairo_xlib_surface_set_drawable (_cairosurf, win(),
  159. _rgeom->_dx, _rgeom->_dy);
  160. c = _rgeom->_lncol [_state] ? 1.0 : 0.0;
  161. a = _angle * M_PI / 180;
  162. r = _rgeom->_rad;
  163. x = _rgeom->_xref;
  164. y = _rgeom->_yref;
  165. cairo_new_path (_cairotype);
  166. cairo_move_to (_cairotype, x, y);
  167. x += r * sin (a);
  168. y -= r * cos (a);
  169. cairo_line_to (_cairotype, x, y);
  170. cairo_set_source_rgb (_cairotype, c, c, c);
  171. cairo_set_line_width (_cairotype, 2.2);
  172. cairo_stroke (_cairotype);
  173. }
  174. }