/*
   ColorSelect.c : Color selection dialog window.
   Copyright (C) 1999 Jean-Hugues Deschenes.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   History : 
      JH.D., 10/08/1999, initial typing
  
   Note : The current version of this toolkit is for linux 2.2.0.
*/

#include "ColorSelect.h"
#include <X11/Xlib.h>

const gchar*  gGCItemData = "GC Item Data";
const gchar*  gRadioItemData = "Radio Item Data";

/**********************************************************************************/
/********************** Color Selelection internal functions **********************/
/**********************************************************************************/
void CSI_gdk_query_color (GdkColormap* colormap, GdkColor* colordef)
{
  GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
  XColor *xcolordef;
  
  g_return_if_fail (colormap != NULL);
  g_return_if_fail (colordef != NULL);
  
  xcolordef = g_new(XColor, 1);
  xcolordef->pixel = colordef->pixel;

  XQueryColor (private->xdisplay, private->xcolormap, xcolordef);

  colordef->red = xcolordef->red;
  colordef->green = xcolordef->green;
  colordef->blue = xcolordef->blue;

  g_free(xcolordef);

}

/**********************************************************************************/
/************************ Color Selection Dialog Callbacks ************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSDCBDestroy(GtkButton* button, gpointer pmData)
{
  colorSelectWindow*  pCSWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pCSWin = (colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    }

  /* Destroy the window */
  gtk_widget_destroy(pCSWin->ColorSelectDialog);

  /* Remove the reference to the old dialog */
  pCSWin->ColorSelectDialog = NULL;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSDCBChanged(GtkButton* button, gpointer pmData)
{
  colorSelectWindow*  pCSWin;      /* The window for whom this was called */
  gdouble             NewColor[4]; /* The new color */
  GdkColor            NewGdkColor; /* The GdkColor equivalent of NewColor */

  /* Do we have anything meaningfull */
  if((pCSWin = (colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    }

  /* Get the new color from the color selection window */
  gtk_color_selection_get_color(
           GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->colorsel),
	   NewColor);

  /* Stuff the new color in the required structure */
  NewGdkColor.red   = NewColor[0] * 0xffff;
  NewGdkColor.green = NewColor[1] * 0xffff;
  NewGdkColor.blue  = NewColor[2] * 0xffff;

  /* Allocate the new color in the colormap */
  gdk_color_alloc(gdk_colormap_get_system(), &NewGdkColor);

  /* Set the new color in the Active GdkGC */
  gdk_gc_set_foreground(pCSWin->ActiveGC, &NewGdkColor);

  /* Destroy the window */
  gtk_widget_destroy(pCSWin->ColorSelectDialog);

  /* Remove the reference to the old dialog */
  pCSWin->ColorSelectDialog = NULL;

  /* Refresh the color selection button */
  gdk_draw_rectangle (pCSWin->ColorDisplay->window,
		      pCSWin->ActiveGC,
		      TRUE,
		      0, 0,
		      pCSWin->ColorDisplay->allocation.width,
		      pCSWin->ColorDisplay->allocation.height);

}

/**********************************************************************************/
/**************************** Signal handling functions ***************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description : Redraws the screen using selected GC
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
static gint
CSSHExposeEvent (GtkWidget *widget, GdkEventExpose *event, colorSelectWindow *pCSWin)
{
  /* Has an item been selected for configuration? */
  if(pCSWin->ActiveGC != NULL)
    gdk_draw_rectangle (widget->window,
			pCSWin->ActiveGC,
			TRUE,
			0, 0,
			widget->allocation.width,
			widget->allocation.height);

  return FALSE;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
gint CSSHDeleteEvent(GtkWidget* pmWidget, GdkEvent* pmEvent, gpointer pmData)
{
  /* Close it */
  return(FALSE);
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSSHDestroy(GtkWidget* pmWidget, gpointer pmData)
{
  colorSelectWindow*  pCSWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */ 
  if((pCSWin =(colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    } 

  /* Call on the cancel callback */ 
  pCSWin->CBCancel(pCSWin->SysView); 
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSSHSelectItem(GtkList* ListBox, GtkWidget* pmWidget, gpointer pmData)
{
  colorSelectWindow*  pCSWin;       /* The window for whom this was called */
  GdkGCValues         TempGCValues; /* Temporary structure so that other line attributes remain intact */

  /* Do we have anything meaningfull */
  if((pCSWin = (colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    }

  /* Set the active GC */
  pCSWin->ActiveGC = (GdkGC*) gtk_object_get_data(GTK_OBJECT (pmWidget), gGCItemData);

  /* Allow use of button */
  gtk_widget_set_sensitive(pCSWin->ColorSelectButton, TRUE);

  /* Allow LineType selection */
  gtk_widget_set_sensitive(pCSWin->LineTypeFrame, TRUE);

  /* Get the current values of the Active GC */
  gdk_gc_get_values(pCSWin->ActiveGC, &TempGCValues);

  /* Display the active GC's linetype using radio buttons */
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pCSWin->LTRadioSolid),
			       (TempGCValues.line_style == GDK_LINE_SOLID));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pCSWin->LTRadioOnOffDash),
			       (TempGCValues.line_style == GDK_LINE_ON_OFF_DASH));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pCSWin->LTRadioDoubleDash),
			       (TempGCValues.line_style == GDK_LINE_DOUBLE_DASH));

  /* Update the Button */
  gdk_draw_rectangle (pCSWin->ColorDisplay->window,
		      pCSWin->ActiveGC,
		      TRUE,
		      0, 0,
		      pCSWin->ColorDisplay->allocation.width,
		      pCSWin->ColorDisplay->allocation.height);

}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSSHSelectLineType(GtkButton* RadioButton, gpointer pmData)
{
  colorSelectWindow*  pCSWin;       /* The window for whom this was called */
  GdkLineStyle        TempLT;       /* The line type gotten from the widget */
  GdkGCValues         TempGCValues; /* Temporary structure so that other line attributes remain intact */

  /* Do we have anything meaningfull */
  if((pCSWin = (colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    }

  /* Get the selected linetype from the RadioButton data */
  TempLT = (GdkLineStyle) gtk_object_get_data(GTK_OBJECT(RadioButton), gRadioItemData);

  /* Get the current values of the Active GC */
  gdk_gc_get_values(pCSWin->ActiveGC, &TempGCValues);

  /* Set the new linetype in the Active GC */
  gdk_gc_set_line_attributes(pCSWin->ActiveGC,
			     TempGCValues.line_width,
			     TempLT,
			     TempGCValues.cap_style,
			     TempGCValues.join_style);
  

}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSSHShowColorDialog(GtkButton* button, gpointer pmData)
{
  colorSelectWindow*  pCSWin;          /* The window for whom this was called */
  GdkGCValues         GCValues;        /* the values of the active GC */
  gdouble             CurrentColor[4]; /* The currently selected color */

  /* Do we have anything meaningful? */
  if((pCSWin = (colorSelectWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Color Selection Window \n");
    exit(1);
    }

  /* If there is alerady a color selection window, it is visible! */
  if(pCSWin->ColorSelectDialog != NULL) return;

  /* get the values from the current GC and query X for them*/
  gdk_gc_get_values((GdkGC*) pCSWin->ActiveGC, &GCValues);
  CSI_gdk_query_color(gdk_colormap_get_system(), &GCValues.foreground);

  /* Stuff the calculated values in the array required by gtk_color_selection_set_color */
  CurrentColor[0] = (gdouble) GCValues.foreground.red / (gdouble) 65535;
  CurrentColor[1] = (gdouble) GCValues.foreground.green / (gdouble) 65535;
  CurrentColor[2] = (gdouble) GCValues.foreground.blue / (gdouble) 65535;
  CurrentColor[3] = 0;  /* give default value for opacity */

  /* Create a new color selection dialog */
  pCSWin->ColorSelectDialog = gtk_color_selection_dialog_new("Select new color");

  /* Disable use of opacity */
  gtk_color_selection_set_opacity(
	    GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->colorsel),
	    FALSE);

  /* Assume a slow machine - update occasionally */
  gtk_color_selection_set_update_policy(
	    GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->colorsel),
	    GTK_UPDATE_DELAYED);

  /* Set the color to the dialog */
  gtk_color_selection_set_color(
	    GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->colorsel),
	    CurrentColor);

  /* Attach signal to destroy window when we're done */
  gtk_signal_connect(
	     GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->cancel_button),
	     "clicked", 
	     GTK_SIGNAL_FUNC(CSDCBDestroy),
	     pCSWin);

  /* Attach signal to update the ActiveGC */
  gtk_signal_connect(
	     GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(pCSWin->ColorSelectDialog)->ok_button),
	     "clicked", 
	     GTK_SIGNAL_FUNC(CSDCBChanged),
	     pCSWin);

 
  /* Display the window */
  gtk_widget_show(GTK_WIDGET(pCSWin->ColorSelectDialog));

}

/**********************************************************************************/
/******************************* Windowing functions ******************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSConnectSignals(colorSelectWindow* pmCSWin)
{
  /* Connect the generic signals */
  gtk_signal_connect(GTK_OBJECT(pmCSWin->Window),
		     "delete_event",
		     GTK_SIGNAL_FUNC(CSSHDeleteEvent),
		     pmCSWin);
  gtk_signal_connect(GTK_OBJECT(pmCSWin->Window),
		     "destroy",
		     GTK_SIGNAL_FUNC(CSSHDestroy),
		     pmCSWin);

  /* Connect the drawing area signal */
  gtk_signal_connect (GTK_OBJECT (pmCSWin->ColorDisplay), "expose_event",
		      (GtkSignalFunc) CSSHExposeEvent, pmCSWin);

  /* Connect the listbox signal */
  gtk_signal_connect (GTK_OBJECT (pmCSWin->ItemsList), "select-child",
		      (GtkSignalFunc) CSSHSelectItem, pmCSWin);

  /* Connect the color selection button */
  gtk_signal_connect(GTK_OBJECT(pmCSWin->ColorSelectButton), "clicked",
		     GTK_SIGNAL_FUNC(CSSHShowColorDialog), pmCSWin);

  /* Connect the Line Type selection radio buttons */
  gtk_signal_connect(GTK_OBJECT(pmCSWin->LTRadioSolid), "toggled",
		     GTK_SIGNAL_FUNC(CSSHSelectLineType), pmCSWin);
  gtk_signal_connect(GTK_OBJECT(pmCSWin->LTRadioOnOffDash), "toggled",
		     GTK_SIGNAL_FUNC(CSSHSelectLineType), pmCSWin);
  gtk_signal_connect(GTK_OBJECT(pmCSWin->LTRadioDoubleDash), "toggled",
		     GTK_SIGNAL_FUNC(CSSHSelectLineType), pmCSWin);

  /* Connect the Ok and Cancel buttons */
  gtk_signal_connect(GTK_OBJECT(pmCSWin->OKButton),
		     "clicked",
		     GTK_SIGNAL_FUNC(pmCSWin->CBOK),
		     pmCSWin);

  gtk_signal_connect_object(GTK_OBJECT(pmCSWin->OKButton),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pmCSWin->Window));

  gtk_signal_connect_object(GTK_OBJECT(pmCSWin->CancelButton),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pmCSWin->Window));
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSShowColorSelectWindow(colorSelectWindow* pmCSWin, eventGraph* pmEGraph)
{
  /* This should never happen */
  if(pmEGraph == NULL)
    {
    g_print("no event graph passed to CSShowColorSelectWindow");
    exit(1);
    }

  /* Make sure no GC is selected */
  pmCSWin->ActiveGC = NULL;

  /* Make OK button default choice */
  gtk_widget_grab_default(pmCSWin->OKButton);

  /* Show it all to the world */
  gtk_widget_show(pmCSWin->VBox);
  gtk_widget_show(pmCSWin->ListHBox);
  gtk_widget_show(pmCSWin->ButtonsHBox);
  gtk_widget_show(pmCSWin->MainTable);
  gtk_widget_show(pmCSWin->ItemsList);
  gtk_widget_show(pmCSWin->ScrolledList);
  gtk_widget_show(pmCSWin->ColorLabel);
  gtk_widget_show(pmCSWin->ColorSelectButton);
  gtk_widget_show(pmCSWin->ColorDisplay);
  gtk_widget_show(pmCSWin->LineTypeFrame);
  gtk_widget_show(pmCSWin->LineTypeVBox);
  gtk_widget_show(pmCSWin->LTRadioSolid);
  gtk_widget_show(pmCSWin->LTRadioOnOffDash);
  gtk_widget_show(pmCSWin->LTRadioDoubleDash);
  gtk_widget_show(pmCSWin->OKButton);
  gtk_widget_show(pmCSWin->CancelButton);

  /* Set title */
  gtk_window_set_title(GTK_WINDOW(pmCSWin->Window), "Select colors");

  /* Display in the center of screen */
  gtk_window_set_position(GTK_WINDOW(pmCSWin->Window), GTK_WIN_POS_CENTER);

  /* Make Color Selection window always visible */
  gtk_window_set_transient_for(GTK_WINDOW(pmCSWin->Window), 
			       GTK_WINDOW(pmCSWin->ParentWin));

  /* Display it */
  gtk_widget_show(pmCSWin->Window);

  if(pmCSWin->BackgroundGC == NULL)
    {
    /* Create the temporary graphic contexts */
    pmCSWin->BackgroundGC = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->HorizonGC    = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->ProcessGC    = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->Process0GC   = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->KernelGC     = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->SelectedGC   = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->SysCallGC    = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->TrapGC       = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->InterruptGC  = gdk_gc_new(pmCSWin->ColorDisplay->window);
    pmCSWin->TextGC       = gdk_gc_new(pmCSWin->ColorDisplay->window);
    }

  /* Give ourselves an equivalent of the EG's GCs */
  gdk_gc_copy(pmCSWin->BackgroundGC, pmEGraph->BackgroundGC);
  gdk_gc_copy(pmCSWin->HorizonGC,    pmEGraph->HorizonGC);
  gdk_gc_copy(pmCSWin->ProcessGC,    pmEGraph->ProcessGC);
  gdk_gc_copy(pmCSWin->Process0GC,   pmEGraph->Process0GC);
  gdk_gc_copy(pmCSWin->KernelGC,     pmEGraph->KernelGC);
  gdk_gc_copy(pmCSWin->SelectedGC,   pmEGraph->SelectedGC);
  gdk_gc_copy(pmCSWin->SysCallGC,    pmEGraph->SysCallGC);
  gdk_gc_copy(pmCSWin->TrapGC,       pmEGraph->TrapGC);
  gdk_gc_copy(pmCSWin->InterruptGC,  pmEGraph->InterruptGC);
  gdk_gc_copy(pmCSWin->TextGC,       pmEGraph->TextGC);


  /* Populate the list */
  CSAddListItems(pmCSWin->ItemsList, "Background",       pmCSWin->BackgroundGC);
  CSAddListItems(pmCSWin->ItemsList, "Horizon",          pmCSWin->HorizonGC);
  CSAddListItems(pmCSWin->ItemsList, "Processes",        pmCSWin->ProcessGC);
#if 0
  CSAddListItems(pmCSWin->ItemsList, "Process 0",        pmCSWin->Process0GC);
#endif
  CSAddListItems(pmCSWin->ItemsList, "Kernel",           pmCSWin->KernelGC);
  CSAddListItems(pmCSWin->ItemsList, "Selected process", pmCSWin->SelectedGC);
  CSAddListItems(pmCSWin->ItemsList, "System call",      pmCSWin->SysCallGC);
  CSAddListItems(pmCSWin->ItemsList, "Trap",             pmCSWin->TrapGC);
  CSAddListItems(pmCSWin->ItemsList, "Interrupts",       pmCSWin->InterruptGC);
  CSAddListItems(pmCSWin->ItemsList, "Text",             pmCSWin->TextGC);
}


/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSAddListItems(GtkWidget* pmCSItemsList, char* pmItemText, GdkGC* AssociatedGC)
{
  GtkWidget* NewItem;

  /* Create the new list item */
  NewItem = gtk_list_item_new_with_label(pmItemText);
  
  /* Insert the list item in the list */
  gtk_container_add (GTK_CONTAINER (pmCSItemsList), NewItem);

  /* Make sure that item is visible */
  gtk_widget_show (NewItem);

  /* Put pointer to process in label */
  gtk_object_set_data(GTK_OBJECT(NewItem), gGCItemData, (gpointer) AssociatedGC);
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
colorSelectWindow* CSCreateColorSelectWindow(gpointer     pmSysView,
					     GtkWidget*   pmParentWin,
					     _CSCBOK*     pmCBOK,
					     _CSCBCancel* pmCBCancel)
{
  colorSelectWindow* pCSWin;          /* Color selection window */

  /* Create a new trace file selection window */
  pCSWin = (colorSelectWindow*) g_malloc(sizeof(colorSelectWindow));

  /* Initialize empty fields */
  pCSWin->ColorSelectDialog = NULL;
  pCSWin->ActiveGC          = NULL;
  pCSWin->BackgroundGC      = NULL;

  /* Put the given data in the right place */
  pCSWin->SysView  = pmSysView;
  pCSWin->ParentWin= pmParentWin;
  pCSWin->CBOK     = pmCBOK;
  pCSWin->CBCancel = pmCBCancel;

  /* Build the window */
  pCSWin->Window = gtk_window_new(GTK_WINDOW_DIALOG);
  pCSWin->VBox   = gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(pCSWin->Window), pCSWin->VBox);

  /* Build HBoxes and pack them */
  pCSWin->ListHBox    = gtk_hbox_new(FALSE, 0);
  pCSWin->ButtonsHBox = gtk_hbox_new(TRUE, 5);
  gtk_box_pack_start(GTK_BOX(pCSWin->VBox), pCSWin->ListHBox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pCSWin->VBox), pCSWin->ButtonsHBox, FALSE, FALSE, 0);

  /* Create list of configurable items and pack it */
  pCSWin->ScrolledList = gtk_scrolled_window_new(NULL, NULL);
  pCSWin->ItemsList    = gtk_list_new();
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pCSWin->ScrolledList),
				 GTK_POLICY_AUTOMATIC,
				 GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pCSWin->ScrolledList),
					pCSWin->ItemsList);
  gtk_widget_set_usize(GTK_WIDGET(pCSWin->ScrolledList), 125, 100);
  gtk_box_pack_start(GTK_BOX(pCSWin->ListHBox), pCSWin->ScrolledList, FALSE, FALSE, 0);

  /* Create packing table and pack it */
  pCSWin->MainTable = gtk_table_new(gCSLayoutHeight, gCSLayoutWidth, TRUE);
  gtk_box_pack_start(GTK_BOX(pCSWin->ListHBox), pCSWin->MainTable, TRUE, TRUE, 0);
  
  /* Create the color selection button and pack it */
  pCSWin->ColorLabel        = gtk_label_new("Color:");
  pCSWin->ColorSelectButton = gtk_button_new();
  pCSWin->ColorDisplay      = gtk_drawing_area_new();
  gtk_label_set_justify(GTK_LABEL(pCSWin->ColorLabel), GTK_JUSTIFY_RIGHT);
  gtk_widget_set_usize(GTK_WIDGET(pCSWin->ColorDisplay), 50, 50);
  gtk_container_add(GTK_CONTAINER(pCSWin->ColorSelectButton), pCSWin->ColorDisplay);
  gtk_widget_set_sensitive(pCSWin->ColorSelectButton, FALSE); /* Disable Color selection button */
  gtk_table_attach_defaults(GTK_TABLE(pCSWin->MainTable), pCSWin->ColorLabel,
			    0, 1,
			    1, 2);
  gtk_table_attach_defaults(GTK_TABLE(pCSWin->MainTable), pCSWin->ColorSelectButton,
			    1, 2,
			    1, 2);

  /* Create Line Type selection Frame and pack it */
  pCSWin->LineTypeFrame      = gtk_frame_new("Line Type :");
  pCSWin->LineTypeVBox       = gtk_vbox_new(FALSE, 3);
  pCSWin->LTRadioBtnGroup    = NULL;   /* initialize the button group */
  pCSWin->LTRadioSolid       = gtk_radio_button_new_with_label(pCSWin->LTRadioBtnGroup, "Solid");
  pCSWin->LTRadioBtnGroup    = gtk_radio_button_group(GTK_RADIO_BUTTON(pCSWin->LTRadioSolid));
  pCSWin->LTRadioOnOffDash   = gtk_radio_button_new_with_label(pCSWin->LTRadioBtnGroup, "On/Off dashed");
  pCSWin->LTRadioBtnGroup    = gtk_radio_button_group(GTK_RADIO_BUTTON(pCSWin->LTRadioOnOffDash));
  pCSWin->LTRadioDoubleDash  = gtk_radio_button_new_with_label(pCSWin->LTRadioBtnGroup, "Double dashed");
  pCSWin->LTRadioBtnGroup    = gtk_radio_button_group(GTK_RADIO_BUTTON(pCSWin->LTRadioDoubleDash));

  gtk_table_attach(GTK_TABLE(pCSWin->MainTable), pCSWin->LineTypeFrame,
		   0, gCSLayoutWidth, 3, gCSLayoutHeight,
		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 5);
  gtk_container_add(GTK_CONTAINER(pCSWin->LineTypeFrame), pCSWin->LineTypeVBox);
  gtk_box_pack_start(GTK_BOX(pCSWin->LineTypeVBox), pCSWin->LTRadioSolid, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pCSWin->LineTypeVBox), pCSWin->LTRadioOnOffDash, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pCSWin->LineTypeVBox), pCSWin->LTRadioDoubleDash, TRUE, TRUE, 0);
  gtk_widget_set_sensitive(pCSWin->LineTypeFrame, FALSE);

  /* Remember which linetype each object configures */
  gtk_object_set_data(GTK_OBJECT(pCSWin->LTRadioSolid), gRadioItemData, (gpointer) GDK_LINE_SOLID);
  gtk_object_set_data(GTK_OBJECT(pCSWin->LTRadioOnOffDash), gRadioItemData, (gpointer) GDK_LINE_ON_OFF_DASH);
  gtk_object_set_data(GTK_OBJECT(pCSWin->LTRadioDoubleDash), gRadioItemData, (gpointer) GDK_LINE_DOUBLE_DASH);

  /* Create OK and cancel buttons and pack them */
  pCSWin->OKButton     = gtk_button_new_with_label("OK");
  pCSWin->CancelButton = gtk_button_new_with_label("Cancel");
  GTK_WIDGET_SET_FLAGS(pCSWin->OKButton, GTK_CAN_DEFAULT);  /* Allow OK button to be default */
  gtk_box_pack_start(GTK_BOX(pCSWin->ButtonsHBox), pCSWin->OKButton, TRUE, TRUE, 2);
  gtk_box_pack_start(GTK_BOX(pCSWin->ButtonsHBox), pCSWin->CancelButton, TRUE, TRUE, 2);

  /* Give it to the caller */
  return pCSWin;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void CSDestroyColorSelectWindow(colorSelectWindow* pmCSWin)
{
  if(pmCSWin != NULL)
    {
    /* destroy the temporary GCs */
    gdk_gc_destroy(pmCSWin->BackgroundGC);
    gdk_gc_destroy(pmCSWin->HorizonGC);
    gdk_gc_destroy(pmCSWin->ProcessGC);
    gdk_gc_destroy(pmCSWin->Process0GC);
    gdk_gc_destroy(pmCSWin->KernelGC);
    gdk_gc_destroy(pmCSWin->SelectedGC);
    gdk_gc_destroy(pmCSWin->SysCallGC);
    gdk_gc_destroy(pmCSWin->TrapGC);
    gdk_gc_destroy(pmCSWin->InterruptGC);
    gdk_gc_destroy(pmCSWin->TextGC);
      
    /* Remove the reference to the first so that it will be reconstructed */
    pmCSWin->BackgroundGC = NULL;

    /* Free space used by structure */
    g_free(pmCSWin);
    }

  return;
}
