Logo Search packages:      
Sourcecode: gamgi version File versions  Download package

gamgi_mesa_select.c

/*******************************************
 *
 * $GAMGI/src/mesa/gamgi_mesa_select.c
 *
 * Copyright (C) 2001, 2004 Carlos Pereira
 *
 * Distributed under the terms of the GNU
 * General Public License: $GAMGI/LICENSE
 *
 */

#include "gamgi_engine.h"
#include "gamgi_gtk.h"
#include "gamgi_global.h"

#include "gamgi_engine_list.h"
#include "gamgi_engine_count.h"
#include "gamgi_gtk_dialog.h"
#include "gamgi_gtk_object.h"
#include "gamgi_gtk_text_create.h"
#include "gamgi_gtk_text_copy.h"
#include "gamgi_gtk_text_select.h"
#include "gamgi_gtk_text_link.h"
#include "gamgi_gtk_text_modify.h"
#include "gamgi_gtk_text_remove.h"
#include "gamgi_gtk_bond_create.h"
#include "gamgi_gtk_bond_select.h"
#include "gamgi_gtk_bond_link.h"
#include "gamgi_gtk_bond_modify.h"
#include "gamgi_gtk_bond_remove.h"
#include "gamgi_gtk_atom_create.h"
#include "gamgi_gtk_atom_copy.h"
#include "gamgi_gtk_atom_select.h"
#include "gamgi_gtk_atom_link.h"
#include "gamgi_gtk_atom_modify.h"
#include "gamgi_gtk_atom_measure.h"
#include "gamgi_gtk_atom_remove.h"
#include "gamgi_gtk_direction_create.h"
#include "gamgi_gtk_direction_select.h"
#include "gamgi_gtk_direction_link.h"
#include "gamgi_gtk_direction_modify.h"
#include "gamgi_gtk_direction_measure.h"
#include "gamgi_gtk_direction_remove.h"
#include "gamgi_gtk_plane_create.h"
#include "gamgi_gtk_plane_select.h"
#include "gamgi_gtk_plane_link.h"
#include "gamgi_gtk_plane_modify.h"
#include "gamgi_gtk_plane_measure.h"
#include "gamgi_gtk_plane_remove.h"
#include "gamgi_gtk_group_copy.h"
#include "gamgi_gtk_group_select.h"
#include "gamgi_gtk_group_link.h"
#include "gamgi_gtk_group_modify.h"
#include "gamgi_gtk_group_measure.h"
#include "gamgi_gtk_group_remove.h"
#include "gamgi_gtk_molecule_copy.h"
#include "gamgi_gtk_molecule_select.h"
#include "gamgi_gtk_molecule_link.h"
#include "gamgi_gtk_molecule_measure.h"
#include "gamgi_gtk_molecule_remove.h"
#include "gamgi_gtk_cluster_copy.h"
#include "gamgi_gtk_cluster_select.h"
#include "gamgi_gtk_cluster_link.h"
#include "gamgi_gtk_cluster_measure.h"
#include "gamgi_gtk_cluster_remove.h"
#include "gamgi_gtk_cell_create.h"
#include "gamgi_gtk_cell_copy.h"
#include "gamgi_gtk_cell_select.h"
#include "gamgi_gtk_cell_modify.h"
#include "gamgi_gtk_cell_link.h"
#include "gamgi_gtk_cell_measure.h"
#include "gamgi_gtk_cell_remove.h"
#include "gamgi_gtk_assembly_copy.h"
#include "gamgi_gtk_assembly_select.h"
#include "gamgi_gtk_assembly_link.h"
#include "gamgi_gtk_assembly_remove.h"
#include "gamgi_gtk_light_copy.h"
#include "gamgi_gtk_light_modify.h"
#include "gamgi_gtk_light_select.h"
#include "gamgi_gtk_light_link.h"
#include "gamgi_gtk_light_remove.h"
#include "gamgi_gtk_layer_copy.h"
#include "gamgi_gtk_layer_modify.h"
#include "gamgi_gtk_layer_select.h"
#include "gamgi_gtk_layer_link.h"
#include "gamgi_gtk_layer_remove.h"
#include "gamgi_gtk_window_copy.h"
#include "gamgi_gtk_window_select.h"
#include "gamgi_gtk_window_link.h"
#include "gamgi_gtk_window_remove.h"
#include "gamgi_mesa_area.h"
#include "gamgi_mesa_scan.h"

static void static_select (gamgi_object *object, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;

if (object->class == GAMGI_ENGINE_WINDOW)
  {
  window = GAMGI_CAST_WINDOW object;
  gdk_window_raise (window->window->window);
  }

if (object->class == GAMGI_ENGINE_LAYER)
  {
  gamgi_gtk_object_layer_local (GAMGI_CAST_LAYER object, window);
  gtk_widget_queue_draw (window->area);
  }

gamgi_gtk_object_focus_local (object, window);
}

static void static_apply (gamgi_object *object, void *data)
{
gamgi_gtk_dialog_beep ();
(* gamgi->function) (object, data);
}

static gamgi_slist *static_color (gamgi_slist *slist_old, int color_new)
{
gamgi_slist *slist;
int color_old;

slist = slist_old;
while (slist != NULL)
  {
  color_old = GAMGI_POINTER_TO_INT (slist->data);
  if (color_old == color_new) return slist_old;
  slist = slist->next;
  }
slist = gamgi_engine_slist_add_start (slist_old);
slist->data = GAMGI_INT_TO_POINTER (color_new);

return slist;
}

static gamgi_slist *static_pixel (int x, int y)
{
int i, color, n = gamgi->gamgi->tolerance;
int pixels = pow (2*n + 1, 2);
unsigned char *rgb;
gamgi_slist *slist = NULL;
int r1, r0, g1, g0, b1, b0;

/*****************************************************
 * gamgi->r, gamgi->g, gamgi->b represent the number *
 * of missing bits when compared with 8 (True Color) *
 *****************************************************/

r0 = pow (2, gamgi->r);
r1 = pow (2, 8 - gamgi->r);

g0 = pow (2, gamgi->g);
g1 = pow (2, 8 - gamgi->g);

b0 = pow (2, gamgi->b);
b1 = pow (2, 8 - gamgi->b);

/*********************************************************************
 * grab colors for all 2*n+1 pixels in the square going from the     *
 * lower-left corner (x-n, y-n) to the upper-right corner (x+n, y+n) *
 *********************************************************************/

rgb = gamgi_mesa_area_grab (x-n, y-n, 2*n+1, 2*n+1);

i = 0;
do
  {
  /**********************************************************
   * shift color bits to the right and then to the left,    *
   * to replace undefined bits by zeros. For example,       *
   * in a graphic system running 16 color bits per pixel,   *
   * distributed as 5 6 5, [rrrrr???] [gggggg??] [bbbbb???] *
   * would be replaced by [rrrrr000] [gggggg00] [bbbbb000]  *
   **********************************************************/

  rgb[i] = (rgb[i] >> gamgi->r) << gamgi->r;
  rgb[i+1] = (rgb[i+1] >> gamgi->g) << gamgi->g;
  rgb[i+2] = (rgb[i+2] >> gamgi->b) << gamgi->b;

  /**********************************************************************
   * r1,g1,b1 represent the number of color sequences recognized by     *
   * the graphic system. When scanning objects, b changes faster (less  *
   * important channel), then g, and finally r (more important channel) *
   *                                                                    *
   * r0,g0,b0 represent the number of sequences that become equal       *
   * for each channel, as the lower bits are ignored, so to get the     *
   * number of real colors scanned we have to divide by r0,g0,b0        *
   **********************************************************************/

  color = b1 * g1 * rgb[3*i]/r0 + b1 * rgb[3*i+1]/g0 + rgb[3*i+2]/b0;
  if (color != 0) slist = static_color (slist, color);
  }
  while (++i < pixels);

free (rgb);

return slist;
}

static void static_start (void)
{
unsigned char off[3] = {0, 0, 0};

/********************************
 * switch off colors and lights *
 ********************************/

glClearColor (0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3ubv (off);
glDisable (GL_LIGHTING);
glDisable (GL_NORMALIZE);
glDisable (GL_DITHER);
  
/**********************
 * reset object color *
 **********************/

gamgi->rgb[0] = 0; gamgi->rgb[1] = 0; gamgi->rgb[2] = 0;
}

static gamgi_object *static_object (gamgi_window *window, 
int x, int y, int class, gamgi_bool global)
{
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (window->area);
GdkGLContext *glcontext = gtk_widget_get_gl_context (window->area);
gamgi_object **array;
gamgi_object *object;
gamgi_slist *slist;
int index, number = 0;

/*************************************
 * count number of candidate objects *
 *************************************/

if (global == TRUE)
  gamgi_engine_count_window (window, class, &number);
else
  gamgi_engine_count_layer (window->layer, class, &number);
if (number == 0) return NULL;

/*******************************************************
 * allocate array to store candidate objects addresses *
 *******************************************************/

array = (gamgi_object **) malloc (number * sizeof (object));
if (array == NULL) return NULL;

/*********************************************************
 * draw candidate objects in back buffer, each one with  *
 * a different color, and store their addresses in array *
 *********************************************************/

if (gdk_gl_drawable_gl_begin (gldrawable, glcontext) == TRUE)
  {
  static_start ();

  if (global == TRUE)
    gamgi_mesa_scan_window (window, class, array);
  else
    gamgi_mesa_scan_layer (window->layer, window, class, array);

  gdk_gl_drawable_gl_end (gldrawable);
  }

/************************************************
 * grab sampling area and build a list with     *
   all the non-background colors in there,      *
   each one corresponding to a different object *
 *                                              *
 *     a selection is invalid when no object    *
 *        or more than one has been found       *
 ************************************************/

slist = static_pixel (x, y);
if (slist == NULL || slist->next != NULL) object = NULL;
else
  {
  index = GAMGI_POINTER_TO_INT (slist->data);
  object = GAMGI_CAST_OBJECT array[index - 1];
  }

/******************
 * free resources *
 ******************/

free (array);
gamgi_engine_slist_remove_all (slist);

return object;
}

static void static_activate (GtkWidget *widget, void *data)
{
gamgi_object *object;

object = GAMGI_CAST_OBJECT g_object_get_data (G_OBJECT (widget), "object");

static_apply (object, data);
}

static GtkWidget *static_item (GtkWidget *menu,
gamgi_object *object, gamgi_window *window)
{
GtkWidget *item;
char string[GAMGI_ENGINE_STRING];

sprintf (string, "%s %d", object->name, object->number);
item = gtk_menu_item_new_with_label (string);
g_object_set_data (G_OBJECT (item), "object", object);

if (menu == NULL) menu = gtk_menu_new ();
gtk_menu_append (GTK_MENU (menu), item);

g_signal_connect (GTK_OBJECT (item), "activate",
G_CALLBACK (static_activate), window);
gtk_widget_show (item);

return menu;
}

static void static_window (gamgi_window *window, gamgi_window *window_start)
{
GtkWidget *menu = NULL;

do
  {
  menu = static_item (menu, GAMGI_CAST_OBJECT window_start, window);
  } while ((window_start = window_start->next) != NULL);

/********************************
 * list of items cannot be NULL *
 ********************************/

gtk_menu_popup ((GtkMenu *) menu, NULL, NULL, NULL, NULL, 1, 0);
}

static void static_menu (gamgi_window *window, gamgi_dlist *dlist_start)
{
gamgi_dlist *dlist;
GtkWidget *menu = NULL;

for (dlist = dlist_start; dlist != NULL; dlist = dlist->next)
  menu = static_item (menu, GAMGI_CAST_OBJECT dlist->data, window);
  
/*****************************
 * list of items can be NULL *
 *****************************/

if (menu != NULL)
  gtk_menu_popup ((GtkMenu *) menu, NULL, NULL, NULL, NULL, 1, 0);
}

static void static_light (gamgi_window *window, gamgi_bool global)
{
gamgi_layer *layer;
gamgi_object *object;
gamgi_dlist *dlist_w, *dlist_l;
GtkWidget *menu = NULL;

if (global == FALSE)
  { static_menu (window, window->layer->light_start); return; }

for (dlist_w = window->layer_start; dlist_w != NULL; dlist_w = dlist_w->next)
  {
  layer = GAMGI_CAST_LAYER dlist_w->data;
  for (dlist_l = layer->light_start; dlist_l != NULL; dlist_l = dlist_l->next)
    {
    object = GAMGI_CAST_OBJECT dlist_l->data;
    menu = static_item (menu, object, window);
    }
  }

/*****************************
 * list of items can be NULL *
 *****************************/

if (menu != NULL)
  gtk_menu_popup ((GtkMenu *) menu, NULL, NULL, NULL, NULL, 1, 0);
}

static void static_recursive (gamgi_window *window,
int x, int y, int class, gamgi_bool global)
{
gamgi_object *object;
GtkWidget *menu = NULL;

object = static_object (window, x, y, class, global);
if (object == NULL) return;

if (object->object->class != class)
  { static_apply (object, window); return; }

do
  {
  menu = static_item (menu, object, window);
  object = object->object;
  } while (object->class == class);

/********************************
 * list of items cannot be NULL *
 ********************************/

gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, 0);
}

gamgi_window *gamgi_mesa_select_window (void)
{
gamgi_window *window;

/*********************************************************
 * Search for top window with active task dialog:        *
 * Only one task dialog can be active in Gamgi at        *
 * any time, called from any window (the window_dialog). *
 *********************************************************/

for (window = gamgi->window_start; window != NULL; window = window->next)
  if (window->action != FALSE) return window;

return NULL;
}

gamgi_bool gamgi_mesa_select_action (gamgi_window *window_mouse, int x, int y)
{
gamgi_window *window_dialog;

/*************************************************
 * search for top window with active task dialog *
 *************************************************/

window_dialog = gamgi_mesa_select_window ();
if (window_dialog == NULL) return FALSE;
gamgi->window_dialog = window_dialog;

switch (window_dialog->action)
  {
  /******************************************************
   * list of all dialog tasks with mouse press activity *
   ******************************************************/

  case GAMGI_GTK_TEXT_CREATE:
  gamgi_gtk_text_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_TEXT_COPY:
  gamgi_gtk_text_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_TEXT_SELECT:
  gamgi_gtk_text_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_TEXT_LINK:
  gamgi_gtk_text_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_TEXT_MODIFY:
  gamgi_gtk_text_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_TEXT_REMOVE:
  gamgi_gtk_text_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_BOND_CREATE:
  gamgi_gtk_bond_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_BOND_SELECT:
  gamgi_gtk_bond_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_BOND_LINK:
  gamgi_gtk_bond_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_BOND_MODIFY:
  gamgi_gtk_bond_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_BOND_REMOVE:
  gamgi_gtk_bond_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_CREATE:
  gamgi_gtk_atom_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_COPY:
  gamgi_gtk_atom_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_SELECT:
  gamgi_gtk_atom_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_LINK:
  gamgi_gtk_atom_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_MODIFY:
  gamgi_gtk_atom_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_MEASURE:
  gamgi_gtk_atom_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ATOM_REMOVE:
  gamgi_gtk_atom_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_CREATE:
  gamgi_gtk_direction_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_SELECT:
  gamgi_gtk_direction_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_LINK:
  gamgi_gtk_direction_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_MODIFY:
  gamgi_gtk_direction_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_MEASURE:
  gamgi_gtk_direction_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_DIRECTION_REMOVE:
  gamgi_gtk_direction_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_CREATE:
  gamgi_gtk_plane_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_SELECT:
  gamgi_gtk_plane_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_LINK:
  gamgi_gtk_plane_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_MODIFY:
  gamgi_gtk_plane_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_MEASURE:
  gamgi_gtk_plane_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_PLANE_REMOVE:
  gamgi_gtk_plane_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_COPY:
  gamgi_gtk_group_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_SELECT:
  gamgi_gtk_group_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_LINK:
  gamgi_gtk_group_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_MODIFY:
  gamgi_gtk_group_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_MEASURE:
  gamgi_gtk_group_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_GROUP_REMOVE:
  gamgi_gtk_group_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_MOLECULE_COPY:
  gamgi_gtk_molecule_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_MOLECULE_SELECT:
  gamgi_gtk_molecule_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_MOLECULE_LINK:
  gamgi_gtk_molecule_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_MOLECULE_MEASURE:
  gamgi_gtk_molecule_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_MOLECULE_REMOVE:
  gamgi_gtk_molecule_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CLUSTER_COPY:
  gamgi_gtk_cluster_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CLUSTER_SELECT:
  gamgi_gtk_cluster_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CLUSTER_LINK:
  gamgi_gtk_cluster_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CLUSTER_MEASURE:
  gamgi_gtk_cluster_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CLUSTER_REMOVE:
  gamgi_gtk_cluster_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_CREATE:
  gamgi_gtk_cell_create_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_COPY:
  gamgi_gtk_cell_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_SELECT:
  gamgi_gtk_cell_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_MODIFY:
  gamgi_gtk_cell_modify_press (window_mouse, x, y, window_dialog);
  return TRUE; 

  case GAMGI_GTK_CELL_LINK:
  gamgi_gtk_cell_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_MEASURE:
  gamgi_gtk_cell_measure_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_CELL_REMOVE:
  gamgi_gtk_cell_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ASSEMBLY_COPY:
  gamgi_gtk_assembly_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ASSEMBLY_SELECT:
  gamgi_gtk_assembly_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ASSEMBLY_LINK:
  gamgi_gtk_assembly_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_ASSEMBLY_REMOVE:
  gamgi_gtk_assembly_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LIGHT_COPY:
  gamgi_gtk_light_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LIGHT_SELECT:
  gamgi_gtk_light_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LIGHT_LINK:
  gamgi_gtk_light_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LIGHT_MODIFY:
  gamgi_gtk_light_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LIGHT_REMOVE:
  gamgi_gtk_light_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LAYER_COPY:
  gamgi_gtk_layer_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LAYER_SELECT:
  gamgi_gtk_layer_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LAYER_LINK:
  gamgi_gtk_layer_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LAYER_MODIFY:
  gamgi_gtk_layer_modify_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_LAYER_REMOVE:
  gamgi_gtk_layer_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_WINDOW_COPY:
  gamgi_gtk_window_copy_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_WINDOW_SELECT:
  gamgi_gtk_window_select_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_WINDOW_LINK:
  gamgi_gtk_window_link_press (window_mouse, x, y, window_dialog);
  return TRUE;

  case GAMGI_GTK_WINDOW_REMOVE:
  gamgi_gtk_window_remove_press (window_mouse, x, y, window_dialog);
  return TRUE;
  }

return FALSE;
}

void gamgi_mesa_select_old (unsigned char *color)
{
float rgb[4];

glGetFloatv (GL_CURRENT_COLOR, rgb);

color[0] = rgb[0] * 255;
color[1] = rgb[1] * 255;
color[2] = rgb[2] * 255;
}

gamgi_bool gamgi_mesa_select_new (unsigned char *color)
{
unsigned char *rgb = gamgi->rgb;

/************************************************
 * This code works for 16, 24 and 32 rgb color  *
 * bits or even other exotic depth combinations *
 ************************************************/

rgb[2] += 1 << gamgi->b;
if (rgb[2] == 0)
  {
  rgb[1] += 1 << gamgi->g;
  if (rgb[1] == 0)
    {
    rgb[0] += 1 << gamgi->r;
    if (rgb[0] == 0)
      {
      /***********************************************************
       * Error: more than 2**r * 2**g * 2**b objects to select   *
       *                                                         *
       * this is tested before, so GAMGI should never come here  *
       *                                                         *
       * we can remove this rather large limit on the number of  *
       * objects per layer that can be selected, by scanning the *
       * image more than once, and taking down the objects that  *
       * failed each sucessive test until the number of elegible *
       * objects becomes smaller than the number of colors.      *
       ***********************************************************/
       
      return FALSE;
      }
    }
  }

color[0] = rgb[0];
color[1] = rgb[1];
color[2] = rgb[2];

return TRUE;
}

void gamgi_mesa_select_object (gamgi_window *window, int x, int y,
gamgi_enum class, gamgi_bool global, gamgi_function2 function)
{
gamgi_object *object;

/***************************************
 * when no local function is supplied, *
 * normal object selection is assumed  *
 ***************************************/

if (function == NULL)
  gamgi->function = static_select;
else
  gamgi->function = function;

/*************************************
 * select object using a combination *
 * of rendering and menu techniques  *
 *************************************/

switch (class)
  {
  case GAMGI_ENGINE_GAMGI: 
  break;

  case GAMGI_ENGINE_WINDOW: 
  static_window (window, gamgi->window_start);
  break;

  case GAMGI_ENGINE_LAYER: 
  static_menu (window, window->layer_start);
  break;

  case GAMGI_ENGINE_LIGHT:
  static_light (window, global);
  break;
  
  case GAMGI_ENGINE_ASSEMBLY: case GAMGI_ENGINE_CLUSTER:
  case GAMGI_ENGINE_GROUP: case GAMGI_ENGINE_TEXT:
  static_recursive (window, x, y, class, global);
  break;

  default:
  object = static_object (window, x, y, class, global);
  if (object != NULL) static_apply (object, window);
  break;
  }

/**************************
 * reset object selection *
 **************************/

window->selection = FALSE;
}

Generated by  Doxygen 1.6.0   Back to index