int main () { int i; #ifdef SYMBIAN g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); g_set_print_handler(mrtPrintHandler); #endif /*SYMBIAN*/ for (i = 0; i < SIZE; i++) array[i] = g_random_int (); g_qsort_with_data (array, SIZE, sizeof (guint32), sort, NULL); for (i = 0; i < SIZE - 1; i++) g_assert (array[i] <= array[i+1]); /* 0 elemenents is a valid case */ g_qsort_with_data (array, 0, sizeof (guint32), sort, NULL); #ifdef SYMBIAN testResultXml("qsort-test"); #endif /* EMULATOR */ return 0; }
void gnome_vfs_ace_add_perm (GnomeVFSACE *entry, GnomeVFSACLPerm perm) { GnomeVFSACEPrivate *priv; PermSet *permset; gint i; g_assert (GNOME_VFS_IS_ACE(entry)); priv = entry->priv; permset = &priv->perm_set; for (i=0; i<permset->count; i++) { if (permset->perms[i] == perm) return; } if (permset->array_len < permset->count) { permset->perms = g_realloc (permset->perms, sizeof(GnomeVFSACLPerm) * (permset->count + 2)); permset->array_len++; } permset->perms[permset->count] = perm; permset->count++; g_qsort_with_data (permset->perms, permset->count++, sizeof (GnomeVFSACLPerm), (GCompareDataFunc) cmp_perm, NULL); }
static gboolean gst_interleave_channel_positions_to_mask (GValueArray * positions, gint default_ordering_map[64], guint64 * mask) { gint i; guint channels; GstAudioChannelPosition *pos; gboolean ret; channels = positions->n_values; pos = g_new (GstAudioChannelPosition, channels); for (i = 0; i < channels; i++) { GValue *val; val = g_value_array_get_nth (positions, i); pos[i] = g_value_get_enum (val); } /* sort the default ordering map according to the position order */ for (i = 0; i < channels; i++) { default_ordering_map[i] = i; } g_qsort_with_data (default_ordering_map, channels, sizeof (*default_ordering_map), compare_positions, pos); ret = gst_audio_channel_positions_to_mask (pos, channels, FALSE, mask); g_free (pos); return ret; }
static void permset_set (PermSet *set, GnomeVFSACLPerm *perms) { GnomeVFSACLPerm *iter; guint bytes_to_copy; int n; g_assert (perms); for (iter = perms, n = 0; *iter; iter++) { n++; } bytes_to_copy = sizeof (GnomeVFSACLPerm) * (n + 1); g_free (set->perms); set->perms = g_memdup (perms, bytes_to_copy); /* sort the array */ g_qsort_with_data (set->perms, n, sizeof (GnomeVFSACLPerm), (GCompareDataFunc) cmp_perm, NULL); set->count = n; set->array_len = n; }
/** * gtk_distribute_natural_allocation: * @extra_space: Extra space to redistribute among children after subtracting * minimum sizes and any child padding from the overall allocation * @n_requested_sizes: Number of requests to fit into the allocation * @sizes: An array of structs with a client pointer and a minimum/natural size * in the orientation of the allocation. * * Distributes @extra_space to child @sizes by bringing smaller * children up to natural size first. * * The remaining space will be added to the @minimum_size member of the * GtkRequestedSize struct. If all sizes reach their natural size then * the remaining space is returned. * * Returns: The remainder of @extra_space after redistributing space * to @sizes. */ gint gtk_distribute_natural_allocation (gint extra_space, guint n_requested_sizes, GtkRequestedSize *sizes) { guint *spreading; gint i; g_return_val_if_fail (extra_space >= 0, 0); spreading = g_newa (guint, n_requested_sizes); for (i = 0; i < n_requested_sizes; i++) spreading[i] = i; /* Distribute the container's extra space c_gap. We want to assign * this space such that the sum of extra space assigned to children * (c^i_gap) is equal to c_cap. The case that there's not enough * space for all children to take their natural size needs some * attention. The goals we want to achieve are: * * a) Maximize number of children taking their natural size. * b) The allocated size of children should be a continuous * function of c_gap. That is, increasing the container size by * one pixel should never make drastic changes in the distribution. * c) If child i takes its natural size and child j doesn't, * child j should have received at least as much gap as child i. * * The following code distributes the additional space by following * these rules. */ /* Sort descending by gap and position. */ g_qsort_with_data (spreading, n_requested_sizes, sizeof (guint), compare_gap, sizes); /* Distribute available space. * This master piece of a loop was conceived by Behdad Esfahbod. */ for (i = n_requested_sizes - 1; extra_space > 0 && i >= 0; --i) { /* Divide remaining space by number of remaining children. * Sort order and reducing remaining space by assigned space * ensures that space is distributed equally. */ gint glue = (extra_space + i) / (i + 1); gint gap = sizes[(spreading[i])].natural_size - sizes[(spreading[i])].minimum_size; gint extra = MIN (glue, gap); sizes[spreading[i]].minimum_size += extra; extra_space -= extra; } return extra_space; }
void cp_strings_sort(char **str_array) { g_qsort_with_data( str_array, (int)g_strv_length(str_array), sizeof(*str_array), (GCompareDataFunc)cmpstrp, NULL ); }
/*-------------------------------------------------------------- * arc_table_index_sort_with_data() */ void gfsm_arc_table_index_sort_with_data(gfsmArcTableIndex *tabx, GCompareDataFunc compare_func, gpointer data) { gfsmArc **firstp = (gfsmArc**)tabx->first->pdata; gfsmArc **firstp_max = firstp + tabx->first->len - 1; for ( ; firstp < firstp_max; firstp++) { gfsmArc *min = *firstp; gfsmArc *max = *(firstp+1); g_qsort_with_data(min, max-min, sizeof(gfsmArc), compare_func, data); } }
/* Only sorts the directories and playlist files. * The songs stay in the order it came from mpd. */ void filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func) { unsigned first, last; const struct mpd_entity *iter; assert(filelist && filelist->entries); if (filelist->entries->len < 2) return; /* If the first entry is NULL, skip it, because NULL stands for "[..]" */ iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, 0))->entity; first = (iter == NULL)? 1 : 0; /* find the last directory entry */ for (last = first+1; last < filelist->entries->len; last++) { iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, last))->entity; if (mpd_entity_get_type(iter) != MPD_ENTITY_TYPE_DIRECTORY) break; } if (last == filelist->entries->len - 1) last++; /* sort the directories */ if (last - first > 1) g_qsort_with_data(filelist->entries->pdata + first, last - first, sizeof(gpointer), filelist_compare_indirect, compare_func); /* find the first playlist entry */ for (first = last; first < filelist->entries->len; first++) { iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, first))->entity; if (mpd_entity_get_type(iter) == MPD_ENTITY_TYPE_PLAYLIST) break; } /* sort the playlist entries */ if (filelist->entries->len - first > 1) g_qsort_with_data(filelist->entries->pdata + first, filelist->entries->len - first, sizeof(gpointer), filelist_compare_indirect, compare_func); }
/** * g_ptr_array_sort_with_data: * @array: a #GPtrArray * @compare_func: comparison function * @user_data: data to pass to @compare_func * * Like g_ptr_array_sort(), but the comparison function has an extra * user data argument. * * Note that the comparison function for g_ptr_array_sort_with_data() * doesn't take the pointers from the array as arguments, it takes * pointers to the pointers in the array. * * This is guaranteed to be a stable sort since version 2.32. */ void g_ptr_array_sort_with_data (GPtrArray *array, GCompareDataFunc compare_func, gpointer user_data) { g_return_if_fail (array != NULL); g_qsort_with_data (array->pdata, array->len, sizeof (gpointer), compare_func, user_data); }
/** * g_ptr_array_sort: * @array: a #GPtrArray * @compare_func: comparison function * * Sorts the array, using @compare_func which should be a qsort()-style * comparison function (returns less than zero for first arg is less * than second arg, zero for equal, greater than zero if irst arg is * greater than second arg). * * Note that the comparison function for g_ptr_array_sort() doesn't * take the pointers from the array as arguments, it takes pointers to * the pointers in the array. * * This is guaranteed to be a stable sort since version 2.32. */ void g_ptr_array_sort (GPtrArray *array, GCompareFunc compare_func) { g_return_if_fail (array != NULL); /* Don't use qsort as we want a guaranteed stable sort */ g_qsort_with_data (array->pdata, array->len, sizeof (gpointer), (GCompareDataFunc)compare_func, NULL); }
/** * g_array_sort_with_data: * @array: a #GArray * @compare_func: comparison function * @user_data: data to pass to @compare_func * * Like g_array_sort(), but the comparison function receives an extra * user data argument. * * This is guaranteed to be a stable sort since version 2.32. * * There used to be a comment here about making the sort stable by * using the addresses of the elements in the comparison function. * This did not actually work, so any such code should be removed. */ void g_array_sort_with_data (GArray *farray, GCompareDataFunc compare_func, gpointer user_data) { GRealArray *array = (GRealArray*) farray; g_return_if_fail (array != NULL); g_qsort_with_data (array->data, array->len, array->elt_size, compare_func, user_data); }
/** * g_array_sort: * @array: a #GArray * @compare_func: comparison function * * Sorts a #GArray using @compare_func which should be a qsort()-style * comparison function (returns less than zero for first arg is less * than second arg, zero for equal, greater zero if first arg is * greater than second arg). * * This is guaranteed to be a stable sort since version 2.32. */ void g_array_sort (GArray *farray, GCompareFunc compare_func) { GRealArray *array = (GRealArray*) farray; g_return_if_fail (array != NULL); /* Don't use qsort as we want a guaranteed stable sort */ g_qsort_with_data (array->data, array->len, array->elt_size, (GCompareDataFunc)compare_func, NULL); }
/** * g_value_array_sort_with_data: (rename-to g_value_array_sort) * @value_array: #GValueArray to sort * @compare_func: (scope call): function to compare elements * @user_data: (closure): extra data argument provided for @compare_func * * Sort @value_array using @compare_func to compare the elements according * to the semantics of #GCompareDataFunc. * * The current implementation uses the same sorting algorithm as standard * C qsort() function. * * Returns: (transfer none): the #GValueArray passed in as @value_array * * Deprecated: 2.32: Use #GArray and g_array_sort_with_data(). */ GValueArray* g_value_array_sort_with_data (GValueArray *value_array, GCompareDataFunc compare_func, gpointer user_data) { g_return_val_if_fail (value_array != NULL, NULL); g_return_val_if_fail (compare_func != NULL, NULL); if (value_array->n_values) g_qsort_with_data (value_array->values, value_array->n_values, sizeof (value_array->values[0]), compare_func, user_data); return value_array; }
void custom_list_resort (CustomList * custom_list) { GtkTreePath *path; gint *neworder, i; if (custom_list->num_rows < 2) return; /* resort */ g_qsort_with_data (custom_list->rows, custom_list->num_rows, sizeof (chanlistrow *), (GCompareDataFunc) custom_list_qsort_compare_func, custom_list); /* let other objects know about the new order */ neworder = malloc (sizeof (gint) * custom_list->num_rows); for (i = custom_list->num_rows - 1; i >= 0; i--) { /* Note that the API reference might be wrong about * this, see bug number 124790 on bugs.gnome.org. * Both will work, but one will give you 'jumpy' * selections after row reordering. */ /* neworder[(custom_list->rows[i])->pos] = i; */ neworder[i] = (custom_list->rows[i])->pos; (custom_list->rows[i])->pos = i; } path = gtk_tree_path_new (); gtk_tree_model_rows_reordered (GTK_TREE_MODEL (custom_list), path, NULL, neworder); gtk_tree_path_free (path); free (neworder); }
static void gst_net_client_internal_clock_observe_times (GstNetClientInternalClock * self, GstClockTime local_1, GstClockTime remote_1, GstClockTime remote_2, GstClockTime local_2) { GstClockTime current_timeout = 0; GstClockTime local_avg, remote_avg; gdouble r_squared; GstClock *clock; GstClockTime rtt, rtt_limit, min_update_interval; /* Use for discont tracking */ GstClockTime time_before = 0; GstClockTime min_guess = 0; GstClockTimeDiff time_discont = 0; gboolean synched, now_synched; GstClockTime internal_time, external_time, rate_num, rate_den; GstClockTime orig_internal_time, orig_external_time, orig_rate_num, orig_rate_den; GstClockTime max_discont; GstClockTime last_rtts[MEDIAN_PRE_FILTERING_WINDOW]; GstClockTime median; gint i; GST_OBJECT_LOCK (self); rtt_limit = self->roundtrip_limit; GST_LOG_OBJECT (self, "local1 %" G_GUINT64_FORMAT " remote1 %" G_GUINT64_FORMAT " remote2 %" G_GUINT64_FORMAT " local2 %" G_GUINT64_FORMAT, local_1, remote_1, remote_2, local_2); /* If the server told us a poll interval and it's bigger than the * one configured via the property, use the server's */ if (self->last_remote_poll_interval != GST_CLOCK_TIME_NONE && self->last_remote_poll_interval > self->minimum_update_interval) min_update_interval = self->last_remote_poll_interval; else min_update_interval = self->minimum_update_interval; GST_OBJECT_UNLOCK (self); if (local_2 < local_1) { GST_LOG_OBJECT (self, "Dropping observation: receive time %" GST_TIME_FORMAT " < send time %" GST_TIME_FORMAT, GST_TIME_ARGS (local_1), GST_TIME_ARGS (local_2)); goto bogus_observation; } if (remote_2 < remote_1) { GST_LOG_OBJECT (self, "Dropping observation: remote receive time %" GST_TIME_FORMAT " < send time %" GST_TIME_FORMAT, GST_TIME_ARGS (remote_1), GST_TIME_ARGS (remote_2)); goto bogus_observation; } /* The round trip time is (assuming symmetric path delays) * delta = (local_2 - local_1) - (remote_2 - remote_1) */ rtt = GST_CLOCK_DIFF (local_1, local_2) - GST_CLOCK_DIFF (remote_1, remote_2); if ((rtt_limit > 0) && (rtt > rtt_limit)) { GST_LOG_OBJECT (self, "Dropping observation: RTT %" GST_TIME_FORMAT " > limit %" GST_TIME_FORMAT, GST_TIME_ARGS (rtt), GST_TIME_ARGS (rtt_limit)); goto bogus_observation; } for (i = 1; i < MEDIAN_PRE_FILTERING_WINDOW; i++) self->last_rtts[i - 1] = self->last_rtts[i]; self->last_rtts[i - 1] = rtt; if (self->last_rtts_missing) { self->last_rtts_missing--; } else { memcpy (&last_rtts, &self->last_rtts, sizeof (last_rtts)); g_qsort_with_data (&last_rtts, MEDIAN_PRE_FILTERING_WINDOW, sizeof (GstClockTime), (GCompareDataFunc) compare_clock_time, NULL); median = last_rtts[MEDIAN_PRE_FILTERING_WINDOW / 2]; /* FIXME: We might want to use something else here, like only allowing * things in the interquartile range, or also filtering away delays that * are too small compared to the median. This here worked well enough * in tests so far. */ if (rtt > 2 * median) { GST_LOG_OBJECT (self, "Dropping observation, long RTT %" GST_TIME_FORMAT " > 2 * median %" GST_TIME_FORMAT, GST_TIME_ARGS (rtt), GST_TIME_ARGS (median)); goto bogus_observation; } } /* Track an average round trip time, for a bit of smoothing */ /* Always update before discarding a sample, so genuine changes in * the network get picked up, eventually */ if (self->rtt_avg == GST_CLOCK_TIME_NONE) self->rtt_avg = rtt; else if (rtt < self->rtt_avg) /* Shorter RTTs carry more weight than longer */ self->rtt_avg = (3 * self->rtt_avg + rtt) / 4; else self->rtt_avg = (15 * self->rtt_avg + rtt) / 16; if (rtt > 2 * self->rtt_avg) { GST_LOG_OBJECT (self, "Dropping observation, long RTT %" GST_TIME_FORMAT " > 2 * avg %" GST_TIME_FORMAT, GST_TIME_ARGS (rtt), GST_TIME_ARGS (self->rtt_avg)); goto bogus_observation; } /* The difference between the local and remote clock (again assuming * symmetric path delays): * * local_1 + delta / 2 - remote_1 = theta * or * local_2 - delta / 2 - remote_2 = theta * * which gives after some simple algebraic transformations: * * (remote_1 - local_1) + (remote_2 - local_2) * theta = ------------------------------------------- * 2 * * * Thus remote time at local_avg is equal to: * * local_avg + theta = * * local_1 + local_2 (remote_1 - local_1) + (remote_2 - local_2) * ----------------- + ------------------------------------------- * 2 2 * * = * * remote_1 + remote_2 * ------------------- = remote_avg * 2 * * We use this for our clock estimation, i.e. local_avg at remote clock * being the same as remote_avg. */ local_avg = (local_2 + local_1) / 2; remote_avg = (remote_2 + remote_1) / 2; GST_LOG_OBJECT (self, "remoteavg %" G_GUINT64_FORMAT " localavg %" G_GUINT64_FORMAT, remote_avg, local_avg); clock = GST_CLOCK_CAST (self); /* Store what the clock produced as 'now' before this update */ gst_clock_get_calibration (GST_CLOCK_CAST (self), &orig_internal_time, &orig_external_time, &orig_rate_num, &orig_rate_den); internal_time = orig_internal_time; external_time = orig_external_time; rate_num = orig_rate_num; rate_den = orig_rate_den; min_guess = gst_clock_adjust_with_calibration (GST_CLOCK_CAST (self), local_1, internal_time, external_time, rate_num, rate_den); time_before = gst_clock_adjust_with_calibration (GST_CLOCK_CAST (self), local_2, internal_time, external_time, rate_num, rate_den); /* Maximum discontinuity, when we're synched with the master. Could make this a property, * but this value seems to work fine */ max_discont = self->rtt_avg / 4; /* If the remote observation was within a max_discont window around our min/max estimates, we're synched */ synched = (GST_CLOCK_DIFF (remote_avg, min_guess) < (GstClockTimeDiff) (max_discont) && GST_CLOCK_DIFF (time_before, remote_avg) < (GstClockTimeDiff) (max_discont)); if (gst_clock_add_observation_unapplied (GST_CLOCK_CAST (self), local_avg, remote_avg, &r_squared, &internal_time, &external_time, &rate_num, &rate_den)) { /* Now compare the difference (discont) in the clock * after this observation */ time_discont = GST_CLOCK_DIFF (time_before, gst_clock_adjust_with_calibration (GST_CLOCK_CAST (self), local_2, internal_time, external_time, rate_num, rate_den)); /* If we were in sync with the remote clock, clamp the allowed * discontinuity to within quarter of one RTT. In sync means our send/receive estimates * of remote time correctly windowed the actual remote time observation */ if (synched && ABS (time_discont) > max_discont) { GstClockTimeDiff offset; GST_DEBUG_OBJECT (clock, "Too large a discont, clamping to 1/4 average RTT = %" GST_TIME_FORMAT, GST_TIME_ARGS (max_discont)); if (time_discont > 0) { /* Too large a forward step - add a -ve offset */ offset = max_discont - time_discont; if (-offset > external_time) external_time = 0; else external_time += offset; } else { /* Too large a backward step - add a +ve offset */ offset = -(max_discont + time_discont); external_time += offset; } time_discont += offset; } /* Check if the new clock params would have made our observation within range */ now_synched = (GST_CLOCK_DIFF (remote_avg, gst_clock_adjust_with_calibration (GST_CLOCK_CAST (self), local_1, internal_time, external_time, rate_num, rate_den)) < (GstClockTimeDiff) (max_discont)) && (GST_CLOCK_DIFF (gst_clock_adjust_with_calibration (GST_CLOCK_CAST (self), local_2, internal_time, external_time, rate_num, rate_den), remote_avg) < (GstClockTimeDiff) (max_discont)); /* Only update the clock if we had synch or just gained it */ if (synched || now_synched || self->skipped_updates > MAX_SKIPPED_UPDATES) { gst_clock_set_calibration (GST_CLOCK_CAST (self), internal_time, external_time, rate_num, rate_den); /* ghetto formula - shorter timeout for bad correlations */ current_timeout = (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND; current_timeout = MIN (current_timeout, gst_clock_get_timeout (GST_CLOCK_CAST (self))); self->skipped_updates = 0; /* FIXME: When do we consider the clock absolutely not synced anymore? */ gst_clock_set_synced (GST_CLOCK (self), TRUE); } else { /* Restore original calibration vars for the report, we're not changing the clock */ internal_time = orig_internal_time; external_time = orig_external_time; rate_num = orig_rate_num; rate_den = orig_rate_den; time_discont = 0; self->skipped_updates++; } } /* Limit the polling to at most one per minimum_update_interval */ if (rtt < min_update_interval) current_timeout = MAX (min_update_interval - rtt, current_timeout); GST_OBJECT_LOCK (self); if (self->busses) { GstStructure *s; GstMessage *msg; GList *l; /* Output a stats message, whether we updated the clock or not */ s = gst_structure_new ("gst-netclock-statistics", "synchronised", G_TYPE_BOOLEAN, synched, "rtt", G_TYPE_UINT64, rtt, "rtt-average", G_TYPE_UINT64, self->rtt_avg, "local", G_TYPE_UINT64, local_avg, "remote", G_TYPE_UINT64, remote_avg, "discontinuity", G_TYPE_INT64, time_discont, "remote-min-estimate", G_TYPE_UINT64, min_guess, "remote-max-estimate", G_TYPE_UINT64, time_before, "remote-min-error", G_TYPE_INT64, GST_CLOCK_DIFF (remote_avg, min_guess), "remote-max-error", G_TYPE_INT64, GST_CLOCK_DIFF (remote_avg, time_before), "request-send", G_TYPE_UINT64, local_1, "request-receive", G_TYPE_UINT64, local_2, "r-squared", G_TYPE_DOUBLE, r_squared, "timeout", G_TYPE_UINT64, current_timeout, "internal-time", G_TYPE_UINT64, internal_time, "external-time", G_TYPE_UINT64, external_time, "rate-num", G_TYPE_UINT64, rate_num, "rate-den", G_TYPE_UINT64, rate_den, "rate", G_TYPE_DOUBLE, (gdouble) (rate_num) / rate_den, "local-clock-offset", G_TYPE_INT64, GST_CLOCK_DIFF (internal_time, external_time), NULL); msg = gst_message_new_element (GST_OBJECT (self), s); for (l = self->busses; l; l = l->next) gst_bus_post (l->data, gst_message_ref (msg)); gst_message_unref (msg); } GST_OBJECT_UNLOCK (self); GST_INFO ("next timeout: %" GST_TIME_FORMAT, GST_TIME_ARGS (current_timeout)); self->timeout_expiration = gst_util_get_timestamp () + current_timeout; return; bogus_observation: /* Schedule a new packet again soon */ self->timeout_expiration = gst_util_get_timestamp () + (GST_SECOND / 4); return; }
void e_table_sorting_utils_sort (ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, gint *map_table, gint rows) { gint total_rows; gint i; gint j; gint cols; ETableSortClosure closure; g_return_if_fail (E_IS_TABLE_MODEL (source)); g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); g_return_if_fail (E_IS_TABLE_HEADER (full_header)); total_rows = e_table_model_row_count (source); cols = e_table_sort_info_sorting_get_count (sort_info); closure.cols = cols; closure.vals = g_new (gpointer, total_rows * cols); closure.sort_type = g_new (GtkSortType, cols); closure.compare = g_new (GCompareDataFunc, cols); closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; spec = e_table_sort_info_sorting_get_nth ( sort_info, j, &closure.sort_type[j]); col = e_table_header_get_column_by_spec (full_header, spec); if (col == NULL) { gint last = e_table_header_count (full_header) - 1; col = e_table_header_get_column (full_header, last); } for (i = 0; i < rows; i++) { closure.vals[map_table[i] * cols + j] = e_table_model_value_at (source, col->spec->compare_col, map_table[i]); } closure.compare[j] = col->compare; } g_qsort_with_data ( map_table, rows, sizeof (gint), e_sort_callback, &closure); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; spec = e_table_sort_info_sorting_get_nth ( sort_info, j, &closure.sort_type[j]); col = e_table_header_get_column_by_spec (full_header, spec); if (col == NULL) { gint last = e_table_header_count (full_header) - 1; col = e_table_header_get_column (full_header, last); } for (i = 0; i < rows; i++) { e_table_model_free_value (source, col->spec->compare_col, closure.vals[map_table[i] * cols + j]); } } g_free (closure.vals); g_free (closure.sort_type); g_free (closure.compare); e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); }
static void table_sorter_sort (ETableSorter *table_sorter) { gint rows; gint i; gint j; gint cols; gint group_cols; struct qsort_data qd; if (table_sorter->sorted) return; rows = e_table_model_row_count (table_sorter->source); group_cols = e_table_sort_info_grouping_get_count (table_sorter->sort_info); cols = e_table_sort_info_sorting_get_count (table_sorter->sort_info) + group_cols; table_sorter->sorted = g_new (int, rows); for (i = 0; i < rows; i++) table_sorter->sorted[i] = i; qd.cols = cols; qd.table_sorter = table_sorter; qd.vals = g_new (gpointer , rows * cols); qd.ascending = g_new (int, cols); qd.compare = g_new (GCompareDataFunc, cols); qd.cmp_cache = e_table_sorting_utils_create_cmp_cache (); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; GtkSortType sort_type; if (j < group_cols) spec = e_table_sort_info_grouping_get_nth ( table_sorter->sort_info, j, &sort_type); else spec = e_table_sort_info_sorting_get_nth ( table_sorter->sort_info, j - group_cols, &sort_type); col = e_table_header_get_column_by_spec ( table_sorter->full_header, spec); if (col == NULL) { gint last = e_table_header_count ( table_sorter->full_header) - 1; col = e_table_header_get_column ( table_sorter->full_header, last); } for (i = 0; i < rows; i++) { qd.vals[i * cols + j] = e_table_model_value_at ( table_sorter->source, col->spec->model_col, i); } qd.compare[j] = col->compare; qd.ascending[j] = (sort_type == GTK_SORT_ASCENDING); } g_qsort_with_data (table_sorter->sorted, rows, sizeof (gint), qsort_callback, &qd); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; GtkSortType sort_type; if (j < group_cols) spec = e_table_sort_info_grouping_get_nth ( table_sorter->sort_info, j, &sort_type); else spec = e_table_sort_info_sorting_get_nth ( table_sorter->sort_info, j - group_cols, &sort_type); col = e_table_header_get_column_by_spec ( table_sorter->full_header, spec); if (col == NULL) { gint last = e_table_header_count ( table_sorter->full_header) - 1; col = e_table_header_get_column ( table_sorter->full_header, last); } for (i = 0; i < rows; i++) { e_table_model_free_value (table_sorter->source, col->spec->model_col, qd.vals[i * cols + j]); } } g_free (qd.vals); g_free (qd.ascending); g_free (qd.compare); e_table_sorting_utils_free_cmp_cache (qd.cmp_cache); }
void e_table_sorting_utils_tree_sort (ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, ETreePath *map_table, gint count) { ETableSortClosure closure; gint cols; gint i, j; gint *map; ETreePath *map_copy; g_return_if_fail (E_IS_TREE_MODEL (source)); g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); g_return_if_fail (E_IS_TABLE_HEADER (full_header)); cols = e_table_sort_info_sorting_get_count (sort_info); closure.cols = cols; closure.vals = g_new (gpointer , count * cols); closure.sort_type = g_new (GtkSortType, cols); closure.compare = g_new (GCompareDataFunc, cols); closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; spec = e_table_sort_info_sorting_get_nth ( sort_info, j, &closure.sort_type[j]); col = e_table_header_get_column_by_spec (full_header, spec); if (col == NULL) { gint last = e_table_header_count (full_header) - 1; col = e_table_header_get_column (full_header, last); } for (i = 0; i < count; i++) { closure.vals[i * cols + j] = e_tree_model_sort_value_at (source, map_table[i], col->spec->compare_col); } closure.compare[j] = col->compare; } map = g_new (int, count); for (i = 0; i < count; i++) { map[i] = i; } g_qsort_with_data ( map, count, sizeof (gint), e_sort_callback, &closure); map_copy = g_new (ETreePath, count); for (i = 0; i < count; i++) { map_copy[i] = map_table[i]; } for (i = 0; i < count; i++) { map_table[i] = map_copy[map[i]]; } for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; spec = e_table_sort_info_sorting_get_nth ( sort_info, j, &closure.sort_type[j]); col = e_table_header_get_column_by_spec (full_header, spec); if (col == NULL) { gint last = e_table_header_count (full_header) - 1; col = e_table_header_get_column (full_header, last); } for (i = 0; i < count; i++) { e_tree_model_free_value (source, col->spec->compare_col, closure.vals[i * cols + j]); } } g_free (map); g_free (map_copy); g_free (closure.vals); g_free (closure.sort_type); g_free (closure.compare); e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); }
gboolean flatpak_builtin_ls_remote (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GHashTable) refs = NULL; GHashTableIter iter; gpointer key; gpointer value; g_autoptr(GHashTable) names = NULL; guint n_keys; g_autofree const char **keys = NULL; int i; const char *repository; const char **arches = flatpak_get_arches (); const char *opt_arches[] = {NULL, NULL}; context = g_option_context_new (_(" REMOTE - Show available runtimes and applications")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); if (!flatpak_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error)) return FALSE; if (!opt_app && !opt_runtime) opt_app = opt_runtime = TRUE; if (argc < 2) return usage_error (context, _("REMOTE must be specified"), error); if (argc > 2) return usage_error (context, _("Too many arguments"), error); repository = argv[1]; if (!flatpak_dir_list_remote_refs (dir, repository, &refs, cancellable, error)) return FALSE; names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); if (opt_arch != NULL) { if (strcmp (opt_arch, "*") == 0) arches = NULL; else { opt_arches[0] = opt_arch; arches = opt_arches; } } g_hash_table_iter_init (&iter, refs); while (g_hash_table_iter_next (&iter, &key, &value)) { const char *ref = key; const char *checksum = value; const char *name = NULL; g_auto(GStrv) parts = NULL; parts = flatpak_decompose_ref (ref, NULL); if (parts == NULL) { g_debug ("Invalid remote ref %s\n", ref); continue; } if (opt_only_updates) { g_autofree char *deployed = NULL; deployed = flatpak_dir_read_active (dir, ref, cancellable); if (deployed == NULL) continue; if (g_strcmp0 (deployed, checksum) == 0) continue; } if (arches != NULL && !g_strv_contains (arches, parts[2])) continue; if (strcmp (parts[0], "runtime") == 0 && !opt_runtime) continue; if (strcmp (parts[0], "app") == 0 && !opt_app) continue; if (!opt_show_details) name = parts[1]; else name = ref; if (g_hash_table_lookup (names, name) == NULL) g_hash_table_insert (names, g_strdup (name), g_strdup (checksum)); } keys = (const char **) g_hash_table_get_keys_as_array (names, &n_keys); g_qsort_with_data (keys, n_keys, sizeof (char *), (GCompareDataFunc) flatpak_strcmp0_ptr, NULL); FlatpakTablePrinter *printer = flatpak_table_printer_new (); for (i = 0; i < n_keys; i++) { flatpak_table_printer_add_column (printer, keys[i]); if (opt_show_details) { g_autofree char *value = NULL; value = g_strdup ((char *) g_hash_table_lookup (names, keys[i])); value[MIN (strlen (value), 12)] = 0; flatpak_table_printer_add_column (printer, value); } flatpak_table_printer_finish_row (printer); } flatpak_table_printer_print (printer); flatpak_table_printer_free (printer); return TRUE; }
static void rc_gui_list2_dnd_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *seldata, guint info, guint time, gpointer data) { guint length = 0; gint i, j, k; gint *reorder_array = NULL; gint *indices = NULL; gint *index = NULL; gint target = 0; guint insert_num = 0; GList *path_list_foreach = NULL; GtkTreeViewDropPosition pos; GtkTreePath *path_start = NULL; GtkTreePath *path_drop = NULL; gint list_length = 0; gboolean insert_flag = FALSE; GList *path_list = NULL; gchar *uris = NULL; gchar **uri_array = NULL; gchar *uri = NULL; guint count = 0; gboolean flag = FALSE; gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW( rc_ui->list2_tree_view), x,y, &path_drop, &pos); if(path_drop!=NULL) { index = gtk_tree_path_get_indices(path_drop); target = index[0]; gtk_tree_path_free(path_drop); } else target = -2; switch(info) { case 1: { memcpy(&path_list, gtk_selection_data_get_data(seldata), sizeof(path_list)); if(path_list==NULL) break; length = g_list_length(path_list); indices = g_new(gint, length); for(path_list_foreach=path_list;path_list_foreach!=NULL; path_list_foreach=g_list_next(path_list_foreach)) { path_start = path_list_foreach->data; index = gtk_tree_path_get_indices(path_start); indices[count] = index[0]; count++; } g_qsort_with_data(indices, length, sizeof(gint), (GCompareDataFunc)rc_gui_list2_comp_func, NULL); if(pos==GTK_TREE_VIEW_DROP_AFTER || pos==GTK_TREE_VIEW_DROP_INTO_OR_AFTER) target++; list_length = gtk_tree_model_iter_n_children( rc_ui->list2_tree_model, NULL); if(target<0) target = list_length; reorder_array = g_new0(gint, list_length); i = 0; j = 0; count = 0; while(i<list_length) { if((j>=length || count!=indices[j]) && count!=target) { reorder_array[i] = count; count++; i++; } else if(count==target && !insert_flag) { for(k=0;k<length;k++) { if(target==indices[k]) { target++; count++; } reorder_array[i] = indices[k]; i++; } reorder_array[i] = target; i++; count++; insert_flag = TRUE; } else if(j<length && count==indices[j]) { count++; j++; } else break; } gtk_list_store_reorder(GTK_LIST_STORE(rc_ui->list2_tree_model), reorder_array); g_free(reorder_array); g_free(indices); break; } case 6: { uris = (gchar *)gtk_selection_data_get_data(seldata); if(uris==NULL) break; if(pos==GTK_TREE_VIEW_DROP_AFTER || pos==GTK_TREE_VIEW_DROP_INTO_OR_AFTER) target++; list_length = gtk_tree_model_iter_n_children( rc_ui->list2_tree_model, NULL); if(target<0) target = list_length; uri_array = g_uri_list_extract_uris(uris); insert_num = 0; for(count=0;uri_array[count]!=NULL;count++) { uri = uri_array[count]; if(rc_player_check_supported_format(uri)) { flag = rc_plist_insert_music(uri, rc_gui_list1_get_selected_index(), target); target++; insert_num++; } } g_strfreev(uri_array); if(insert_num>0) rc_gui_status_task_set(1, insert_num); break; } case 7: { rc_debug_module_perror(module_name, "Unknown dnd data in list2: %s", gtk_selection_data_get_data(seldata)); } default: break; } }