]> Pileus Git - ~andy/gtk/blob - modules/other/gail/tests/testlib.c
gtk: remove "gboolean homogeneous" from gtk_box_new()
[~andy/gtk] / modules / other / gail / tests / testlib.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "testlib.h" 
5
6 static gint     _get_position_in_array          (gint           window,
7                                                 gchar           *the_test_name);
8 static gint     _get_position_in_parameters     (gint           window,
9                                                 gchar           *label,
10                                                 gint            position);
11 static void     _create_output_window           (OutputWindow   **outwin);
12 static gboolean _create_select_tests_window     (AtkObject      *obj,
13                                                 TLruntest       runtest,
14                                                 OutputWindow    **outwin);
15 static void     _toggle_selectedcb              (GtkWidget      *widget,
16                                                 gpointer        test);
17 static void     _testselectioncb                (GtkWidget      *widget,
18                                                 gpointer        data);
19 static void     _destroy                        (GtkWidget      *widget,
20                                                 gpointer        data);
21
22 /* General functions */
23
24 /**
25  * find_object_by_role:
26  * @obj: An #AtkObject
27  * @roles: An array of roles to search for
28  * @num_roles: The number of entries in @roles
29  *
30  * Find the #AtkObject which is a decendant of the specified @obj
31  * which is of an #AtkRole type specified in the @roles array.
32  *
33  * Returns: the #AtkObject that meets the specified criteria or NULL
34  * if no object is found. 
35  **/
36 AtkObject*
37 find_object_by_role (AtkObject *obj,
38                      AtkRole   *roles,
39                      gint      num_roles)
40 {
41   /*
42    * Find the first object which is a descendant of the specified object
43    * which matches the specified role.
44    *
45    * This function returns a reference to the AtkObject which should be
46    * removed when finished with the object.
47    */
48   gint i, j;
49   gint n_children;
50   AtkObject *child;
51
52   if (obj == NULL)
53     return NULL;
54
55   for (j=0; j < num_roles; j++)
56     {
57       if (atk_object_get_role (obj) == roles[j])
58         return obj;
59     }
60
61   n_children = atk_object_get_n_accessible_children (obj);
62   for (i = 0; i < n_children; i++)
63     {
64       AtkObject* found_obj;
65
66       child = atk_object_ref_accessible_child (obj, i);
67
68       if (child == NULL)
69         continue;
70
71       for (j=0; j < num_roles; j++)
72         {
73           if (atk_object_get_role (child) == roles[j])
74             return child;
75         }
76
77       found_obj = find_object_by_role (child, roles, num_roles);
78       g_object_unref (child);
79       if (found_obj)
80         return found_obj;
81     }
82   return NULL;
83 }
84
85 /**
86  * find_object_by_name_and_role:
87  * @obj: An #AtkObject
88  * @name: The GTK widget name
89  * @roles: An array of roles to search for
90  * @num_roles: The number of entries in @roles
91  *
92  * Find the #AtkObject which is a decendant of the specified @obj
93  * which is of an #AtkRole type specified in the @roles array which
94  * also has the GTK widget name specified in @name.
95  *
96  * Returns: the #AtkObject that meets the specified criteria or NULL
97  * if no object is found. 
98  **/
99 AtkObject*
100 find_object_by_name_and_role(AtkObject   *obj,
101                              const gchar *name,
102                              AtkRole     *roles,
103                              gint        num_roles)
104 {
105   AtkObject *child;
106   GtkWidget* widget;
107   gint i, j;
108   gint n_children;
109
110   if (obj == NULL)
111     return NULL;
112
113   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
114   if (GTK_IS_WIDGET (widget))
115     {
116       if (strcmp (name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
117         {
118           for (j=0; j < num_roles; j++)
119             {
120               if (atk_object_get_role (obj) == roles[j])
121                 return obj;
122             }
123         }
124     }
125
126   n_children = atk_object_get_n_accessible_children (obj);
127   for (i = 0; i < n_children; i++)
128     {
129       AtkObject* found_obj;
130  
131       child = atk_object_ref_accessible_child (obj, i);
132
133       if (child == NULL)
134         continue;
135
136       widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
137       if (GTK_IS_WIDGET (widget))
138         {
139           if (strcmp(name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
140             {
141               for (j=0; j < num_roles; j++)
142                 {
143                   if (atk_object_get_role (child) == roles[j])
144                     return child;
145                 }
146             }
147         }
148       found_obj = find_object_by_name_and_role (child, name, roles, num_roles);
149       g_object_unref (child);
150       if (found_obj)
151         return found_obj;
152     }
153   return NULL;
154 }
155
156 /**
157  * find_object_by_accessible_name_and_role:
158  * @obj: An #AtkObject
159  * @name: The accessible name
160  * @roles: An array of roles to search for
161  * @num_roles: The number of entries in @roles
162  *
163  * Find the #AtkObject which is a decendant of the specified @obj
164  * which has the specified @name and matches one of the 
165  * specified @roles.
166  * 
167  * Returns: the #AtkObject that meets the specified criteria or NULL
168  * if no object is found. 
169  */
170 AtkObject*
171 find_object_by_accessible_name_and_role (AtkObject   *obj,
172                                          const gchar *name,
173                                          AtkRole     *roles,
174                                          gint        num_roles)
175 {
176   AtkObject *child;
177   gint i, j;
178   gint n_children;
179   G_CONST_RETURN gchar *accessible_name;
180
181   if (obj == NULL)
182     return NULL;
183
184   accessible_name = atk_object_get_name (obj);
185   if (accessible_name && (strcmp(name, accessible_name) == 0))
186     {
187       for (j=0; j < num_roles; j++)
188         {
189           if (atk_object_get_role (obj) == roles[j])
190             return obj;
191         }
192     }
193
194   n_children = atk_object_get_n_accessible_children (obj);
195   for (i = 0; i < n_children; i++)
196     {
197       AtkObject* found_obj;
198
199       child = atk_object_ref_accessible_child (obj, i);
200
201       if (child == NULL)
202         continue;
203
204       accessible_name = atk_object_get_name (child);
205       if (accessible_name && (strcmp(name, accessible_name) == 0))
206         {
207           for (j=0; j < num_roles; j++)
208             {
209               if (atk_object_get_role (child) == roles[j])
210                 return child;
211             }
212         }
213       found_obj = find_object_by_accessible_name_and_role (child, name, 
214                                                            roles, num_roles);
215       g_object_unref (child);
216       if (found_obj)
217         return found_obj;
218     }
219   return NULL;
220 }
221
222 /**
223  * find_object_by_name_and_role:
224  * @obj: An #AtkObject
225  * @type: The type 
226  *
227  * Find the #AtkObject which is a decendant of the specified @obj
228  * which has the specified @type.
229  * 
230  * Returns: the #AtkObject that meets the specified criteria or NULL
231  * if no object is found. 
232  */
233 AtkObject*
234 find_object_by_type (AtkObject *obj, 
235                      gchar     *type)
236 {
237   /*
238    * Find the first object which is a descendant of the specified object
239    * which matches the specified type.
240    *
241    * This function returns a reference to the AtkObject which should be
242    * removed when finished with the object.
243    */
244   gint i;
245   gint n_children;
246   AtkObject *child;
247   G_CONST_RETURN gchar * typename = NULL;
248
249   if (obj == NULL)
250     return NULL;
251
252   typename = g_type_name (G_OBJECT_TYPE (obj));
253   if (strcmp (typename, type) == 0)
254      return obj;
255
256   n_children = atk_object_get_n_accessible_children (obj);
257   for (i = 0; i < n_children; i++)
258     {
259       AtkObject* found_obj;
260
261       child = atk_object_ref_accessible_child (obj, i);
262
263       if (child == NULL)
264         continue;
265
266       typename = g_type_name (G_OBJECT_TYPE (child));
267
268       if (strcmp (typename, type) == 0)
269         return child;
270
271       found_obj = find_object_by_type (child, type);
272       g_object_unref (child);
273       if (found_obj)
274         return found_obj;
275     }
276   return NULL;
277 }
278
279 /**
280  * already_accessed_atk_object
281  * @obj: An #AtkObject
282  *
283  * Keeps a static GPtrArray of objects that have been passed into this
284  * function. 
285  *
286  * Returns: TRUE if @obj has been passed into this function before
287  * and FALSE otherwise.
288  */
289 gboolean
290 already_accessed_atk_object (AtkObject *obj)
291 {
292   static GPtrArray *obj_array = NULL;
293   gboolean found = FALSE;
294   gint i;
295
296   /*
297    * We create a property handler for each object if one was not associated
298    * with it already.
299    *
300    * We add it to our array of objects which have property handlers; if an
301    * object is destroyed it remains in the array.
302    */
303   if (obj_array == NULL)
304     obj_array = g_ptr_array_new ();
305
306   for (i = 0; i < obj_array->len; i++)
307     {
308       if (obj == g_ptr_array_index (obj_array, i))
309         {
310           found = TRUE;
311           break;
312         }
313     }
314   if (!found)
315     g_ptr_array_add (obj_array, obj);
316
317   return found;
318 }
319
320 /**
321  * display_children
322  * @obj: An #AtkObject
323  * @depth: Number of spaces to indent output.
324  * @child_number: The child number of this object.
325  *
326  * Displays the hierarchy of widgets starting from @obj.
327  **/
328 void
329 display_children (AtkObject *obj, 
330                   gint      depth, 
331                   gint      child_number)
332 {
333   display_children_to_depth(obj, -1, depth, child_number);
334 }
335
336 /**
337  * display_children_to_depth
338  * @obj: An #AtkObject
339  * @to_depth: Display to this depth.
340  * @depth: Number of spaces to indent output.
341  * @child_number: The child number of this object.
342  *
343  * Displays the hierarchy of widgets starting from @obj only
344  * to the specified depth.
345  **/
346 void
347 display_children_to_depth (AtkObject *obj,
348                            gint      to_depth,
349                            gint      depth,
350                            gint      child_number)
351 {
352   AtkRole role;
353   const gchar *rolename;
354   const gchar *typename;
355   gint n_children, parent_index, i;
356
357   if (to_depth >= 0 && depth > to_depth)
358      return;
359
360   if (obj == NULL)
361      return;
362
363   for (i=0; i < depth; i++)
364     g_print(" ");
365
366   role = atk_object_get_role (obj);
367   rolename = atk_role_get_name (role);
368
369  /*
370   * Note that child_number and parent_index should be the same
371   * unless there is an error.
372   */
373   parent_index = atk_object_get_index_in_parent(obj);
374   g_print("child <%d == %d> ", child_number, parent_index);
375
376   n_children = atk_object_get_n_accessible_children (obj);
377   g_print ("children <%d> ", n_children);
378
379   if (rolename)
380     g_print("role <%s>, ", rolename);
381   else
382     g_print("role <error>");
383
384   if (GTK_IS_ACCESSIBLE(obj))
385     {
386       GtkWidget *widget;
387
388       widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
389       g_print("name <%s>, ", gtk_widget_get_name(GTK_WIDGET (widget)));
390     }
391   else
392     g_print("name <NULL>, ");
393
394   typename = g_type_name (G_OBJECT_TYPE (obj));
395   g_print ("typename <%s>\n", typename);
396
397   for (i = 0; i < n_children; i++)
398     {
399       AtkObject *child;
400
401       child = atk_object_ref_accessible_child (obj, i);
402       if (child != NULL)
403         {
404           display_children_to_depth (child, to_depth, depth + 1, i);
405           g_object_unref (G_OBJECT (child));
406         }
407     }
408 }
409
410 /* Test GUI logic */
411
412 /* GUI Information for the Select Tests Window */
413 typedef struct
414 {
415   GtkWidget     *selecttestsWindow;
416   GtkWidget     *hbox;
417   GtkWidget     *vbox;
418   GtkWidget     *label;
419   GtkWidget     *textInsert;
420   GtkWidget     *button;
421   gchar         *selecttestsTitle;
422 }MainDialog;
423
424 /* Functionality information about each added test */
425 typedef struct
426 {
427   GtkWidget     *toggleButton;
428   GtkWidget     *hbox;
429   GtkWidget     *parameterLabel[MAX_PARAMS];
430   GtkWidget     *parameterInput[MAX_PARAMS];
431   gchar         *testName;
432   gint          numParameters;
433 }TestList;
434
435 typedef struct
436 {
437    TLruntest   runtest;
438    AtkObject*  obj;
439    gint        win_num;
440 }TestCB;
441
442 static MainDialog      *md[MAX_WINDOWS];
443 static OutputWindow    *ow;
444
445 /* An array containing function information on all of the tests */
446 static TestList        listoftests[MAX_WINDOWS][MAX_TESTS];
447
448 /* A counter for the actual number of added tests */
449 gint                   counter;
450
451 /* A global for keeping track of the window numbers */
452 static gint            window_no = 0;
453 /* An array containing the names of the tests that are "on" */
454 static gchar           *onTests[MAX_WINDOWS][MAX_TESTS]; 
455 static gint            g_visibleDialog = 0;
456 static gint            testcount[MAX_WINDOWS];
457 static TestCB          testcb[MAX_WINDOWS];
458
459 /**
460  * create_windows:
461  * @obj: An #AtkObject
462  * @runtest: The callback function to run when the "Run Tests" button
463  *   is clicked.
464  * @outwin: The output window to use.  If NULL is passed in, then 
465  *   create a new one.
466  *
467  * Creates the test window and the output window (if @outwin is NULL)
468  * Runs _create_output_window() and _create_select_tests_window() 
469  * and sets g_visibleDialog to 1
470  *
471  * Returns: The window number of the created window if successful, -1 otherwise.
472  **/
473 gint
474 create_windows (AtkObject    *obj,
475                 TLruntest    runtest,
476                 OutputWindow **outwin)
477 {
478   gboolean valid;  
479   gint tmp;
480
481   g_visibleDialog = 1;
482   _create_output_window(outwin); 
483   valid = _create_select_tests_window(obj, runtest, outwin);
484   if (valid)
485     {
486       tmp = window_no;
487       window_no++;
488       return tmp;
489     }
490   else
491     return -1;
492 }
493
494 /** 
495  * _create_output_window
496  * @outwin: If outwin is passed in as NULL, a new output window is created
497  *   otherwise, the outwin passed in is shared.
498  *
499  * Creates the Test Result Output Window .
500  **/
501 static void
502 _create_output_window (OutputWindow **outwin)
503 {
504   GtkWidget *view;
505   GtkWidget *scrolled_window;
506   OutputWindow *localow;
507
508   if (*outwin == NULL)
509     {
510       localow = (OutputWindow *) malloc (sizeof(OutputWindow));
511    
512       localow->outputBuffer = gtk_text_buffer_new(NULL);
513       view = gtk_text_view_new_with_buffer(GTK_TEXT_BUFFER(localow->outputBuffer));
514       gtk_widget_set_size_request (view, 700, 500);
515       gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
516       gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);   
517
518       localow->outputWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
519       gtk_window_set_title(GTK_WINDOW(localow->outputWindow), "Test Output");
520       scrolled_window = gtk_scrolled_window_new(NULL, NULL);
521
522       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
523                                      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
524       gtk_container_add(GTK_CONTAINER(localow->outputWindow), scrolled_window);
525       gtk_container_add(GTK_CONTAINER(scrolled_window), view);
526       gtk_text_buffer_get_iter_at_offset(localow->outputBuffer, &localow->outputIter, 0);
527       gtk_widget_show(view);
528       gtk_widget_show(scrolled_window);
529       gtk_widget_show(localow->outputWindow);
530
531       gtk_text_buffer_set_text(GTK_TEXT_BUFFER(localow->outputBuffer),
532         "\n\nWelcome to the test GUI:\nTest results are printed here\n\n", 58);
533       gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(localow->outputBuffer),
534                                           &localow->outputIter, 0);
535       *outwin = localow;
536       ow = *outwin;
537     }
538 }
539
540 /** 
541  * _create_select_tests_window:
542  * @obj: An #AtkObject
543  * @runtest: The callback function that is run when the "Run Tests"
544  *   button is clicked.
545  * @outwin: The output window to use.
546  *
547  * Creates the Test Select Window 
548  *
549  * Returns: TRUE if successful, FALSE otherwise
550  **/
551 static gboolean
552 _create_select_tests_window (AtkObject    *obj,
553                              TLruntest    runtest,
554                              OutputWindow **outwin)
555 {
556   AtkText   *textwidget;
557   GtkWidget *hbuttonbox;
558   GtkWidget *scrolledWindow;
559
560   if (window_no >= 0 && window_no < MAX_WINDOWS)
561     {
562       md[window_no] = (MainDialog *) malloc (sizeof(MainDialog));
563      
564       textwidget = ATK_TEXT (obj);
565      
566       /* Setup Window */
567       md[window_no]->selecttestsTitle = "Test Setting";
568       md[window_no]->selecttestsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
569       gtk_window_set_title (GTK_WINDOW( ow->outputWindow),
570                             md[window_no]->selecttestsTitle);
571       gtk_window_set_resizable (GTK_WINDOW(md[window_no]->selecttestsWindow),
572                                 FALSE);
573       gtk_window_set_position (GTK_WINDOW(md[window_no]->selecttestsWindow),
574                                GTK_WIN_POS_CENTER); 
575       g_signal_connect (md[window_no]->selecttestsWindow, 
576                         "destroy",
577                         G_CALLBACK (_destroy),
578                         &md[window_no]->selecttestsWindow);
579      
580       /* Setup Scrolling */
581       scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
582       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
583                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 
584       gtk_widget_set_size_request (scrolledWindow, 500, 600);
585       gtk_container_add (GTK_CONTAINER (md[window_no]->selecttestsWindow), 
586                          scrolledWindow);
587       
588       /* Setup Layout */
589       md[window_no]->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
590       gtk_box_set_homogeneous (GTK_BOX (md[window_no]->vbox), TRUE);
591       md[window_no]->button = gtk_button_new_with_mnemonic ("_Run Tests");
592       hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
593       gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
594                                  GTK_BUTTONBOX_SPREAD);
595       gtk_box_pack_end (GTK_BOX (hbuttonbox),
596                         GTK_WIDGET (md[window_no]->button), TRUE, TRUE, 0);
597       gtk_box_pack_end (GTK_BOX (md[window_no]->vbox), hbuttonbox,
598                         TRUE, TRUE, 0);
599       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
600                                              md[window_no]->vbox);
601
602       testcb[window_no].runtest = runtest;
603       testcb[window_no].obj = obj;
604       testcb[window_no].win_num = window_no; 
605       g_signal_connect (md[window_no]->button, 
606                         "clicked",
607                         G_CALLBACK (_testselectioncb),
608                         (gpointer)&testcb[window_no]);
609      
610       /* Show all */
611       gtk_widget_grab_focus (md[window_no]->button);
612       gtk_widget_show (md[window_no]->button);
613       gtk_widget_show (hbuttonbox); 
614       gtk_widget_show (scrolledWindow); 
615       gtk_widget_show_all (GTK_WIDGET (md[window_no]->selecttestsWindow));
616       return TRUE;
617     }
618   else
619     return FALSE;
620 }
621
622 /** 
623  * add_test
624  * @window: The window number
625  * @name: The test name
626  * @num_params: The number of arguments the test uses.
627  * @parameter_names: The names of each argument.
628  * @default_names: The default values of each argument.
629  *
630  * Adds a Test with the passed-in details to the Tests Select Window.  
631  *
632  * Returns: FALSE if the num_params passed in is greater than
633  * MAX_PARAMS, otherwise returns TRUE 
634  *
635  **/
636 gboolean
637 add_test (gint   window, 
638           gchar  *name,
639           gint   num_params,
640           gchar* parameter_names[],
641           gchar* default_names[])
642 {
643   gint i;
644
645   if (num_params > MAX_PARAMS)
646     return FALSE;
647   else
648     {
649       md[window]->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
650       gtk_box_set_spacing (GTK_BOX (md[window]->hbox), 10);
651       gtk_container_set_border_width (GTK_CONTAINER (md[window]->hbox), 10);
652       gtk_container_add (GTK_CONTAINER (md[window]->vbox), md[window]->hbox);
653       listoftests[window][testcount[window]].toggleButton =
654          gtk_toggle_button_new_with_label (name);
655       gtk_box_pack_start (GTK_BOX (md[window]->hbox),
656           listoftests[window][testcount[window]].toggleButton, FALSE, FALSE, 0);
657       listoftests[window][testcount[window]].testName = name;
658       listoftests[window][testcount[window]].numParameters = num_params;
659       for (i=0; i<num_params; i++) 
660         {
661           listoftests[window][testcount[window]].parameterLabel[i] =
662             gtk_label_new (parameter_names[i]);
663           gtk_box_pack_start (GTK_BOX (md[window]->hbox),
664           listoftests[window][testcount[window]].parameterLabel[i], FALSE, FALSE, 0);
665           listoftests[window][testcount[window]].parameterInput[i] = gtk_entry_new();
666           gtk_entry_set_text (GTK_ENTRY (listoftests[window][testcount[window]].parameterInput[i]),
667             default_names[i]);
668           gtk_widget_set_size_request (listoftests[window][testcount[window]].parameterInput[i], 50, 22);
669           gtk_box_pack_start (GTK_BOX (md[window]->hbox),
670             listoftests[window][testcount[window]].parameterInput[i], FALSE, FALSE, 0);
671           gtk_widget_set_sensitive (
672             GTK_WIDGET (listoftests[window][testcount[window]].parameterLabel[i]), FALSE);
673           gtk_widget_set_sensitive (
674             GTK_WIDGET (listoftests[window][testcount[window]].parameterInput[i]), FALSE);
675           gtk_widget_show (listoftests[window][testcount[window]].parameterLabel[i]);
676           gtk_widget_show (listoftests[window][testcount[window]].parameterInput[i]);
677         }
678       g_signal_connect (listoftests[window][testcount[window]].toggleButton,
679                         "toggled",
680                         G_CALLBACK (_toggle_selectedcb),
681                         (gpointer)&(listoftests[window][testcount[window]]));
682       gtk_widget_show (listoftests[window][testcount[window]].toggleButton);
683       gtk_widget_show (md[window]->hbox);
684       gtk_widget_show (md[window]->vbox);
685
686       testcount[window]++;
687       counter++;
688       return TRUE;
689     }  
690 }
691
692 /** 
693  * tests_set:
694  * @window: The window number
695  * @count: Passes back the number of tests on.
696  *
697  * Gets an array of strings corresponding to the tests that are "on".
698  * A test is assumed on if the toggle button is on and if all its
699  * parameters have values.
700  *
701  * Returns: an array of strings corresponding to the tests that
702  * are "on".
703  **/
704 gchar **tests_set(gint window, int *count)
705 {
706   gint        i =0, j = 0, num;
707   gboolean    nullparam;
708   gchar*      input;
709
710   *count = 0;
711   for (i = 0; i < MAX_TESTS; i++)
712       onTests[window][i] = NULL;
713
714   for (i = 0; i < testcount[window]; i++)
715     {
716       nullparam = FALSE;
717       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (listoftests[window][i].toggleButton)))
718         {
719           num = listoftests[window][i].numParameters;
720           for (j = 0; j < num; j++)
721             {
722               input = gtk_editable_get_chars (
723                     GTK_EDITABLE (listoftests[window][i].parameterInput[j]), 0, -1);
724
725               if (input != NULL && (! strcmp(input, "")))
726                 nullparam = TRUE;
727             } 
728           if (!nullparam)
729             {
730               onTests[window][*count] = listoftests[window][i].testName;
731               *count = *count + 1; 
732             }
733         }
734     } 
735   return onTests[window];
736 }
737
738 /**
739  * _get_position_in_array:
740  * @window: The window number
741  * @the_test_name: The name of the test
742  *
743  * Gets the index of the passed-in @the_test_name.
744  *
745  * Returns: the position in listoftests[] of @the_test_name
746  **/
747 static gint
748 _get_position_in_array(gint  window,
749                        gchar *the_test_name)
750 {
751   gint        i;
752   
753   for (i = 0; i < testcount[window]; i++)
754     {
755       if (strcmp(listoftests[window][i].testName, the_test_name) == 0)
756         return i;
757     }
758   return -1;
759 }
760
761 /**
762  * _get_position_in_parameters:
763  * @window: The window number
764  * @label: The label name
765  * @position: The parameter position
766  *
767  * Gets the index of the passed-in parameter @label.
768  *
769  * Returns: the position in parameterLabel[] (a member of
770  * listoftests[]) of @label 
771  **/
772 static gint
773 _get_position_in_parameters(gint  window,
774                             gchar *label,
775                             gint  position)
776 {
777   gint                    i;
778   G_CONST_RETURN gchar    *label_string;
779   
780   for (i = 0; i < MAX_PARAMS; i++)
781     {
782       label_string = gtk_label_get_text( 
783                GTK_LABEL (listoftests[window][position].parameterLabel[i]));
784
785       if (strcmp(label_string, label) == 0)
786         return i;
787     }
788   return -1;
789 }
790
791 /** 
792  * set_output_buffer:
793  * @output: The string to add to the output buffer
794  * 
795  * Tidies up the output Window 
796  **/
797 void
798 set_output_buffer(gchar *output)
799 {
800   gtk_text_buffer_insert (GTK_TEXT_BUFFER (ow->outputBuffer),
801                           &ow->outputIter, output, strlen(output));
802   gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (ow->outputBuffer),
803                                       &ow->outputIter, 0);
804 }
805
806 /**
807  * isVisibleDialog:
808  *
809  * Informs user if a visible test window running.
810  *
811  * Returns: TRUE if g_visibleDialog is set to 1, otherwise FALSE
812  **/
813 gboolean
814 isVisibleDialog(void)
815 {
816  if (g_visibleDialog >= 1)
817    return TRUE;
818  else
819    return FALSE;
820 }
821
822 /**
823  * get_arg_of_func:
824  * @window: The window number
825  * @function_name: The name of the function
826  * @arg_label: The label of the argument.
827  *
828  * Gets the user input associated with the @function_name and @arg_label.
829  *
830  * Returns: the user input associated with the @function_name and @arg_label.
831  **/
832 gchar*
833 get_arg_of_func (gint  window,
834                  gchar *function_name,
835                  gchar *arg_label)
836 {
837   G_CONST_RETURN gchar       *argString;
838   gchar                      *retString;
839   gint                       position, paramPosition;
840
841   position =  _get_position_in_array(window, function_name);
842
843   if (position == -1)
844     {
845       g_print("No such function\n");
846       return NULL;
847     }
848
849   paramPosition = _get_position_in_parameters(window, arg_label, position);
850
851   if (paramPosition == -1)
852     {
853       g_print("No such parameter Label\n");
854       return NULL;
855     }
856
857   if (position != -1 && paramPosition != -1)
858     {
859       argString = gtk_editable_get_chars (
860         GTK_EDITABLE (listoftests[window][position].parameterInput[paramPosition]),
861       0, -1);
862       retString = g_strdup(argString);
863     }
864   else
865     retString = NULL;
866
867   return retString;
868 }
869
870 /**
871  * string_to_int:
872  * @the_string: The string to convert
873  *
874  * Converts the passed-in string to an integer 
875  *
876  * Returns: An integer corresponding to @the_string.
877  **/
878 int
879 string_to_int (const char *the_string)
880 {
881   char *end_ptr;
882   double ret_val;
883   int int_ret_val; 
884
885   while (1)
886     {
887       ret_val = strtod( the_string, &end_ptr);
888       if (*end_ptr == '\0')
889         break;
890       else
891         printf("\nError: input must be a number\n");
892     }
893    
894   int_ret_val = (int) ret_val;
895   return (int_ret_val);
896 }
897
898 /** 
899  * _toggle_selectedcb:
900  * @widget: The ToggleButton widget
901  * @test: user data containing the TestList structure.
902  *
903  * Toggle Button Callback, activating the text entry fields 
904  **/
905 static void
906 _toggle_selectedcb (GtkWidget *widget,
907                     gpointer  test)
908 {
909   int i;
910   TestList *testlist = (TestList *) test;
911   gboolean toggled;
912   gboolean sensitive;
913   toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
914   if (toggled)
915     sensitive = TRUE;
916   else
917     sensitive = FALSE;
918
919   for (i=0; i < testlist->numParameters; i++)
920     {
921       gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterLabel[i]),
922                                 sensitive);
923       gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterInput[i]),
924                                 sensitive);
925     }
926 }
927
928 /* 
929  * _testselectioncb:
930  * widget: The Button widget
931  * data: The user data containing a TestCB structure
932  *
933  * Callback for when the "Run Tests" button is pressed 
934  **/
935 static void
936 _testselectioncb (GtkWidget *widget,
937                   gpointer data)
938 {
939   TestCB* local_testcb = (TestCB *)data;
940   local_testcb->runtest(local_testcb->obj, local_testcb->win_num);
941 }
942
943 /**
944  * _destroy:
945  * @widget: The GUI widget
946  * @data: User data, not used.
947  *
948  * Destroy Callback.
949  **/
950 static void
951 _destroy (GtkWidget *widget,
952           gpointer  data)
953 {
954   gtk_main_quit();
955 }
956