Example #1
0
gboolean mouse_xy_movement(GtkWidget *widget, GdkEventMotion *event)
{
	// caught a mouse movement event
	double coordx, coordy;
	gchar *buffer;
	int excode;
	select_t *new_select = select_create();
	select_t *select_added = select_create();
	select_t *select_omitted = select_create();

	if (!fldstate.mouse_selection)
		fldstate.mouse_selection = select_create();
	coordx = event->x;
	coordy = event->y;
	pixel_to_field(&coordx, &coordy);
	if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
	{
		coordx = round(coordx);
		coordy = round(coordy);
	}
	if (fldstate.mouse_clicked == 0x1 && mouse_currentMode == SELECTONE)
	{
		// click drag
		// get what's currently in selection rectangle
		new_select = field_select_in_rectangle(new_select, fldstate.mouse_clickx, fldstate.mouse_clicky,
				coordx, coordy, false);
		// then find what's been added, what's gone
		select_add_multiple(select_added, new_select);
		select_add_multiple(select_omitted, fldstate.mouse_selection);
		select_remove_multiple(select_added, fldstate.mouse_selection);
		select_remove_multiple(select_omitted, new_select);

		// Store new set
		select_clear(fldstate.mouse_selection);
		select_add_multiple(fldstate.mouse_selection, new_select);
		select_update_center(fldstate.mouse_selection);

		// add new dots
		if (event->state == (GDK_BUTTON_PRESS_MASK | GDK_CONTROL_MASK))
		{
			//select_push_all(&pstate.select, &select_added, true);
			//select_add_multiple(&pstate.select, &select_omitted, true);
			select_toggle_multiple(pstate.select, select_added);
			select_toggle_multiple(pstate.select, select_omitted);
		}
		else if (event->state == GDK_BUTTON_PRESS_MASK)
		{
			// normal or shift-clicked
			//select_push_all(&pstate.select, &select_added, false);
			//pstate.select = select_drop_multiple(pstate.select, select_omitted);
			select_add_multiple(pstate.select, select_added);
			// drop ommitted dots
			select_remove_multiple(pstate.select, select_omitted);
		}
	}
	else
		fldstate.mouse_selection = NULL;
	fldstate.mousex = coordx;
	fldstate.mousey = coordy;
	// store mouse event
	excode = fieldrel_convert_xy_to_relation(&coordx, &coordy, &buffer);
	select_added = select_destroy(select_added);
	select_omitted = select_destroy(select_omitted);
	new_select = select_destroy(new_select);
	if (excode == -1)
		return FALSE;


	gtk_statusbar_pop(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(context_id));
	gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(context_id), buffer);
	g_free(buffer);
	dr_canvas_refresh(drill);

	return TRUE;
}
Example #2
0
gboolean mouse_unclicked(GtkWidget *widget, GdkEventButton *event)
{
	// handle un-click events on canvas
	double x, y;
	int index;
	int form_index;
	form_child_t *form2;
	select_t *select = pstate.select;
	select_t *form_select = select_create();
	form_coord_attr_t form_attr;
	//double x1, y1;
	form_child_t *form;
	form = pshow->sets->currset->forms;
	x = event->x;
	y = event->y;
	pixel_to_field(&x, &y);
	if (event->button == 1)
	{
		switch(mouse_currentMode)
		{
			case SELECTONE:
				select_add_multiple_forms(form_select, select);
				// move a performer
				mouse_clickx = x - mouse_clickx;
				mouse_clicky = y - mouse_clicky;
				form = form_find_selected_with_endpoint(form_select, fldstate.mouse_clickx, fldstate.mouse_clicky);
				if (form)
				{
					//select_remove_form(form_select, form->parent->index);
					select_remove_form(form_select, form_child_get_index(form));
				}
				if ((event->state & ~GDK_SHIFT_MASK)== GDK_BUTTON_PRESS_MASK)
				{
					// regular click
					// move dots

					if (!mouse_discarded && form_endpoint_contains_coords(form, fldstate.mouse_clickx, fldstate.mouse_clicky))
					{	
						// move forms
						while (form && form_endpoint_contains_coords(form, fldstate.mouse_clickx, fldstate.mouse_clicky))
						{
							if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
							{
								// Move on a 1-step grid
								//form_move_endpoint_grid(form, fldstate.mouse_clickx, fldstate.mouse_clicky, x, y);
								form_move_endpoint(form, fldstate.mouse_clickx, fldstate.mouse_clicky, x, y, 1.0);
							}
							else
							{
								// move off of the grid
								form_move_endpoint(form, fldstate.mouse_clickx, fldstate.mouse_clicky, x, y, 0.0);
							}
							if ((form2 = form_find_selected_with_endpoint_hole(form_select, x, y)) != NULL)
							{
								// Move dot into endpoint hole
								//select_remove_form(form_select, form2->parent->index);
								select_remove_form(form_select, form_child_get_index(form2));
								form_contains_coords(form2, &form_attr, x, y);
								index = form_attr.formindex;
								//index = form_find_index_with_coords(form2, x, y);
								form_add_index_to_hole_with_coords(form2, index, x, y);
							}
							if ((form = form_find_selected_with_endpoint(form_select, fldstate.mouse_clickx, fldstate.mouse_clicky)) != NULL)
							{
								// remove form from checking
								//select_remove_form(form_select, form->parent->index);
								select_remove_form(form_select, form_child_get_index(form));
							}
						}
						select_update_center(pstate.select);
						dr_canvas_refresh(drill);
					}
					else if ((mouse_clickx != 0 || mouse_clicky != 0) && !mouse_discarded)
					{
						// move a selected dot 
						if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
						{
							//coords_movexy_grid(mouse_clickx, mouse_clicky);
							coords_selected_movexy_grid(pshow->sets->currset->coords, pstate.select, mouse_clickx, mouse_clicky);
						}
						else
						{
							//coords_movexy(mouse_clickx, mouse_clicky);
							coords_selected_movexy(pshow->sets->currset->coords, pstate.select, mouse_clickx, mouse_clicky);
						}
						select_update_center(pstate.select);
						dr_canvas_refresh(drill);
					}
				}
				break;
			case ADDFORM:
				// add a form
				select_head(pstate.select);
				form = form_container_get_form_child(pshow->topforms, select_get_form(pstate.select));
				form_set_endpoint(form, 0, 0, x, y, 0.0);
				form_set_endpoint(form, 0, 0, fldstate.mouse_clickx, fldstate.mouse_clicky, 0.0);
				form_add_to_current_set(form);
				form_update_line(form);
				mouse_currentMode = SELECTONE;
				select_update_center(pstate.select);
				dr_canvas_refresh(drill);
				break;
				
		}
	}
	else if (event->button == 3)
	{
		// right-click
		if ((form_find_with_coords(form_select, pstate.setnum, x, y)))
		{
			select_head(form_select);
			//form = form_find_with_coords(pshow->sets->currset->forms, x, y);
			while ((form_index = select_get_form_advance(form_select)) != -1)
			{
				form = form_container_get_form_child(pshow->topforms, form_index);
				//index = form_find_index_with_coords(form, x, y);
				form_contains_coords(form, &form_attr, x, y);
				index = form_attr.realindex;
				//printf("%i\n", index);
				if (index != -1)
					form_unmanage_dot(form, index);
			}
		}
	}

	fldstate.mouse_clicked = 0;
	select_destroy(form_select);
	dr_canvas_refresh(drill);
	return TRUE;
}
Example #3
0
/* in order to save builtin numbers, create a single socket function with
 * options socket_request(SockOperation,....)  */
xsbBool xsb_socket_request(CTXTdecl)
{
  int ecode = 0;  /* error code for socket ops */
  int timeout_flag;
  SOCKET sock_handle;
  int domain, portnum;
  SOCKADDR_IN socket_addr;
  struct linger sock_linger_opt;
  int rc;
  char *message_buffer = NULL; /* initialized to keep compiler happy */
  UInteger msg_len = 0;	  /* initialized to keep compiler happy */
  char char_read;

  switch (ptoc_int(CTXTc 1)) {
  case SOCKET_ROOT: /* this is the socket() request */
    /* socket_request(SOCKET_ROOT,+domain,-socket_fd,-Error,_,_,_) 
       Currently only AF_INET domain */
    domain = (int)ptoc_int(CTXTc 2); 
    if (!translate_domain(domain, &domain)) {
      return FALSE;
    }
    
    sock_handle = socket(domain, SOCK_STREAM, IPPROTO_TCP);
	
    /* error handling */
    if (BAD_SOCKET(sock_handle)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_REQUEST");
    } else {
      ecode = SOCK_OK;
    }

    ctop_int(CTXTc 3, (SOCKET) sock_handle);
	
    return set_error_code(CTXTc ecode, 4, "SOCKET_REQUEST");

  case SOCKET_BIND:
    /* socket_request(SOCKET_BIND,+domain,+sock_handle,+port,-Error,_,_) 
       Currently only supports AF_INET */
    sock_handle = (SOCKET) ptoc_int(CTXTc 3);
    portnum = (int)ptoc_int(CTXTc 4);
    domain = (int)ptoc_int(CTXTc 2);

    if (!translate_domain(domain, &domain)) {
      return FALSE;
    }
    
    /* Bind server to the agreed upon port number.
    ** See commdef.h for the actual port number. */
    FillWithZeros(socket_addr);
    socket_addr.sin_port = htons((unsigned short)portnum);
    socket_addr.sin_family = AF_INET;
#ifndef WIN_NT
    socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
    
    rc = bind(sock_handle, (PSOCKADDR) &socket_addr, sizeof(socket_addr));
	
    /* error handling */
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_BIND");
    } else
      ecode = SOCK_OK;

    return set_error_code(CTXTc ecode, 5, "SOCKET_BIND");

  case SOCKET_LISTEN: 
    /* socket_request(SOCKET_LISTEN,+sock_handle,+length,-Error,_,_,_) */
    sock_handle = (SOCKET) ptoc_int(CTXTc 2);
    rc = listen(sock_handle, (int)ptoc_int(CTXTc 3));

    /* error handling */
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_LISTEN");
    } else
      ecode = SOCK_OK;

    return set_error_code(CTXTc ecode, 4, "SOCKET_LISTEN");

  case SOCKET_ACCEPT:
    timeout_flag = socket_accept(CTXTc (SOCKET *)&rc, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */ 
      if (BAD_SOCKET(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_ACCEPT");
	sock_handle = rc; /* shut up warning */
      } else {
	sock_handle = rc; /* accept() returns sock_out */
	ecode = SOCK_OK;
      }
	       
      ctop_int(CTXTc 3, (SOCKET) sock_handle);
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_ACCEPT");	  
    }
  case SOCKET_CONNECT: {
    /* socket_request(SOCKET_CONNECT,+domain,+sock_handle,+port,
       +hostname,-Error) */
    timeout_flag = socket_connect(CTXTc &rc, (int)pflags[SYS_TIMER]);

    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 6, "SOCKET_CONNECT");
    } else if (timeout_flag == TIMER_SETUP_ERR) {
      return set_error_code(CTXTc TIMER_SETUP_ERR, 6, "SOCKET_CONNECT");
    } else {
      /* error handling */
      if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_CONNECT");
	/* close, because if connect() fails then socket becomes unusable */
	closesocket(ptoc_int(CTXTc 3));
      } else {
	ecode = SOCK_OK;
      }
      return set_error_code(CTXTc ecode,  6,  "SOCKET_CONNECT");
    }
  }

  case SOCKET_CLOSE: 
    /* socket_request(SOCKET_CLOSE,+sock_handle,-Error,_,_,_,_) */
    
    sock_handle = (SOCKET)ptoc_int(CTXTc 2);
    
    /* error handling */
    rc = closesocket(sock_handle);
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_CLOSE");
    } else
      ecode = SOCK_OK;
    
    return set_error_code(CTXTc ecode, 3, "SOCKET_CLOSE");
    
  case SOCKET_RECV:
    /* socket_request(SOCKET_RECV,+Sockfd, -Msg, -Error,_,_,_) */
    // TODO: consider adding protection against interrupts, EINTR, like
    //       in socket_get0.
    timeout_flag = socket_recv(CTXTc &rc, &message_buffer, &msg_len, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      switch (rc) {
      case SOCK_OK:
	ecode = SOCK_OK;
	break;
      case SOCK_READMSG_FAILED:
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_RECV");
	break;
      case SOCK_READMSG_EOF:
	ecode = SOCK_EOF;
	break;
      case SOCK_HEADER_LEN_MISMATCH:
	ecode = XSB_SOCKET_ERRORCODE;
	break;
      default:
	xsb_abort("XSB bug: [SOCKET_RECV] invalid return code from readmsg");
      }
	       
      if (message_buffer != NULL) {
	/* use message_buffer+XSB_MSG_HEADER_LENGTH because the first
	   XSB_MSG_HEADER_LENGTH bytes are for the message length header */
	ctop_string(CTXTc 3, (char*)message_buffer+XSB_MSG_HEADER_LENGTH);
	mem_dealloc(message_buffer,msg_len,OTHER_SPACE);
      } else {  /* this happens at the end of a file */
	ctop_string(CTXTc 3, (char*)"");
      }
	       
      return set_error_code(CTXTc ecode, 4, "SOCKET_RECV");  
    }
	       
  case SOCKET_SEND:
    /* socket_request(SOCKET_SEND,+Sockfd, +Msg, -Error,_,_,_) */
    timeout_flag = socket_send(CTXTc &rc, (int)pflags[SYS_TIMER]);
    
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_SEND");
      } else {
	ecode = SOCK_OK;
      }
      return set_error_code(CTXTc ecode,  4,  "SOCKET_SEND"); 
    }

  case SOCKET_GET0:
    /* socket_request(SOCKET_GET0,+Sockfd,-C,-Error,_,_,_) */
    message_buffer = &char_read;
    timeout_flag = socket_get0(CTXTc &rc, message_buffer, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /*error handling */ 
      switch (rc) {
      case 1:
	ctop_int(CTXTc 3,(unsigned char)message_buffer[0]);
	ecode = SOCK_OK;
	break;
      case 0:
	ecode = SOCK_EOF;
	break;
      default:
	ctop_int(CTXTc 3,-1);
	perror("SOCKET_GET0");
	ecode = XSB_SOCKET_ERRORCODE;
      }
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_GET0");
    }    
  case SOCKET_PUT:
    /* socket_request(SOCKET_PUT,+Sockfd,+C,-Error_,_,_) */
    timeout_flag = socket_put(CTXTc &rc, (int)pflags[SYS_TIMER]);
	       
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      if (rc == 1) {
	ecode = SOCK_OK;
      } else if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_PUT");
      }
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_PUT");
    }
  case SOCKET_SET_OPTION: {
    /* socket_request(SOCKET_SET_OPTION,+Sockfd,+OptionName,+Value,_,_,_) */
    
    char *option_name = ptoc_string(CTXTc 3);
    
    sock_handle = (SOCKET)ptoc_int(CTXTc 2);

    /* Set the "linger" parameter to a small number of seconds */
    if (0==strcmp(option_name,"linger")) {
      int  linger_time=(int)ptoc_int(CTXTc 4);
      
      if (linger_time < 0) {
	sock_linger_opt.l_onoff = FALSE;
	sock_linger_opt.l_linger = 0;
      } else {
	sock_linger_opt.l_onoff = TRUE;
	sock_linger_opt.l_linger = linger_time;
      }
      
      if (SETSOCKOPT(sock_handle, SOL_SOCKET, SO_LINGER,
		     &sock_linger_opt, sizeof(sock_linger_opt))
	  < 0) {
	xsb_warn(CTXTc "[SOCKET_SET_OPTION] Cannot set socket linger time");
	return FALSE;
      } 
    }else {
      xsb_warn(CTXTc "[SOCKET_SET_OPTION] Invalid option, `%s'", option_name);
      return FALSE;
    }
    
    return TRUE;
  }

  case SOCKET_SET_SELECT:  {  
    /*socket_request(SOCKET_SET_SELECT,+connection_name,
      +R_sockfd,+W_sockfd,+E_sockfd) */
    prolog_term R_sockfd, W_sockfd, E_sockfd;
    int i, connection_count;
    int rmax_fd=0, wmax_fd=0, emax_fd=0; 
    char *connection_name = ptoc_string(CTXTc 2);
    
    /* bind fds to input arguments */
    R_sockfd = reg_term(CTXTc 3);
    W_sockfd = reg_term(CTXTc 4);
    E_sockfd = reg_term(CTXTc 5);	
    
    /* initialize the array of connect_t structure for select call */	
    init_connections(CTXT); 
    
    SYS_MUTEX_LOCK(MUTEX_SOCKETS);
    /* check whether the same connection name exists */
    for (i=0;i<MAXCONNECT;i++) {
      if ((connections[i].empty_flag==FALSE) &&
	  (strcmp(connection_name,connections[i].connection_name)==0)) 	
	xsb_abort("[SOCKET_SET_SELECT] Connection `%s' already exists!",
		  connection_name);
    }
    
    /* check whether there is empty slot left for connection */	
    if ((connection_count=checkslot())<MAXCONNECT) {
      if (connections[connection_count].connection_name == NULL) {
	connections[connection_count].connection_name = connection_name;
	connections[connection_count].empty_flag = FALSE;
	
	/* call the utility function separately to take the fds in */
	list_sockfd(R_sockfd, &connections[connection_count].readset,
		    &rmax_fd, &connections[connection_count].read_fds,
		    &connections[connection_count].sizer);
	list_sockfd(W_sockfd, &connections[connection_count].writeset,
		    &wmax_fd, &connections[connection_count].write_fds,
		    &connections[connection_count].sizew);
	list_sockfd(E_sockfd, &connections[connection_count].exceptionset, 
		    &emax_fd,&connections[connection_count].exception_fds,
		    &connections[connection_count].sizee);
	
	connections[connection_count].maximum_fd =
	  xsb_max(xsb_max(rmax_fd,wmax_fd), emax_fd);
      } else 
	/* if this one is reached, it is probably a bug */
	xsb_abort("[SOCKET_SET_SELECT] All connections are busy!");
    } else
      xsb_abort("[SOCKET_SET_SELECT] Max number of collections exceeded!");
    SYS_MUTEX_UNLOCK(MUTEX_SOCKETS);
    
    return TRUE;
  }
  
  case SOCKET_SELECT: {
    /* socket_request(SOCKET_SELECT,+connection_name, +timeout
       -avail_rsockfds,-avail_wsockfds,
       -avail_esockfds,-ecode)
       Returns 3 prolog_terms for available socket fds */

    prolog_term Avail_rsockfds, Avail_wsockfds, Avail_esockfds;
    prolog_term Avail_rsockfds_tail, Avail_wsockfds_tail, Avail_esockfds_tail;

    int maxfd;
    int i;       /* index for connection_count */
    char *connection_name = ptoc_string(CTXTc 2);
    struct timeval *tv;
    prolog_term timeout_term;
    int timeout =0;
    int connectname_found = FALSE;
    int count=0;			

    SYS_MUTEX_LOCK(MUTEX_SOCKETS);
    /* specify the time out */
    timeout_term = reg_term(CTXTc 3);
    if (isointeger(timeout_term)) {
      timeout = (int)oint_val(timeout_term);
      /* initialize tv */
      tv = (struct timeval *)mem_alloc(sizeof(struct timeval),LEAK_SPACE);
      tv->tv_sec = timeout;
      tv->tv_usec = 0;
    } else
      tv = NULL; /* no timeouts */

    /* initialize the prolog term */ 
    Avail_rsockfds = p2p_new(CTXT);
    Avail_wsockfds = p2p_new(CTXT);
    Avail_esockfds = p2p_new(CTXT); 

    /* bind to output arguments */
    Avail_rsockfds = reg_term(CTXTc 4);
    Avail_wsockfds = reg_term(CTXTc 5);
    Avail_esockfds = reg_term(CTXTc 6);

    Avail_rsockfds_tail = Avail_rsockfds;
    Avail_wsockfds_tail = Avail_wsockfds;
    Avail_esockfds_tail = Avail_esockfds;

    /*
      // This was wrong. Lists are now made inside test_ready()
      c2p_list(CTXTc Avail_rsockfds_tail);
      c2p_list(CTXTc Avail_wsockfds_tail);	
      c2p_list(CTXTc Avail_esockfds_tail); 
    */
    
    for (i=0; i < MAXCONNECT; i++) {
      /* find the matching connection_name to select */
      if(connections[i].empty_flag==FALSE) {
	if (strcmp(connection_name, connections[i].connection_name) == 0) {
	  connectname_found = TRUE;
	  count = i;
	  break;
	} 
      }
    }
    if( i >= MAXCONNECT )  /* if no matching connection_name */
      xsb_abort("[SOCKET_SELECT] connection `%s' doesn't exist",
		connection_name); 
    
    /* compute maxfd for select call */
    maxfd = connections[count].maximum_fd + 1;

    /* FD_SET all sockets */
    set_sockfd( CTXTc count );

    /* test whether the socket fd is available */
    rc = select(maxfd, &connections[count].readset, 
		&connections[count].writeset,
		&connections[count].exceptionset, tv);
    
    /* error handling */	
    if (rc == 0)     /* timed out */
      ecode = TIMEOUT_ERR;
    else if (SOCKET_OP_FAILED(rc)) {
      perror("SOCKET_SELECT");
      ecode = XSB_SOCKET_ERRORCODE;
    } else {      /* no error */
      ecode = SOCK_OK;
	 
      /* call the utility function to return the available socket fds */
      test_ready(CTXTc &Avail_rsockfds_tail, &connections[count].readset,
		 connections[count].read_fds,connections[count].sizer);

      test_ready(CTXTc &Avail_wsockfds_tail, &connections[count].writeset,
		 connections[count].write_fds,connections[count].sizew);

      test_ready(CTXTc &Avail_esockfds_tail,&connections[count].exceptionset,
		 connections[count].exception_fds,connections[count].sizee);
    }
    SYS_MUTEX_UNLOCK(MUTEX_SOCKETS);

    if (tv) mem_dealloc((struct timeval *)tv,sizeof(struct timeval),LEAK_SPACE);
    SQUASH_LINUX_COMPILER_WARN(connectname_found) ; 
    return set_error_code(CTXTc ecode, 7, "SOCKET_SELECT");
  }

  case SOCKET_SELECT_DESTROY:  { 
    /*socket_request(SOCKET_SELECT_DESTROY, +connection_name) */
    char *connection_name = ptoc_string(CTXTc 2);
    select_destroy(CTXTc connection_name);
    return TRUE;
  }

  default:
    xsb_warn(CTXTc "[SOCKET_REQUEST] Invalid socket request %d", (int) ptoc_int(CTXTc 1));
    return FALSE;
  }

  /* This trick would report a bug, if a newly added case
     doesn't have a return clause */
  xsb_bug("SOCKET_REQUEST case %d has no return clause", ptoc_int(CTXTc 1));
}