1 /* xscreensaver, Copyright (c) 1997, 1998, 2003 by Jamie Zawinski <jwz@jwz.org> 2 * 3 * Permission to use, copy, modify, distribute, and sell this software and its 4 * documentation for any purpose is hereby granted without fee, provided that 5 * the above copyright notice appear in all copies and that both that 6 * copyright notice and this permission notice appear in supporting 7 * documentation. No representations are made about the suitability of this 8 * software for any purpose. It is provided "as is" without express or 9 * implied warranty. 10 */ 11 12 #ifndef __YARANDOM_H__ 13 #define __YARANDOM_H__ 14 15 #ifdef HAVE_CONFIG_H 16 # include "config.h" 17 #endif 18 19 #ifdef HAVE_INTTYPES_H 20 # include <inttypes.h> 21 #endif 22 23 #undef random 24 #undef rand 25 #undef drand48 26 #undef srandom 27 #undef srand 28 #undef frand 29 #undef sranddev 30 #undef srandomdev 31 #undef arc4random 32 #undef arc4random_addrandom 33 #undef arc4random_buf 34 #undef arc4random_stir 35 #undef arc4random_uniform 36 #undef erand48 37 #undef jrand48 38 #undef lcong48 39 #undef lrand48 40 #undef mrand48 41 #undef nrand48 42 #undef seed48 43 #undef srand48 44 #undef rand_r 45 #undef RAND_MAX 46 47 #ifdef VMS 48 # include "vms-gtod.h" 49 #endif 50 51 extern unsigned int ya_random (void); 52 extern void ya_rand_init (unsigned int); 53 54 #define random() ya_random() 55 #define RAND_MAX 0xFFFFFFFF 56 57 /*#define srandom(i) ya_rand_init(0)*/ 58 59 /* Define these away to keep people from using the wrong APIs in xscreensaver. 60 */ 61 #define rand __ERROR_use_random_not_rand_in_xscreensaver__ 62 #define drand48 __ERROR_use_frand_not_drand48_in_xscreensaver__ 63 #define srandom __ERROR_do_not_call_srandom_in_xscreensaver__ 64 #define srand __ERROR_do_not_call_srand_in_xscreensaver__ 65 #define sranddev __ERROR_do_not_call_sranddev_in_xscreensaver__ 66 #define ya_rand_init __ERROR_do_not_call_ya_rand_init_in_xscreensaver__ 67 #define srandomdev __ERROR_do_not_call_srandomdev_in_xscreensaver__ 68 #define arc4random __ERROR_do_not_call_arc4random_in_xscreensaver__ 69 #define arc4random_addrandom __ERROR_do_not_call_arc4random_in_xscreensaver__ 70 #define arc4random_buf __ERROR_do_not_call_arc4random_in_xscreensaver__ 71 #define arc4random_stir __ERROR_do_not_call_arc4random_in_xscreensaver__ 72 #define arc4random_uniform __ERROR_do_not_call_arc4random_in_xscreensaver__ 73 #define erand48 __ERROR_do_not_call_erand48_in_xscreensaver__ 74 #define jrand48 __ERROR_do_not_call_jrand48_in_xscreensaver__ 75 #define lcong48 __ERROR_do_not_call_lcong48_in_xscreensaver__ 76 #define lrand48 __ERROR_do_not_call_lrand48_in_xscreensaver__ 77 #define mrand48 __ERROR_do_not_call_mrand48_in_xscreensaver__ 78 #define nrand48 __ERROR_do_not_call_nrand48_in_xscreensaver__ 79 #define seed48 __ERROR_do_not_call_seed48_in_xscreensaver__ 80 #define srand48 __ERROR_do_not_call_srand48_in_xscreensaver__ 81 #define rand_r __ERROR_do_not_call_rand_r_in_xscreensaver__ 82 83 84 #if defined (__GNUC__) && (__GNUC__ >= 2) 85 /* Implement frand using GCC's statement-expression extension. */ 86 87 # define frand(f) \ 88 __extension__ \ 89 ({ double tmp = ((((double) random()) * ((double) (f))) / \ 90 ((double) ((unsigned int)~0))); \ 91 tmp < 0 ? (-tmp) : tmp; }) 92 93 #else /* not GCC2 - implement frand using a global variable.*/ 94 95 static double _frand_tmp_; 96 # define frand(f) \ 97 (_frand_tmp_ = ((((double) random()) * ((double) (f))) / \ 98 ((double) ((unsigned int)~0))), \ 99 _frand_tmp_ < 0 ? (-_frand_tmp_) : _frand_tmp_) 100 101 #endif /* not GCC2 */ 102 103 /* Compatibility with the xlockmore RNG API 104 (note that the xlockmore hacks never expect negative numbers.) 105 */ 106 #define LRAND() ((long) (random() & 0x7fffffff)) 107 108 /* The first NRAND(n) is much faster, when uint64_t is available to allow it. 109 * Especially on ARM and other processors without built-in division. 110 * 111 * n must be greater than zero. 112 * 113 * The division by RAND_MAX+1 should optimize down to a bit shift. 114 * 115 * Although the result here is never negative, this needs to return signed 116 * integers: A binary operator in C requires operands have the same type, and 117 * if one side is signed and the other is unsigned, but they're both the same 118 * size, then the signed operand is cast to unsigned, and the result is 119 * similarly unsigned. This can potentially cause problems when idioms like 120 * "NRAND(n) * RANDSIGN()" (where RANDSIGN() returns either -1 or 1) is used 121 * to get random numbers from the range (-n,n). 122 */ 123 #ifdef HAVE_INTTYPES_H 124 # define NRAND(n) ((int32_t) ((uint64_t) random() * (uint32_t) (n) / \ 125 ((uint64_t) RAND_MAX + 1))) 126 #else 127 # define NRAND(n) ((int) (LRAND() % (n))) 128 #endif 129 130 #define MAXRAND (2147483648.0) /* unsigned 1<<31 as a float */ 131 #define SRAND(n) /* already seeded by screenhack.c */ 132 133 #endif /* __YARANDOM_H__ */ 134