/** * g_rand_new_with_seed: * @seed: a value to initialize the random number generator. * * Creates a new random number generator initialized with @seed. * * Return value: the new #GRand. **/ GRand* g_rand_new_with_seed (guint32 seed) { GRand *rand = g_new0 (GRand, 1); g_rand_set_seed (rand, seed); return rand; }
/** * ORBit_genuid_init: * @type: how strong / weak we want to be * * initializes randomness bits * * Return value: TRUE if we achieve the strength desired **/ gboolean ORBit_genuid_init (ORBitGenUidType type) { GTimeVal time; gboolean hit_strength; genuid_pid = getpid (); #ifndef G_OS_WIN32 genuid_uid = getuid (); #endif inc_lock = link_mutex_new(); glib_prng = g_rand_new (); g_get_current_time (&time); g_rand_set_seed (glib_prng, (time.tv_sec << 20) ^ time.tv_usec); genuid_type = type; switch (genuid_type) { case ORBIT_GENUID_STRONG: #ifndef G_OS_WIN32 random_fd = open ("/dev/urandom", O_RDONLY); if (random_fd < 0) random_fd = open ("/dev/random", O_RDONLY); hit_strength = (random_fd >= 0); #else if (CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) hit_strength = TRUE; else hit_strength = FALSE; #endif #if LINK_SSL_SUPPORT hit_strength = TRUE; /* foolishly trust OpenSSL */ #endif break; default: hit_strength = TRUE; break; } return hit_strength; }
int main(int argc, char *argv[]) { guint xres_min = 2, xres_max = 10000, rand_seed = 42; gdouble xres_step = 1.06; GOptionEntry entries[] = { { "xres-min", 's', 0, G_OPTION_ARG_INT, &xres_min, "Smallest field xres to test", "N", }, { "xres-max", 'S', 0, G_OPTION_ARG_INT, &xres_max, "Largest field xres to test", "N", }, { "xres-step", 'q', 0, G_OPTION_ARG_DOUBLE, &xres_step, "Field xres step factor", "Q", }, { "random-seed", 'r', 0, G_OPTION_ARG_INT, &rand_seed, "Random seed", "R", }, { NULL, 0, 0, 0, NULL, NULL, NULL, }, }; GError *error = NULL; GOptionContext *context = g_option_context_new("- measure distance transform speed"); g_option_context_add_main_entries(context, entries, NULL); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("Arguments parsing failed: %s\n", error->message); return 1; } g_option_context_free(context); gwy_type_init(); setvbuf(stdout, (char*)NULL, _IOLBF, 0); GRand *rng = g_rand_new(); g_rand_set_seed(rng, rand_seed); for (guint xres = xres_min; xres <= xres_max; xres = MAX(xres + 1, (guint)(xres_step*xres + 0.5))) { distance_transform(xres, rng); } g_rand_free(rng); return 0; }
END_TEST START_TEST(test_atree_random_value) { ATree *at; gint result; gint key; gint data; gint *random; at = a_tree_new(); if (at == NULL) { ck_abort_msg ("Failed to create ATree\n"); } else { key = 1; data = 1; g_rand_set_seed( at->random, 0 ); result = atree_insert( at, GINT_TO_POINTER(&key), GINT_TO_POINTER(&data) ); ck_assert_int_eq( result, 0 ); random = atree_random_value( at ); if (random == NULL) { ck_abort_msg ("random values is NULL\n"); } else { ck_assert_int_eq( *random, data ); } a_tree_destroy( at ); } }
static void prepare_coef (params *p) { GimpRGB color1; GimpRGB color2; gdouble scalex = svals.scalex; gdouble scaley = svals.scaley; GRand *gr; gr = g_rand_new (); g_rand_set_seed (gr, svals.seed); switch (svals.colorization) { case BILINEAR: p->blend = bilinear; break; case SINUS: p->blend = cosinus; break; case LINEAR: default: p->blend = linear; } if (svals.perturbation==IDEAL) { /* Presumably the 0 * g_rand_int ()s are to pop random * values off the prng, I don't see why though. */ p->c11= 0 * g_rand_int (gr); p->c12= g_rand_double_range (gr, -1, 1) * scaley; p->c13= g_rand_double_range (gr, 0, 2 * G_PI); p->c21= 0 * g_rand_int (gr); p->c22= g_rand_double_range (gr, -1, 1) * scaley; p->c23= g_rand_double_range (gr, 0, 2 * G_PI); p->c31= g_rand_double_range (gr, -1, 1) * scalex; p->c32= 0 * g_rand_int (gr); p->c33= g_rand_double_range (gr, 0, 2 * G_PI); } else { p->c11= g_rand_double_range (gr, -1, 1) * scalex; p->c12= g_rand_double_range (gr, -1, 1) * scaley; p->c13= g_rand_double_range (gr, 0, 2 * G_PI); p->c21= g_rand_double_range (gr, -1, 1) * scalex; p->c22= g_rand_double_range (gr, -1, 1) * scaley; p->c23= g_rand_double_range (gr, 0, 2 * G_PI); p->c31= g_rand_double_range (gr, -1, 1) * scalex; p->c32= g_rand_double_range (gr, -1, 1) * scaley; p->c33= g_rand_double_range (gr, 0, 2 * G_PI); } if (svals.tiling) { p->c11= ROUND (p->c11/(2*G_PI))*2*G_PI; p->c12= ROUND (p->c12/(2*G_PI))*2*G_PI; p->c21= ROUND (p->c21/(2*G_PI))*2*G_PI; p->c22= ROUND (p->c22/(2*G_PI))*2*G_PI; p->c31= ROUND (p->c31/(2*G_PI))*2*G_PI; p->c32= ROUND (p->c32/(2*G_PI))*2*G_PI; } color1 = svals.col1; color2 = svals.col2; if (drawable_is_grayscale) { gimp_rgb_set (&color1, 1.0, 1.0, 1.0); gimp_rgb_set (&color2, 0.0, 0.0, 0.0); } else { switch (svals.colors) { case USE_COLORS: break; case B_W: gimp_rgb_set (&color1, 1.0, 1.0, 1.0); gimp_rgb_set (&color2, 0.0, 0.0, 0.0); break; case USE_FG_BG: gimp_context_get_background (&color1); gimp_context_get_foreground (&color2); break; } } gimp_rgba_get_uchar (&color1, &p->r, &p->g, &p->b, &p->a); gimp_rgba_subtract (&color2, &color1); p->dr = color2.r * 255.0; p->dg = color2.g * 255.0; p->db = color2.b * 255.0; p->da = color2.a * 255.0; g_rand_free (gr); }
// This function: // - is called once for each motion event // - does motion event interpolation // - paints zero, one or several dabs // - decides whether the stroke is finished (for undo/redo) // returns true if the stroke is finished or empty bool stroke_to (Surface * surface, float x, float y, float pressure, float xtilt, float ytilt, double dtime) { //printf("%f %f %f %f\n", (double)dtime, (double)x, (double)y, (double)pressure); float tilt_ascension = 0.0; float tilt_declination = 90.0; if (xtilt != 0 || ytilt != 0) { // shield us from insane tilt input xtilt = CLAMP(xtilt, -1.0, 1.0); ytilt = CLAMP(ytilt, -1.0, 1.0); assert(std::isfinite(xtilt) && std::isfinite(ytilt)); tilt_ascension = 180.0*atan2(-xtilt, ytilt)/M_PI; float e; if (abs(xtilt) > abs(ytilt)) { e = sqrt(1+ytilt*ytilt); } else { e = sqrt(1+xtilt*xtilt); } float rad = hypot(xtilt, ytilt); float cos_alpha = rad/e; if (cos_alpha >= 1.0) cos_alpha = 1.0; // fix numerical inaccuracy tilt_declination = 180.0*acos(cos_alpha)/M_PI; assert(std::isfinite(tilt_ascension)); assert(std::isfinite(tilt_declination)); } // printf("xtilt %f, ytilt %f\n", (double)xtilt, (double)ytilt); // printf("ascension %f, declination %f\n", (double)tilt_ascension, (double)tilt_declination); pressure = CLAMP(pressure, 0.0, 1.0); if (!std::isfinite(x) || !std::isfinite(y) || (x > 1e10 || y > 1e10 || x < -1e10 || y < -1e10)) { // workaround attempt for https://gna.org/bugs/?14372 g_print("Warning: ignoring brush::stroke_to with insane inputs (x = %f, y = %f)\n", (double)x, (double)y); x = 0.0; y = 0.0; pressure = 0.0; } // the assertion below is better than out-of-memory later at save time assert(x < 1e8 && y < 1e8 && x > -1e8 && y > -1e8); if (dtime < 0) g_print("Time jumped backwards by dtime=%f seconds!\n", dtime); if (dtime <= 0) dtime = 0.0001; // protect against possible division by zero bugs if (dtime > 0.100 && pressure && states[STATE_PRESSURE] == 0) { // Workaround for tablets that don't report motion events without pressure. // This is to avoid linear interpolation of the pressure between two events. stroke_to (surface, x, y, 0.0, 90.0, 0.0, dtime-0.0001); dtime = 0.0001; } g_rand_set_seed (rng, states[STATE_RNG_SEED]); { // calculate the actual "virtual" cursor position // noise first if (settings[BRUSH_TRACKING_NOISE]->base_value) { // OPTIMIZE: expf() called too often float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value); x += rand_gauss (rng) * settings[BRUSH_TRACKING_NOISE]->base_value * base_radius; y += rand_gauss (rng) * settings[BRUSH_TRACKING_NOISE]->base_value * base_radius; } float fac = 1.0 - exp_decay (settings[BRUSH_SLOW_TRACKING]->base_value, 100.0*dtime); x = states[STATE_X] + (x - states[STATE_X]) * fac; y = states[STATE_Y] + (y - states[STATE_Y]) * fac; } // draw many (or zero) dabs to the next position // see doc/stroke2dabs.png float dist_moved = states[STATE_DIST]; float dist_todo = count_dabs_to (x, y, pressure, dtime); //if (dtime > 5 || dist_todo > 300) { if (dtime > 5 || reset_requested) { reset_requested = false; /* TODO: if (dist_todo > 300) { // this happens quite often, eg when moving the cursor back into the window // FIXME: bad to hardcode a distance treshold here - might look at zoomed image // better detect leaving/entering the window and reset then. g_print ("Warning: NOT drawing %f dabs.\n", dist_todo); g_print ("dtime=%f, dx=%f\n", dtime, x-states[STATE_X]); //must_reset = 1; } */ //printf("Brush reset.\n"); for (int i=0; i<STATE_COUNT; i++) { states[i] = 0; } states[STATE_X] = x; states[STATE_Y] = y; states[STATE_PRESSURE] = pressure; // not resetting, because they will get overwritten below: //dx, dy, dpress, dtime states[STATE_ACTUAL_X] = states[STATE_X]; states[STATE_ACTUAL_Y] = states[STATE_Y]; states[STATE_STROKE] = 1.0; // start in a state as if the stroke was long finished return true; } //g_print("dist = %f\n", states[STATE_DIST]); enum { UNKNOWN, YES, NO } painted = UNKNOWN; double dtime_left = dtime; float step_dx, step_dy, step_dpressure, step_dtime; float step_declination, step_ascension; while (dist_moved + dist_todo >= 1.0) { // there are dabs pending { // linear interpolation (nonlinear variant was too slow, see SVN log) float frac; // fraction of the remaining distance to move if (dist_moved > 0) { // "move" the brush exactly to the first dab (moving less than one dab) frac = (1.0 - dist_moved) / dist_todo; dist_moved = 0; } else { // "move" the brush from one dab to the next frac = 1.0 / dist_todo; } step_dx = frac * (x - states[STATE_X]); step_dy = frac * (y - states[STATE_Y]); step_dpressure = frac * (pressure - states[STATE_PRESSURE]); step_dtime = frac * (dtime_left - 0.0); step_declination = frac * (tilt_declination - states[STATE_DECLINATION]); step_ascension = frac * (tilt_ascension - states[STATE_ASCENSION]); // Though it looks different, time is interpolated exactly like x/y/pressure. } update_states_and_setting_values (step_dx, step_dy, step_dpressure, step_declination, step_ascension, step_dtime); bool painted_now = prepare_and_draw_dab (surface); if (painted_now) { painted = YES; } else if (painted == UNKNOWN) { painted = NO; } dtime_left -= step_dtime; dist_todo = count_dabs_to (x, y, pressure, dtime_left); } { // "move" the brush to the current time (no more dab will happen) // Important to do this at least once every event, because // brush_count_dabs_to depends on the radius and the radius can // depend on something that changes much faster than only every // dab (eg speed). step_dx = x - states[STATE_X]; step_dy = y - states[STATE_Y]; step_dpressure = pressure - states[STATE_PRESSURE]; step_declination = tilt_declination - states[STATE_DECLINATION]; step_ascension = tilt_ascension - states[STATE_ASCENSION]; step_dtime = dtime_left; //dtime_left = 0; but that value is not used any more update_states_and_setting_values (step_dx, step_dy, step_dpressure, step_declination, step_ascension, step_dtime); } // save the fraction of a dab that is already done now states[STATE_DIST] = dist_moved + dist_todo; //g_print("dist_final = %f\n", states[STATE_DIST]); // next seed for the RNG (GRand has no get_state() and states[] must always contain our full state) states[STATE_RNG_SEED] = g_rand_int(rng); // stroke separation logic (for undo/redo) if (painted == UNKNOWN) { if (stroke_current_idling_time > 0 || stroke_total_painting_time == 0) { // still idling painted = NO; } else { // probably still painting (we get more events than brushdabs) painted = YES; //if (pressure == 0) g_print ("info: assuming 'still painting' while there is no pressure\n"); } } if (painted == YES) { //if (stroke_current_idling_time > 0) g_print ("idling ==> painting\n"); stroke_total_painting_time += dtime; stroke_current_idling_time = 0; // force a stroke split after some time if (stroke_total_painting_time > 4 + 3*pressure) { // but only if pressure is not being released // FIXME: use some smoothed state for dpressure, not the output of the interpolation code // (which might easily wrongly give dpressure == 0) if (step_dpressure >= 0) { return true; } } } else if (painted == NO) { //if (stroke_current_idling_time == 0) g_print ("painting ==> idling\n"); stroke_current_idling_time += dtime; if (stroke_total_painting_time == 0) { // not yet painted, start a new stroke if we have accumulated a lot of irrelevant motion events if (stroke_current_idling_time > 1.0) { return true; } } else { // Usually we have pressure==0 here. But some brushes can paint // nothing at full pressure (eg gappy lines, or a stroke that // fades out). In either case this is the prefered moment to split. if (stroke_total_painting_time+stroke_current_idling_time > 0.9 + 5*pressure) { return true; } } } return false; }
void prim_tileable(gchar *maz, guint x, guint y) { GSList *front_cells=NULL; guint current, pos; guint up, down, left, right; guint progress=0, max_progress; char d, i; guint c=0; gint rnd = mvals.seed; g_rand_set_seed (gr, rnd); gimp_progress_init (_("Constructing tileable maze using Prim's Algorithm")); /* OUT is zero, so we should be already initalized. */ max_progress=x*y/4; /* Pick someplace to start. */ pos = x * 2 * g_rand_int_range (gr, 0, y/2) + 2 * g_rand_int_range(gr, 0, x/2); maz[pos]=IN; /* Add frontier. */ up=CELL_UP_TILEABLE(pos); down=CELL_DOWN_TILEABLE(pos); left=CELL_LEFT_TILEABLE(pos); right=CELL_RIGHT_TILEABLE(pos); maz[up]=maz[down]=maz[left]=maz[right]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up)); front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down)); front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left)); front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right)); /* While frontier is not empty do the following... */ while(g_slist_length(front_cells) > 0) { /* Remove one cell at random from frontier and place it in IN. */ current = g_rand_int_range (gr, 0, g_slist_length(front_cells)); pos = GPOINTER_TO_UINT(g_slist_nth(front_cells,current)->data); front_cells=g_slist_remove(front_cells,GUINT_TO_POINTER(pos)); maz[pos]=IN; /* If the cell has any neighbors in OUT, remove them from OUT and place them in FRONTIER. */ up=CELL_UP_TILEABLE(pos); down=CELL_DOWN_TILEABLE(pos); left=CELL_LEFT_TILEABLE(pos); right=CELL_RIGHT_TILEABLE(pos); d=0; switch (maz[up]) { case OUT: maz[up]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up)); break; case IN: d=1; break; default: ; } switch (maz[down]) { case OUT: maz[down]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down)); break; case IN: d=d|2; break; default: ; } switch (maz[left]) { case OUT: maz[left]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left)); break; case IN: d=d|4; break; default: ; } switch (maz[right]) { case OUT: maz[right]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right)); break; case IN: d=d|8; break; default: ; } /* The cell is guaranteed to have at least one neighbor in IN (otherwise it would not have been in FRONTIER); pick one such neighbor at random and connect it to the new cell (ie knock out a wall). */ if (!d) { g_warning("maze: prim's tileable: Lack of neighbors.\n" "seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", mvals.seed, x, y, mvals.multiple, mvals.offset); break; } c=0; do { rnd = (rnd * mvals.multiple + mvals.offset); i = 3 & (rnd / d); if (++c > 100) { /* Break and try to salvage something */ i=99; /* if it looks like we're going to be */ break; /* here forever... */ } } while ( !(d & ( 1 << i) ) ); switch (i) { case 0: maz[WALL_UP_TILEABLE(pos)]=IN; break; case 1: maz[WALL_DOWN_TILEABLE(pos)]=IN; break; case 2: maz[WALL_LEFT_TILEABLE(pos)]=IN; break; case 3: maz[WALL_RIGHT_TILEABLE(pos)]=IN; break; case 99: break; default: g_warning("maze: prim's tileable: Going in unknown direction.\n" "i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", i, d, mvals.seed, x, y, mvals.multiple, mvals.offset); } if (progress++ % PRIMS_PROGRESS_UPDATE) gimp_progress_update ((double) progress / (double) max_progress); } /* while front_cells */ g_slist_free(front_cells); }
/* This function (as well as prim_tileable) make use of the somewhat unclean practice of storing ints as pointers. I've been informed that this may cause problems with 64-bit stuff. However, hopefully it will be okay, since the only values stored are positive. If it does break, let me know, and I'll go cry in a corner for a while before I get up the strength to re-code it. */ void prim(gint pos, gchar *maz, guint x, guint y) { GSList *front_cells=NULL; guint current; gint up, down, left, right; /* Not unsigned, because macros return -1. */ guint progress=0, max_progress; char d, i; guint c=0; gint rnd = mvals.seed; g_rand_set_seed (gr, rnd); gimp_progress_init (_("Constructing maze using Prim's Algorithm")); /* OUT is zero, so we should be already initalized. */ max_progress=x*y/4; /* Starting position has already been determined by the calling function. */ maz[pos]=IN; /* For now, repeating everything four times seems manageable. But when Gimp is extended to drawings in n-dimensional space instead of 2D, this will require a bit of a re-write. */ /* Add frontier. */ up=CELL_UP(pos); down=CELL_DOWN(pos); left=CELL_LEFT(pos); right=CELL_RIGHT(pos); if (up >= 0) { maz[up]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up)); } if (down >= 0) { maz[down]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down)); } if (left >= 0) { maz[left]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left)); } if (right >= 0) { maz[right]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right)); } /* While frontier is not empty do the following... */ while(g_slist_length(front_cells) > 0) { /* Remove one cell at random from frontier and place it in IN. */ current = g_rand_int_range (gr, 0, g_slist_length(front_cells)); pos = GPOINTER_TO_INT(g_slist_nth(front_cells,current)->data); front_cells=g_slist_remove(front_cells,GINT_TO_POINTER(pos)); maz[pos]=IN; /* If the cell has any neighbors in OUT, remove them from OUT and place them in FRONTIER. */ up=CELL_UP(pos); down=CELL_DOWN(pos); left=CELL_LEFT(pos); right=CELL_RIGHT(pos); d=0; if (up>=0) { switch (maz[up]) { case OUT: maz[up]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(up)); break; case IN: d=1; break; default: ; } } if (down>=0) { switch (maz[down]) { case OUT: maz[down]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(down)); break; case IN: d=d|2; break; default: ; } } if (left>=0) { switch (maz[left]) { case OUT: maz[left]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(left)); break; case IN: d=d|4; break; default: ; } } if (right>=0) { switch (maz[right]) { case OUT: maz[right]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(right)); break; case IN: d=d|8; break; default: ; } } /* The cell is guaranteed to have at least one neighbor in IN (otherwise it would not have been in FRONTIER); pick one such neighbor at random and connect it to the new cell (ie knock out a wall). */ if (!d) { g_warning("maze: prim: Lack of neighbors.\n" "seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", mvals.seed, x, y, mvals.multiple, mvals.offset); break; } c=0; do { rnd = (rnd * mvals.multiple + mvals.offset); i = 3 & (rnd / d); if (++c > 100) { /* Break and try to salvage something */ i=99; /* if it looks like we're going to be */ break; /* here forever... */ } } while ( !(d & ( 1 << i) ) ); switch (i) { case 0: maz[WALL_UP(pos)]=IN; break; case 1: maz[WALL_DOWN(pos)]=IN; break; case 2: maz[WALL_LEFT(pos)]=IN; break; case 3: maz[WALL_RIGHT(pos)]=IN; break; case 99: break; default: g_warning("maze: prim: Going in unknown direction.\n" "i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", i, d, mvals.seed, x, y, mvals.multiple, mvals.offset); } if (progress++ % PRIMS_PROGRESS_UPDATE) gimp_progress_update ((double) progress / (double) max_progress); } /* while front_cells */ g_slist_free(front_cells); } /* prim */
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; /* assume the best! */ static GimpParam values[1]; INIT_I18N (); /* * Get the specified drawable, do standard initialization. */ if (strcmp (name, PLUG_IN_PROC[0]) == 0) rndm_type = RNDM_HURL; else if (strcmp (name, PLUG_IN_PROC[1]) == 0) rndm_type = RNDM_PICK; else if (strcmp (name, PLUG_IN_PROC[2]) == 0) rndm_type = RNDM_SLUR; run_mode = param[0].data.d_int32; drawable = gimp_drawable_get(param[2].data.d_drawable); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gr = g_rand_new (); /* * Make sure the drawable type is appropriate. */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id) || gimp_drawable_is_indexed (drawable->drawable_id)) { gimp_tile_cache_ntiles (2 * drawable->ntile_cols); switch (run_mode) { /* * If we're running interactively, pop up the dialog box. */ case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC[rndm_type - 1], &pivals); if (! randomize_dialog (drawable)) /* return on Cancel */ return; break; /* * If we're not interactive (probably scripting), we * get the parameters from the param[] array, since * we don't use the dialog box. Make sure they all * parameters have legitimate values. */ case GIMP_RUN_NONINTERACTIVE: if (nparams != 7) { status = GIMP_PDB_CALLING_ERROR; } else { pivals.rndm_pct = (gdouble) param[3].data.d_float; pivals.rndm_rcount = (gdouble) param[4].data.d_float; pivals.randomize = (gboolean) param[5].data.d_int32; pivals.seed = (gint) param[6].data.d_int32; if (pivals.randomize) pivals.seed = g_random_int (); if ((rndm_type != RNDM_PICK && rndm_type != RNDM_SLUR && rndm_type != RNDM_HURL) || (pivals.rndm_pct < 1.0 || pivals.rndm_pct > 100.0) || (pivals.rndm_rcount < 1.0 || pivals.rndm_rcount > 100.0)) { status = GIMP_PDB_CALLING_ERROR; } } break; /* * If we're running with the last set of values, get those values. */ case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC[rndm_type - 1], &pivals); if (pivals.randomize) pivals.seed = g_random_int (); break; /* * Hopefully we never get here! */ default: break; } if (status == GIMP_PDB_SUCCESS) { gimp_progress_init_printf ("%s", gettext (RNDM_NAME[rndm_type - 1])); /* * Initialize the g_rand() function seed */ g_rand_set_seed (gr, pivals.seed); randomize (drawable, NULL); /* * If we ran interactively (even repeating) update the display. */ if (run_mode != GIMP_RUN_NONINTERACTIVE) { gimp_displays_flush (); } /* * If we use the dialog popup, set the data for future use. */ if (run_mode == GIMP_RUN_INTERACTIVE) { gimp_set_data (PLUG_IN_PROC[rndm_type - 1], &pivals, sizeof (RandomizeVals)); } } } else { /* * If we got the wrong drawable type, we need to complain. */ status = GIMP_PDB_EXECUTION_ERROR; } /* * DONE! * Set the status where GIMP can see it, and let go * of the drawable. */ g_rand_free (gr); values[0].data.d_status = status; gimp_drawable_detach(drawable); }
/* ibus stress test Send random key press and release event message to ibus-daemon. Key kind are a-z and space. Check ibus-daemon and ibus engine crash. */ gint main (gint argc, gchar **argv) { GTimer *timer; GRand *rnd; BusTestClient *client; /* num of send space key */ guint32 seed = (guint32) time (NULL); int count = 0; int send_key_num = 0; setlocale (LC_ALL, ""); gtk_set_locale (); gtk_init (&argc, &argv); /* need to set active engine */ client = bus_test_client_new (); if (client == NULL) { g_printerr ("don't create test-client instance."); exit(1); } timer = g_timer_new (); rnd = g_rand_new (); g_rand_set_seed (rnd, seed); g_print("random seed:%u\n",seed); g_timer_start (timer); while (1) { guint keysym; if (send_key_num > MAX_SEND_KEY_NUM) { break; } if (!bus_test_client_is_connected (client)) { g_printerr ("ibus-daemon is disconnected\n"); break; } if (!bus_test_client_is_enabled (client)) { g_printerr ("ibus engine is enabled\n"); break; } if(count>0 || g_rand_int_range (rnd, 0, 5) == 0) { /* send space key 20% */ if (count == 0) { count = g_rand_int_range (rnd, 0, MAX_RANDOM_SPACE) + 1; } if (count-- == 1) { keysym = IBUS_KEY_Return; } else { keysym = IBUS_KEY_space; } } else { /* send random a-z key */ keysym = g_rand_int_range (rnd, 0, 'z'-'a'+1) + 'a'; } bus_test_client_send_key (client, keysym); send_key_num += 1; /* limit the typing rate to 800 hits/minutes */ _sleep (1000 * 60 / 800); } g_print ("%f sec\n", g_timer_elapsed (timer, NULL)); return 0; }