1 /*
2  *  driversetup.c
3  *
4  *  $Id$
5  *
6  *  The iODBC driver manager.
7  *
8  *  Copyright (C) 1996-2021 OpenLink Software <iodbc@openlinksw.com>
9  *  All Rights Reserved.
10  *
11  *  This software is released under the terms of either of the following
12  *  licenses:
13  *
14  *      - GNU Library General Public License (see LICENSE.LGPL)
15  *      - The BSD License (see LICENSE.BSD).
16  *
17  *  Note that the only valid version of the LGPL license as far as this
18  *  project is concerned is the original GNU Library General Public License
19  *  Version 2, dated June 1991.
20  *
21  *  While not mandated by the BSD license, any patches you make to the
22  *  iODBC source code may be contributed back into the iODBC project
23  *  at your discretion. Contributions will benefit the Open Source and
24  *  Data Access community as a whole. Submissions may be made at:
25  *
26  *      http://www.iodbc.org
27  *
28  *
29  *  GNU Library Generic Public License Version 2
30  *  ============================================
31  *  This library is free software; you can redistribute it and/or
32  *  modify it under the terms of the GNU Library General Public
33  *  License as published by the Free Software Foundation; only
34  *  Version 2 of the License dated June 1991.
35  *
36  *  This library is distributed in the hope that it will be useful,
37  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
38  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39  *  Library General Public License for more details.
40  *
41  *  You should have received a copy of the GNU Library General Public
42  *  License along with this library; if not, write to the Free
43  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
44  *
45  *
46  *  The BSD License
47  *  ===============
48  *  Redistribution and use in source and binary forms, with or without
49  *  modification, are permitted provided that the following conditions
50  *  are met:
51  *
52  *  1. Redistributions of source code must retain the above copyright
53  *     notice, this list of conditions and the following disclaimer.
54  *  2. Redistributions in binary form must reproduce the above copyright
55  *     notice, this list of conditions and the following disclaimer in
56  *     the documentation and/or other materials provided with the
57  *     distribution.
58  *  3. Neither the name of OpenLink Software Inc. nor the names of its
59  *     contributors may be used to endorse or promote products derived
60  *     from this software without specific prior written permission.
61  *
62  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
66  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
67  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
68  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73  */
74 
75 
76 #include "gui.h"
77 
78 
79 static char* STRCONN = "%s\0Driver=%s\0Setup=%s\0\0";
80 static int STRCONN_NB_TOKENS = 3;
81 
82 char *szKeysColumnNames[] = {
83   "Keyword",
84   "Value"
85 };
86 
87 char *szKeysButtons[] = {
88   "_Add",
89   "_Update"
90 };
91 
92 
93 static void
addkeywords_to_list(GtkWidget * widget,LPCSTR attrs,TDRIVERSETUP * driversetup_t)94 addkeywords_to_list (GtkWidget *widget, LPCSTR attrs,
95     TDRIVERSETUP *driversetup_t)
96 {
97   char *curr, *cour;
98   char *data[2];
99 
100   if (!GTK_IS_CLIST (widget))
101     return;
102   gtk_clist_clear (GTK_CLIST (widget));
103 
104   for (curr = (LPSTR) attrs; *curr; curr += (STRLEN (curr) + 1))
105     {
106       if (!strncasecmp (curr, "Driver=", STRLEN ("Driver=")))
107 	{
108 	  gtk_entry_set_text (GTK_ENTRY (driversetup_t->driver_entry),
109 	      curr + STRLEN ("Driver="));
110 	  continue;
111 	}
112 
113       if (!strncasecmp (curr, "Setup=", STRLEN ("Setup=")))
114 	{
115 	  gtk_entry_set_text (GTK_ENTRY (driversetup_t->setup_entry),
116 	      curr + STRLEN ("Setup="));
117 	  continue;
118 	}
119 
120       data[0] = curr;
121 
122       if ((cour = strchr (curr, '=')))
123 	{
124 	  data[1] = cour + 1;
125 	  *cour = 0;
126 	  gtk_clist_append (GTK_CLIST (widget), data);
127 	  *cour = '=';
128 	}
129       else
130 	{
131 	  data[1] = "";
132 	  gtk_clist_append (GTK_CLIST (widget), data);
133 	}
134     }
135 
136   if (GTK_CLIST (widget)->rows > 0)
137     gtk_clist_sort (GTK_CLIST (widget));
138 }
139 
140 
141 static void
parse_attribute_line(TDRIVERSETUP * driversetup_t,LPCSTR driver,LPCSTR attrs,BOOL add)142 parse_attribute_line (TDRIVERSETUP *driversetup_t, LPCSTR driver,
143     LPCSTR attrs, BOOL add)
144 {
145   if (driver)
146     {
147       gtk_entry_set_text (GTK_ENTRY (driversetup_t->name_entry), driver);
148       if (add)
149 	gtk_entry_set_editable (GTK_ENTRY (driversetup_t->name_entry), FALSE);
150       else
151 	gtk_entry_set_editable (GTK_ENTRY (driversetup_t->name_entry), TRUE);
152     }
153 
154   addkeywords_to_list (driversetup_t->key_list, attrs, driversetup_t);
155 }
156 
157 
158 static void
driver_file_choosen(GtkWidget * widget,TDRIVERSETUP * driversetup_t)159 driver_file_choosen (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
160 {
161   if (driversetup_t)
162     {
163       gtk_entry_set_text (GTK_ENTRY (driversetup_t->driver_entry),
164 	  gtk_file_selection_get_filename (GTK_FILE_SELECTION (driversetup_t->
165 		  filesel)));
166       driversetup_t->filesel = NULL;
167     }
168 }
169 
170 
171 static void
setup_file_choosen(GtkWidget * widget,TDRIVERSETUP * driversetup_t)172 setup_file_choosen (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
173 {
174   if (driversetup_t)
175     {
176       gtk_entry_set_text (GTK_ENTRY (driversetup_t->setup_entry),
177 	  gtk_file_selection_get_filename (GTK_FILE_SELECTION (driversetup_t->
178 		  filesel)));
179       driversetup_t->filesel = NULL;
180     }
181 }
182 
183 
184 static void
driversetup_browsedriver_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)185 driversetup_browsedriver_clicked (GtkWidget *widget,
186     TDRIVERSETUP *driversetup_t)
187 {
188   GtkWidget *filesel;
189 
190   if (driversetup_t)
191     {
192       filesel = gtk_file_selection_new ("Choose your driver library ...");
193       gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
194       gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
195 	  gtk_entry_get_text (GTK_ENTRY (driversetup_t->driver_entry)));
196       /* Ok button events */
197       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
198 	      ok_button), "clicked", GTK_SIGNAL_FUNC (driver_file_choosen),
199 	  driversetup_t);
200       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
201 	      ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
202       /* Cancel button events */
203       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
204 	      cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_main_quit),
205 	  NULL);
206       /* Close window button events */
207       gtk_signal_connect (GTK_OBJECT (filesel), "delete_event",
208 	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
209 
210       driversetup_t->filesel = filesel;
211 
212       gtk_widget_show_all (filesel);
213       gtk_main ();
214       gtk_widget_destroy (filesel);
215 
216       driversetup_t->filesel = NULL;
217     }
218 }
219 
220 
221 static void
driversetup_browsesetup_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)222 driversetup_browsesetup_clicked (GtkWidget *widget,
223     TDRIVERSETUP *driversetup_t)
224 {
225   GtkWidget *filesel;
226 
227   if (driversetup_t)
228     {
229       filesel = gtk_file_selection_new ("Choose your setup library ...");
230       gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
231       gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
232 	  gtk_entry_get_text (GTK_ENTRY (driversetup_t->setup_entry)));
233       /* Ok button events */
234       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
235 	      ok_button), "clicked", GTK_SIGNAL_FUNC (setup_file_choosen),
236 	  driversetup_t);
237       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
238 	      ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
239       /* Cancel button events */
240       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->
241 	      cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_main_quit),
242 	  NULL);
243       /* Close window button events */
244       gtk_signal_connect (GTK_OBJECT (filesel), "delete_event",
245 	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
246 
247       driversetup_t->filesel = filesel;
248 
249       gtk_widget_show_all (filesel);
250       gtk_main ();
251       gtk_widget_destroy (filesel);
252 
253       driversetup_t->filesel = NULL;
254     }
255 }
256 
257 
258 static void
driversetup_add_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)259 driversetup_add_clicked (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
260 {
261   char *szKey;
262   char *data[2];
263   int i = 0;
264 
265   if (driversetup_t)
266     {
267       data[0] = (char*)gtk_entry_get_text (GTK_ENTRY (driversetup_t->key_entry));
268       if (!STRLEN (data[0]))
269 	goto done;
270       data[1] = (char*)gtk_entry_get_text (GTK_ENTRY (driversetup_t->value_entry));
271 
272       for (i = 0; i < GTK_CLIST (driversetup_t->key_list)->rows; i++)
273 	{
274 	  gtk_clist_get_text (GTK_CLIST (driversetup_t->key_list), i, 0,
275 	      &szKey);
276 	  if (!strcmp (szKey, data[0]))
277 	    {
278 	      gtk_clist_remove (GTK_CLIST (driversetup_t->key_list), i);
279 	      break;
280 	    }
281 	}
282 
283       gtk_clist_append (GTK_CLIST (driversetup_t->key_list), data);
284       if (GTK_CLIST (driversetup_t->key_list)->rows > 0)
285 	gtk_clist_sort (GTK_CLIST (driversetup_t->key_list));
286 
287     done:
288       gtk_entry_set_text (GTK_ENTRY (driversetup_t->key_entry), "");
289       gtk_entry_set_text (GTK_ENTRY (driversetup_t->value_entry), "");
290     }
291 }
292 
293 
294 static void
driversetup_update_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)295 driversetup_update_clicked (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
296 {
297   char *data[2];
298   int i;
299 
300   if (driversetup_t)
301     {
302       data[0] = (char*)gtk_entry_get_text (GTK_ENTRY (driversetup_t->key_entry));
303       if (STRLEN (data[0]))
304 	{
305 	  data[1] = (char*)gtk_entry_get_text (GTK_ENTRY (driversetup_t->value_entry));
306 
307 	  if (GTK_CLIST (driversetup_t->key_list)->selection != NULL)
308 	    i = GPOINTER_TO_INT (GTK_CLIST (driversetup_t->key_list)->selection->
309 		data);
310 	  else
311 	    i = 0;
312 
313 	  /* An update operation */
314 	  if (i < GTK_CLIST (driversetup_t->key_list)->rows)
315 	    {
316 	      gtk_clist_set_text (GTK_CLIST (driversetup_t->key_list), i, 0,
317 		  data[0]);
318 	      gtk_clist_set_text (GTK_CLIST (driversetup_t->key_list), i, 1,
319 		  data[1]);
320 	    }
321 	}
322 
323       gtk_entry_set_text (GTK_ENTRY (driversetup_t->key_entry), "");
324       gtk_entry_set_text (GTK_ENTRY (driversetup_t->value_entry), "");
325     }
326 }
327 
328 
329 static void
driversetup_list_select(GtkWidget * widget,gint row,gint column,GdkEvent * event,TDRIVERSETUP * driversetup_t)330 driversetup_list_select (GtkWidget *widget, gint row, gint column,
331     GdkEvent *event, TDRIVERSETUP *driversetup_t)
332 {
333   char *szKey, *szValue;
334 
335   if (driversetup_t && GTK_CLIST (driversetup_t->key_list)->selection != NULL)
336     {
337       gtk_clist_get_text (GTK_CLIST (driversetup_t->key_list),
338 	  GPOINTER_TO_INT (GTK_CLIST (driversetup_t->key_list)->selection->
339 	      data), 0, &szKey);
340       gtk_clist_get_text (GTK_CLIST (driversetup_t->key_list),
341 	  GPOINTER_TO_INT (GTK_CLIST (driversetup_t->key_list)->selection->
342 	      data), 1, &szValue);
343       gtk_entry_set_text (GTK_ENTRY (driversetup_t->key_entry), szKey);
344       gtk_entry_set_text (GTK_ENTRY (driversetup_t->value_entry), szValue);
345       gtk_widget_set_sensitive (driversetup_t->bupdate, TRUE);
346     }
347 }
348 
349 
350 static void
driversetup_list_unselect(GtkWidget * widget,gint row,gint column,GdkEvent * event,TDRIVERSETUP * driversetup_t)351 driversetup_list_unselect (GtkWidget *widget, gint row, gint column,
352     GdkEvent *event, TDRIVERSETUP *driversetup_t)
353 {
354   if (driversetup_t)
355     {
356       gtk_widget_set_sensitive (driversetup_t->bupdate, FALSE);
357       gtk_entry_set_text (GTK_ENTRY (driversetup_t->key_entry), "");
358       gtk_entry_set_text (GTK_ENTRY (driversetup_t->value_entry), "");
359     }
360 }
361 
362 
363 static void
driversetup_ok_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)364 driversetup_ok_clicked (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
365 {
366   char *curr, *cour, *szKey, *szValue;
367   int i = 0, size;
368 
369   if (driversetup_t)
370     {
371       driversetup_t->connstr = (char *) malloc (sizeof (char) * (size =
372 	      ((STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
373 				  name_entry))) ?
374 		      STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
375 				  name_entry))) + 1 : 0) +
376 		  (STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
377 				  driver_entry))) ?
378 		      STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
379 				  driver_entry))) + STRLEN ("Driver=") +
380 		      1 : 0) +
381 		  (STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
382 				  setup_entry))) ?
383 		      STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
384 				  setup_entry))) + STRLEN ("Setup=") +
385 		      1 : 0) + 1)));
386 
387       if (driversetup_t->connstr)
388 	{
389 	  for (curr = STRCONN, cour = driversetup_t->connstr;
390 	      i < STRCONN_NB_TOKENS; i++, curr += (STRLEN (curr) + 1))
391 	    switch (i)
392 	      {
393 	      case 0:
394 		if (STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
395 				name_entry))))
396 		  {
397 		    sprintf (cour, curr,
398 			gtk_entry_get_text (GTK_ENTRY (driversetup_t->
399 				name_entry)));
400 		    cour += (STRLEN (cour) + 1);
401 		  }
402 		break;
403 	      case 1:
404 		if (STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
405 				driver_entry))))
406 		  {
407 		    sprintf (cour, curr,
408 			gtk_entry_get_text (GTK_ENTRY (driversetup_t->
409 				driver_entry)));
410 		    cour += (STRLEN (cour) + 1);
411 		  }
412 		break;
413 	      case 2:
414 		if (STRLEN (gtk_entry_get_text (GTK_ENTRY (driversetup_t->
415 				setup_entry))))
416 		  {
417 		    sprintf (cour, curr,
418 			gtk_entry_get_text (GTK_ENTRY (driversetup_t->
419 				setup_entry)));
420 		    cour += (STRLEN (cour) + 1);
421 		  }
422 		break;
423 	      };
424 
425 	  for (i = 0; i < GTK_CLIST (driversetup_t->key_list)->rows; i++)
426 	    {
427 	      gtk_clist_get_text (GTK_CLIST (driversetup_t->key_list), i, 0,
428 		  &szKey);
429 	      gtk_clist_get_text (GTK_CLIST (driversetup_t->key_list), i, 1,
430 		  &szValue);
431 
432 	      cour = (char *) driversetup_t->connstr;
433 	      driversetup_t->connstr =
434 		  (LPSTR) malloc (size + STRLEN (szKey) + STRLEN (szValue) +
435 		  2);
436 	      if (driversetup_t->connstr)
437 		{
438 		  memcpy (driversetup_t->connstr, cour, size);
439 		  sprintf (driversetup_t->connstr + size - 1, "%s=%s", szKey,
440 		      szValue);
441 		  free (cour);
442 		  size += STRLEN (szKey) + STRLEN (szValue) + 2;
443 		}
444 	      else
445 		driversetup_t->connstr = cour;
446 	    }
447 
448 	  driversetup_t->connstr[size - 1] = 0;
449 	}
450 
451       driversetup_t->name_entry = driversetup_t->driver_entry =
452 	  driversetup_t->setup_entry = NULL;
453       driversetup_t->key_list = driversetup_t->filesel = NULL;
454 
455       gtk_signal_disconnect_by_func (GTK_OBJECT (driversetup_t->mainwnd),
456 	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
457       gtk_main_quit ();
458       gtk_widget_destroy (driversetup_t->mainwnd);
459     }
460 }
461 
462 
463 static void
driversetup_cancel_clicked(GtkWidget * widget,TDRIVERSETUP * driversetup_t)464 driversetup_cancel_clicked (GtkWidget *widget, TDRIVERSETUP *driversetup_t)
465 {
466   if (driversetup_t)
467     {
468       driversetup_t->connstr = (LPSTR) - 1L;
469 
470       driversetup_t->name_entry = driversetup_t->driver_entry =
471 	  driversetup_t->setup_entry = NULL;
472       driversetup_t->key_list = driversetup_t->filesel = NULL;
473 
474       gtk_signal_disconnect_by_func (GTK_OBJECT (driversetup_t->mainwnd),
475 	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
476       gtk_main_quit ();
477       gtk_widget_destroy (driversetup_t->mainwnd);
478     }
479 }
480 
481 
482 static gint
delete_event(GtkWidget * widget,GdkEvent * event,TDRIVERSETUP * driversetup_t)483 delete_event (GtkWidget *widget, GdkEvent *event,
484     TDRIVERSETUP *driversetup_t)
485 {
486   driversetup_cancel_clicked (widget, driversetup_t);
487 
488   return FALSE;
489 }
490 
491 
492 LPSTR
create_driversetup(HWND hwnd,LPCSTR driver,LPCSTR attrs,BOOL add,BOOL user)493 create_driversetup (HWND hwnd, LPCSTR driver, LPCSTR attrs, BOOL add, BOOL user)
494 {
495   GdkPixmap *pixmap;
496   GdkBitmap *mask;
497   GtkStyle *style;
498 
499 
500   GtkWidget *driversetup;
501   GtkWidget *dialog_vbox6;
502   GtkWidget *vbox26;
503   GtkWidget *frame57;
504   GtkWidget *alignment49;
505   GtkWidget *table6;
506   GtkWidget *label99;
507   GtkWidget *label100;
508   GtkWidget *label101;
509   GtkWidget *t_name;
510   GtkWidget *t_driver;
511   GtkWidget *t_setup;
512   GtkWidget *b_browse;
513   GtkWidget *b_browse1;
514   GtkWidget *frame58;
515   GtkWidget *alignment50;
516   GtkWidget *scrolledwindow16;
517   GtkWidget *clist1;
518   GtkWidget *label97;
519   GtkWidget *label98;
520   GtkWidget *frame59;
521   GtkWidget *alignment51;
522   GtkWidget *table7;
523   GtkWidget *label102;
524   GtkWidget *label103;
525   GtkWidget *t_keyword;
526   GtkWidget *t_value;
527   GtkWidget *b_add;
528   GtkWidget *b_update;
529   GtkWidget *dialog_action_area6;
530   GtkWidget *b_cancel;
531   GtkWidget *b_ok;
532   TDRIVERSETUP driversetup_t;
533 
534 
535   if (hwnd == NULL || !GTK_IS_WIDGET (hwnd))
536     return (LPSTR) attrs;
537 
538   driversetup = gtk_dialog_new ();
539   gtk_widget_set_name (driversetup, "driversetup");
540   gtk_widget_set_size_request (driversetup, 505, 480);
541   gtk_window_set_title (GTK_WINDOW (driversetup), _("ODBC Driver Add/Setup"));
542   gtk_window_set_position (GTK_WINDOW (driversetup), GTK_WIN_POS_CENTER);
543   gtk_window_set_modal (GTK_WINDOW (driversetup), TRUE);
544   gtk_window_set_default_size (GTK_WINDOW (driversetup), 600, 450);
545   gtk_window_set_type_hint (GTK_WINDOW (driversetup), GDK_WINDOW_TYPE_HINT_DIALOG);
546 
547 #if GTK_CHECK_VERSION(2,0,0)
548   gtk_widget_show (driversetup);
549 #endif
550 
551   dialog_vbox6 = GTK_DIALOG (driversetup)->vbox;
552   gtk_widget_set_name (dialog_vbox6, "dialog_vbox6");
553   gtk_widget_show (dialog_vbox6);
554 
555   vbox26 = gtk_vbox_new (FALSE, 0);
556   gtk_widget_set_name (vbox26, "vbox26");
557   gtk_widget_show (vbox26);
558   gtk_box_pack_start (GTK_BOX (dialog_vbox6), vbox26, TRUE, TRUE, 0);
559 
560   frame57 = gtk_frame_new (NULL);
561   gtk_widget_set_name (frame57, "frame57");
562   gtk_widget_show (frame57);
563   gtk_box_pack_start (GTK_BOX (vbox26), frame57, FALSE, TRUE, 0);
564   gtk_frame_set_shadow_type (GTK_FRAME (frame57), GTK_SHADOW_NONE);
565 
566   alignment49 = gtk_alignment_new (0.5, 0.5, 1, 1);
567   gtk_widget_set_name (alignment49, "alignment49");
568   gtk_widget_show (alignment49);
569   gtk_container_add (GTK_CONTAINER (frame57), alignment49);
570   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment49), 16, 0, 4, 4);
571 
572   table6 = gtk_table_new (3, 3, FALSE);
573   gtk_widget_set_name (table6, "table6");
574   gtk_widget_show (table6);
575   gtk_container_add (GTK_CONTAINER (alignment49), table6);
576   gtk_table_set_row_spacings (GTK_TABLE (table6), 6);
577   gtk_table_set_col_spacings (GTK_TABLE (table6), 10);
578 
579   label99 = gtk_label_new (_("Description of the driver :"));
580   gtk_widget_set_name (label99, "label99");
581   gtk_widget_show (label99);
582   gtk_table_attach (GTK_TABLE (table6), label99, 0, 1, 0, 1,
583                     (GtkAttachOptions) (GTK_FILL),
584                     (GtkAttachOptions) (0), 0, 0);
585   gtk_misc_set_alignment (GTK_MISC (label99), 0, 0.5);
586 
587   label100 = gtk_label_new (_("            Driver file name :"));
588   gtk_widget_set_name (label100, "label100");
589   gtk_widget_show (label100);
590   gtk_table_attach (GTK_TABLE (table6), label100, 0, 1, 1, 2,
591                     (GtkAttachOptions) (GTK_FILL),
592                     (GtkAttachOptions) (0), 0, 0);
593   gtk_label_set_justify (GTK_LABEL (label100), GTK_JUSTIFY_RIGHT);
594   gtk_misc_set_alignment (GTK_MISC (label100), 0, 0.5);
595 
596   label101 = gtk_label_new (_("            Setup file name :"));
597   gtk_widget_set_name (label101, "label101");
598   gtk_widget_show (label101);
599   gtk_table_attach (GTK_TABLE (table6), label101, 0, 1, 2, 3,
600                     (GtkAttachOptions) (GTK_FILL),
601                     (GtkAttachOptions) (0), 0, 0);
602   gtk_label_set_justify (GTK_LABEL (label101), GTK_JUSTIFY_RIGHT);
603   gtk_misc_set_alignment (GTK_MISC (label101), 0, 0.5);
604 
605   t_name = gtk_entry_new ();
606   gtk_widget_set_name (t_name, "t_name");
607   gtk_widget_show (t_name);
608   gtk_table_attach (GTK_TABLE (table6), t_name, 1, 2, 0, 1,
609                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
610                     (GtkAttachOptions) (0), 0, 0);
611 
612   t_driver = gtk_entry_new ();
613   gtk_widget_set_name (t_driver, "t_driver");
614   gtk_widget_show (t_driver);
615   gtk_table_attach (GTK_TABLE (table6), t_driver, 1, 2, 1, 2,
616                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
617                     (GtkAttachOptions) (0), 0, 0);
618 
619   t_setup = gtk_entry_new ();
620   gtk_widget_set_name (t_setup, "t_setup");
621   gtk_widget_show (t_setup);
622   gtk_table_attach (GTK_TABLE (table6), t_setup, 1, 2, 2, 3,
623                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
624                     (GtkAttachOptions) (0), 0, 0);
625 
626   b_browse = gtk_button_new_with_mnemonic (_("Browse . . ."));
627   gtk_widget_set_name (b_browse, "b_browse");
628   gtk_widget_show (b_browse);
629   gtk_table_attach (GTK_TABLE (table6), b_browse, 2, 3, 1, 2,
630                     (GtkAttachOptions) (GTK_FILL),
631                     (GtkAttachOptions) (0), 0, 0);
632 
633   b_browse1 = gtk_button_new_with_mnemonic (_("  Browse . . . "));
634   gtk_widget_set_name (b_browse1, "b_browse1");
635   gtk_widget_show (b_browse1);
636   gtk_table_attach (GTK_TABLE (table6), b_browse1, 2, 3, 2, 3,
637                     (GtkAttachOptions) (GTK_FILL),
638                     (GtkAttachOptions) (0), 0, 0);
639 
640   frame58 = gtk_frame_new (NULL);
641   gtk_widget_set_name (frame58, "frame58");
642   gtk_widget_show (frame58);
643   gtk_box_pack_start (GTK_BOX (vbox26), frame58, TRUE, TRUE, 0);
644   gtk_widget_set_size_request (frame58, -1, 220);
645   gtk_frame_set_shadow_type (GTK_FRAME (frame58), GTK_SHADOW_NONE);
646 
647   alignment50 = gtk_alignment_new (0.5, 0.5, 1, 1);
648   gtk_widget_set_name (alignment50, "alignment50");
649   gtk_widget_show (alignment50);
650   gtk_container_add (GTK_CONTAINER (frame58), alignment50);
651   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment50), 0, 0, 4, 4);
652 
653   scrolledwindow16 = gtk_scrolled_window_new (NULL, NULL);
654   gtk_widget_set_name (scrolledwindow16, "scrolledwindow16");
655   gtk_widget_show (scrolledwindow16);
656   gtk_container_add (GTK_CONTAINER (alignment50), scrolledwindow16);
657   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow16), GTK_SHADOW_IN);
658 
659   clist1 = gtk_clist_new (2);
660   gtk_widget_set_name (clist1, "clist1");
661   gtk_widget_show (clist1);
662   gtk_container_add (GTK_CONTAINER (scrolledwindow16), clist1);
663   gtk_clist_set_column_width (GTK_CLIST (clist1), 0, 134);
664   gtk_clist_set_column_width (GTK_CLIST (clist1), 1, 80);
665   gtk_clist_column_titles_show (GTK_CLIST (clist1));
666 
667   label97 = gtk_label_new (_("Keyword"));
668   gtk_widget_set_name (label97, "label97");
669   gtk_widget_show (label97);
670   gtk_clist_set_column_widget (GTK_CLIST (clist1), 0, label97);
671   gtk_widget_set_size_request (label97, 134, -1);
672 
673   label98 = gtk_label_new (_("Value"));
674   gtk_widget_set_name (label98, "label98");
675   gtk_widget_show (label98);
676   gtk_clist_set_column_widget (GTK_CLIST (clist1), 1, label98);
677   gtk_widget_set_size_request (label98, 80, -1);
678 
679   frame59 = gtk_frame_new (NULL);
680   gtk_widget_set_name (frame59, "frame59");
681   gtk_widget_show (frame59);
682   gtk_box_pack_start (GTK_BOX (vbox26), frame59, FALSE, TRUE, 0);
683   gtk_frame_set_shadow_type (GTK_FRAME (frame59), GTK_SHADOW_NONE);
684 
685   alignment51 = gtk_alignment_new (0.5, 0.5, 1, 1);
686   gtk_widget_set_name (alignment51, "alignment51");
687   gtk_widget_show (alignment51);
688   gtk_container_add (GTK_CONTAINER (frame59), alignment51);
689   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment51), 10, 10, 4, 4);
690 
691   table7 = gtk_table_new (2, 3, FALSE);
692   gtk_widget_set_name (table7, "table7");
693   gtk_widget_show (table7);
694   gtk_container_add (GTK_CONTAINER (alignment51), table7);
695   gtk_table_set_row_spacings (GTK_TABLE (table7), 6);
696   gtk_table_set_col_spacings (GTK_TABLE (table7), 10);
697 
698   label102 = gtk_label_new (_("Keyword :"));
699   gtk_widget_set_name (label102, "label102");
700   gtk_widget_show (label102);
701   gtk_table_attach (GTK_TABLE (table7), label102, 0, 1, 0, 1,
702                     (GtkAttachOptions) (GTK_FILL),
703                     (GtkAttachOptions) (0), 0, 0);
704   gtk_misc_set_alignment (GTK_MISC (label102), 0, 0.5);
705 
706   label103 = gtk_label_new (_("    Value :"));
707   gtk_widget_set_name (label103, "label103");
708   gtk_widget_show (label103);
709   gtk_table_attach (GTK_TABLE (table7), label103, 0, 1, 1, 2,
710                     (GtkAttachOptions) (GTK_FILL),
711                     (GtkAttachOptions) (0), 0, 0);
712   gtk_misc_set_alignment (GTK_MISC (label103), 0, 0.5);
713 
714   t_keyword = gtk_entry_new ();
715   gtk_widget_set_name (t_keyword, "t_keyword");
716   gtk_widget_show (t_keyword);
717   gtk_table_attach (GTK_TABLE (table7), t_keyword, 1, 2, 0, 1,
718                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
719                     (GtkAttachOptions) (0), 0, 0);
720 
721   t_value = gtk_entry_new ();
722   gtk_widget_set_name (t_value, "t_value");
723   gtk_widget_show (t_value);
724   gtk_table_attach (GTK_TABLE (table7), t_value, 1, 2, 1, 2,
725                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
726                     (GtkAttachOptions) (0), 0, 0);
727 
728   b_add = gtk_button_new_from_stock ("gtk-add");
729   gtk_widget_set_name (b_add, "b_add");
730   gtk_widget_show (b_add);
731   gtk_table_attach (GTK_TABLE (table7), b_add, 2, 3, 0, 1,
732                     (GtkAttachOptions) (GTK_FILL),
733                     (GtkAttachOptions) (0), 0, 0);
734 
735   b_update = gtk_button_new_with_mnemonic (_("_Update"));
736   gtk_widget_set_name (b_update, "b_update");
737   gtk_widget_show (b_update);
738   gtk_table_attach (GTK_TABLE (table7), b_update, 2, 3, 1, 2,
739                     (GtkAttachOptions) (GTK_FILL),
740                     (GtkAttachOptions) (0), 0, 0);
741 
742   dialog_action_area6 = GTK_DIALOG (driversetup)->action_area;
743   gtk_widget_set_name (dialog_action_area6, "dialog_action_area6");
744   gtk_widget_show (dialog_action_area6);
745   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area6), GTK_BUTTONBOX_END);
746 
747   b_cancel = gtk_button_new_from_stock ("gtk-cancel");
748   gtk_widget_set_name (b_cancel, "b_cancel");
749   gtk_widget_show (b_cancel);
750   gtk_dialog_add_action_widget (GTK_DIALOG (driversetup), b_cancel, GTK_RESPONSE_CANCEL);
751   GTK_WIDGET_SET_FLAGS (b_cancel, GTK_CAN_DEFAULT);
752 
753   b_ok = gtk_button_new_from_stock ("gtk-ok");
754   gtk_widget_set_name (b_ok, "b_ok");
755   gtk_widget_show (b_ok);
756   gtk_dialog_add_action_widget (GTK_DIALOG (driversetup), b_ok, GTK_RESPONSE_OK);
757   GTK_WIDGET_SET_FLAGS (b_ok, GTK_CAN_DEFAULT);
758 
759   /* Store pointers to all widgets, for use by lookup_widget(). */
760   GLADE_HOOKUP_OBJECT_NO_REF (driversetup, driversetup, "driversetup");
761   GLADE_HOOKUP_OBJECT_NO_REF (driversetup, dialog_vbox6, "dialog_vbox6");
762   GLADE_HOOKUP_OBJECT (driversetup, vbox26, "vbox26");
763   GLADE_HOOKUP_OBJECT (driversetup, frame57, "frame57");
764   GLADE_HOOKUP_OBJECT (driversetup, alignment49, "alignment49");
765   GLADE_HOOKUP_OBJECT (driversetup, table6, "table6");
766   GLADE_HOOKUP_OBJECT (driversetup, label99, "label99");
767   GLADE_HOOKUP_OBJECT (driversetup, label100, "label100");
768   GLADE_HOOKUP_OBJECT (driversetup, label101, "label101");
769   GLADE_HOOKUP_OBJECT (driversetup, t_name, "t_name");
770   GLADE_HOOKUP_OBJECT (driversetup, t_driver, "t_driver");
771   GLADE_HOOKUP_OBJECT (driversetup, t_setup, "t_setup");
772   GLADE_HOOKUP_OBJECT (driversetup, b_browse, "b_browse");
773   GLADE_HOOKUP_OBJECT (driversetup, b_browse1, "b_browse1");
774   GLADE_HOOKUP_OBJECT (driversetup, frame58, "frame58");
775   GLADE_HOOKUP_OBJECT (driversetup, alignment50, "alignment50");
776   GLADE_HOOKUP_OBJECT (driversetup, scrolledwindow16, "scrolledwindow16");
777   GLADE_HOOKUP_OBJECT (driversetup, clist1, "clist1");
778   GLADE_HOOKUP_OBJECT (driversetup, label97, "label97");
779   GLADE_HOOKUP_OBJECT (driversetup, label98, "label98");
780   GLADE_HOOKUP_OBJECT (driversetup, frame59, "frame59");
781   GLADE_HOOKUP_OBJECT (driversetup, alignment51, "alignment51");
782   GLADE_HOOKUP_OBJECT (driversetup, table7, "table7");
783   GLADE_HOOKUP_OBJECT (driversetup, label102, "label102");
784   GLADE_HOOKUP_OBJECT (driversetup, label103, "label103");
785   GLADE_HOOKUP_OBJECT (driversetup, t_keyword, "t_keyword");
786   GLADE_HOOKUP_OBJECT (driversetup, t_value, "t_value");
787   GLADE_HOOKUP_OBJECT (driversetup, b_add, "b_add");
788   GLADE_HOOKUP_OBJECT (driversetup, b_update, "b_update");
789   GLADE_HOOKUP_OBJECT_NO_REF (driversetup, dialog_action_area6, "dialog_action_area6");
790   GLADE_HOOKUP_OBJECT (driversetup, b_cancel, "b_cancel");
791   GLADE_HOOKUP_OBJECT (driversetup, b_ok, "b_ok");
792 
793   /* Ok button events */
794   gtk_signal_connect (GTK_OBJECT (b_ok), "clicked",
795       GTK_SIGNAL_FUNC (driversetup_ok_clicked), &driversetup_t);
796   /* Cancel button events */
797   gtk_signal_connect (GTK_OBJECT (b_cancel), "clicked",
798       GTK_SIGNAL_FUNC (driversetup_cancel_clicked), &driversetup_t);
799   /* Add button events */
800   gtk_signal_connect (GTK_OBJECT (b_add), "clicked",
801       GTK_SIGNAL_FUNC (driversetup_add_clicked), &driversetup_t);
802   /* Update button events */
803   gtk_signal_connect (GTK_OBJECT (b_update), "clicked",
804       GTK_SIGNAL_FUNC (driversetup_update_clicked), &driversetup_t);
805   /* Close window button events */
806   gtk_signal_connect (GTK_OBJECT (driversetup), "delete_event",
807       GTK_SIGNAL_FUNC (delete_event), &driversetup_t);
808   gtk_signal_connect (GTK_OBJECT (driversetup), "destroy",
809       GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
810   /* List events */
811   gtk_signal_connect (GTK_OBJECT (clist1), "select_row",
812       GTK_SIGNAL_FUNC (driversetup_list_select), &driversetup_t);
813   gtk_signal_connect (GTK_OBJECT (clist1), "unselect_row",
814       GTK_SIGNAL_FUNC (driversetup_list_unselect), &driversetup_t);
815   /* Browse button events */
816   gtk_signal_connect (GTK_OBJECT (b_browse), "clicked",
817       GTK_SIGNAL_FUNC (driversetup_browsedriver_clicked), &driversetup_t);
818   gtk_signal_connect (GTK_OBJECT (b_browse1), "clicked",
819       GTK_SIGNAL_FUNC (driversetup_browsesetup_clicked), &driversetup_t);
820 
821   driversetup_t.name_entry = t_name;
822   driversetup_t.driver_entry = t_driver;
823   driversetup_t.key_list = clist1;
824   driversetup_t.bupdate = b_update;
825   driversetup_t.key_entry = t_keyword;
826   driversetup_t.value_entry = t_value;
827   driversetup_t.mainwnd = driversetup;
828   driversetup_t.setup_entry = t_setup;
829 
830   /* Parse the attributes line */
831   parse_attribute_line (&driversetup_t, driver, attrs, add);
832 
833   gtk_widget_show_all (driversetup);
834   gtk_main ();
835 
836   return driversetup_t.connstr;
837 }
838