From 56624afb9d3fe29cc992505ad87153a579c3221b Mon Sep 17 00:00:00 2001 From: edgrif <edgrif> Date: Tue, 18 Nov 2003 10:32:21 +0000 Subject: [PATCH] initial versions --- src/zmapControl/README | 12 ++ src/zmapControl/makefile | 37 ++++ src/zmapControl/zmapControl.c | 322 ++++++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100755 src/zmapControl/README create mode 100755 src/zmapControl/makefile create mode 100755 src/zmapControl/zmapControl.c diff --git a/src/zmapControl/README b/src/zmapControl/README new file mode 100755 index 000000000..edb76b33a --- /dev/null +++ b/src/zmapControl/README @@ -0,0 +1,12 @@ +================================================================================ +ZMapControl + + +This directory contains the code that controls an instance of a "ZMap". A +ZMap is created when a sequence is to be displayed and it includes not only +the ZMap window but also the code to monitor that window and to create and +control threads to retrieve and convert data from servers. + +This code is the interface by which a ZMap is controlled, it is not an executable +in its own right but must be linked in with other code that makes calls to +this code. diff --git a/src/zmapControl/makefile b/src/zmapControl/makefile new file mode 100755 index 000000000..5ae830b54 --- /dev/null +++ b/src/zmapControl/makefile @@ -0,0 +1,37 @@ +# +# Makes the code that creates/manages/destroys an individual ZMap +# + + +# use this as a template.... + +# bootstrap stuff, without these make can't find the files to include which define +# all the macros/rules and dependencies. +# +ROOT_DIRECTORY = .. + +# local macros +CONT_PRIV_HDRS = ZMap_P.h +PUB_HDRS = ZMap.h +CONT_SRC = zmapControl.c +CONT_OBJ = zmapControl.o + + + +# +# These must all be set for the common includes to work. +# Need to include AceConn header. +# +CURRENT_LIB = $(ZMAP_LIB) +CURRENT_OBJ = $(CONT_OBJ) +CURRENT_DEP = $(PUB_HDRS) $(CONT_PRIV_HDRS) +CURRENT_SRC = $(CONT_PRIV_HDRS) $(CONT_SRC) +CURRENT_INC = + +# +# point to common make include file which contains all the rules etc. +# +ROOT_DIRECTORY = .. +MAKE_DIR = $(ROOT_DIRECTORY)/zmapMake +include $(MAKE_DIR)/build.make + diff --git a/src/zmapControl/zmapControl.c b/src/zmapControl/zmapControl.c new file mode 100755 index 000000000..bbd20b53b --- /dev/null +++ b/src/zmapControl/zmapControl.c @@ -0,0 +1,322 @@ +/* File: zmapControl.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap 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. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 17 18:49 2003 (edgrif) + * Created: Thu Jul 24 16:06:44 2003 (edgrif) + * CVS info: $Id: zmapControl.c,v 1.1 2003-11-18 10:32:22 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <gtk/gtk.h> +#include <ZMap_P.h> + + + +static void killGUI(ZMap zmap) ; +static void killZMap(ZMap zmap) ; +static gint idleCB(gpointer cb_data) ; +static void checkConnection(ZMap zmap) ; +static void startConnectionChecking(ZMap zmap) ; +static void stopConnectionChecking(ZMap zmap) ; + + + +/* Trivial at the moment..... */ +ZMap zMapCreate(void *app_data, ZMapCallbackFunc destroy_func) +{ + ZMap zmap = NULL ; + + zmap = g_new(ZMapStruct, sizeof(ZMapStruct)) ; + + zmap->app_data = app_data ; + zmap->destroy_zmap_cb = destroy_func ; + + zmap->state = ZMAP_INIT ; + + return zmap ; +} + + + +/* Create a new zmap with its window and a connection to a database via a thread, + * at this point the ZMap is blank and waiting to be told to load some data. */ +gboolean zMapConnect(ZMap zmap, char *machine, int port, char *sequence) +{ + gboolean result = TRUE ; + + if (result) + { + if (!(zmap->connection = zMapConnCreate(machine, port, sequence))) + result = FALSE ; + } + + /* We should pass in the address of our "idle" function to the window create routine...or + * perhaps we can just set up the idle function here.....better ?? */ + + if (result) + { + /* The destroy_func bit is probably not right...needs to be another window func... */ + if ((zmap->window = zMapWindowCreate(machine, port, sequence, + zmap->destroy_zmap_cb, zmap->app_data))) + { + zmap->state = ZMAP_CONNECTED ; + + } + else + { + /* NOTE, we do a _kill_ here, not a destroy. This just signals the thread to die, it + * will actually die sometime later and be properly cleaned up by code in + * zMapManagerCheckConnections() */ + zMapConnKill(zmap->connection) ; + + result = FALSE ; + } + } + + /* Now set up our idle routine to check the connection. */ + if (result) + { + startConnectionChecking(zmap) ; + } + + + return result ; +} + + +gboolean zMapLoad(ZMap zmap, char *sequence) +{ + gboolean result = TRUE ; + + zMapConnLoadData(zmap->connection) ; + + return result ; +} + + +/* Reset an existing ZMap, this call will: + * + * - leave the ZMap window displayed and hold onto user information such as machine/port + * sequence etc so user does not have to add the data again. + * - Free all ZMap window data that was specific to the view being loaded. + * - Kill the existing server thread and start a new one from scratch. + * + * After this call the ZMap will be ready for the user to try again with the existing + * machine/port/sequence or to enter data for a new sequence etc. + * + * */ +gboolean zMapReset(ZMap zmap) +{ + + /* We need a new windows call to reset the window and blank it. */ + + /* We need to destroy the existing thread connection and start a new one...watch out, + * remember the destroy will be asynchronous..... */ + + return TRUE ; +} + + + +/* Called to kill a zmap window and get the associated thread killed, this latter will be + * asynchronous. */ +gboolean zMapDestroy(ZMap zmap) +{ + stopConnectionChecking(zmap) ; + + killGUI(zmap) ; + + /* NOTE, we do a _kill_ here, not a destroy. This just signals the thread to die, it + * will actually die sometime later and be properly cleaned up by code in + * zMapManagerCheckConnections() */ + zMapConnKill(zmap->connection) ; + + return TRUE ; +} + + + +/* Start and stop our idle function (gets run when the GUI is doing nothing). This routine + * checks the status of the connection to the server. */ +static void startConnectionChecking(ZMap zmap) +{ + zmap->idle_handle = gtk_idle_add(idleCB, (gpointer)zmap) ; + + return ; +} + +static void stopConnectionChecking(ZMap zmap) +{ + gtk_idle_remove(zmap->idle_handle) ; + + return ; +} + + + +/* This is really the guts of the code to check what a connection thread is up + * to. Every time the GUI thread has stopped doing things this routine gets called + * so then we check our connection for action..... */ +static gint idleCB(gpointer cb_data) +{ + ZMap zmap = (ZMap)cb_data ; + + checkConnection(zmap) ; + + return 1 ; /* > 0 tells gtk to keep calling idleCB */ +} + + + + +/* This function checks the status of the connection and checks for any reply and + * then acts on it. + * + * NOTE that you cannot use a condvar here, if the connection thread signals us using a + * condvar we will probably miss it, that just doesn't work, we have to pole for changes + * and this is possible because this routine is called from the idle function of the GUI. + * */ +static void checkConnection(ZMap zmap) +{ + ZMapThreadReply reply ; + + if (zmap->connection) + { + gboolean got_value ; + void *data = NULL ; + char *err_msg = NULL ; + +#ifdef ED_G_NEVER_INCLUDE_THIS_CODE + ZMAP_DEBUG(("GUI: checking connection for thread %x\n", + zMapConnGetThreadid(zmap->connection))) ; +#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */ + + data = NULL ; + if (!(got_value = zMapConnGetReplyWithData(zmap->connection, &reply, &data, &err_msg))) + { + printf("GUI: thread state locked, cannot access it....\n") ; + } + else + { + +#ifdef ED_G_NEVER_INCLUDE_THIS_CODE + ZMAP_DEBUG(("GUI: got state for thread %x, state = %s\n", + zMapConnGetThreadid(zmap->connection), + zmapVarGetStringState(reply))) ; +#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */ + + + if (reply == ZMAP_REPLY_WAIT) + { + ; /* nothing to do. */ + } + else if (reply == ZMAP_REPLY_GOTDATA) + { + ZMAP_DEBUG(("GUI: got data for thread %x\n", + zMapConnGetThreadid(zmap->connection))) ; + + zMapConnSetReply(zmap->connection, ZMAP_REPLY_WAIT) ; + + /* Signal the ZMap that there is work to be done. */ + zMapWindowSignalData(zmap->window, data) ; + } + else if (reply == ZMAP_REPLY_DIED) + { + /* This means the thread has failed for some reason and we should clean up. */ + ZMAP_DEBUG(("GUI: thread %x has died so cleaning up....\n", + zMapConnGetThreadid(zmap->connection))) ; + + if (err_msg && *err_msg) + zmapGUIShowMsg(err_msg) ; + + killZMap(zmap) ; + } + else if (reply == ZMAP_REPLY_CANCELLED) + { + /* This means the thread was cancelled so we should clean up..... */ + ZMAP_DEBUG(("GUI: thread %x has been cancelled so cleaning up....\n", + zMapConnGetThreadid(zmap->connection))) ; + + killZMap(zmap) ; + } + } + } + + return ; +} + + + + + +/* + * ------------------- Internal functions ------------------- + */ + +/* SOME ORDER ISSUES NEED TO BE ATTENDED TO HERE...WHEN SHOULD THE IDLE ROUTINE BE REMOVED ? */ + + +/* Calls the control window callback to remove any reference to the zmap and then destroys + * the actual zmap itself. + * + * The window pointer must be null'd because this prevents us trying to doubly destroy + * the window when a thread is killed but only signals its own destruction some time + * later. + * */ +static void killGUI(ZMap zmap) +{ + + /* is this the correct order...better if the window disappears first probably ?? */ + + (*(zmap->destroy_zmap_cb))(zmap, zmap->app_data) ; + + zMapWindowDestroy(zmap->window) ; + zmap->window = NULL ; + + return ; +} + + + +/* destroys the window if this has not happened yet and then destroys the slave thread + * control block. + */ +static void killZMap(ZMap zmap) +{ + stopConnectionChecking(zmap) ; + + if (zmap->window != NULL) + { + killGUI(zmap) ; + } + + zMapConnDestroy(zmap->connection) ; + + return ; +} + + -- GitLab