Exemple #1
0
/**
 * 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;
}
Exemple #2
0
/**
 * 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;
}
Exemple #4
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 );
    }
}
Exemple #5
0
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;
  }
Exemple #7
0
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);
}
Exemple #8
0
/* 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 */
Exemple #9
0
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);
}
Exemple #10
0
/* 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;
}