diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index 90d40f66fd3c10acbe1aad27daf2c2b508c227fa..0097e47b6d6315e651b225d2737a531d5ff447d5 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -14,7 +14,6 @@
 #include "MElement.h"
 #include "Numeric.h"
 #include "FlGui.h"
-#include "VertexArray.h"
 #include "Context.h"
 
 static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &click2)
@@ -108,9 +107,9 @@ void openglWindow::draw()
 {
   // some drawing routines can create data (STL triangulations, etc.):
   // make sure that we don't fire draw() while we are already drawing,
-  // e.g. due to an impromptu Fl::check(). The same lock is also used in 
-  // _processSelectionBuffer to guarantee that we don't mix GL_RENDER and
-  // GL_SELECT rendering passes.
+  // e.g. due to an impromptu Fl::check(). The same lock is also used
+  // in _select to guarantee that we don't mix GL_RENDER and GL_SELECT
+  // rendering passes.
   if(_lock) return;
   _lock = true;
 
@@ -430,10 +429,9 @@ int openglWindow::handle(int event)
         std::vector<GFace*> faces;
         std::vector<GRegion*> regions;
         std::vector<MElement*> elements;
-        bool res = _processSelectionBuffer(_selection, false, 
-                                           CTX::instance()->mouseHoverMeshes, 
-                                           (int)_curr.win[0], (int)_curr.win[1], 5, 5,
-                                           vertices, edges, faces, regions, elements);
+        bool res = _select(_selection, false, CTX::instance()->mouseHoverMeshes, 
+                           (int)_curr.win[0], (int)_curr.win[1], 5, 5,
+                           vertices, edges, faces, regions, elements);
         if((_selection == ENT_ALL && res) ||
            (_selection == ENT_POINT && vertices.size()) ||
            (_selection == ENT_LINE && edges.size()) || 
@@ -461,220 +459,24 @@ int openglWindow::handle(int event)
   }
 }
 
-class hit{
- public:
-  GLuint type, ient, depth, type2, ient2;
-  hit(GLuint t, GLuint i, GLuint d, GLuint t2=0, GLuint i2=0) 
-    : type(t), ient(i), depth(d), type2(t2), ient2(i2) {}
-};
-
-class hitDepthLessThan{
- public:
-  bool operator()(const hit &h1, const hit &h2) const
-  {
-    return h1.depth < h2.depth;
-  }
-};
-
-// returns the element at a given position in a vertex array (element
-// pointers are not always stored: returning 0 is not an error)
-static MElement *getElement(GEntity *e, int va_type, int index)
+bool openglWindow::_select(int type, bool multiple, bool mesh, 
+                           int x, int y, int w, int h,
+                           std::vector<GVertex*> &vertices,
+                           std::vector<GEdge*> &edges,
+                           std::vector<GFace*> &faces,
+                           std::vector<GRegion*> &regions,
+                           std::vector<MElement*> &elements)
 {
-  switch(va_type){
-  case 2: 
-    if(e->va_lines && index < e->va_lines->getNumElementPointers())
-      return *e->va_lines->getElementPointerArray(index);
-    break;
-  case 3:
-    if(e->va_triangles && index < e->va_triangles->getNumElementPointers())
-      return *e->va_triangles->getElementPointerArray(index);
-    break;
-  }
-  return 0;
-}
-
-bool openglWindow::_processSelectionBuffer(int type, bool multipleSelection,
-                                           bool meshSelection, int x, int y, int w, int h,
-                                           std::vector<GVertex*> &vertices,
-                                           std::vector<GEdge*> &edges,
-                                           std::vector<GFace*> &faces,
-                                           std::vector<GRegion*> &regions,
-                                           std::vector<MElement*> &elements)
-{
-  vertices.clear();
-  edges.clear();
-  faces.clear();
-  regions.clear();
-  elements.clear();
-
-  // In our case the selection buffer size is equal to between 5 and 7
-  // times the maximum number of possible hits
-  GModel *m = GModel::current();
-  int eles = (meshSelection && CTX::instance()->pickElements) ? 
-    4 * m->getNumMeshElements() : 0;
-  int size = 7 * (m->getNumVertices() + m->getNumEdges() + m->getNumFaces() + 
-                  m->getNumRegions() + eles);
-
-  if(!size) return false; // we won't get any hits: the model is empty!
-
-  size += 1000; // security
-
   // same lock as in draw() to prevent firing up a GL_SELECT rendering pass
   // while a GL_RENDER pass is happening (due to the asynchronus nature of
   // Fl::check()s
   if(_lock) return false;
   _lock = true;
-
   make_current();
-  GLuint *selectionBuffer = new GLuint[size];
-  glSelectBuffer(size, selectionBuffer);
-
-  glRenderMode(GL_SELECT);
-  _ctx->render_mode = drawContext::GMSH_SELECT;
-
-  glInitNames();
-  glPushMatrix();
-  _ctx->initProjection(x, y, w, h);
-  _ctx->initPosition();
-  _ctx->drawGeom();
-  if(meshSelection) _ctx->drawMesh();
-  glPopMatrix();
-
-  GLint numhits = glRenderMode(GL_RENDER);
-  _ctx->render_mode = drawContext::GMSH_RENDER;
-
+  bool ret = _ctx->select(type, multiple, mesh, x, y, w, h, 
+                          vertices, edges, faces, regions, elements);
   _lock = false;
-
-  if(!numhits){ // no hits
-    delete [] selectionBuffer;
-    return false;
-  }
-  else if(numhits < 0){ // overflow
-    delete [] selectionBuffer;
-    Msg::Warning("Too many entities selected");
-    return false;
-  }
-
-  std::vector<hit> hits;
-  GLuint *ptr = selectionBuffer;
-  for(int i = 0; i < numhits; i++) {
-    // in Gmsh 'names' should always be 0, 2 or 4:
-    // * names == 0 means that there is nothing on the stack
-    // * if names == 2, the first name is the type of the entity 
-    //   (0 for point, 1 for edge, 2 for face or 3 for volume) and
-    //   the second is the entity number;
-    // * if names == 4, the first name is the type of the entity,
-    //   the second is the entity number, the third is the type
-    //   of vertex array (2 for line, 3 for triangle, 4 for quad)
-    //   and the fourth is the index of the element in the vertex
-    //   array
-    GLuint names = *ptr++; 
-    *ptr++; // mindepth
-    GLuint maxdepth = *ptr++;
-    if(names == 2){
-      GLuint depth = maxdepth;
-      GLuint type = *ptr++; 
-      GLuint ient = *ptr++;
-      hits.push_back(hit(type, ient, depth));
-    }
-    else if(names == 4){
-      GLuint depth = maxdepth;
-      GLuint type = *ptr++; 
-      GLuint ient = *ptr++;
-      GLuint type2 = *ptr++; 
-      GLuint ient2 = *ptr++;
-      hits.push_back(hit(type, ient, depth, type2, ient2));
-    }
-  }
-
-  delete [] selectionBuffer;
-  
-  if(!hits.size()){ // no entities
-    return false;
-  }
-
-  // sort hits to get closest entities first
-  std::sort(hits.begin(), hits.end(), hitDepthLessThan());
-
-  // filter result: if type == ENT_NONE, return the closest entity of
-  // "lowest dimension" (point < line < surface < volume). Otherwise,
-  // return the closest entity of type "type"
-  GLuint typmin = 10;
-  for(unsigned int i = 0; i < hits.size(); i++)
-    typmin = std::min(typmin, hits[i].type);
-
-  for(unsigned int i = 0; i < hits.size(); i++) {
-    if((type == ENT_ALL) ||
-       (type == ENT_NONE && hits[i].type == typmin) ||
-       (type == ENT_POINT && hits[i].type == 0) ||
-       (type == ENT_LINE && hits[i].type == 1) ||
-       (type == ENT_SURFACE && hits[i].type == 2) ||
-       (type == ENT_VOLUME && hits[i].type == 3)){
-      switch (hits[i].type) {
-      case 0:
-        {
-          GVertex *v = m->getVertexByTag(hits[i].ient);
-          if(!v){
-            Msg::Error("Problem in point selection processing");
-            return false;
-          }
-          vertices.push_back(v);
-          if(!multipleSelection) return true;
-        }
-        break;
-      case 1:
-        {
-          GEdge *e = m->getEdgeByTag(hits[i].ient);
-          if(!e){
-            Msg::Error("Problem in line selection processing");
-            return false;
-          }
-          if(hits[i].type2){
-            MElement *ele = getElement(e, hits[i].type2, hits[i].ient2);
-            if(ele) elements.push_back(ele);
-          }
-          edges.push_back(e);
-          if(!multipleSelection) return true;
-        }
-        break;
-      case 2:
-        {
-          GFace *f = m->getFaceByTag(hits[i].ient);
-          if(!f){
-            Msg::Error("Problem in surface selection processing");
-            return false;
-          }
-          if(hits[i].type2){
-            MElement *ele = getElement(f, hits[i].type2, hits[i].ient2);
-            if(ele) elements.push_back(ele);
-          }
-          faces.push_back(f);
-          if(!multipleSelection) return true;
-        }
-        break;
-      case 3:
-        {
-          GRegion *r = m->getRegionByTag(hits[i].ient);
-          if(!r){
-            Msg::Error("Problem in volume selection processing");
-            return false;
-          }
-          if(hits[i].type2){
-            MElement *ele = getElement(r, hits[i].type2, hits[i].ient2);
-            if(ele) elements.push_back(ele);
-          }
-          regions.push_back(r);
-          if(!multipleSelection) return true;
-        }
-        break;
-      }
-    }
-  }
-
-  if(vertices.size() || edges.size() || faces.size() || 
-     regions.size() || elements.size()) 
-    return true;
-  return false;
+  return ret;
 }
 
 char openglWindow::selectEntity(int type, 
@@ -730,10 +532,10 @@ char openglWindow::selectEntity(int type,
         selectionMode = false;
         return 'c';
       }
-      else if(_processSelectionBuffer(_selection, multi, true, _trySelectionXYWH[0],
-                                      _trySelectionXYWH[1], _trySelectionXYWH[2],
-                                      _trySelectionXYWH[3], vertices, edges, faces, 
-                                      regions, elements)){
+      else if(_select(_selection, multi, true, _trySelectionXYWH[0],
+                      _trySelectionXYWH[1], _trySelectionXYWH[2],
+                      _trySelectionXYWH[3], vertices, edges, faces, 
+                      regions, elements)){
         _selection = ENT_NONE;
         selectionMode = false;
         if(add)
diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h
index 85b3efdc760895327df90a06e141d1f56c44727b..af9c11c165a71e32b8375bdc311c6a7c4cf4a7ba 100644
--- a/Fltk/openglWindow.h
+++ b/Fltk/openglWindow.h
@@ -30,14 +30,10 @@ class openglWindow : public Fl_Gl_Window {
   double _lassoXY[2];
   void _drawScreenMessage();
   void _drawBorder();
-  bool _processSelectionBuffer(int type, 
-                               bool multipleSelection, bool meshSelection,
-                               int x, int y, int w, int h,
-                               std::vector<GVertex*> &vertices,
-                               std::vector<GEdge*> &edges,
-                               std::vector<GFace*> &faces,
-                               std::vector<GRegion*> &regions,
-                               std::vector<MElement*> &elements);
+  bool _select(int type, bool multiple, bool mesh, int x, int y, int w, int h,
+               std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges,
+               std::vector<GFace*> &faces, std::vector<GRegion*> &regions,
+               std::vector<MElement*> &elements);
  protected:
   void draw();
   int handle(int);
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index 8e9eeaeff0f1a562a10d4dcb8bcac0e401ca385c..fd45d67146d28a200278c454b80fd81b4fa351a8 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -11,8 +11,10 @@
 #include "Context.h"
 #include "Numeric.h"
 #include "GModel.h"
+#include "MElement.h"
 #include "PView.h"
 #include "PViewOptions.h"
+#include "VertexArray.h"
 #include "gl2ps.h"
 
 #if defined(HAVE_FLTK)
@@ -644,3 +646,209 @@ void drawContext::world2Viewport(double xyz[3], double win[3])
   glGetDoublev(GL_MODELVIEW_MATRIX, model);
   gluProject(xyz[0], xyz[1], xyz[2], model, proj, viewport, &win[0], &win[1], &win[2]);
 }
+
+class hit{
+ public:
+  GLuint type, ient, depth, type2, ient2;
+  hit(GLuint t, GLuint i, GLuint d, GLuint t2=0, GLuint i2=0) 
+    : type(t), ient(i), depth(d), type2(t2), ient2(i2) {}
+};
+
+class hitDepthLessThan{
+ public:
+  bool operator()(const hit &h1, const hit &h2) const
+  {
+    return h1.depth < h2.depth;
+  }
+};
+
+// returns the element at a given position in a vertex array (element
+// pointers are not always stored: returning 0 is not an error)
+static MElement *getElement(GEntity *e, int va_type, int index)
+{
+  switch(va_type){
+  case 2: 
+    if(e->va_lines && index < e->va_lines->getNumElementPointers())
+      return *e->va_lines->getElementPointerArray(index);
+    break;
+  case 3:
+    if(e->va_triangles && index < e->va_triangles->getNumElementPointers())
+      return *e->va_triangles->getElementPointerArray(index);
+    break;
+  }
+  return 0;
+}
+
+bool drawContext::select(int type, bool multiple, bool mesh,
+                         int x, int y, int w, int h, 
+                         std::vector<GVertex*> &vertices,
+                         std::vector<GEdge*> &edges, 
+                         std::vector<GFace*> &faces,
+                         std::vector<GRegion*> &regions,
+                         std::vector<MElement*> &elements)
+{
+  vertices.clear();
+  edges.clear();
+  faces.clear();
+  regions.clear();
+  elements.clear();
+
+  // in our case the selection buffer size is equal to between 5 and 7
+  // times the maximum number of possible hits
+  GModel *m = GModel::current();
+  int eles = (mesh && CTX::instance()->pickElements) ? 4 * m->getNumMeshElements() : 0;
+  int size = 7 * (m->getNumVertices() + m->getNumEdges() + m->getNumFaces() + 
+                  m->getNumRegions() + eles);
+
+  if(!size) return false; // the model is empty, don't bother!
+
+  // allocate selection buffer
+  size += 1000; // just to make sure
+  GLuint *selectionBuffer = new GLuint[size];
+  glSelectBuffer(size, selectionBuffer);
+
+  // do one rendering pass in select mode
+  render_mode = drawContext::GMSH_SELECT;
+  glRenderMode(GL_SELECT);
+  glInitNames();
+  glPushMatrix();
+  initProjection(x, y, w, h);
+  initPosition();
+  drawGeom();
+  if(mesh) drawMesh();
+  glPopMatrix();
+  GLint numhits = glRenderMode(GL_RENDER);
+  render_mode = drawContext::GMSH_RENDER;
+
+  if(!numhits){ // no hits
+    delete [] selectionBuffer;
+    return false;
+  }
+  else if(numhits < 0){ // overflow
+    delete [] selectionBuffer;
+    Msg::Warning("Too many entities selected");
+    return false;
+  }
+
+  // decode the hits
+  std::vector<hit> hits;
+  GLuint *ptr = selectionBuffer;
+  for(int i = 0; i < numhits; i++) {
+    // in Gmsh 'names' should always be 0, 2 or 4:
+    // * names == 0 means that there is nothing on the stack
+    // * if names == 2, the first name is the type of the entity 
+    //   (0 for point, 1 for edge, 2 for face or 3 for volume) and
+    //   the second is the entity number;
+    // * if names == 4, the first name is the type of the entity,
+    //   the second is the entity number, the third is the type
+    //   of vertex array (2 for line, 3 for triangle, 4 for quad)
+    //   and the fourth is the index of the element in the vertex
+    //   array
+    GLuint names = *ptr++; 
+    *ptr++; // mindepth
+    GLuint maxdepth = *ptr++;
+    if(names == 2){
+      GLuint depth = maxdepth;
+      GLuint type = *ptr++; 
+      GLuint ient = *ptr++;
+      hits.push_back(hit(type, ient, depth));
+    }
+    else if(names == 4){
+      GLuint depth = maxdepth;
+      GLuint type = *ptr++; 
+      GLuint ient = *ptr++;
+      GLuint type2 = *ptr++; 
+      GLuint ient2 = *ptr++;
+      hits.push_back(hit(type, ient, depth, type2, ient2));
+    }
+  }
+
+  delete [] selectionBuffer;
+  
+  if(!hits.size()){ // no entities
+    return false;
+  }
+
+  // sort hits to get closest entities first
+  std::sort(hits.begin(), hits.end(), hitDepthLessThan());
+
+  // filter result: if type == ENT_NONE, return the closest entity of
+  // "lowest dimension" (point < line < surface < volume). Otherwise,
+  // return the closest entity of type "type"
+  GLuint typmin = 10;
+  for(unsigned int i = 0; i < hits.size(); i++)
+    typmin = std::min(typmin, hits[i].type);
+
+  for(unsigned int i = 0; i < hits.size(); i++) {
+    if((type == ENT_ALL) ||
+       (type == ENT_NONE && hits[i].type == typmin) ||
+       (type == ENT_POINT && hits[i].type == 0) ||
+       (type == ENT_LINE && hits[i].type == 1) ||
+       (type == ENT_SURFACE && hits[i].type == 2) ||
+       (type == ENT_VOLUME && hits[i].type == 3)){
+      switch (hits[i].type) {
+      case 0:
+        {
+          GVertex *v = m->getVertexByTag(hits[i].ient);
+          if(!v){
+            Msg::Error("Problem in point selection processing");
+            return false;
+          }
+          vertices.push_back(v);
+          if(!multiple) return true;
+        }
+        break;
+      case 1:
+        {
+          GEdge *e = m->getEdgeByTag(hits[i].ient);
+          if(!e){
+            Msg::Error("Problem in line selection processing");
+            return false;
+          }
+          if(hits[i].type2){
+            MElement *ele = getElement(e, hits[i].type2, hits[i].ient2);
+            if(ele) elements.push_back(ele);
+          }
+          edges.push_back(e);
+          if(!multiple) return true;
+        }
+        break;
+      case 2:
+        {
+          GFace *f = m->getFaceByTag(hits[i].ient);
+          if(!f){
+            Msg::Error("Problem in surface selection processing");
+            return false;
+          }
+          if(hits[i].type2){
+            MElement *ele = getElement(f, hits[i].type2, hits[i].ient2);
+            if(ele) elements.push_back(ele);
+          }
+          faces.push_back(f);
+          if(!multiple) return true;
+        }
+        break;
+      case 3:
+        {
+          GRegion *r = m->getRegionByTag(hits[i].ient);
+          if(!r){
+            Msg::Error("Problem in volume selection processing");
+            return false;
+          }
+          if(hits[i].type2){
+            MElement *ele = getElement(r, hits[i].type2, hits[i].ient2);
+            if(ele) elements.push_back(ele);
+          }
+          regions.push_back(r);
+          if(!multiple) return true;
+        }
+        break;
+      }
+    }
+  }
+
+  if(vertices.size() || edges.size() || faces.size() || 
+     regions.size() || elements.size()) 
+    return true;
+  return false;
+}
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index 2d7295c145ccad6d7dfa29c63e09df8029df27c8..4319b4f26c5c1987e77d8fcf953c2da6143f1875 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -27,6 +27,11 @@
 
 class PView;
 class GModel;
+class GVertex;
+class GEdge;
+class GFace;
+class GRegion;
+class MElement;
 
 class drawTransform {
  public:
@@ -164,6 +169,10 @@ class drawContext {
   void unproject(double x, double y, double p[3], double d[3]);
   void viewport2World(double win[3], double xyz[3]);
   void world2Viewport(double xyz[3], double win[3]);
+  bool select(int type, bool multiple, bool mesh, int x, int y, int w, int h, 
+              std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, 
+              std::vector<GFace*> &faces, std::vector<GRegion*> &regions,
+              std::vector<MElement*> &elements);
   int fix2dCoordinates(double *x, double *y);
   void draw3d();
   void draw2d();
diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp
index c4063a46f765070fec93b8905809827edc8f625c..d8a1a71f59cc882e0595422cf3bbd00a3e8b08ff 100644
--- a/Mesh/Field.cpp
+++ b/Mesh/Field.cpp
@@ -1217,11 +1217,11 @@ class AttractorField : public Field
     dist = new ANNdist[1];
     n_nodes_by_edge = 20;
     options["NodesList"] = new FieldOptionList
-      (nodes_id, "Indices of nodes in the geomtric model", &update_needed);
+      (nodes_id, "Indices of nodes in the geometric model", &update_needed);
     options["EdgesList"] = new FieldOptionList
       (edges_id, "Indices of curves in the geometric model", &update_needed);
     options["NNodesByEdge"] = new FieldOptionInt
-      (n_nodes_by_edge, "Number of nodes used to discetized each curve",
+      (n_nodes_by_edge, "Number of nodes used to discretized each curve",
        &update_needed);
     options["FacesList"] = new FieldOptionList
       (faces_id, "Indices of surfaces in the geometric model (Warning: might\n"
diff --git a/utils/api_demos/mainAntTweakBar.cpp b/utils/api_demos/mainAntTweakBar.cpp
index 0c6eb9b6542a6f5f03cab07c9e6be4012dbd8cd1..0e6a7ed6c0ea2243d0bed69caa31b5b87a779944 100644
--- a/utils/api_demos/mainAntTweakBar.cpp
+++ b/utils/api_demos/mainAntTweakBar.cpp
@@ -14,7 +14,9 @@
 #include <gmsh/MElement.h>
 #include <gmsh/drawContext.h>
 
-drawContext *ctx = 0;
+static drawContext *ctx = 0;
+static mousePosition clickPos, prevPos;
+static int specialKey = 0;
 
 class drawContextTw : public drawContextGlobal{
  public:
@@ -70,9 +72,6 @@ void keyboard(unsigned char key, int x, int y)
   glutPostRedisplay();
 }
 
-static mousePosition clickPos, prevPos;
-static int specialKey = 0;
-
 void mouseMotion(int x, int y)
 {
   if(TwEventMouseMotionGLUT(x, y)) return;
@@ -108,6 +107,29 @@ void mouseMotion(int x, int y)
   glutPostRedisplay();
 }
 
+void mousePassiveMotion(int x, int y)
+{
+  if(TwEventMouseMotionGLUT(x, y)) return;
+
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
+  bool ret = ctx->select(ENT_ALL, false, false, x, y, 5, 5,
+                         vertices, edges, faces, regions, elements);
+  if(ret){
+    GEntity *ge = 0;
+    if(vertices.size()) ge = vertices[0];
+    else if(edges.size()) ge = edges[0];
+    else if(faces.size()) ge = faces[0];
+    else if(regions.size()) ge = regions[0];
+    MElement *me = elements.size() ? elements[0] : 0;
+    printf("%s %s\n", ge ? ge->getInfoString().c_str() : "", 
+           me ? me->getInfoString().c_str() : "");
+  }
+}
+
 void mouseButton(int button, int state, int x, int y)
 {
   if(TwEventMouseButtonGLUT(button, state, x, y)) return;
@@ -214,7 +236,7 @@ int main(int argc, char **argv)
   glutReshapeFunc(reshape);
   glutMouseFunc(mouseButton);
   glutMotionFunc(mouseMotion);
-  glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
+  glutPassiveMotionFunc(mousePassiveMotion);
   glutKeyboardFunc(keyboard);
   glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT);
   TwGLUTModifiersFunc(glutGetModifiers);