]> Pileus Git - ~andy/gtk/blob - modules/other/gail/tests/testlib.c
Move the gail tests from standalone gail to gtk+. Bug #504568.
[~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 (obj)->widget;
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 (child)->widget;
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 (obj)->widget;
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_usize(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 (GTK_OBJECT(md[window_no]->selecttestsWindow), 
576                           "destroy",
577                           GTK_SIGNAL_FUNC(_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_usize (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_vbox_new (TRUE, 0);
590       md[window_no]->button = gtk_button_new_with_mnemonic ("_Run Tests");
591       hbuttonbox = gtk_hbutton_box_new ();
592       gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
593                                  GTK_BUTTONBOX_SPREAD);
594       gtk_box_pack_end_defaults (GTK_BOX (hbuttonbox), 
595                                  GTK_WIDGET (md[window_no]->button));
596       gtk_box_pack_end_defaults (GTK_BOX (md[window_no]->vbox), hbuttonbox);
597       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
598                                              md[window_no]->vbox);
599
600       testcb[window_no].runtest = runtest;
601       testcb[window_no].obj = obj;
602       testcb[window_no].win_num = window_no; 
603       g_signal_connect (GTK_OBJECT (md[window_no]->button), 
604                           "clicked",
605                           GTK_SIGNAL_FUNC (_testselectioncb),  
606                           (gpointer)&testcb[window_no]);
607      
608       /* Show all */
609       gtk_widget_grab_focus (md[window_no]->button);
610       gtk_widget_show (md[window_no]->button);
611       gtk_widget_show (hbuttonbox); 
612       gtk_widget_show (scrolledWindow); 
613       gtk_widget_show_all (GTK_WIDGET (md[window_no]->selecttestsWindow));
614       return TRUE;
615     }
616   else
617     return FALSE;
618 }
619
620 /** 
621  * add_test
622  * @window: The window number
623  * @name: The test name
624  * @num_params: The number of arguments the test uses.
625  * @parameter_names: The names of each argument.
626  * @default_names: The default values of each argument.
627  *
628  * Adds a Test with the passed-in details to the Tests Select Window.  
629  *
630  * Returns: FALSE if the num_params passed in is greater than
631  * MAX_PARAMS, otherwise returns TRUE 
632  *
633  **/
634 gboolean
635 add_test (gint   window, 
636           gchar  *name,
637           gint   num_params,
638           gchar* parameter_names[],
639           gchar* default_names[])
640 {
641   gint i;
642
643   if (num_params > MAX_PARAMS)
644     return FALSE;
645   else
646     {
647       md[window]->hbox = gtk_hbox_new (FALSE, 0);
648       gtk_box_set_spacing (GTK_BOX (md[window]->hbox), 10);
649       gtk_container_set_border_width (GTK_CONTAINER (md[window]->hbox), 10);
650       gtk_container_add (GTK_CONTAINER (md[window]->vbox), md[window]->hbox);
651       listoftests[window][testcount[window]].toggleButton =
652          gtk_toggle_button_new_with_label (name);
653       gtk_box_pack_start (GTK_BOX (md[window]->hbox),
654           listoftests[window][testcount[window]].toggleButton, FALSE, FALSE, 0);
655       listoftests[window][testcount[window]].testName = name;
656       listoftests[window][testcount[window]].numParameters = num_params;
657       for (i=0; i<num_params; i++) 
658         {
659           listoftests[window][testcount[window]].parameterLabel[i] =
660             gtk_label_new (parameter_names[i]);
661           gtk_box_pack_start (GTK_BOX (md[window]->hbox),
662           listoftests[window][testcount[window]].parameterLabel[i], FALSE, FALSE, 0);
663           listoftests[window][testcount[window]].parameterInput[i] = gtk_entry_new();
664           gtk_entry_set_text (GTK_ENTRY (listoftests[window][testcount[window]].parameterInput[i]),
665             default_names[i]);
666           gtk_widget_set_usize (listoftests[window][testcount[window]].parameterInput[i], 50, 22);
667           gtk_box_pack_start (GTK_BOX (md[window]->hbox),
668             listoftests[window][testcount[window]].parameterInput[i], FALSE, FALSE, 0);
669           gtk_widget_set_sensitive (
670             GTK_WIDGET (listoftests[window][testcount[window]].parameterLabel[i]), FALSE);
671           gtk_widget_set_sensitive (
672             GTK_WIDGET (listoftests[window][testcount[window]].parameterInput[i]), FALSE);
673           gtk_widget_show (listoftests[window][testcount[window]].parameterLabel[i]);
674           gtk_widget_show (listoftests[window][testcount[window]].parameterInput[i]);
675         }
676       g_signal_connect (GTK_OBJECT (listoftests[window][testcount[window]].toggleButton),
677                           "toggled", 
678                           GTK_SIGNAL_FUNC(_toggle_selectedcb),
679                           (gpointer)&(listoftests[window][testcount[window]]));
680       gtk_widget_show (listoftests[window][testcount[window]].toggleButton);
681       gtk_widget_show (md[window]->hbox);
682       gtk_widget_show (md[window]->vbox);
683
684       testcount[window]++;
685       counter++;
686       return TRUE;
687     }  
688 }
689
690 /** 
691  * tests_set:
692  * @window: The window number
693  * @count: Passes back the number of tests on.
694  *
695  * Gets an array of strings corresponding to the tests that are "on".
696  * A test is assumed on if the toggle button is on and if all its
697  * parameters have values.
698  *
699  * Returns: an array of strings corresponding to the tests that
700  * are "on".
701  **/
702 gchar **tests_set(gint window, int *count)
703 {
704   gint        i =0, j = 0, num;
705   gboolean    nullparam;
706   gchar*      input;
707
708   *count = 0;
709   for (i = 0; i < MAX_TESTS; i++)
710       onTests[window][i] = NULL;
711
712   for (i = 0; i < testcount[window]; i++)
713     {
714       nullparam = FALSE;
715       if (GTK_TOGGLE_BUTTON(listoftests[window][i].toggleButton)->active)
716         {
717           num = listoftests[window][i].numParameters;
718           for (j = 0; j < num; j++)
719             {
720               input = gtk_editable_get_chars (
721                     GTK_EDITABLE (listoftests[window][i].parameterInput[j]), 0, -1);
722
723               if (input != NULL && (! strcmp(input, "")))
724                 nullparam = TRUE;
725             } 
726           if (!nullparam)
727             {
728               onTests[window][*count] = listoftests[window][i].testName;
729               *count = *count + 1; 
730             }
731         }
732     } 
733   return onTests[window];
734 }
735
736 /**
737  * _get_position_in_array:
738  * @window: The window number
739  * @the_test_name: The name of the test
740  *
741  * Gets the index of the passed-in @the_test_name.
742  *
743  * Returns: the position in listoftests[] of @the_test_name
744  **/
745 static gint
746 _get_position_in_array(gint  window,
747                        gchar *the_test_name)
748 {
749   gint        i;
750   
751   for (i = 0; i < testcount[window]; i++)
752     {
753       if (strcmp(listoftests[window][i].testName, the_test_name) == 0)
754         return i;
755     }
756   return -1;
757 }
758
759 /**
760  * _get_position_in_parameters:
761  * @window: The window number
762  * @label: The label name
763  * @position: The parameter position
764  *
765  * Gets the index of the passed-in parameter @label.
766  *
767  * Returns: the position in parameterLabel[] (a member of
768  * listoftests[]) of @label 
769  **/
770 static gint
771 _get_position_in_parameters(gint  window,
772                             gchar *label,
773                             gint  position)
774 {
775   gint                    i;
776   G_CONST_RETURN gchar    *label_string;
777   
778   for (i = 0; i < MAX_PARAMS; i++)
779     {
780       label_string = gtk_label_get_text( 
781                GTK_LABEL (listoftests[window][position].parameterLabel[i]));
782
783       if (strcmp(label_string, label) == 0)
784         return i;
785     }
786   return -1;
787 }
788
789 /** 
790  * set_output_buffer:
791  * @output: The string to add to the output buffer
792  * 
793  * Tidies up the output Window 
794  **/
795 void
796 set_output_buffer(gchar *output)
797 {
798   gtk_text_buffer_insert (GTK_TEXT_BUFFER (ow->outputBuffer),
799                           &ow->outputIter, output, strlen(output));
800   gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (ow->outputBuffer),
801                                       &ow->outputIter, 0);
802 }
803
804 /**
805  * isVisibleDialog:
806  *
807  * Informs user if a visible test window running.
808  *
809  * Returns: TRUE if g_visibleDialog is set to 1, otherwise FALSE
810  **/
811 gboolean
812 isVisibleDialog(void)
813 {
814  if (g_visibleDialog >= 1)
815    return TRUE;
816  else
817    return FALSE;
818 }
819
820 /**
821  * get_arg_of_func:
822  * @window: The window number
823  * @function_name: The name of the function
824  * @arg_label: The label of the argument.
825  *
826  * Gets the user input associated with the @function_name and @arg_label.
827  *
828  * Returns: the user input associated with the @function_name and @arg_label.
829  **/
830 gchar*
831 get_arg_of_func (gint  window,
832                  gchar *function_name,
833                  gchar *arg_label)
834 {
835   G_CONST_RETURN gchar       *argString;
836   gchar                      *retString;
837   gint                       position, paramPosition;
838
839   position =  _get_position_in_array(window, function_name);
840
841   if (position == -1)
842     {
843       g_print("No such function\n");
844       return NULL;
845     }
846
847   paramPosition = _get_position_in_parameters(window, arg_label, position);
848
849   if (paramPosition == -1)
850     {
851       g_print("No such parameter Label\n");
852       return NULL;
853     }
854
855   if (position != -1 && paramPosition != -1)
856     {
857       argString = gtk_editable_get_chars (
858         GTK_EDITABLE (listoftests[window][position].parameterInput[paramPosition]),
859       0, -1);
860       retString = g_strdup(argString);
861     }
862   else
863     retString = NULL;
864
865   return retString;
866 }
867
868 /**
869  * string_to_int:
870  * @the_string: The string to convert
871  *
872  * Converts the passed-in string to an integer 
873  *
874  * Returns: An integer corresponding to @the_string.
875  **/
876 int
877 string_to_int (const char *the_string)
878 {
879   char *end_ptr;
880   double ret_val;
881   int int_ret_val; 
882
883   while (1)
884     {
885       ret_val = strtod( the_string, &end_ptr);
886       if (*end_ptr == '\0')
887         break;
888       else
889         printf("\nError: input must be a number\n");
890     }
891    
892   int_ret_val = (int) ret_val;
893   return (int_ret_val);
894 }
895
896 /** 
897  * _toggle_selectedcb:
898  * @widget: The ToggleButton widget
899  * @test: user data containing the TestList structure.
900  *
901  * Toggle Button Callback, activating the text entry fields 
902  **/
903 static void
904 _toggle_selectedcb (GtkWidget *widget,
905                     gpointer  test)
906 {
907   int i;
908   TestList *testlist = (TestList *) test;
909   gboolean toggled;
910   gboolean sensitive;
911   toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
912   if (toggled)
913     sensitive = TRUE;
914   else
915     sensitive = FALSE;
916
917   for (i=0; i < testlist->numParameters; i++)
918     {
919       gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterLabel[i]),
920                                 sensitive);
921       gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterInput[i]),
922                                 sensitive);
923     }
924 }
925
926 /* 
927  * _testselectioncb:
928  * widget: The Button widget
929  * data: The user data containing a TestCB structure
930  *
931  * Callback for when the "Run Tests" button is pressed 
932  **/
933 static void
934 _testselectioncb (GtkWidget *widget,
935                   gpointer data)
936 {
937   TestCB* local_testcb = (TestCB *)data;
938   local_testcb->runtest(local_testcb->obj, local_testcb->win_num);
939 }
940
941 /**
942  * _destroy:
943  * @widget: The GUI widget
944  * @data: User data, not used.
945  *
946  * Destroy Callback.
947  **/
948 static void
949 _destroy (GtkWidget *widget,
950           gpointer  data)
951 {
952   gtk_main_quit();
953 }
954