rotor.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: rotor.c /main/3 1995/11/02 16:08:34 rswiston $ */
  24. /*
  25. */
  26. /* *
  27. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  28. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  29. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  30. * (c) Copyright 1993, 1994 Novell, Inc. *
  31. */
  32. /*-
  33. * rotor.c - A swirly rotor for dtscreen, the X Window System lockscreen.
  34. *
  35. * Copyright (c) 1991 by Patrick J. Naughton.
  36. *
  37. * See dtscreen.c for copying information.
  38. *
  39. * Revision History:
  40. * 11-Nov-90: put into dtscreen (by Steve Zellers, zellers@sun.com)
  41. * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator)
  42. */
  43. /*
  44. * A 'batchcount' of 3 or 4 works best!
  45. */
  46. #include <stdio.h>
  47. #include <math.h>
  48. #include <stdlib.h>
  49. #include "dtscreen.h"
  50. #define SAVE 100 /* this is a good constant to tweak */
  51. #define REPS 50
  52. #define MAXANGLE 10000.0 /* irrectangular */
  53. #define DEFAULTCOUNT 3
  54. /*typedef unsigned char Boolean; */
  55. #define IDENT(X) X
  56. #if defined (__STDC__) || defined (AIXV3)
  57. #define CAT(X,Y) X##Y
  58. #else
  59. #define CAT(X,Y) IDENT(X)Y
  60. #endif
  61. struct elem {
  62. float angle;
  63. float radius;
  64. float start_radius;
  65. float end_radius;
  66. float radius_drift_max;
  67. float radius_drift_now;
  68. float ratio;
  69. float start_ratio;
  70. float end_ratio;
  71. float ratio_drift_max;
  72. float ratio_drift_now;
  73. };
  74. typedef struct flightstruct {
  75. struct elem *elements;
  76. int pix;
  77. int lastx,
  78. lasty;
  79. int num,
  80. rotor,
  81. prev;
  82. int savex[SAVE],
  83. savey[SAVE];
  84. float angle;
  85. int centerx,
  86. centery;
  87. Boolean firsttime;
  88. Boolean smallscreen; /* for iconified view */
  89. Boolean forward;
  90. Boolean unused;
  91. } flightstruct;
  92. void
  93. initrotor(perwindow *pwin)
  94. {
  95. flightstruct *fs;
  96. XWindowAttributes xgwa;
  97. int x;
  98. struct elem *pelem;
  99. Boolean wassmall;
  100. if (pwin->data) free(pwin->data);
  101. pwin->data = (void *)malloc(sizeof(flightstruct));
  102. memset(pwin->data, 0, sizeof(flightstruct));
  103. fs = (flightstruct *)pwin->data;
  104. XGetWindowAttributes(dsp, pwin->w, &xgwa);
  105. fs->centerx = xgwa.width / 2;
  106. fs->centery = xgwa.height / 2;
  107. /*
  108. * sometimes, you go into small view, only to see a really whizzy pattern
  109. * that you would like to look more closely at. Normally, clicking in the
  110. * icon reinitializes everything - but I don't, cuz I'm that kind of guy.
  111. * HENCE, the wassmall stuff you see here.
  112. */
  113. wassmall = fs->smallscreen;
  114. fs->smallscreen = (xgwa.width < 100);
  115. if (wassmall && !fs->smallscreen)
  116. fs->firsttime = True;
  117. else {
  118. if (batchcount > 12)
  119. batchcount = DEFAULTCOUNT;
  120. fs->num = batchcount;
  121. if ((fs->elements = (struct elem *)
  122. malloc(sizeof(struct elem) * fs->num)) == 0) {
  123. perror("malloc");
  124. exit(1);
  125. }
  126. memset(fs->savex, 0, sizeof(fs->savex));
  127. pelem = fs->elements;
  128. for (x = fs->num; --x >= 0; pelem++) {
  129. pelem->radius_drift_max = 1.0;
  130. pelem->radius_drift_now = 1.0;
  131. pelem->end_radius = 100.0;
  132. pelem->ratio_drift_max = 1.0;
  133. pelem->ratio_drift_now = 1.0;
  134. pelem->end_ratio = 10.0;
  135. }
  136. fs->rotor = 0;
  137. fs->prev = 1;
  138. fs->lastx = fs->centerx;
  139. fs->lasty = fs->centery;
  140. fs->angle = (random() % (long) MAXANGLE) / 3;
  141. fs->forward = fs->firsttime = True;
  142. }
  143. XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
  144. XFillRectangle(dsp, pwin->w, pwin->gc, 0, 0, xgwa.width, xgwa.height);
  145. }
  146. void
  147. drawrotor(perwindow *pwin)
  148. {
  149. flightstruct *fs;
  150. struct elem *pelem;
  151. int thisx,
  152. thisy;
  153. int i,
  154. rp;
  155. int x1,
  156. y1,
  157. x2,
  158. y2;
  159. #define SCALE(W,N) CAT(W,N)/=12; CAT(W,N)+=(CAT(fs->center,W)-2)
  160. #define SCALEIFSMALL() if (fs->smallscreen) { \
  161. SCALE(x,1); SCALE(x,2); \
  162. SCALE(y,1); SCALE(y,2); \
  163. }
  164. fs = (flightstruct *)pwin->data;
  165. for (rp = 0; rp < REPS; rp++) {
  166. thisx = fs->centerx;
  167. thisy = fs->centery;
  168. for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) {
  169. if (pelem->radius_drift_max <= pelem->radius_drift_now) {
  170. pelem->start_radius = pelem->end_radius;
  171. pelem->end_radius =
  172. (float) (random() % 40000) / 100.0 - 200.0;
  173. pelem->radius_drift_max =
  174. (float) (random() % 100000) + 10000.0;
  175. pelem->radius_drift_now = 0.0;
  176. }
  177. if (pelem->ratio_drift_max <= pelem->ratio_drift_now) {
  178. pelem->start_ratio = pelem->end_ratio;
  179. pelem->end_ratio =
  180. (float) (random() % 2000) / 100.0 - 10.0;
  181. pelem->ratio_drift_max =
  182. (float) (random() % 100000) + 10000.0;
  183. pelem->ratio_drift_now = 0.0;
  184. }
  185. pelem->ratio = pelem->start_ratio +
  186. (pelem->end_ratio - pelem->start_ratio) /
  187. pelem->ratio_drift_max * pelem->ratio_drift_now;
  188. pelem->angle = fs->angle * pelem->ratio;
  189. pelem->radius = pelem->start_radius +
  190. (pelem->end_radius - pelem->start_radius) /
  191. pelem->radius_drift_max * pelem->radius_drift_now;
  192. thisx += (int) (cos(pelem->angle) * pelem->radius);
  193. thisy += (int) (sin(pelem->angle) * pelem->radius);
  194. pelem->ratio_drift_now += 1.0;
  195. pelem->radius_drift_now += 1.0;
  196. }
  197. if (fs->firsttime)
  198. fs->firsttime = False;
  199. else {
  200. XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
  201. x1 = (int) fs->savex[fs->rotor];
  202. y1 = (int) fs->savey[fs->rotor];
  203. x2 = (int) fs->savex[fs->prev];
  204. y2 = (int) fs->savey[fs->prev];
  205. SCALEIFSMALL()
  206. XDrawLine(dsp, pwin->w, pwin->gc, x1, y1, x2, y2);
  207. if (!mono && pwin->perscreen->npixels > 2) {
  208. XSetForeground(dsp, pwin->gc,
  209. pwin->perscreen->pixels[fs->pix]);
  210. if (++fs->pix >= pwin->perscreen->npixels)
  211. fs->pix = 0;
  212. } else
  213. XSetForeground(dsp, pwin->gc,
  214. WhitePixelOfScreen(pwin->perscreen->screen));
  215. x1 = fs->lastx;
  216. y1 = fs->lasty;
  217. x2 = thisx;
  218. y2 = thisy;
  219. SCALEIFSMALL()
  220. XDrawLine(dsp, pwin->w, pwin->gc, x1, y1, x2, y2);
  221. }
  222. fs->savex[fs->rotor] = fs->lastx = thisx;
  223. fs->savey[fs->rotor] = fs->lasty = thisy;
  224. ++fs->rotor;
  225. fs->rotor %= SAVE;
  226. ++fs->prev;
  227. fs->prev %= SAVE;
  228. if (fs->forward) {
  229. fs->angle += 0.01;
  230. if (fs->angle >= MAXANGLE) {
  231. fs->angle = MAXANGLE;
  232. fs->forward = False;
  233. }
  234. } else {
  235. fs->angle -= 0.1;
  236. if (fs->angle <= 0) {
  237. fs->angle = 0.0;
  238. fs->forward = True;
  239. }
  240. }
  241. }
  242. }