Revision: 75324
          http://sourceforge.net/p/brlcad/code/75324
Author:   starseeker
Date:     2020-04-09 18:02:59 +0000 (Thu, 09 Apr 2020)
Log Message:
-----------
Revert back the attempt to push Tcl/Tk out of libdm/libfb - close, but Windows 
isn't happy and there is no telling how deep that rabbit hole goes.

Modified Paths:
--------------
    brlcad/trunk/include/dm/bview.h
    brlcad/trunk/include/dm/defines.h
    brlcad/trunk/include/dm/dm_xvars.h
    brlcad/trunk/include/dm.h
    brlcad/trunk/include/fb.h
    brlcad/trunk/include/tclcad.h
    brlcad/trunk/src/adrt/isst.c
    brlcad/trunk/src/libdm/CMakeLists.txt
    brlcad/trunk/src/libdm/dm-Null.c
    brlcad/trunk/src/libdm/dm-Null.h
    brlcad/trunk/src/libdm/dm-X.c
    brlcad/trunk/src/libdm/dm-generic.c
    brlcad/trunk/src/libdm/dm-glx.h
    brlcad/trunk/src/libdm/dm-ogl.c
    brlcad/trunk/src/libdm/dm-osgl.cpp
    brlcad/trunk/src/libdm/dm-plot.c
    brlcad/trunk/src/libdm/dm-ps.c
    brlcad/trunk/src/libdm/dm-qt.cpp
    brlcad/trunk/src/libdm/dm-txt.c
    brlcad/trunk/src/libdm/dm-wgl.c
    brlcad/trunk/src/libdm/dm_private.h
    brlcad/trunk/src/libdm/query.c
    brlcad/trunk/src/libfb/CMakeLists.txt
    brlcad/trunk/src/libfb/fb_generic.c
    brlcad/trunk/src/libfb/fb_private.h
    brlcad/trunk/src/libtclcad/CMakeLists.txt
    brlcad/trunk/src/libtclcad/libfuncs.c
    brlcad/trunk/src/libtclcad/tclcad_obj.c
    brlcad/trunk/src/mged/attach.c
    brlcad/trunk/src/mged/doevent.c
    brlcad/trunk/src/mged/mged.c
    brlcad/trunk/src/mged/mged.h
    brlcad/trunk/src/mged/mged_dm.h
    brlcad/trunk/src/mged/setup.c
    brlcad/trunk/src/util/plot3-dm.c

Added Paths:
-----------
    brlcad/trunk/src/libdm/dm-tk.c
    brlcad/trunk/src/libdm/dm-tk.h
    brlcad/trunk/src/libdm/dm_obj.c
    brlcad/trunk/src/libdm/tcl.c
    brlcad/trunk/src/libfb/if_tk.c
    brlcad/trunk/src/libfb/tcl.c

Removed Paths:
-------------
    brlcad/trunk/src/libtclcad/dm_tcl.c

Modified: brlcad/trunk/include/dm/bview.h
===================================================================
--- brlcad/trunk/include/dm/bview.h     2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/dm/bview.h     2020-04-09 18:02:59 UTC (rev 75324)
@@ -308,7 +308,6 @@
     void                (*vo_callback)();       /**< @brief  called in 
vo_update with vo_clientData and vop */
     void *              vo_clientData;          /**< @brief  passed to 
vo_callback */
     int                 vo_zclip;
-    void                (*vo_eval)(void *context, const char *cmd);  /**< 
@brief  called in vo_update */
     void               *interp;
 };
 #define VIEW_OBJ_NULL ((struct view_obj *)0)

Modified: brlcad/trunk/include/dm/defines.h
===================================================================
--- brlcad/trunk/include/dm/defines.h   2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/dm/defines.h   2020-04-09 18:02:59 UTC (rev 75324)
@@ -34,9 +34,6 @@
 #  endif
 #endif
 
-/* TODO - global var, need to eliminate */
-DM_EXPORT extern int vectorThreshold;
-
 /** @} */
 /*
  * Local Variables:

Modified: brlcad/trunk/include/dm/dm_xvars.h
===================================================================
--- brlcad/trunk/include/dm/dm_xvars.h  2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/dm/dm_xvars.h  2020-04-09 18:02:59 UTC (rev 75324)
@@ -27,15 +27,24 @@
 
 #include "common.h"
 
-#include "dm.h"
-
-#include "tk.h" // For X11 types on Windows (config_win.h asserts we have 
them...)
-
 #ifdef HAVE_X11_XLIB_H
 #  include <X11/Xlib.h>
 #  include <X11/Xutil.h>
 #endif
 
+#ifdef HAVE_TK
+#  include "tk.h"
+#  define HAVE_X11_TYPES 1
+#endif
+#ifdef IF_WGL
+#include "tkWinInt.h"
+#endif
+
+#if !defined(HAVE_TK) && !defined(TK_WINDOW_TYPEDEF)
+typedef void *Tk_Window;
+#  define TK_WINDOW_TYPEDEF 1
+#endif
+
 #if !defined(HAVE_X11_TYPES) && !defined(HAVE_X11_XLIB_H)
 typedef long Display;
 typedef long Window;
@@ -52,8 +61,8 @@
 struct dm_xvars {
     Display *dpy;
     Window win;
-    dm_win top;
-    dm_win xtkwin;
+    Tk_Window top;
+    Tk_Window xtkwin;
     int depth;
     Colormap cmap;
 #ifdef IF_WGL
@@ -65,6 +74,10 @@
     XVisualInfo *vip;
     XFontStruct *fontstruct;
 #endif
+#ifdef DM_TK
+    int tkfontset;
+    Tk_Font tkfontstruct;
+#endif
     int devmotionnotify;
     int devbuttonpress;
     int devbuttonrelease;

Modified: brlcad/trunk/include/dm.h
===================================================================
--- brlcad/trunk/include/dm.h   2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/dm.h   2020-04-09 18:02:59 UTC (rev 75324)
@@ -223,57 +223,7 @@
 /* Hide the dm structure behind a typedef */
 typedef struct dm_internal dm;
 
-/* To avoid (at least in principle) hardcoded assumptions about parent
- * toolkits, we use a context container that is supplied by callers
- * telling libdm how to get certain specific information needed to
- * initialize and manipulate the display context */
-typedef void * dm_win;
-typedef void * dm_dpy;
-typedef long unsigned int dm_cmap;
-typedef long unsigned int dm_winid;
-typedef void * dm_visual_info;
-typedef void * dm_screen;
-typedef unsigned long dm_pixmap;
-struct dm_context {
-    /* Tk_MainWindow */
-    dm_win (*dm_window_main)(dm *);
-    /* Tk_CreateWindowFromPath */
-    dm_win (*dm_window_create_from_path)(dm *, dm_win, const char *, const 
char *);
-    /* Tk_NameToWindow */
-    dm_win (*dm_window_from_name)(dm *, const char *, dm_win);
-    /* Tk_CreateWindow */
-    dm_win (*dm_window_create_embedded)(dm *dmp, dm_win, const char *);
-    /* Tk_Name */
-    const char *(*dm_window_name)(dm *dmp, dm_win);
-    /* Tk_WindowId */
-    int (*dm_window_id)(dm *, dm_win);
-    /* Tk_MakeWindowExist */
-    void (*dm_window_make_exist)(dm *, dm_win);
-    /* Tk_MapWindow */
-    void(*dm_window_map)(dm *, dm_win);
-    /* Tk_SetWindowVisual */
-    int (*dm_window_set_visual)(dm *, dm_win, dm_visual_info, dm_cmap);
-    /* Tk_DestroyWindow */
-    void (*dm_window_destroy)(dm *, dm_win);
-    /* _init_dm */
-    int (*dm_init)(dm *, const char *);
-    /* Tk_GeometryRequest */
-    void (*dm_window_geom)(dm *, dm_win, int *width, int *height);
-    /* Tk_Display */
-    dm_dpy (*dm_display)(dm *, dm_win);
-    /* Tk_GetPixmap */
-    dm_pixmap (*dm_get_pixmap)(dm *, dm_dpy, dm_winid, dm_win, int width, int 
height);
-    /* Tk_FreePixmap */
-    void (*dm_free_pixmap)(dm *, dm_dpy, dm_pixmap);
-    /* Tk_SetWindowBackground */
-    void (*dm_window_set_bg)(dm *, dm_win, unsigned long);
-    /* Tk_Screen */
-    dm_screen (*dm_get_screen)(dm *, dm_win);
-    /* Tk_CreateEventHandler */
-    void (*dm_eventhandler_create)(dm *, dm_win);
-    /* Tk_DeleteEventHandler */
-    void (*dm_eventhandler_delete)(dm *, dm_win);
-};
+#define DM_OPEN(_interp, _type, _argc, _argv) dm_open(_interp, _type, _argc, 
_argv)
 
 __BEGIN_DECLS
 
@@ -281,6 +231,7 @@
 DM_EXPORT extern dm dm_plot;
 DM_EXPORT extern dm dm_ps;
 DM_EXPORT extern dm dm_rtgl;
+DM_EXPORT extern dm dm_tk;
 DM_EXPORT extern dm dm_wgl;
 DM_EXPORT extern dm dm_X;
 DM_EXPORT extern dm dm_txt;
@@ -287,8 +238,8 @@
 DM_EXPORT extern dm dm_qt;
 DM_EXPORT extern dm dm_osgl;
 
+DM_EXPORT extern int Dm_Init(void *interp);
 DM_EXPORT extern dm *dm_open(Tcl_Interp *interp,
-                            struct dm_context *context,
                             int type,
                             int argc,
                             const char *argv[]);
@@ -354,10 +305,6 @@
                                                      int *labelsColor_arg, 
ClientData labelsHookClientdata_arg),
                                    ClientData labelsHookClientdata);
 
-/* query.c */
-DM_EXPORT extern int dm_validXType(const char *dpy_string, const char *name);
-DM_EXPORT extern char *dm_bestXType(const char *dpy_string);
-
 /* rect.c */
 DM_EXPORT extern void dm_draw_rect(dm *dmp,
                                   struct bview_interactive_rect_state *grsp);
@@ -392,7 +339,7 @@
 DM_EXPORT extern unsigned long dm_get_id(dm *dmp);
 DM_EXPORT extern void dm_set_id(dm *dmp, unsigned long new_id);
 DM_EXPORT extern int dm_get_displaylist(dm *dmp);
-DM_EXPORT extern int dm_close(dm *dmp, struct dm_context *context);
+DM_EXPORT extern int dm_close(dm *dmp);
 DM_EXPORT extern unsigned char *dm_get_bg(dm *dmp);
 DM_EXPORT extern int dm_set_bg(dm *dmp, unsigned char r, unsigned char g, 
unsigned char b);
 DM_EXPORT extern unsigned char *dm_get_fg(dm *dmp);
@@ -400,14 +347,12 @@
 DM_EXPORT extern int dm_reshape(dm *dmp, int width, int height);
 DM_EXPORT extern int dm_make_current(dm *dmp);
 DM_EXPORT extern vect_t *dm_get_clipmin(dm *dmp);
-DM_EXPORT extern void dm_set_clipmin(dm *dmp, vect_t clipmin);
 DM_EXPORT extern vect_t *dm_get_clipmax(dm *dmp);
-DM_EXPORT extern void dm_set_clipmax(dm *dmp, vect_t clipmax);
 DM_EXPORT extern int dm_get_bound_flag(dm *dmp);
 DM_EXPORT extern void dm_set_bound(dm *dmp, fastf_t val);
 DM_EXPORT extern int dm_get_stereo(dm *dmp);
 DM_EXPORT extern int dm_set_win_bounds(dm *dmp, fastf_t *w);
-DM_EXPORT extern int dm_configure_win(dm *dmp, struct dm_context *context, int 
force);
+DM_EXPORT extern int dm_configure_win(dm *dmp, int force);
 DM_EXPORT extern struct bu_vls *dm_get_pathname(dm *dmp);
 DM_EXPORT extern struct bu_vls *dm_get_dname(dm *dmp);
 DM_EXPORT extern struct bu_vls *dm_get_tkname(dm *dmp);
@@ -415,7 +360,6 @@
 DM_EXPORT extern void dm_set_fontsize(dm *dmp, int size);
 DM_EXPORT extern int dm_get_light_flag(dm *dmp);
 DM_EXPORT extern void dm_set_light_flag(dm *dmp, int size);
-DM_EXPORT extern int dm_get_light(dm *dmp);
 DM_EXPORT extern int dm_set_light(dm *dmp, int light);
 DM_EXPORT extern void *dm_get_public_vars(dm *dmp);
 DM_EXPORT extern void *dm_get_private_vars(dm *dmp);
@@ -454,24 +398,13 @@
 DM_EXPORT extern int dm_draw_points_3d(dm *dmp, int npoints, point_t *points);
 DM_EXPORT extern int dm_draw(dm *dmp, struct bn_vlist *(*callback)(void *), 
void **data);
 DM_EXPORT extern int dm_draw_obj(dm *dmp, struct display_list *obj);
-DM_EXPORT extern int dm_get_depth_mask(dm *dmp);
 DM_EXPORT extern int dm_set_depth_mask(dm *dmp, int d_on);
-DM_EXPORT extern int dm_get_debug(dm *dmp);
 DM_EXPORT extern int dm_debug(dm *dmp, int lvl);
-DM_EXPORT extern const char *dm_get_logfile(dm *dmp);
 DM_EXPORT extern int dm_logfile(dm *dmp, const char *filename);
 DM_EXPORT extern fb *dm_get_fb(dm *dmp);
 DM_EXPORT extern int dm_get_fb_visible(dm *dmp);
 DM_EXPORT extern int dm_set_fb_visible(dm *dmp, int is_fb_visible);
-DM_EXPORT extern int dm_get_clearbufferafter(dm *dmp);
-DM_EXPORT extern void dm_set_clearbufferafter(dm *dmp, int clearBufferAfter);
 
-DM_EXPORT extern void dm_flush(dm *dmp);
-DM_EXPORT extern void *dm_os_window(dm *dmp);
-DM_EXPORT extern void *dm_device_context(dm *dmp);
-
-DM_EXPORT extern int dm_png_write(dm *dmp, FILE *fp, struct bu_vls *msgs);
-
 /* TODO - dm_vp is supposed to go away, but until we figure it out
  * expose it here to allow dm hiding */
 DM_EXPORT extern fastf_t *dm_get_vp(dm *dmp);
@@ -503,7 +436,7 @@
 #  include "../src/libdm/dm_private.h"
 #endif
 
-#define DM_OPEN(_interp, _context, _type, _argc, _argv) dm_open(_interp, 
_context, _type, _argc, _argv)
+#define DM_OPEN(_interp, _type, _argc, _argv) dm_open(_interp, _type, _argc, 
_argv)
 #define DM_CLOSE(_dmp) _dmp->dm_close(_dmp)
 #define DM_DRAW_BEGIN(_dmp) _dmp->dm_drawBegin(_dmp)
 #define DM_DRAW_END(_dmp) _dmp->dm_drawEnd(_dmp)

Modified: brlcad/trunk/include/fb.h
===================================================================
--- brlcad/trunk/include/fb.h   2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/fb.h   2020-04-09 18:02:59 UTC (rev 75324)
@@ -199,6 +199,11 @@
 #define FB_DEBUG_RW 4  /* Contents of reads and writes */
 #define FB_DEBUG_BRW 8 /* Buffered IO rpixel and wpixel */
 
+/* tcl.c */
+/* The presence of Tcl_Interp as an arg prevents giving arg list */
+FB_EXPORT extern void fb_tcl_setup(void);
+FB_EXPORT extern int Fb_Init(Tcl_Interp *interp);
+
 /**
  * report version information about LIBFB
  */
@@ -294,7 +299,6 @@
 FB_EXPORT extern int fbs_close(struct fbserv_obj *fbsp);
 
 
-FB_EXPORT extern int Fbo_Init(Tcl_Interp *interp);
 
 __END_DECLS
 

Modified: brlcad/trunk/include/tclcad.h
===================================================================
--- brlcad/trunk/include/tclcad.h       2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/include/tclcad.h       2020-04-09 18:02:59 UTC (rev 75324)
@@ -471,25 +471,7 @@
  */
 TCLCAD_EXPORT extern int tclcad_init(Tcl_Interp *interp, int init_gui, struct 
bu_vls *tlog);
 
-/**
- * Create Tcl specific I/O handlers
- */
-TCLCAD_EXPORT void
-tclcad_create_io_handler(void **chan, struct bu_process *p, int fd, int mode, 
void *data, ged_io_handler_callback_t callback);
 
-/**
- * Delete Tcl specific I/O handlers
- */
-TCLCAD_EXPORT void
-tclcad_delete_io_handler(void *interp, void *chan, struct bu_process *p, int 
fd, void *data, ged_io_handler_callback_t callback);
-
-
-TCLCAD_EXPORT extern int Fb_Init(Tcl_Interp *interp);
-TCLCAD_EXPORT extern int Dm_Init(Tcl_Interp *interp);
-
-
-TCLCAD_EXPORT extern struct dm_context dm_tk_context;
-
 __END_DECLS
 
 #endif /* TCLCAD_H */

Modified: brlcad/trunk/src/adrt/isst.c
===================================================================
--- brlcad/trunk/src/adrt/isst.c        2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/adrt/isst.c        2020-04-09 18:02:59 UTC (rev 75324)
@@ -547,7 +547,7 @@
 {
     char *av[] = { "Ogl_open", "-t", "0", "-n", ".w0", "-W", "800", "-N", 
"600", NULL };
 
-    dmp = dm_open(interp, &dm_tk_context, dm_default_type(), 
sizeof(av)/sizeof(void*)-1, (const char **)av);
+    dmp = dm_open(interp, dm_default_type(), sizeof(av)/sizeof(void*)-1, 
(const char **)av);
 
     if (dmp == DM_NULL) {
        printf("dm failed?\n");

Modified: brlcad/trunk/src/libdm/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libdm/CMakeLists.txt       2020-04-09 17:21:45 UTC (rev 
75323)
+++ brlcad/trunk/src/libdm/CMakeLists.txt       2020-04-09 18:02:59 UTC (rev 
75324)
@@ -9,6 +9,8 @@
   ${X11_INCLUDE_DIR}
   ${OPENGL_INCLUDE_DIR_GL}
   ${OPENGL_INCLUDE_DIR_GLX}
+  ${TCL_INCLUDE_PATH}
+  ${TK_INCLUDE_PATH}
   ${Qt5Widgets_INCLUDE_DIRS}
   ${OPENTHREADS_INCLUDE_DIR}
   ${OSG_INCLUDE_DIR}
@@ -47,6 +49,13 @@
   set_property(SOURCE dm-ogl.c APPEND PROPERTY COMPILE_DEFINITIONS 
FB_USE_INTERNAL_API)
 endif(BRLCAD_ENABLE_X11 AND BRLCAD_ENABLE_OPENGL AND BRLCAD_ENABLE_TK)
 
+if(BRLCAD_ENABLE_TK AND NOT WIN32)
+  list(APPEND libdm_DEFINES DM_TK IF_TK)
+  set(DM_TKLIB ${TCL_LIBRARY} ${TK_LIBRARY})
+  set(dmtk_srcs dm-tk.c)
+  set_property(SOURCE dm-tk.c APPEND PROPERTY COMPILE_DEFINITIONS 
FB_USE_INTERNAL_API)
+endif(BRLCAD_ENABLE_TK AND NOT WIN32)
+
 if(BRLCAD_ENABLE_QT)
   CHECK_CXX_FLAG(Wno-float-equal)
 
@@ -79,6 +88,8 @@
   ${dmw32_srcs}
   ${dmogl_srcs}
   ${dmosg_srcs}
+  ${dmrtgl_srcs}
+  ${dmtk_srcs}
   ${dmqt_srcs}
   adc.c
   axes.c
@@ -88,6 +99,7 @@
   dm-generic.c
   dm-plot.c
   dm-ps.c
+  dm_obj.c
   dm_util.c
   dm-txt.c
   grid.c
@@ -97,10 +109,11 @@
   query.c
   rect.c
   scale.c
+  tcl.c
   vers.c
   )
 set_property(SOURCE dm_obj.c APPEND PROPERTY COMPILE_DEFINITIONS 
FB_USE_INTERNAL_API)
-BRLCAD_ADDLIB(libdm "${LIBDM_SRCS}" 
"librt;libfb;${DM_X_LIBS};${DM_EXTRA_LIBS};${PNG_LIBRARIES}")
+BRLCAD_ADDLIB(libdm "${LIBDM_SRCS}" 
"librt;libfb;${DM_X_LIBS};${DM_TKLIB};${DM_EXTRA_LIBS};${PNG_LIBRARIES}")
 set_target_properties(libdm PROPERTIES VERSION 20.0.1 SOVERSION 20)
 
 if(BRLCAD_ENABLE_OSG)
@@ -110,6 +123,9 @@
   endif(CPP_DLL_DEFINES)
 endif(BRLCAD_ENABLE_OSG)
 
+if(BRLCAD_BUILD_LOCAL_TK AND BRLCAD_ENABLE_TK)
+  add_dependencies(libdm tk)
+endif(BRLCAD_BUILD_LOCAL_TK AND BRLCAD_ENABLE_TK)
 if(BRLCAD_ENABLE_OSG)
   add_dependencies(libdm profont_ProFont_ttf_cp)
 endif(BRLCAD_ENABLE_OSG)
@@ -129,6 +145,8 @@
   dm-ps.h
   dm-qt.cpp
   dm-qt.h
+  dm-tk.c
+  dm-tk.h
   dm-wgl.c
   dm-wgl.h
   dm_private.h

Modified: brlcad/trunk/src/libdm/dm-Null.c
===================================================================
--- brlcad/trunk/src/libdm/dm-Null.c    2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-Null.c    2020-04-09 18:02:59 UTC (rev 75324)
@@ -35,7 +35,7 @@
 
 
 int
-null_close(struct dm_internal *UNUSED(dmp), struct dm_context *UNUSED(context))
+null_close(struct dm_internal *UNUSED(dmp))
 {
     return 0;
 }
@@ -168,7 +168,7 @@
 
 
 int
-null_configureWin(struct dm_internal *UNUSED(dmp), struct dm_context 
*UNUSED(context), int UNUSED(force))
+null_configureWin(struct dm_internal *UNUSED(dmp), int UNUSED(force))
 {
     return 0;
 }

Modified: brlcad/trunk/src/libdm/dm-Null.h
===================================================================
--- brlcad/trunk/src/libdm/dm-Null.h    2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-Null.h    2020-04-09 18:02:59 UTC (rev 75324)
@@ -35,7 +35,7 @@
 
 
 DM_EXPORT extern int
-null_close(dm *dmp, struct dm_context *context);
+null_close(dm *dmp);
 
 
 DM_EXPORT extern int
@@ -111,7 +111,7 @@
 
 
 DM_EXPORT extern int
-null_configureWin(dm *dmp, struct dm_context *context, int force);
+null_configureWin(dm *dmp, int force);
 
 
 DM_EXPORT extern int

Modified: brlcad/trunk/src/libdm/dm-X.c
===================================================================
--- brlcad/trunk/src/libdm/dm-X.c       2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-X.c       2020-04-09 18:02:59 UTC (rev 75324)
@@ -51,6 +51,10 @@
 #  undef X_NOT_POSIX
 #endif
 
+#ifdef HAVE_TK
+#  include "tk.h"
+#endif
+
 #include "vmath.h"
 #include "bu/endian.h"
 #include "bn.h"
@@ -154,7 +158,7 @@
 
 
 HIDDEN int
-X_configureWin_guts(struct dm_internal *dmp, struct dm_context *context, int 
force)
+X_configureWin_guts(struct dm_internal *dmp, int force)
 {
     XWindowAttributes xwa;
     XFontStruct *newfontstruct;
@@ -179,9 +183,14 @@
     }
 
 #ifdef HAVE_TK
-    (*context->dm_free_pixmap)(dmp, pubvars->dpy, privars->pix);
-    privars->pix = (Pixmap)(*context->dm_get_pixmap)(dmp, pubvars->dpy, 
DefaultRootWindow(pubvars->dpy),
-                    pubvars->xtkwin, dmp->dm_width, dmp->dm_height);
+    Tk_FreePixmap(pubvars->dpy,
+                 privars->pix);
+    privars->pix =
+       Tk_GetPixmap(pubvars->dpy,
+                    DefaultRootWindow(pubvars->dpy),
+                    dmp->dm_width,
+                    dmp->dm_height,
+                    Tk_Depth(pubvars->xtkwin));
 #endif
 
     /* First time through, load a font or quit */
@@ -271,7 +280,7 @@
 
 
 HIDDEN XVisualInfo *
-X_choose_visual(struct dm_internal *dmp, struct dm_context *context)
+X_choose_visual(struct dm_internal *dmp)
 {
     XVisualInfo *vip, vitemp, *vibase, *maxvip;
     int num, i, j;
@@ -333,7 +342,10 @@
            }
 
 #ifdef HAVE_TK
-           if ((*context->dm_window_set_visual)(dmp, pubvars->xtkwin, 
(dm_visual_info)maxvip, pubvars->cmap)) {
+           if (Tk_SetWindowVisual(pubvars->xtkwin,
+                                  maxvip->visual,
+                                  maxvip->depth,
+                                  pubvars->cmap)) {
                pubvars->depth = maxvip->depth;
 
                bu_free(good, "dealloc good visuals");
@@ -364,7 +376,7 @@
  * Gracefully release the display.
  */
 HIDDEN int
-X_close(struct dm_internal *dmp, struct dm_context *context)
+X_close(struct dm_internal *dmp)
 {
     struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
     struct x_vars *privars = (struct x_vars *)dmp->dm_vars.priv_vars;
@@ -376,7 +388,8 @@
 
 #ifdef HAVE_TK
        if (privars->pix)
-           (*context->dm_free_pixmap)(dmp, pubvars->dpy, privars->pix);
+           Tk_FreePixmap(pubvars->dpy,
+                         privars->pix);
 #endif
 
        /*XXX Possibly need to free the colormap */
@@ -386,7 +399,7 @@
 
 #ifdef HAVE_TK
        if (pubvars->xtkwin)
-           (*context->dm_window_destroy)(dmp, pubvars->xtkwin);
+           Tk_DestroyWindow(pubvars->xtkwin);
 #endif
 
     }
@@ -407,7 +420,7 @@
  *
  */
 struct dm_internal *
-X_open_dm(Tcl_Interp *interp, struct dm_context *context, int argc, char 
**argv)
+X_open_dm(Tcl_Interp *interp, int argc, char **argv)
 {
     static int count = 0;
     int make_square = -1;
@@ -425,12 +438,18 @@
     struct bu_vls str = BU_VLS_INIT_ZERO;
     struct bu_vls init_proc_vls = BU_VLS_INIT_ZERO;
     struct dm_internal *dmp = (struct dm_internal *)NULL;
-    dm_win tkwin = NULL;
+    Tk_Window tkwin = (Tk_Window)NULL;
     Screen *screen = (Screen *)NULL;
 
     struct dm_xvars *pubvars = NULL;
     struct x_vars *privars = NULL;
 
+#ifdef HAVE_TK
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
+#endif
+
     BU_ALLOC(dmp, struct dm_internal);
 
     *dmp = dm_X; /* struct copy */
@@ -442,15 +461,6 @@
     BU_ALLOC(dmp->dm_vars.priv_vars, struct x_vars);
     privars = (struct x_vars *)dmp->dm_vars.priv_vars;
 
-#ifdef HAVE_TK
-    if ((tkwin = (*context->dm_window_main)(dmp)) == NULL) {
-       bu_free((void *)privars, "privars");
-       bu_free((void *)pubvars, "pubvars");
-       bu_free((void *)dmp, "dmp");
-       return DM_NULL;
-    }
-#endif
-
     bu_vls_init(&dmp->dm_pathName);
     bu_vls_init(&dmp->dm_tkName);
     bu_vls_init(&dmp->dm_dName);
@@ -484,8 +494,9 @@
     if (dmp->dm_top) {
 #ifdef HAVE_TK
        /* Make xtkwin a toplevel window */
-       pubvars->xtkwin = (*context->dm_window_create_from_path)(dmp, tkwin,
-               bu_vls_cstr(&dmp->dm_pathName), bu_vls_cstr(&dmp->dm_dName));
+       pubvars->xtkwin = Tk_CreateWindowFromPath(interp, tkwin,
+                                                 
bu_vls_addr(&dmp->dm_pathName),
+                                                 bu_vls_addr(&dmp->dm_dName));
        pubvars->top = pubvars->xtkwin;
 #endif
     } else {
@@ -500,7 +511,8 @@
            bu_vls_strncpy(&top_vls, (const char 
*)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
 
 #ifdef HAVE_TK
-           pubvars->top = (*context->dm_window_from_name)(dmp, 
bu_vls_cstr(&top_vls), tkwin);
+           pubvars->top =
+               Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
 #endif
            bu_vls_free(&top_vls);
        }
@@ -507,25 +519,30 @@
 
 #ifdef HAVE_TK
        /* Make xtkwin an embedded window */
-       pubvars->xtkwin = (*context->dm_window_create_embedded)(dmp, 
pubvars->top, cp + 1);
+       pubvars->xtkwin =
+           Tk_CreateWindow(interp, pubvars->top,
+                           cp + 1, (char *)NULL);
 #endif
     }
 
     if (pubvars->xtkwin == NULL) {
        bu_log("X_open_dm: Failed to open %s\n", 
bu_vls_addr(&dmp->dm_pathName));
-       (void)X_close(dmp, context);
+       (void)X_close(dmp);
        return DM_NULL;
     }
 
 #ifdef HAVE_TK
-    const char *winname = (*context->dm_window_name)(dmp, pubvars->xtkwin);
-    bu_vls_printf(&dmp->dm_tkName, "%s", winname);
+    bu_vls_printf(&dmp->dm_tkName, "%s",
+                 (char *)Tk_Name(pubvars->xtkwin));
 #endif
 
-    if ((*context->dm_init)(dmp, bu_vls_cstr(&init_proc_vls)) == BRLCAD_ERROR) 
{
-       bu_vls_free(&init_proc_vls);
+    bu_vls_printf(&str, "_init_dm %s %s\n",
+                 bu_vls_addr(&init_proc_vls),
+                 bu_vls_addr(&dmp->dm_pathName));
+
+    if (Tcl_Eval(interp, bu_vls_addr(&str)) == BRLCAD_ERROR) {
        bu_vls_free(&str);
-       (void)X_close(dmp, context);
+       (void)X_close(dmp);
        return DM_NULL;
     }
 
@@ -534,13 +551,13 @@
 
     pubvars->dpy = NULL;
 #ifdef HAVE_TK
-    pubvars->dpy = (Display *)(*context->dm_display)(dmp, pubvars->top);
+    pubvars->dpy = Tk_Display(pubvars->top);
 #endif
 
     /* make sure there really is a display before proceeding. */
     if (!pubvars->dpy) {
        bu_log("ERROR: Unable to attach to display (%s)\n", 
bu_vls_addr(&dmp->dm_pathName));
-       (void)X_close(dmp, context);
+       (void)X_close(dmp);
        return DM_NULL;
     }
 
@@ -549,7 +566,7 @@
     if (!screen) {
 #ifdef HAVE_TK
        /* failed to get a default screen, try harder */
-       screen = (Screen *)(*context->dm_get_screen)(dmp, pubvars->top);
+       screen = Tk_Screen(pubvars->top);
 #endif
     }
 
@@ -556,7 +573,7 @@
     /* make sure there really is a screen before processing. */
     if (!screen) {
        bu_log("ERROR: Unable to attach to screen (%s)\n", 
bu_vls_addr(&dmp->dm_pathName));
-       (void)X_close(dmp, context);
+       (void)X_close(dmp);
        return DM_NULL;
     }
 
@@ -593,21 +610,28 @@
     }
 
 #ifdef HAVE_TK
-    (*context->dm_window_geom)(dmp, pubvars->xtkwin, &dmp->dm_width, 
&dmp->dm_height);
+    Tk_GeometryRequest(pubvars->xtkwin,
+                      dmp->dm_width,
+                      dmp->dm_height);
 #endif
 
     /* must do this before MakeExist */
-    if ((pubvars->vip = X_choose_visual(dmp, context)) == NULL) {
+    if ((pubvars->vip = X_choose_visual(dmp)) == NULL) {
        bu_log("X_open_dm: Can't get an appropriate visual.\n");
-       (void)X_close(dmp, context);
+       (void)X_close(dmp);
        return DM_NULL;
     }
 
 #ifdef HAVE_TK
-    (*context->dm_window_make_exist)(dmp, pubvars->xtkwin);
-    pubvars->win = (*context->dm_window_id)(dmp, pubvars->xtkwin);
+    Tk_MakeWindowExist(pubvars->xtkwin);
+    pubvars->win = Tk_WindowId(pubvars->xtkwin);
     dmp->dm_id = pubvars->win;
-    privars->pix = (Pixmap)(*context->dm_get_pixmap)(dmp, pubvars->dpy, 
pubvars->win, pubvars->xtkwin, dmp->dm_width, dmp->dm_height);
+    privars->pix =
+       Tk_GetPixmap(pubvars->dpy,
+                    pubvars->win,
+                    dmp->dm_width,
+                    dmp->dm_height,
+                    Tk_Depth(pubvars->xtkwin));
 #endif
 
     if (privars->is_trueColor) {
@@ -725,11 +749,12 @@
 
     privars->xmat = &(privars->mod_mat[0]);
 
-    (void)X_configureWin_guts(dmp, context, 1);
+    (void)X_configureWin_guts(dmp, 1);
 
 #ifdef HAVE_TK
-    (*context->dm_window_set_bg)(dmp, pubvars->xtkwin, privars->bg);
-    (*context->dm_window_map)(dmp, pubvars->xtkwin);
+    Tk_SetWindowBackground(pubvars->xtkwin,
+                          privars->bg);
+    Tk_MapWindow(pubvars->xtkwin);
 #endif
 
     return dmp;
@@ -820,7 +845,7 @@
 HIDDEN int
 X_drawVList(struct dm_internal *dmp, struct bn_vlist *vp)
 {
-    extern int vectorThreshold;        /* defined in libdm/dm-generic.c */
+    extern int vectorThreshold;        /* defined in libdm/tcl.c */
 
     static vect_t spnt, lpnt, pnt;
     struct bn_vlist *tvp;
@@ -1411,10 +1436,10 @@
 
 
 HIDDEN int
-X_configureWin(struct dm_internal *dmp, struct dm_context *context, int force)
+X_configureWin(struct dm_internal *dmp, int force)
 {
     /* don't force */
-    return X_configureWin_guts(dmp, context, force);
+    return X_configureWin_guts(dmp, force);
 }
 
 

Modified: brlcad/trunk/src/libdm/dm-generic.c
===================================================================
--- brlcad/trunk/src/libdm/dm-generic.c 2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-generic.c 2020-04-09 18:02:59 UTC (rev 75324)
@@ -27,13 +27,6 @@
 
 #include <string.h>
 
-#include "dm/dm_xvars.h"
-
-#ifdef DM_X
-#  include <X11/Xutil.h>
-#endif
-
-#include "png.h"
 #include "tcl.h"
 
 #include "vmath.h"
@@ -43,9 +36,6 @@
 #include "dm-Null.h"
 #include "rt/solid.h"
 
-/* TODO: this doesn't belong in here, move to a globals.c or eliminate */
-int vectorThreshold = 100000;
-
 extern dm *plot_open(Tcl_Interp *interp, int argc, const char *argv[]);
 extern dm *ps_open(Tcl_Interp *interp, int argc, const char *argv[]);
 extern dm *txt_open(Tcl_Interp *interp, int argc, const char **argv);
@@ -52,13 +42,17 @@
 
 #ifdef DM_X
 #  if defined(HAVE_TK)
-extern dm *X_open_dm(Tcl_Interp *interp, struct dm_context *context, int argc, 
const char **argv);
+extern dm *X_open_dm(Tcl_Interp *interp, int argc, const char **argv);
 #  endif
 #endif /* DM_X */
 
+#ifdef DM_TK
+extern dm *tk_open_dm(Tcl_Interp *interp, int argc, const char **argv);
+#endif /* DM_TK */
+
 #ifdef DM_OGL
 #  if defined(HAVE_TK)
-extern dm *ogl_open(Tcl_Interp *interp, struct dm_context *context, int argc, 
const char **argv);
+extern dm *ogl_open(Tcl_Interp *interp, int argc, const char **argv);
 extern void ogl_fogHint(dm *dmp, int fastfog);
 extern int ogl_share_dlist(dm *dmp1, dm *dmp2);
 #  endif
@@ -71,7 +65,7 @@
 #endif /* DM_OSG*/
 
 #ifdef DM_OSGL
-extern dm *osgl_open(Tcl_Interp *interp, struct dm_context *context, int argc, 
const char **argv);
+extern dm *osgl_open(Tcl_Interp *interp, int argc, const char **argv);
 extern void osgl_fogHint(dm *dmp, int fastfog);
 extern int osgl_share_dlist(dm *dmp1, dm *dmp2);
 #endif /* DM_OSGL*/
@@ -83,7 +77,7 @@
 #endif /* DM_RTGL */
 
 #ifdef DM_WGL
-extern dm *wgl_open(Tcl_Interp *interp, struct dm_context *context, int argc, 
const char **argv);
+extern dm *wgl_open(Tcl_Interp *interp, int argc, const char **argv);
 extern void wgl_fogHint(dm *dmp, int fastfog);
 extern int wgl_share_dlist(dm *dmp1, dm *dmp2);
 #endif /* DM_WGL */
@@ -110,7 +104,7 @@
 
 
 dm *
-dm_open(Tcl_Interp *interp, struct dm_context *context, int type, int argc, 
const char *argv[])
+dm_open(Tcl_Interp *interp, int type, int argc, const char *argv[])
 {
     switch (type) {
        case DM_TYPE_NULL:
@@ -124,13 +118,17 @@
 #ifdef DM_X
 #  if defined(HAVE_TK)
        case DM_TYPE_X:
-           return X_open_dm(interp, context, argc, argv);
+           return X_open_dm(interp, argc, argv);
 #  endif
 #endif
+#ifdef DM_TK
+       case DM_TYPE_TK:
+           return tk_open_dm(interp, argc, argv);
+#endif
 #ifdef DM_OGL
 #  if defined(HAVE_TK)
        case DM_TYPE_OGL:
-           return ogl_open(interp, context, argc, argv);
+           return ogl_open(interp, argc, argv);
 #  endif
 #endif
 #ifdef DM_OSG
@@ -139,7 +137,7 @@
 #endif
 #ifdef DM_OSGL
        case DM_TYPE_OSGL:
-           return osgl_open(interp, context, argc, argv);
+           return osgl_open(interp, argc, argv);
 #endif
 #ifdef DM_RTGL
        case DM_TYPE_RTGL:
@@ -147,7 +145,7 @@
 #endif
 #ifdef DM_WGL
        case DM_TYPE_WGL:
-           return wgl_open(interp, context, argc, argv);
+           return wgl_open(interp, argc, argv);
 #endif
 #ifdef DM_QT
        case DM_TYPE_QT:
@@ -207,36 +205,6 @@
     }
 }
 
-void
-dm_flush(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return;
-#ifdef DM_X
-    XSync(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy, 0);
-#endif
-}
-
-void *
-dm_os_window(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return NULL;
-#if defined(DM_X) || defined(DM_OGL) || defined(DM_OGL) || defined(DM_WGL)
-    return (void *)&(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
-#endif
-    return NULL;
-}
-
-void *
-dm_device_context(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return NULL;
-#if defined(IF_WGL)
-    return (void *)&(((struct dm_xvars *)dmp->dm_vars.pub_vars)->hdc);
-#endif
-    return NULL;
-}
-
-
 fastf_t
 dm_Xx2Normal(dm *dmp, int x)
 {
@@ -442,10 +410,10 @@
 }
 
 int
-dm_close(dm *dmp, struct dm_context *context)
+dm_close(dm *dmp)
 {
     if (UNLIKELY(!dmp)) return 0;
-    return dmp->dm_close(dmp, context);
+    return dmp->dm_close(dmp);
 }
 
 unsigned char *
@@ -497,12 +465,6 @@
     return  &(dmp->dm_clipmin);
 }
 
-void
-dm_set_clipmin(dm *dmp, vect_t clipmin)
-{
-    if (UNLIKELY(!dmp)) return;
-    VMOVE(dmp->dm_clipmin, clipmin);
-}
 
 vect_t *
 dm_get_clipmax(dm *dmp)
@@ -511,13 +473,6 @@
     return  &(dmp->dm_clipmax);
 }
 
-void
-dm_set_clipmax(dm *dmp, vect_t clipmax)
-{
-    if (UNLIKELY(!dmp)) return;
-    VMOVE(dmp->dm_clipmax, clipmax);
-}
-
 int
 dm_get_bound_flag(dm *dmp)
 {
@@ -546,10 +501,10 @@
     return dmp->dm_stereo;
 }
 int
-dm_configure_win(dm *dmp, struct dm_context *context, int force)
+dm_configure_win(dm *dmp, int force)
 {
     if (UNLIKELY(!dmp)) return 0;
-    return dmp->dm_configureWin(dmp, context, force);
+    return dmp->dm_configureWin(dmp, force);
 }
 
 struct bu_vls *
@@ -839,12 +794,6 @@
     return dmp->dm_draw_obj(dmp, obj);
 }
 int
-dm_get_depth_mask(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return 0;
-    return dmp->dm_depthMask;
-}
-int
 dm_set_depth_mask(dm *dmp, int d_on)
 {
     if (UNLIKELY(!dmp)) return 0;
@@ -851,26 +800,11 @@
     return dmp->dm_setDepthMask(dmp, d_on);
 }
 int
-dm_get_debug(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return 0;
-    return dmp->dm_debugLevel;
-}
-
-int
 dm_debug(dm *dmp, int lvl)
 {
     if (UNLIKELY(!dmp)) return 0;
     return dmp->dm_debug(dmp, lvl);
 }
-
-const char *
-dm_get_logfile(dm *dmp)
-{
-    if (!dmp) return NULL;
-    return bu_vls_cstr(&(dmp->dm_log));
-}
-
 int
 dm_logfile(dm *dmp, const char *filename)
 {
@@ -892,20 +826,6 @@
     dmp->dm_vp = vp;
 }
 
-int
-dm_get_clearbufferafter(dm *dmp)
-{
-    if (UNLIKELY(!dmp)) return 0;
-    return dmp->dm_clearBufferAfter;
-}
-
-void
-dm_set_clearbufferafter(dm *dmp, int clearBufferAfter)
-{
-    if (UNLIKELY(!dmp)) return;
-    dmp->dm_clearBufferAfter = clearBufferAfter;
-}
-
 /* This is the generic "catch-all" hook that is used
  * to run any user supplied callbacks.  If more side
  * effects are needed at the libdm level, a task-specific
@@ -1138,274 +1058,6 @@
     return list;
 }
 
-#if defined(DM_X) || defined(DM_OGL)
-
-#ifdef DM_X
-#  include "dm/dm_xvars.h"
-#  include <X11/Xutil.h>
-#endif /* DM_X */
-
-int
-dm_png_write(dm *dmp, FILE *fp, struct bu_vls *msgs)
-{
-    png_structp png_p;
-    png_infop info_p;
-    XImage *ximage_p;
-    unsigned char **rows;
-    unsigned char *idata;
-    unsigned char *irow;
-    int bytes_per_pixel;
-    int bits_per_channel = 8;  /* bits per color channel */
-    int i, j, k;
-    unsigned char *dbyte0, *dbyte1, *dbyte2, *dbyte3;
-    int red_shift;
-    int green_shift;
-    int blue_shift;
-    int red_bits;
-    int green_bits;
-    int blue_bits;
-
-    png_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    if (!png_p) {
-       if (msgs) {
-           bu_vls_printf(msgs, "png: could not create PNG write structure\n");
-       }
-       return BRLCAD_ERROR;
-    }
-
-    info_p = png_create_info_struct(png_p);
-    if (!info_p) {
-       if (msgs) {
-           bu_vls_printf(msgs, "png: could not create PNG info structure\n");
-       }
-       fclose(fp);
-       return BRLCAD_ERROR;
-    }
-
-    ximage_p = XGetImage(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
-                        ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
-                        0, 0,
-                        dmp->dm_width,
-                        dmp->dm_height,
-                        ~0, ZPixmap);
-    if (!ximage_p) {
-       if (msgs) {
-           bu_vls_printf(msgs, "png: could not get XImage\n");
-       }
-       return BRLCAD_ERROR;
-    }
-
-    bytes_per_pixel = ximage_p->bytes_per_line / ximage_p->width;
-
-    if (bytes_per_pixel == 4) {
-       unsigned long mask;
-       unsigned long tmask;
-
-       /* This section assumes 8 bits per channel */
-
-       mask = ximage_p->red_mask;
-       tmask = 1;
-       for (red_shift = 0; red_shift < 32; red_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-
-       mask = ximage_p->green_mask;
-       tmask = 1;
-       for (green_shift = 0; green_shift < 32; green_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-
-       mask = ximage_p->blue_mask;
-       tmask = 1;
-       for (blue_shift = 0; blue_shift < 32; blue_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-
-       /*
-        * We need to reverse things if the image byte order
-        * is different from the system's byte order.
-        */
-       if (((bu_byteorder() == BU_BIG_ENDIAN) && (ximage_p->byte_order == 
LSBFirst)) ||
-           ((bu_byteorder() == BU_LITTLE_ENDIAN) && (ximage_p->byte_order == 
MSBFirst))) {
-           DM_REVERSE_COLOR_BYTE_ORDER(red_shift, ximage_p->red_mask);
-           DM_REVERSE_COLOR_BYTE_ORDER(green_shift, ximage_p->green_mask);
-           DM_REVERSE_COLOR_BYTE_ORDER(blue_shift, ximage_p->blue_mask);
-       }
-
-    } else if (bytes_per_pixel == 2) {
-       unsigned long mask;
-       unsigned long tmask;
-       int bpb = 8;   /* bits per byte */
-
-       /*XXX
-        * This section probably needs logic similar
-        * to the previous section (i.e. bytes_per_pixel == 4).
-        * That is we may need to reverse things depending on
-        * the image byte order and the system's byte order.
-        */
-
-       mask = ximage_p->red_mask;
-       tmask = 1;
-       for (red_shift = 0; red_shift < 16; red_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-       for (red_bits = red_shift; red_bits < 16; red_bits++) {
-           if (!(tmask & mask))
-               break;
-           tmask = tmask << 1;
-       }
-
-       red_bits = red_bits - red_shift;
-       if (red_shift == 0)
-           red_shift = red_bits - bpb;
-       else
-           red_shift = red_shift - (bpb - red_bits);
-
-       mask = ximage_p->green_mask;
-       tmask = 1;
-       for (green_shift = 0; green_shift < 16; green_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-       for (green_bits = green_shift; green_bits < 16; green_bits++) {
-           if (!(tmask & mask))
-               break;
-           tmask = tmask << 1;
-       }
-
-       green_bits = green_bits - green_shift;
-       green_shift = green_shift - (bpb - green_bits);
-
-       mask = ximage_p->blue_mask;
-       tmask = 1;
-       for (blue_shift = 0; blue_shift < 16; blue_shift++) {
-           if (tmask & mask)
-               break;
-           tmask = tmask << 1;
-       }
-       for (blue_bits = blue_shift; blue_bits < 16; blue_bits++) {
-           if (!(tmask & mask))
-               break;
-           tmask = tmask << 1;
-       }
-       blue_bits = blue_bits - blue_shift;
-
-       if (blue_shift == 0)
-           blue_shift = blue_bits - bpb;
-       else
-           blue_shift = blue_shift - (bpb - blue_bits);
-    } else {
-       if (msgs) {
-           bu_vls_printf(msgs, "png: %d bytes per pixel is not yet 
supported\n", bytes_per_pixel);
-       }
-       return BRLCAD_ERROR;
-    }
-
-    rows = (unsigned char **)bu_calloc(ximage_p->height, sizeof(unsigned char 
*), "rows");
-    idata = (unsigned char *)bu_calloc(ximage_p->height * ximage_p->width, 4, 
"png data");
-
-    /* for each scanline */
-    for (i = ximage_p->height - 1, j = 0; 0 <= i; --i, ++j) {
-       /* irow points to the current scanline in ximage_p */
-       irow = (unsigned char *)(ximage_p->data + 
((ximage_p->height-i-1)*ximage_p->bytes_per_line));
-
-       if (bytes_per_pixel == 4) {
-           unsigned int pixel;
-
-           /* rows[j] points to the current scanline in idata */
-           rows[j] = (unsigned char *)(idata + 
((ximage_p->height-i-1)*ximage_p->bytes_per_line));
-
-           /* for each pixel in current scanline of ximage_p */
-           for (k = 0; k < ximage_p->bytes_per_line; k += bytes_per_pixel) {
-               pixel = *((unsigned int *)(irow + k));
-
-               dbyte0 = rows[j] + k;
-               dbyte1 = dbyte0 + 1;
-               dbyte2 = dbyte0 + 2;
-               dbyte3 = dbyte0 + 3;
-
-               *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
-               *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
-               *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
-               *dbyte3 = 255;
-           }
-       } else if (bytes_per_pixel == 2) {
-           unsigned short spixel;
-           unsigned long pixel;
-
-           /* rows[j] points to the current scanline in idata */
-           rows[j] = (unsigned char *)(idata + 
((ximage_p->height-i-1)*ximage_p->bytes_per_line*2));
-
-           /* for each pixel in current scanline of ximage_p */
-           for (k = 0; k < ximage_p->bytes_per_line; k += bytes_per_pixel) {
-               spixel = *((unsigned short *)(irow + k));
-               pixel = spixel;
-
-               dbyte0 = rows[j] + k*2;
-               dbyte1 = dbyte0 + 1;
-               dbyte2 = dbyte0 + 2;
-               dbyte3 = dbyte0 + 3;
-
-               if (0 <= red_shift)
-                   *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
-               else
-                   *dbyte0 = (pixel & ximage_p->red_mask) << -red_shift;
-
-               *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
-
-               if (0 <= blue_shift)
-                   *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
-               else
-                   *dbyte2 = (pixel & ximage_p->blue_mask) << -blue_shift;
-
-               *dbyte3 = 255;
-           }
-       } else {
-           bu_free(rows, "rows");
-           bu_free(idata, "image data");
-           fclose(fp);
-
-           if (msgs) {
-               bu_vls_printf(msgs, "png: not supported for this platform\n");
-           }
-           return BRLCAD_ERROR;
-       }
-    }
-
-    png_init_io(png_p, fp);
-    png_set_filter(png_p, 0, PNG_FILTER_NONE);
-    png_set_compression_level(png_p, 9);
-    png_set_IHDR(png_p, info_p, ximage_p->width, ximage_p->height, 
bits_per_channel,
-                PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
-                PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-    png_set_gAMA(png_p, info_p, 0.77);
-    png_write_info(png_p, info_p);
-    png_write_image(png_p, rows);
-    png_write_end(png_p, NULL);
-
-    bu_free(rows, "rows");
-    bu_free(idata, "image data");
-
-    return BRLCAD_OK;
-}
-#else
-int
-dm_png_write(dm *UNUSED(dmp), FILE *UNUSED(fp), struct bu_vls *msgs)
-{
-    bu_vls_printf(msgs, "PNG output not supported\n");
-       return BRLCAD_OK;
-}
-#endif // defined(DM_X) || defined(DM_OGL)
-
 /*
  * Local Variables:
  * mode: C

Modified: brlcad/trunk/src/libdm/dm-glx.h
===================================================================
--- brlcad/trunk/src/libdm/dm-glx.h     2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-glx.h     2020-04-09 18:02:59 UTC (rev 75324)
@@ -28,8 +28,6 @@
 
 #include "common.h"
 
-#include "dm.h"
-
 /* Map +/-2048 GED space into -1.0..+1.0 :: x/2048*/
 #define GED2IRIS(x)    (((float)(x))*0.00048828125)
 
@@ -52,8 +50,8 @@
     struct bu_list l;
     Display *dpy;
     Window win;
-    dm_win top;
-    dm_win xtkwin;
+    Tk_Window top;
+    Tk_Window xtkwin;
     int depth;
     int omx, omy;
     unsigned int mb_mask;

Modified: brlcad/trunk/src/libdm/dm-ogl.c
===================================================================
--- brlcad/trunk/src/libdm/dm-ogl.c     2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-ogl.c     2020-04-09 18:02:59 UTC (rev 75324)
@@ -69,6 +69,8 @@
 #undef y1
 #undef j1
 
+#include "tk.h"
+
 #undef VMIN            /* is used in vmath.h, too */
 
 #include "vmath.h"
@@ -94,13 +96,14 @@
 #define YSTEREO                491     /* subfield height, in scanlines */
 #define YOFFSET_LEFT   532     /* YSTEREO + YBLANK ? */
 
-HIDDEN XVisualInfo *ogl_choose_visual(struct dm_internal *dmp, struct 
dm_context *, dm_win tkwin);
+HIDDEN XVisualInfo *ogl_choose_visual(struct dm_internal *dmp, Tk_Window 
tkwin);
 
 /* Display Manager package interface */
 #define IRBOUND 4095.9 /* Max magnification in Rot matrix */
 #define PLOTBOUND 1000.0       /* Max magnification in Rot matrix */
 
-HIDDEN int ogl_close(struct dm_internal *dmp, struct dm_context *context);
+struct dm_internal *ogl_open(Tcl_Interp *interp, int argc, char **argv);
+HIDDEN int ogl_close(struct dm_internal *dmp);
 HIDDEN int ogl_drawBegin(struct dm_internal *dmp);
 HIDDEN int ogl_drawEnd(struct dm_internal *dmp);
 HIDDEN int ogl_normal(struct dm_internal *dmp);
@@ -120,7 +123,7 @@
 HIDDEN int ogl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned 
char g, unsigned char b);
 HIDDEN int ogl_setLineAttr(struct dm_internal *dmp, int width, int style);
 HIDDEN int ogl_configureWin_guts(struct dm_internal *dmp, int force);
-HIDDEN int ogl_configureWin(struct dm_internal *dmp, struct dm_context *, int 
force);
+HIDDEN int ogl_configureWin(struct dm_internal *dmp, int force);
 HIDDEN int ogl_setLight(struct dm_internal *dmp, int lighting_on);
 HIDDEN int ogl_setTransparency(struct dm_internal *dmp, int transparency_on);
 HIDDEN int ogl_setDepthMask(struct dm_internal *dmp, int depthMask_on);
@@ -405,7 +408,7 @@
 
 
 HIDDEN int
-ogl_configureWin(struct dm_internal *dmp, struct dm_context *UNUSED(context), 
int force)
+ogl_configureWin(struct dm_internal *dmp, int force)
 {
     if (!glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
                        ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
@@ -458,7 +461,7 @@
  * OpenGL
  */
 HIDDEN XVisualInfo *
-ogl_choose_visual(struct dm_internal *dmp, struct dm_context *context, dm_win 
tkwin)
+ogl_choose_visual(struct dm_internal *dmp, Tk_Window tkwin)
 {
     struct modifiable_ogl_vars *mvars = (struct modifiable_ogl_vars 
*)dmp->m_vars;
     XVisualInfo *vip, vitemp, *vibase, *maxvip;
@@ -555,7 +558,10 @@
                                    RootWindow(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy,
                                               maxvip->screen), maxvip->visual, 
AllocNone);
 
-               if ((*context->dm_window_set_visual)(dmp, tkwin, maxvip, 
((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap)) {
+               if (Tk_SetWindowVisual(tkwin,
+                                      maxvip->visual, maxvip->depth,
+                                      ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->cmap)) {
+
                    glXGetConfig(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy,
                                 maxvip, GLX_DEPTH_SIZE,
                                 &mvars->depth);
@@ -599,21 +605,21 @@
  * Gracefully release the display.
  */
 HIDDEN int
-ogl_close(struct dm_internal *dmp, struct dm_context *context)
+ogl_close(struct dm_internal *dmp)
 {
-    struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
-    struct ogl_vars *privvars = (struct ogl_vars *)dmp->dm_vars.priv_vars;
-    if (pubvars->dpy) {
-       if (privvars->glxc) {
-           glXMakeCurrent(pubvars->dpy, None, NULL);
-           glXDestroyContext(pubvars->dpy, privvars->glxc);
+    if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy) {
+       if (((struct ogl_vars *)dmp->dm_vars.priv_vars)->glxc) {
+           glXMakeCurrent(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy, 
None, NULL);
+           glXDestroyContext(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                             ((struct ogl_vars 
*)dmp->dm_vars.priv_vars)->glxc);
        }
 
-       if (pubvars->cmap)
-           XFreeColormap(pubvars->dpy, pubvars->cmap);
+       if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap)
+           XFreeColormap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                         ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap);
 
-       if (pubvars->xtkwin)
-           (*context->dm_window_destroy)(dmp, pubvars->xtkwin);
+       if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin)
+           Tk_DestroyWindow(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin);
     }
 
     bu_vls_free(&dmp->dm_pathName);
@@ -632,7 +638,7 @@
  *
  */
 struct dm_internal *
-ogl_open(Tcl_Interp *interp, struct dm_context *context, int argc, char **argv)
+ogl_open(Tcl_Interp *interp, int argc, char **argv)
 {
     static int count = 0;
     GLfloat backgnd[4];
@@ -654,12 +660,16 @@
     Display *tmp_dpy = (Display *)NULL;
     struct dm_internal *dmp = (struct dm_internal *)NULL;
     struct modifiable_ogl_vars *mvars = NULL;
-    dm_win tkwin = NULL;
+    Tk_Window tkwin = (Tk_Window)NULL;
     int screen_number = -1;
 
     struct dm_xvars *pubvars = NULL;
     struct ogl_vars *privvars = NULL;
 
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
+
     BU_GET(dmp, struct dm_internal);
 
     *dmp = dm_ogl; /* struct copy */
@@ -670,13 +680,6 @@
     dmp->dm_bits_per_channel = 8;
     bu_vls_init(&(dmp->dm_log));
 
-    if ((tkwin = (*context->dm_window_main)(dmp)) == NULL) {
-       bu_free((void *)privvars, "privvars");
-       bu_free((void *)pubvars, "pubvars");
-       bu_free((void *)dmp, "dmp");
-       return DM_NULL;
-    }
-
     BU_ALLOC(dmp->dm_vars.pub_vars, struct dm_xvars);
     if (dmp->dm_vars.pub_vars == (void *)NULL) {
        bu_free(dmp, "ogl_open: dmp");
@@ -741,7 +744,7 @@
 
     if ((tmp_dpy = XOpenDisplay(bu_vls_addr(&dmp->dm_dName))) == NULL) {
        bu_vls_free(&init_proc_vls);
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
@@ -751,7 +754,7 @@
 
        if (!XQueryExtension(tmp_dpy, "GLX", &return_val, &return_val, 
&return_val)) {
            bu_vls_free(&init_proc_vls);
-           (void)ogl_close(dmp, context);
+           (void)ogl_close(dmp);
            return DM_NULL;
        }
     }
@@ -785,8 +788,11 @@
 
     if (dmp->dm_top) {
        /* Make xtkwin a toplevel window */
-       pubvars->xtkwin = (*context->dm_window_create_from_path)(dmp, tkwin,
-               bu_vls_cstr(&dmp->dm_pathName), bu_vls_cstr(&dmp->dm_dName));
+       pubvars->xtkwin =
+           Tk_CreateWindowFromPath(interp,
+                                   tkwin,
+                                   bu_vls_addr(&dmp->dm_pathName),
+                                   bu_vls_addr(&dmp->dm_dName));
        pubvars->top = pubvars->xtkwin;
     } else {
        char *cp;
@@ -799,28 +805,35 @@
 
            bu_vls_strncpy(&top_vls, (const char 
*)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
 
-           pubvars->top = (*context->dm_window_from_name)(dmp, 
bu_vls_cstr(&top_vls), tkwin);
+           pubvars->top =
+               Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
            bu_vls_free(&top_vls);
        }
 
        /* Make xtkwin an embedded window */
-       pubvars->xtkwin = (*context->dm_window_create_embedded)(dmp, 
pubvars->top, cp + 1);
+       pubvars->xtkwin =
+           Tk_CreateWindow(interp, pubvars->top,
+                           cp + 1, (char *)NULL);
     }
 
     if (pubvars->xtkwin == NULL) {
        bu_log("dm-Ogl: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
        bu_vls_free(&init_proc_vls);
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
-    const char *winname = (*context->dm_window_name)(dmp, pubvars->xtkwin);
-    bu_vls_printf(&dmp->dm_tkName, "%s", winname);
+    bu_vls_printf(&dmp->dm_tkName, "%s",
+                 (char *)Tk_Name(pubvars->xtkwin));
 
-    if ((*context->dm_init)(dmp, bu_vls_cstr(&init_proc_vls)) == BRLCAD_ERROR) 
{
+    bu_vls_printf(&str, "_init_dm %s %s\n",
+                 bu_vls_addr(&init_proc_vls),
+                 bu_vls_addr(&dmp->dm_pathName));
+
+    if (Tcl_Eval(interp, bu_vls_addr(&str)) == BRLCAD_ERROR) {
        bu_vls_free(&init_proc_vls);
        bu_vls_free(&str);
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
@@ -827,30 +840,33 @@
     bu_vls_free(&init_proc_vls);
     bu_vls_free(&str);
 
-    pubvars->dpy = (Display *)(*context->dm_display)(dmp, pubvars->top);
+    pubvars->dpy =
+       Tk_Display(pubvars->top);
 
     /* make sure there really is a display before proceeding. */
     if (!(pubvars->dpy)) {
        bu_vls_free(&init_proc_vls);
        bu_vls_free(&str);
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
-    (*context->dm_window_geom)(dmp, pubvars->xtkwin, &dmp->dm_width, 
&dmp->dm_height);
+    Tk_GeometryRequest(pubvars->xtkwin,
+                      dmp->dm_width,
+                      dmp->dm_height);
 
     /* must do this before MakeExist */
-    if ((pubvars->vip=ogl_choose_visual(dmp, context, pubvars->xtkwin)) == 
NULL) {
+    if ((pubvars->vip=ogl_choose_visual(dmp, pubvars->xtkwin)) == NULL) {
        bu_log("ogl_open: Can't get an appropriate visual.\n");
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
     pubvars->depth = mvars->depth;
 
-    (*context->dm_window_make_exist)(dmp, pubvars->xtkwin);
+    Tk_MakeWindowExist(pubvars->xtkwin);
 
-    pubvars->win = (*context->dm_window_id)(dmp, pubvars->xtkwin);
+    pubvars->win = Tk_WindowId(pubvars->xtkwin);
     dmp->dm_id = pubvars->win;
 
     /* open GLX context */
@@ -857,7 +873,7 @@
     if ((privvars->glxc =
         glXCreateContext(pubvars->dpy, pubvars->vip, (GLXContext)NULL, 
GL_TRUE))==NULL) {
        bu_log("ogl_open: couldn't create glXContext.\n");
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
@@ -922,11 +938,11 @@
 
 #endif /* HAVE_X11_EXTENSIONS_XINPUT_H */
 
-    (*context->dm_window_map)(dmp, pubvars->xtkwin);
+    Tk_MapWindow(pubvars->xtkwin);
 
     if (!glXMakeCurrent(pubvars->dpy, pubvars->win, privvars->glxc)) {
        bu_log("ogl_open: Couldn't make context current\n");
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 
@@ -933,7 +949,7 @@
     /* display list (fontOffset + char) will display a given ASCII char */
     if ((privvars->fontOffset = glGenLists(128))==0) {
        bu_log("dm-ogl: Can't make display lists for font.\n");
-       (void)ogl_close(dmp, context);
+       (void)ogl_close(dmp);
        return DM_NULL;
     }
 

Modified: brlcad/trunk/src/libdm/dm-osgl.cpp
===================================================================
--- brlcad/trunk/src/libdm/dm-osgl.cpp  2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-osgl.cpp  2020-04-09 18:02:59 UTC (rev 75324)
@@ -80,9 +80,9 @@
 #define PLOTBOUND 1000.0       /* Max magnification in Rot matrix */
 
 extern "C" {
-    struct dm_internal *osgl_open(Tcl_Interp *interp, struct dm_context 
*context, int argc, char **argv);
+    struct dm_internal *osgl_open(Tcl_Interp *interp, int argc, char **argv);
 }
-HIDDEN int osgl_close(struct dm_internal *dmp, struct dm_context *context);
+HIDDEN int osgl_close(struct dm_internal *dmp);
 HIDDEN int osgl_drawBegin(struct dm_internal *dmp);
 HIDDEN int osgl_drawEnd(struct dm_internal *dmp);
 HIDDEN int osgl_normal(struct dm_internal *dmp);
@@ -102,7 +102,7 @@
 HIDDEN int osgl_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned 
char g, unsigned char b);
 HIDDEN int osgl_setLineAttr(struct dm_internal *dmp, int width, int style);
 HIDDEN int osgl_configureWin_guts(struct dm_internal *dmp, int force);
-HIDDEN int osgl_configureWin(struct dm_internal *dmp, struct dm_context 
*context, int force);
+HIDDEN int osgl_configureWin(struct dm_internal *dmp, int force);
 HIDDEN int osgl_setLight(struct dm_internal *dmp, int lighting_on);
 HIDDEN int osgl_setTransparency(struct dm_internal *dmp, int transparency_on);
 HIDDEN int osgl_setDepthMask(struct dm_internal *dmp, int depthMask_on);
@@ -288,7 +288,7 @@
 
 
 HIDDEN int
-osgl_configureWin(struct dm_internal *dmp, struct dm_context *UNUSED(context), 
int force)
+osgl_configureWin(struct dm_internal *dmp, int force)
 {
     ((struct osgl_vars 
*)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
 
@@ -355,7 +355,7 @@
  * Gracefully release the display.
  */
 HIDDEN int
-osgl_close(struct dm_internal *dmp, struct dm_context *UNUSED(context))
+osgl_close(struct dm_internal *dmp)
 {
     ((struct osgl_vars 
*)dmp->dm_vars.priv_vars)->graphicsContext->makeCurrent();
     ((struct osgl_vars 
*)dmp->dm_vars.priv_vars)->graphicsContext->releaseContext();
@@ -362,8 +362,8 @@
 
 
     if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin) {
-       Tk_DeleteEventHandler((Tk_Window)((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin, VisibilityChangeMask, OSGEventProc, 
(ClientData)dmp);
-       Tk_DestroyWindow((Tk_Window)((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin);
+       Tk_DeleteEventHandler(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin, VisibilityChangeMask, OSGEventProc, 
(ClientData)dmp);
+       Tk_DestroyWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
     }
 
     bu_vls_free(&dmp->dm_pathName);
@@ -382,7 +382,7 @@
  *
  */
 extern "C" struct dm_internal *
-osgl_open(Tcl_Interp *interp, struct dm_context *context, int argc, char 
**argv)
+osgl_open(Tcl_Interp *interp, int argc, char **argv)
 {
     static int count = 0;
     GLfloat backgnd[4];
@@ -395,6 +395,10 @@
     struct dm_xvars *pubvars = NULL;
     struct osgl_vars *privvars = NULL;
 
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
+
     BU_GET(dmp, struct dm_internal);
 
     *dmp = dm_osgl; /* struct copy */
@@ -420,13 +424,6 @@
     }
     privvars = (struct osgl_vars *)dmp->dm_vars.priv_vars;
 
-    if ((tkwin = (Tk_Window)(*context->dm_window_main)(dmp)) == NULL) {
-       bu_free((void *)privvars, "privvars");
-       bu_free((void *)pubvars, "pubvars");
-       bu_free((void *)dmp, "dmp");
-       return DM_NULL;
-    }
-
     dmp->dm_get_internal(dmp);
     mvars = (struct modifiable_osgl_vars *)dmp->m_vars;
 
@@ -474,8 +471,11 @@
 
     if (dmp->dm_top) {
        /* Make xtkwin a toplevel window */
-       pubvars->xtkwin = 
(Tk_Window)(*context->dm_window_create_from_path)(dmp, tkwin,
-               bu_vls_cstr(&dmp->dm_pathName), bu_vls_cstr(&dmp->dm_dName));
+       pubvars->xtkwin =
+           Tk_CreateWindowFromPath(interp,
+                                   tkwin,
+                                   bu_vls_addr(&dmp->dm_pathName),
+                                   bu_vls_addr(&dmp->dm_dName));
        pubvars->top = pubvars->xtkwin;
     } else {
        char *cp;
@@ -488,18 +488,21 @@
 
            bu_vls_strncpy(&top_vls, (const char 
*)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
 
-           pubvars->top = (Tk_Window)(*context->dm_window_from_name)(dmp, 
bu_vls_cstr(&top_vls), tkwin);
+           pubvars->top =
+               Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
            bu_vls_free(&top_vls);
        }
 
        /* Make xtkwin an embedded window */
-       pubvars->xtkwin = 
(Tk_Window)((*context->dm_window_create_embedded)(dmp, pubvars->top, cp + 1));
+       pubvars->xtkwin =
+           Tk_CreateWindow(interp, pubvars->top,
+                           cp + 1, (char *)NULL);
     }
 
     if (pubvars->xtkwin == NULL) {
        bu_log("dm-osgl: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
        bu_vls_free(&init_proc_vls);
-       (void)osgl_close(dmp, context);
+       (void)osgl_close(dmp);
        return DM_NULL;
     }
 
@@ -516,7 +519,7 @@
            if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
                bu_vls_free(&init_proc_vls);
                bu_vls_free(&str);
-               (void)osgl_close(dmp, context);
+               (void)osgl_close(dmp);
                return DM_NULL;
            } else {
                Tcl_Obj *tclresult = Tcl_GetObjResult(interp);
@@ -529,7 +532,7 @@
            if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
                bu_vls_free(&init_proc_vls);
                bu_vls_free(&str);
-               (void)osgl_close(dmp, context);
+               (void)osgl_close(dmp);
                return DM_NULL;
            } else {
                Tcl_Obj *tclresult = Tcl_GetObjResult(interp);
@@ -547,13 +550,18 @@
        }
     }
 
-    const char *winname = (*context->dm_window_name)(dmp, pubvars->xtkwin);
-    bu_vls_printf(&dmp->dm_tkName, "%s", winname);
+    bu_vls_printf(&dmp->dm_tkName, "%s",
+                 (char *)Tk_Name(pubvars->xtkwin));
 
-    if ((*context->dm_init)(dmp, bu_vls_cstr(&init_proc_vls)) == BRLCAD_ERROR) 
{
+    /* Important - note that this is a bu_vls_sprintf, to clear the string */
+    bu_vls_sprintf(&str, "_init_dm %s %s\n",
+                 bu_vls_addr(&init_proc_vls),
+                 bu_vls_addr(&dmp->dm_pathName));
+
+    if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
        bu_vls_free(&init_proc_vls);
        bu_vls_free(&str);
-       (void)osgl_close(dmp, context);
+       (void)osgl_close(dmp);
        return DM_NULL;
     }
 
@@ -560,26 +568,29 @@
     bu_vls_free(&init_proc_vls);
     bu_vls_free(&str);
 
-    pubvars->dpy = (Display *)(*context->dm_display)(dmp, pubvars->top);
+    pubvars->dpy =
+       Tk_Display(pubvars->top);
 
     /* make sure there really is a display before proceeding. */
     if (!(pubvars->dpy)) {
        bu_vls_free(&init_proc_vls);
        bu_vls_free(&str);
-       (void)osgl_close(dmp, context);
+       (void)osgl_close(dmp);
        return DM_NULL;
     }
 
-    (*context->dm_window_geom)(dmp, pubvars->xtkwin, &dmp->dm_width, 
&dmp->dm_height);
+    Tk_GeometryRequest(pubvars->xtkwin,
+                      dmp->dm_width,
+                      dmp->dm_height);
 
     pubvars->depth = mvars->depth;
 
-    (*context->dm_window_make_exist)(dmp, pubvars->xtkwin);
+    Tk_MakeWindowExist(pubvars->xtkwin);
 
-    pubvars->win = (*context->dm_window_id)(dmp, pubvars->xtkwin);
+    pubvars->win = Tk_WindowId(pubvars->xtkwin);
     dmp->dm_id = pubvars->win;
 
-    (*context->dm_window_map)(dmp, pubvars->xtkwin);
+    Tk_MapWindow(pubvars->xtkwin);
 
     // Init the Windata Variable that holds the handle for the Window to 
display OSG in.
     // Check the QOSGWidget.cpp example for more logic relevant to this.  Need 
to find
@@ -626,7 +637,7 @@
     if (privvars->fs == NULL) {
        bu_log("dm-osgl: Failed to create font stash");
        bu_vls_free(&init_proc_vls);
-       (void)osgl_close(dmp, context);
+       (void)osgl_close(dmp);
        return DM_NULL;
     }
     privvars->fontNormal = FONS_INVALID;
@@ -676,7 +687,7 @@
     osgl_setLight(dmp, dmp->dm_light);
 
     //Tk_CreateEventHandler(pubvars->xtkwin, 
PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask|VisibilityChangeMask|ButtonReleaseMask,
 OSGEventProc, (ClientData)dmp);
-    Tk_CreateEventHandler((Tk_Window)pubvars->xtkwin, VisibilityChangeMask, 
OSGEventProc, (ClientData)dmp);
+    Tk_CreateEventHandler(pubvars->xtkwin, VisibilityChangeMask, OSGEventProc, 
(ClientData)dmp);
 
     privvars->is_init = 0;
 

Modified: brlcad/trunk/src/libdm/dm-plot.c
===================================================================
--- brlcad/trunk/src/libdm/dm-plot.c    2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-plot.c    2020-04-09 18:02:59 UTC (rev 75324)
@@ -72,7 +72,7 @@
  * Gracefully release the display.
  */
 HIDDEN int
-plot_close(dm *dmp, struct dm_context *UNUSED(context))
+plot_close(dm *dmp)
 {
     if (!dmp)
        return BRLCAD_ERROR;
@@ -652,7 +652,7 @@
                break;
            default:
                Tcl_AppendStringsToObj(obj, "bad PLOT option ", argv[0], "\n", 
(char *)NULL);
-               (void)plot_close(dmp, NULL);
+               (void)plot_close(dmp);
 
                Tcl_SetObjResult(interp, obj);
                return DM_NULL;
@@ -661,7 +661,7 @@
     }
     if (argv[0] == (char *)0) {
        Tcl_AppendStringsToObj(obj, "no filename or filter specified\n", (char 
*)NULL);
-       (void)plot_close(dmp, NULL);
+       (void)plot_close(dmp);
 
        Tcl_SetObjResult(interp, obj);
        return DM_NULL;
@@ -683,7 +683,7 @@
        if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp =
             popen(bu_vls_addr(&((struct plot_vars 
*)dmp->dm_vars.priv_vars)->vls), "w")) == NULL) {
            perror(bu_vls_addr(&((struct plot_vars 
*)dmp->dm_vars.priv_vars)->vls));
-           (void)plot_close(dmp, NULL);
+           (void)plot_close(dmp);
            Tcl_SetObjResult(interp, obj);
            return DM_NULL;
        }
@@ -695,7 +695,7 @@
        if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp =
             fopen(bu_vls_addr(&((struct plot_vars 
*)dmp->dm_vars.priv_vars)->vls), "wb")) == NULL) {
            perror(bu_vls_addr(&((struct plot_vars 
*)dmp->dm_vars.priv_vars)->vls));
-           (void)plot_close(dmp, NULL);
+           (void)plot_close(dmp);
            Tcl_SetObjResult(interp, obj);
            return DM_NULL;
        }

Modified: brlcad/trunk/src/libdm/dm-ps.c
===================================================================
--- brlcad/trunk/src/libdm/dm-ps.c      2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-ps.c      2020-04-09 18:02:59 UTC (rev 75324)
@@ -68,7 +68,7 @@
  * Gracefully release the display.
  */
 HIDDEN int
-ps_close(dm *dmp, struct dm_context *UNUSED(context))
+ps_close(dm *dmp)
 {
     if (!((struct ps_vars *)dmp->dm_vars.priv_vars)->ps_fp)
        return BRLCAD_ERROR;
@@ -634,7 +634,7 @@
                    argv++;
                    if (argv[0] == (char *)0 || argv[0][0] == '-') {
                        Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-                       (void)ps_close(dmp, NULL);
+                       (void)ps_close(dmp);
 
                        Tcl_SetObjResult(interp, obj);
                        return DM_NULL;
@@ -649,7 +649,7 @@
                    argv++;
                    if (argv[0] == (char *)0 || argv[0][0] == '-') {
                        Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-                       (void)ps_close(dmp, NULL);
+                       (void)ps_close(dmp);
 
                        Tcl_SetObjResult(interp, obj);
                        return DM_NULL;
@@ -664,7 +664,7 @@
                    argv++;
                    if (argv[0] == (char *)0 || argv[0][0] == '-') {
                        Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-                       (void)ps_close(dmp, NULL);
+                       (void)ps_close(dmp);
 
                        Tcl_SetObjResult(interp, obj);
                        return DM_NULL;
@@ -682,7 +682,7 @@
                        argv++;
                        if (argv[0] == (char *)0 || argv[0][0] == '-') {
                            Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-                           (void)ps_close(dmp, NULL);
+                           (void)ps_close(dmp);
 
                            Tcl_SetObjResult(interp, obj);
                            return DM_NULL;
@@ -700,7 +700,7 @@
                    argv++;
                    if (argv[0] == (char *)0 || argv[0][0] == '-') {
                        Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-                       (void)ps_close(dmp, NULL);
+                       (void)ps_close(dmp);
 
                        Tcl_SetObjResult(interp, obj);
                        return DM_NULL;
@@ -713,7 +713,7 @@
                break;
            default:
                Tcl_AppendStringsToObj(obj, ps_usage, (char *)0);
-               (void)ps_close(dmp, NULL);
+               (void)ps_close(dmp);
 
                Tcl_SetObjResult(interp, obj);
                return DM_NULL;
@@ -723,7 +723,7 @@
 
     if (argv[0] == (char *)0) {
        Tcl_AppendStringsToObj(obj, "no filename specified\n", (char *)NULL);
-       (void)ps_close(dmp, NULL);
+       (void)ps_close(dmp);
 
        Tcl_SetObjResult(interp, obj);
        return DM_NULL;
@@ -736,7 +736,7 @@
        Tcl_AppendStringsToObj(obj, "f_ps: Error opening file - ",
                               ((struct ps_vars 
*)dmp->dm_vars.priv_vars)->fname,
                               "\n", (char *)NULL);
-       (void)ps_close(dmp, NULL);
+       (void)ps_close(dmp);
 
        Tcl_SetObjResult(interp, obj);
        return DM_NULL;

Modified: brlcad/trunk/src/libdm/dm-qt.cpp
===================================================================
--- brlcad/trunk/src/libdm/dm-qt.cpp    2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-qt.cpp    2020-04-09 18:02:59 UTC (rev 75324)
@@ -61,7 +61,7 @@
  * Release the display manager
  */
 HIDDEN int
-qt_close(dm *dmp, struct dm_context *context)
+qt_close(dm *dmp)
 {
     struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
     struct qt_vars *privars = (struct qt_vars *)dmp->dm_vars.priv_vars;
@@ -77,7 +77,7 @@
     delete privars->parent;
 
     privars->qapp->quit();
-    (*context->dm_window_destroy)(dmp, pubvars->xtkwin);
+    Tk_DestroyWindow(pubvars->xtkwin);
 
     bu_vls_free(&dmp->dm_pathName);
     bu_vls_free(&dmp->dm_tkName);
@@ -572,16 +572,14 @@
 
 
 HIDDEN int
-qt_configureWin(dm *dmp, struct dm_context *context, int force)
+qt_configureWin(dm *dmp, int force)
 {
     struct dm_xvars *pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
     struct qt_vars *privars = (struct qt_vars *)dmp->dm_vars.priv_vars;
 
-    int width = 0;
-    int height = 0;
+    int width = Tk_Width(pubvars->xtkwin);
+    int height = Tk_Height(pubvars->xtkwin);
 
-    (*context->dm_window_geom)(dmp, pubvars->xtkwin, &dmp->dm_width, 
&dmp->dm_height);
-
     if (!force &&
        dmp->dm_height == height &&
        dmp->dm_width == width)
@@ -776,7 +774,7 @@
  *
  */
 dm *
-qt_open(Tcl_Interp *interp, struct dm_context *context, int argc, char **argv)
+qt_open(Tcl_Interp *interp, int argc, char **argv)
 {
     static int count = 0;
     int make_square = -1;
@@ -792,6 +790,10 @@
        return DM_NULL;
     }
 
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
+
     BU_ALLOC(dmp, struct dm_internal);
 
     *dmp = dm_qt; /* struct copy */
@@ -803,13 +805,6 @@
     BU_ALLOC(dmp->dm_vars.priv_vars, struct qt_vars);
     privars = (struct qt_vars *)dmp->dm_vars.priv_vars;
 
-    if ((tkwin = (Tk_Window)(*context->dm_window_main)(dmp)) == NULL) {
-       bu_free((void *)privars, "privars");
-       bu_free((void *)pubvars, "pubvars");
-       bu_free((void *)dmp, "dmp");
-       return DM_NULL;
-    }
-
     bu_vls_init(&dmp->dm_pathName);
     bu_vls_init(&dmp->dm_tkName);
     bu_vls_init(&dmp->dm_dName);
@@ -842,8 +837,9 @@
 
     if (dmp->dm_top) {
        /* Make xtkwin a toplevel window */
-       pubvars->xtkwin = 
(Tk_Window)(*context->dm_window_create_from_path)(dmp, tkwin,
-               bu_vls_cstr(&dmp->dm_pathName), bu_vls_cstr(&dmp->dm_dName));
+       pubvars->xtkwin = Tk_CreateWindowFromPath(interp, tkwin,
+                                                 
bu_vls_addr(&dmp->dm_pathName),
+                                                 bu_vls_addr(&dmp->dm_dName));
        pubvars->top = pubvars->xtkwin;
     } else {
        char *cp;
@@ -856,27 +852,31 @@
 
            bu_vls_strncpy(&top_vls, (const char 
*)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
 
-           pubvars->top = (Tk_Window)(*context->dm_window_from_name)(dmp, 
bu_vls_cstr(&top_vls), tkwin);
+           pubvars->top = Tk_NameToWindow(interp, bu_vls_addr(&top_vls), 
tkwin);
            bu_vls_free(&top_vls);
        }
 
        /* Make xtkwin an embedded window */
-       pubvars->xtkwin = (Tk_Window)(*context->dm_window_create_embedded)(dmp, 
pubvars->top, cp + 1);
+       pubvars->xtkwin =
+           Tk_CreateWindow(interp, pubvars->top,
+                           cp + 1, (char *)NULL);
     }
 
     if (pubvars->xtkwin == NULL) {
        bu_log("qt_open: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
-       (void)qt_close(dmp, context);
+       (void)qt_close(dmp);
        return DM_NULL;
     }
 
-    const char *winname = (*context->dm_window_name)(dmp, pubvars->xtkwin);
-    bu_vls_printf(&dmp->dm_tkName, "%s", winname);
+    bu_vls_printf(&dmp->dm_tkName, "%s", (char *)Tk_Name(pubvars->xtkwin));
 
-    if ((*context->dm_init)(dmp, bu_vls_cstr(&init_proc_vls)) == BRLCAD_ERROR) 
{
+    bu_vls_printf(&str, "_init_dm %s %s\n", bu_vls_addr(&init_proc_vls), 
bu_vls_addr(&dmp->dm_pathName));
+
+    if (Tcl_Eval(interp, bu_vls_addr(&str)) == TCL_ERROR) {
+       bu_log("qt_open: _init_dm failed\n");
        bu_vls_free(&init_proc_vls);
        bu_vls_free(&str);
-       (void)qt_close(dmp, context);
+       (void)qt_close(dmp);
        return DM_NULL;
     }
 
@@ -883,12 +883,12 @@
     bu_vls_free(&init_proc_vls);
     bu_vls_free(&str);
 
-    pubvars->dpy = (Display *)(*context->dm_display)(dmp, pubvars->top);
+    pubvars->dpy = Tk_Display(pubvars->top);
 
     /* make sure there really is a display before proceeding. */
     if (!pubvars->dpy) {
        bu_log("qt_open: Unable to attach to display (%s)\n", 
bu_vls_addr(&dmp->dm_pathName));
-       (void)qt_close(dmp, context);
+       (void)qt_close(dmp);
        return DM_NULL;
     }
 
@@ -913,16 +913,14 @@
            dmp->dm_height = dmp->dm_width;
     }
 
-    (*context->dm_window_geom)(dmp, pubvars->xtkwin, &dmp->dm_width, 
&dmp->dm_height);
+    Tk_GeometryRequest(pubvars->xtkwin, dmp->dm_width, dmp->dm_height);
 
-    (*context->dm_window_make_exist)(dmp, pubvars->xtkwin);
-
-    pubvars->win = (*context->dm_window_id)(dmp, pubvars->xtkwin);
+    Tk_MakeWindowExist(pubvars->xtkwin);
+    pubvars->win = Tk_WindowId(pubvars->xtkwin);
     dmp->dm_id = pubvars->win;
 
-    //(*context->dm_window_set_bg)(dmp, pubvars->xtkwin, privars->bg);
-    (*context->dm_window_map)(dmp, pubvars->xtkwin);
-
+    Tk_SetWindowBackground(pubvars->xtkwin, 0);
+    Tk_MapWindow(pubvars->xtkwin);
     privars->qapp = new QApplication(argc, argv);
 
     privars->parent = QWindow::fromWinId(pubvars->win);
@@ -939,7 +937,7 @@
     qt_setFGColor(dmp, 1, 0, 0, 0, 0);
     qt_setBGColor(dmp, 0, 0, 0);
 
-    qt_configureWin(dmp, context, 1);
+    qt_configureWin(dmp, 1);
 
     MAT_IDN(privars->mod_mat);
     MAT_IDN(privars->disp_mat);

Copied: brlcad/trunk/src/libdm/dm-tk.c (from rev 75269, 
brlcad/trunk/src/libdm/dm-tk.c)
===================================================================
--- brlcad/trunk/src/libdm/dm-tk.c                              (rev 0)
+++ brlcad/trunk/src/libdm/dm-tk.c      2020-04-09 18:02:59 UTC (rev 75324)
@@ -0,0 +1,1128 @@
+/*                          D M - T K . C
+ * BRL-CAD
+ *
+ * Copyright (c) 1988-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file libdm/dm-tk.c
+ *
+ * A Display Manager that should work wherever tk does.
+ *
+ */
+
+#include "common.h"
+
+#ifdef DM_TK
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <string.h>
+
+/* FIXME: suboptimal, just picked the first mac-specific config symbol
+ * encountered to know when to turn on the AquaTk X bindings from Tk.
+ */
+#ifdef HAVE_MACH_THREAD_POLICY_H
+#  define MAC_OSX_TK 1
+#endif
+
+/* Even on a platform that has no real X, I should be able to use the
+ * Xutil that comes with Tk
+ */
+#include <tk.h>
+#include <X11/Xutil.h>
+#include <X11/X.h>
+
+#ifdef HAVE_X11_XOSDEFS_H
+#  include <X11/Xfuncproto.h>
+#  include <X11/Xosdefs.h>
+#endif
+
+#if defined(linux)
+#  undef X_NOT_STDC_ENV
+#  undef X_NOT_POSIX
+#endif
+
+#include "vmath.h"
+#include "bn.h"
+#include "dm.h"
+#include "dm-tk.h"
+#include "dm-X.h"
+#include "dm-Null.h"
+#include "dm/dm_xvars.h"
+#include "dm_private.h"
+#include "rt/solid.h"
+
+#define PLOTBOUND 1000.0       /* Max magnification in Rot matrix */
+
+static fastf_t min_short = (fastf_t)SHRT_MIN;
+static fastf_t max_short = (fastf_t)SHRT_MAX;
+
+extern int vectorThreshold;    /* defined in libdm/tcl.c */
+
+
+/**
+ * @proc tk_close
+ *
+ * Gracefully release the display.
+ */
+HIDDEN int
+tk_close(struct dm_internal *dmp)
+{
+    if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy) {
+       if (((struct x_vars *)dmp->dm_vars.priv_vars)->gc)
+           Tk_FreeGC(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                     ((struct x_vars *)dmp->dm_vars.priv_vars)->gc);
+
+       if (((struct x_vars *)dmp->dm_vars.priv_vars)->pix)
+           Tk_FreePixmap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                         ((struct x_vars *)dmp->dm_vars.priv_vars)->pix);
+
+       /*XXX Possibly need to free the colormap */
+       if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap)
+           Tk_FreeColormap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                         ((struct dm_xvars *)dmp->dm_vars.pub_vars)->cmap);
+
+       if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin)
+           Tk_DestroyWindow(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin);
+
+    }
+
+    bu_vls_free(&dmp->dm_pathName);
+    bu_vls_free(&dmp->dm_tkName);
+    bu_vls_free(&dmp->dm_dName);
+    bu_free(dmp->dm_vars.priv_vars, "tk_close: tk_vars");
+    bu_free(dmp->dm_vars.pub_vars, "tk_close: dm_tkvars");
+    bu_free(dmp, "tk_close: dmp");
+
+    return BRLCAD_OK;
+}
+
+
+/**
+ * @proc tk_drawBegin
+ * This white-washes the dm's pixmap with the background color.
+ */
+HIDDEN int
+tk_drawBegin(struct dm_internal *dmp)
+{
+    XGCValues gcv;
+
+    if (dmp->dm_debugLevel)
+       bu_log("tk_drawBegin()\n");
+
+    /* clear pixmap */
+    gcv.foreground = ((struct x_vars *)dmp->dm_vars.priv_vars)->bg;
+    XChangeGC(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+             GCForeground, &gcv);
+    XFillRectangle(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                  ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+                  ((struct x_vars *)dmp->dm_vars.priv_vars)->gc, 0,
+                  0, dmp->dm_width + 1,
+                  dmp->dm_height + 1);
+
+    /* reset foreground */
+
+    gcv.foreground = ((struct x_vars *)dmp->dm_vars.priv_vars)->fg;
+    XChangeGC(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+             GCForeground, &gcv);
+
+    return BRLCAD_OK;
+}
+
+
+/**
+ * tk_drawEnd
+ * This copies the pixmap into the window.
+ */
+HIDDEN int
+tk_drawEnd(struct dm_internal *dmp)
+{
+    if (dmp->dm_debugLevel)
+       bu_log("tk_drawEnd()\n");
+
+    XCopyArea(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+             ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+             0, 0, dmp->dm_width,
+             dmp->dm_height, 0, 0);
+
+
+    /* Prevent lag between events and updates */
+    XSync(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy, 0);
+
+    return BRLCAD_OK;
+}
+
+
+/**
+ * @proc tk_loadMatrix
+ *
+ * Load a new transformation matrix.  This will be followed by
+ * many calls to tk_drawVList().
+ */
+/* ARGSUSED */
+HIDDEN int
+tk_loadMatrix(struct dm_internal *dmp, fastf_t *mat, int which_eye)
+{
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_loadMatrix()\n");
+
+       bu_log("which eye = %d\t", which_eye);
+       bu_log("transformation matrix = \n");
+
+       bu_log("%g %g %g %g\n", mat[0], mat[1], mat[2], mat[3]);
+       bu_log("%g %g %g %g\n", mat[4], mat[5], mat[6], mat[7]);
+       bu_log("%g %g %g %g\n", mat[8], mat[9], mat[10], mat[11]);
+       bu_log("%g %g %g %g\n", mat[12], mat[13], mat[14], mat[15]);
+    }
+
+    MAT_COPY(((struct x_vars *)dmp->dm_vars.priv_vars)->mod_mat, mat);
+    return BRLCAD_OK;
+}
+
+
+/**
+ * tk_drawVList
+ *
+ */
+
+HIDDEN int
+tk_drawVList(struct dm_internal *dmp, struct bn_vlist *vp)
+{
+    static vect_t spnt, lpnt, pnt;
+    struct bn_vlist *tvp;
+    XSegment segbuf[1024];             /* XDrawSegments list */
+    XSegment *segp;                    /* current segment */
+    int nseg;                  /* number of segments */
+    fastf_t delta;
+    point_t *pt_prev = NULL;
+    point_t tlate;
+    fastf_t dist_prev=1.0;
+    static int nvectors = 0;
+
+    struct x_vars *privars = (struct x_vars *)dmp->dm_vars.priv_vars;
+
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_drawVList()\n");
+       bu_log("vp - %p, perspective - %d\n", (void *)vp, dmp->dm_perspective);
+    }
+
+    /* delta is used in clipping to insure clipped endpoint is slightly
+     * in front of eye plane (perspective mode only).
+     * This value is a SWAG that seems to work OK.
+     */
+    delta = (privars->xmat)[15]*0.0001;
+    if (delta < 0.0)
+       delta = -delta;
+    if (delta < SQRT_SMALL_FASTF)
+       delta = SQRT_SMALL_FASTF;
+
+    nseg = 0;
+    segp = segbuf;
+    for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
+       int i;
+       int nused = tvp->nused;
+       int *cmd = tvp->cmd;
+       point_t *pt = tvp->pt;
+       fastf_t dist;
+
+       /* Viewing region is from -1.0 to +1.0 */
+       /* 2^31 ~= 2e9 -- dynamic range of a long int */
+       /* 2^(31-11) = 2^20 ~= 1e6 */
+       /* Integerize and let the X server do the clipping */
+       for (i = 0; i < nused; i++, cmd++, pt++) {
+           switch (*cmd) {
+               case BN_VLIST_POLY_START:
+               case BN_VLIST_POLY_VERTNORM:
+               case BN_VLIST_TRI_START:
+               case BN_VLIST_TRI_VERTNORM:
+                   continue;
+               case BN_VLIST_MODEL_MAT:
+                   privars->xmat = &(privars->mod_mat[0]);
+                   continue;
+               case BN_VLIST_DISPLAY_MAT:
+                   MAT4X3PNT(tlate, privars->mod_mat, *pt);
+                   privars->disp_mat[3] = tlate[0];
+                   privars->disp_mat[7] = tlate[1];
+                   privars->disp_mat[11] = tlate[2];
+                   privars->xmat = &(privars->disp_mat[0]);
+                   continue;
+               case BN_VLIST_POLY_MOVE:
+               case BN_VLIST_LINE_MOVE:
+               case BN_VLIST_TRI_MOVE:
+                   /* Move, not draw */
+                   if (dmp->dm_debugLevel > 2) {
+                       bu_log("before transformation:\n");
+                       bu_log("pt - %lf %lf %lf\n", V3ARGS(*pt));
+                   }
+
+                   if (dmp->dm_perspective > 0) {
+                       /* cannot apply perspective transformation to
+                        * points behind eye plane!!!!
+                        */
+                       dist = VDOT(*pt, &(privars->xmat)[12]) + 
privars->xmat[15];
+                       if (dist <= 0.0) {
+                           pt_prev = pt;
+                           dist_prev = dist;
+                           continue;
+                       } else {
+                           MAT4X3PNT(lpnt, privars->xmat, *pt);
+                           dist_prev = dist;
+                           pt_prev = pt;
+                       }
+                   } else {
+                           MAT4X3PNT(lpnt, privars->xmat, *pt);
+                   }
+
+                   lpnt[0] *= 2047;
+                   lpnt[1] *= 2047 * dmp->dm_aspect;
+                   lpnt[2] *= 2047;
+                   continue;
+               case BN_VLIST_POLY_DRAW:
+               case BN_VLIST_POLY_END:
+               case BN_VLIST_LINE_DRAW:
+               case BN_VLIST_TRI_DRAW:
+               case BN_VLIST_TRI_END:
+                   /* draw */
+                   if (dmp->dm_debugLevel > 2) {
+                       bu_log("before transformation:\n");
+                       bu_log("pt - %lf %lf %lf\n", V3ARGS(*pt));
+                   }
+
+                   if (dmp->dm_perspective > 0) {
+                       /* cannot apply perspective transformation to
+                        * points behind eye plane!!!!
+                        */
+                       dist = VDOT(*pt, &(privars->xmat)[12]) + 
privars->xmat[15];
+                       if (dmp->dm_debugLevel > 2)
+                           bu_log("dist=%g, dist_prev=%g\n", dist, dist_prev);
+                       if (dist <= 0.0) {
+                           if (dist_prev <= 0.0) {
+                               /* nothing to plot */
+                               dist_prev = dist;
+                               pt_prev = pt;
+                               continue;
+                           } else {
+                               if (pt_prev) {
+                               fastf_t alpha;
+                               vect_t diff;
+                               point_t tmp_pt;
+
+                               /* clip this end */
+                               VSUB2(diff, *pt, *pt_prev);
+                               alpha = (dist_prev - delta) / (dist_prev - 
dist);
+                               VJOIN1(tmp_pt, *pt_prev, alpha, diff);
+                               MAT4X3PNT(pnt, privars->xmat, tmp_pt);
+                               }
+                           }
+                       } else {
+                           if (dist_prev <= 0.0) {
+                               if (pt_prev) {
+                               fastf_t alpha;
+                               vect_t diff;
+                               point_t tmp_pt;
+
+                               /* clip other end */
+                               VSUB2(diff, *pt, *pt_prev);
+                               alpha = (-dist_prev + delta) / (dist - 
dist_prev);
+                               VJOIN1(tmp_pt, *pt_prev, alpha, diff);
+                               MAT4X3PNT(pnt, privars->xmat, tmp_pt);
+                               lpnt[0] *= 2047;
+                               lpnt[1] *= 2047 * dmp->dm_aspect;
+                               lpnt[2] *= 2047;
+                               MAT4X3PNT(pnt, privars->xmat, *pt);
+                               }
+                           } else {
+                               MAT4X3PNT(pnt, privars->xmat, *pt);
+                           }
+                       }
+                       dist_prev = dist;
+                   } else {
+                       MAT4X3PNT(pnt, privars->xmat, *pt);
+                   }
+
+                   pnt[0] *= 2047;
+                   pnt[1] *= 2047 * dmp->dm_aspect;
+                   pnt[2] *= 2047;
+
+                   /* save pnt --- it might get changed by clip() */
+                   VMOVE(spnt, pnt);
+                   pt_prev = pt;
+
+                   if (dmp->dm_debugLevel > 2) {
+                       bu_log("before clipping:\n");
+                       bu_log("clipmin - %lf %lf %lf\n",
+                              dmp->dm_clipmin[X],
+                              dmp->dm_clipmin[Y],
+                              dmp->dm_clipmin[Z]);
+                       bu_log("clipmax - %lf %lf %lf\n",
+                              dmp->dm_clipmax[X],
+                              dmp->dm_clipmax[Y],
+                              dmp->dm_clipmax[Z]);
+                       bu_log("pt1 - %lf %lf %lf\n", lpnt[X], lpnt[Y], 
lpnt[Z]);
+                       bu_log("pt2 - %lf %lf %lf\n", pnt[X], pnt[Y], pnt[Z]);
+                   }
+
+                   if (dmp->dm_zclip) {
+                       if (vclip(lpnt, pnt,
+                                 dmp->dm_clipmin,
+                                 dmp->dm_clipmax) == 0) {
+                           VMOVE(lpnt, spnt);
+                           continue;
+                       }
+                   } else {
+                       /* Check to see if lpnt or pnt contain values that 
exceed
+                          the capacity of a short (segbuf is an array of 
XSegments which
+                          contain shorts). If so, do clipping now. Otherwise, 
let the
+                          X server do the clipping */
+                       if (lpnt[0] < min_short || max_short < lpnt[0] ||
+                           lpnt[1] < min_short || max_short < lpnt[1] ||
+                           pnt[0] < min_short || max_short < pnt[0] ||
+                           pnt[1] < min_short || max_short < pnt[1]) {
+                           /* if the entire line segment will not be visible 
then ignore it */
+                           if (clip(&lpnt[0], &lpnt[1], &pnt[0], &pnt[1]) == 
-1) {
+                               VMOVE(lpnt, spnt);
+                               continue;
+                           }
+                       }
+                   }
+
+                   if (dmp->dm_debugLevel > 2) {
+                       bu_log("after clipping:\n");
+                       bu_log("pt1 - %lf %lf %lf\n", lpnt[X], lpnt[Y], 
lpnt[Z]);
+                       bu_log("pt2 - %lf %lf %lf\n", pnt[X], pnt[Y], pnt[Z]);
+                   }
+
+                   /* convert to X window coordinates */
+                   segp->x1 = (short)GED_TO_Xx(dmp, lpnt[0]);
+                   segp->y1 = (short)GED_TO_Xy(dmp, lpnt[1]);
+                   segp->x2 = (short)GED_TO_Xx(dmp, pnt[0]);
+                   segp->y2 = (short)GED_TO_Xy(dmp, pnt[1]);
+
+                   nseg++;
+                   segp++;
+                   VMOVE(lpnt, spnt);
+
+                   if (nseg == 1024) {
+                       XDrawSegments(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy,
+                                     ((struct x_vars 
*)dmp->dm_vars.priv_vars)->pix,
+                                     ((struct x_vars 
*)dmp->dm_vars.priv_vars)->gc, segbuf, nseg);
+
+                       nseg = 0;
+                       segp = segbuf;
+                   }
+                   break;
+           }
+       }
+
+       nvectors += nused;
+       if (nvectors >= vectorThreshold) {
+           if (dmp->dm_debugLevel)
+               bu_log("tk_drawVList(): handle Tcl events\n");
+
+           nvectors = 0;
+
+           /* Handle events in the queue */
+           while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT));
+       }
+    }
+
+    if (nseg) {
+       XDrawSegments(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                     ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+                     ((struct x_vars *)dmp->dm_vars.priv_vars)->gc, segbuf, 
nseg);
+    }
+
+    return BRLCAD_OK;
+}
+
+
+int
+tk_draw(struct dm_internal *dmp, struct bn_vlist *(*callback_function)(void 
*), void **data)
+{
+    struct bn_vlist *vp;
+    if (!callback_function) {
+       if (data) {
+           vp = (struct bn_vlist *)data;
+           tk_drawVList(dmp, vp);
+       }
+    } else {
+       if (!data) {
+           return BRLCAD_ERROR;
+       } else {
+           (void)callback_function(data);
+       }
+    }
+    return BRLCAD_OK;
+}
+
+
+/*
+ * Restore the display processor to a normal mode of operation
+ * (i.e., not scaled, rotated, displaced, etc.).
+ */
+HIDDEN int
+tk_normal(struct dm_internal *dmp)
+{
+    if (dmp->dm_debugLevel)
+       bu_log("tk_normal()\n");
+
+    return BRLCAD_OK;
+}
+
+
+/*
+ * Output a string into the displaylist.
+ * The starting position of the beam is as specified.
+ */
+/* ARGSUSED */
+HIDDEN int
+tk_drawString2D(struct dm_internal *dmp, const char *str, fastf_t x, fastf_t 
y, int size, int use_aspect)
+{
+    int sx, sy;
+
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_drawString2D():\n");
+       bu_log("\tstr - %s\n", str);
+       bu_log("\tx - %g\n", x);
+       bu_log("\ty - %g\n", y);
+       bu_log("\tsize - %d\n", size);
+
+       bu_log("color = %lu\n", ((struct x_vars *)dmp->dm_vars.priv_vars)->fg);
+       /* bu_log("real_color = %d\n", ((struct x_vars 
*)dmp->dm_vars.priv_vars)->gc->foreground); */
+
+       if (use_aspect) {
+           bu_log("\tuse_aspect - %d\t\taspect ratio - %g\n", use_aspect, 
dmp->dm_aspect);
+       } else
+           bu_log("\tuse_aspect - 0");
+    }
+
+    sx = dm_Normal2Xx(dmp, x);
+    sy = dm_Normal2Xy(dmp, y, use_aspect);
+
+
+    Tk_DrawChars(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+                ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+                ((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontstruct,
+                str, strlen(str), sx, sy);
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_drawLine2D(struct dm_internal *dmp, fastf_t xpos1, fastf_t ypos1, fastf_t 
xpos2, fastf_t ypos2)
+{
+    int sx1, sy1, sx2, sy2;
+
+    sx1 = dm_Normal2Xx(dmp, xpos1);
+    sx2 = dm_Normal2Xx(dmp, xpos2);
+    sy1 = dm_Normal2Xy(dmp, ypos1, 0);
+    sy2 = dm_Normal2Xy(dmp, ypos2, 0);
+
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_drawLine2D()\n");
+       bu_log("x1 = %g, y1 = %g\n", xpos1, ypos1);
+       bu_log("x2 = %g, y2 = %g\n", xpos2, ypos2);
+       bu_log("sx1 = %d, sy1 = %d\n", sx1, sy1);
+       bu_log("sx2 = %d, sy2 = %d\n", sx2, sy2);
+       bu_log("color = %lu\n", ((struct x_vars *)dmp->dm_vars.priv_vars)->fg);
+    }
+
+    XDrawLine(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+             ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+             sx1, sy1, sx2, sy2);
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_drawLine3D(struct dm_internal *dmp, point_t UNUSED(pt1), point_t 
UNUSED(pt2))
+{
+    if (!dmp)
+       return BRLCAD_ERROR;
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_drawLines3D(struct dm_internal *dmp, int npoints, point_t *points, int 
UNUSED(sflag))
+{
+    if (!dmp || npoints < 0 || (npoints > 0 && !points))
+       return BRLCAD_ERROR;
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_drawPoint2D(struct dm_internal *dmp, fastf_t x, fastf_t y)
+{
+    int sx, sy;
+
+    sx = dm_Normal2Xx(dmp, x);
+    sy = dm_Normal2Xy(dmp, y, 0);
+
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_drawPoint2D()\n");
+       bu_log("x = %g, y = %g\n", x, y);
+       bu_log("sx = %d, sy = %d\n", sx, sy);
+    }
+
+    XDrawPoint(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+              ((struct x_vars *)dmp->dm_vars.priv_vars)->pix,
+              ((struct x_vars *)dmp->dm_vars.priv_vars)->gc, sx, sy);
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_setFGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, 
unsigned char b, int strict, fastf_t transparency)
+{
+    XColor color;
+
+    INIT_XCOLOR(&color);
+
+    if (!dmp) {
+       bu_log("WARNING: NULL display (r/g/b => %d/%d/%d; strict => %d; 
transparency => %f)\n", r, g, b, strict, transparency);
+       return BRLCAD_ERROR;
+    }
+
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setFGColor(%d %d %d)\n", r, g, b);
+
+    dmp->dm_fg[0] = r;
+    dmp->dm_fg[1] = g;
+    dmp->dm_fg[2] = b;
+
+    color.red = r << 8;
+    color.green = g << 8;
+    color.blue = b << 8;
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->fg = Tk_GetColorByValue
+       (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin, &color)->pixel;
+
+    XSetForeground(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                  ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+                  ((struct x_vars *)dmp->dm_vars.priv_vars)->fg);
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_setBGColor(struct dm_internal *dmp, unsigned char r, unsigned char g, 
unsigned char b)
+{
+    XColor color;
+
+    INIT_XCOLOR(&color);
+
+    if (!dmp) {
+       bu_log("WARNING: NULL display (r/g/b==%d/%d/%d)\n", r, g, b);
+       return BRLCAD_ERROR;
+    }
+
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setBGColor()\n");
+
+    dmp->dm_bg[0] = r;
+    dmp->dm_bg[1] = g;
+    dmp->dm_bg[2] = b;
+
+    color.red = r << 8;
+    color.green = g << 8;
+    color.blue = b << 8;
+
+    XSetBackground(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                  ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+                  Tk_GetColorByValue(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin,
+                                     &color)->pixel);
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_setLineAttr(struct dm_internal *dmp, int width, int style)
+{
+    int linestyle;
+
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setLineAttr(width: %d, style: %d)\n", width, style);
+
+    dmp->dm_lineWidth = width;
+    dmp->dm_lineStyle = style;
+
+    if (width < 1)
+       width = 1;
+
+    if (style == DM_DASHED_LINE)
+       linestyle = LineOnOffDash;
+    else
+       linestyle = LineSolid;
+
+    XSetLineAttributes(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                      ((struct x_vars *)dmp->dm_vars.priv_vars)->gc,
+                      width, linestyle, CapButt, JoinMiter);
+
+    return BRLCAD_OK;
+}
+
+
+/* ARGSUSED */
+HIDDEN int
+tk_debug(struct dm_internal *dmp, int lvl)
+{
+    dmp->dm_debugLevel = lvl;
+
+    return BRLCAD_OK;
+}
+
+HIDDEN int
+tk_logfile(struct dm_internal *dmp, const char *filename)
+{
+    bu_vls_sprintf(&dmp->dm_log, "%s", filename);
+
+    return BRLCAD_OK;
+}
+
+
+
+HIDDEN int
+tk_setWinBounds(struct dm_internal *dmp, fastf_t *w)
+{
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setWinBounds()\n");
+
+    dmp->dm_clipmin[0] = w[0];
+    dmp->dm_clipmin[1] = w[2];
+    dmp->dm_clipmin[2] = w[4];
+    dmp->dm_clipmax[0] = w[1];
+    dmp->dm_clipmax[1] = w[3];
+    dmp->dm_clipmax[2] = w[5];
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_configureWin_guts(struct dm_internal *dmp, int force)
+{
+    int h, w;
+
+    /* nothing to do */
+    h = Tk_Height(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
+    w = Tk_Width(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
+
+    if (!force && dmp->dm_width==w && dmp->dm_height == h)
+       return BRLCAD_OK;
+
+    dmp->dm_width=w;
+    dmp->dm_width=h;
+
+    dmp->dm_aspect = (fastf_t)dmp->dm_width / (fastf_t)dmp->dm_height;
+
+    if (dmp->dm_debugLevel) {
+       bu_log("tk_configureWin_guts()\n");
+       bu_log("width = %d, height = %d\n", dmp->dm_width, dmp->dm_height);
+    }
+
+    Tk_FreePixmap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                 ((struct x_vars *)dmp->dm_vars.priv_vars)->pix);
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->pix =
+       Tk_GetPixmap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                    DefaultRootWindow(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy),
+                    dmp->dm_width,
+                    dmp->dm_height,
+                    Tk_Depth(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin));
+
+    /* First time through, load a font or quit */
+    if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontset == 0) {
+
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontstruct =
+           Tk_GetFont(dmp->dm_interp, ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin, FONT9);
+
+       if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontstruct == NULL) {
+           /* Try hardcoded backup font */
+
+           ((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontstruct =
+               Tk_GetFont(dmp->dm_interp, ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin, FONTBACK);
+
+           if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontstruct == 
NULL) {
+               bu_log("dm-Tk: Can't open font '%s' or '%s'\n", FONT9, 
FONTBACK);
+               return BRLCAD_ERROR;
+           }
+       }
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontset = 1;
+    }
+
+    /* XXX:  I removed the font-sizing routine from dm-X from here.  Something
+       should be devised to replace it.  --TJM*/
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_configureWin(struct dm_internal *dmp, int force)
+{
+    /* don't force */
+    return tk_configureWin_guts(dmp, force);
+}
+
+
+HIDDEN int
+tk_setLight(struct dm_internal *dmp, int light_on)
+{
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setLight:\n");
+
+    dmp->dm_light = light_on;
+
+    return BRLCAD_OK;
+}
+
+
+HIDDEN int
+tk_setZBuffer(struct dm_internal *dmp, int zbuffer_on)
+{
+    if (dmp->dm_debugLevel)
+       bu_log("tk_setZBuffer:\n");
+
+    dmp->dm_zbuffer = zbuffer_on;
+
+    return BRLCAD_OK;
+}
+
+struct bu_structparse Tk_vparse[] = {
+    {"%g",  1, "bound",         DM_O(dm_bound),         dm_generic_hook, NULL, 
NULL},
+    {"%d",  1, "useBound",      DM_O(dm_boundFlag),     dm_generic_hook, NULL, 
NULL},
+    {"%d",  1, "zclip",         DM_O(dm_zclip),         dm_generic_hook, NULL, 
NULL},
+    {"%d",  1, "debug",         DM_O(dm_debugLevel),    dm_generic_hook, NULL, 
NULL},
+    {"",    0, (char *)0,       0,                      
BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}
+};
+
+struct dm_internal dm_tk = {
+    tk_close,
+    tk_drawBegin,
+    tk_drawEnd,
+    tk_normal,
+    tk_loadMatrix,
+    null_loadPMatrix,
+    tk_drawString2D,
+    tk_drawLine2D,
+    tk_drawLine3D,
+    tk_drawLines3D,
+    tk_drawPoint2D,
+    null_drawPoint3D,
+    null_drawPoints3D,
+    tk_drawVList,
+    tk_drawVList,
+    tk_draw,
+    tk_setFGColor,
+    tk_setBGColor,
+    tk_setLineAttr,
+    tk_configureWin,
+    tk_setWinBounds,
+    tk_setLight,
+    null_setTransparency,
+    null_setDepthMask,
+    tk_setZBuffer,
+    tk_debug,
+    tk_logfile,
+    null_beginDList,
+    null_endDList,
+    null_drawDList,
+    null_freeDLists,
+    null_genDLists,
+    NULL,
+    null_getDisplayImage,      /* display to image function */
+    null_reshape,
+    null_makeCurrent,
+    null_openFb,
+    NULL,
+    NULL,
+    0,
+    0,                         /* no displaylist */
+    0,                         /* no stereo */
+    PLOTBOUND,                 /* zoom-in limit */
+    1,                         /* bound flag */
+    "Tk",
+    "Tk Abstraction Layer",
+    DM_TYPE_TK,
+    1,
+    0,
+    0,
+    0, /* bytes per pixel */
+    0, /* bits per channel */
+    0,
+    0,
+    1.0, /* aspect ratio */
+    0,
+    {0, 0},
+    NULL,
+    NULL,
+    BU_VLS_INIT_ZERO,          /* bu_vls path name*/
+    BU_VLS_INIT_ZERO,          /* bu_vls full name drawing window */
+    BU_VLS_INIT_ZERO,          /* bu_vls short name drawing window */
+    {0, 0, 0},                 /* bg color */
+    {0, 0, 0},                 /* fg color */
+    {GED_MIN, GED_MIN, GED_MIN},       /* clipmin */
+    {GED_MAX, GED_MAX, GED_MAX},       /* clipmax */
+    0,                         /* no debugging */
+    BU_VLS_INIT_ZERO,          /* bu_vls logfile */
+    0,                         /* no perspective */
+    0,                         /* no lighting */
+    0,                         /* no transparency */
+    0,                         /* depth buffer is not writable */
+    0,                         /* no zbuffer */
+    0,                         /* no zclipping */
+    1,                          /* clear back buffer after drawing and swap */
+    0,                          /* not overriding the auto font size */
+    Tk_vparse,
+    FB_NULL,
+    0                          /* Tcl interpreter */
+};
+
+
+struct dm_internal *tk_open_dm(Tcl_Interp *interp, int argc, char **argv);
+
+/* Display Manager package interface */
+
+
+/*
+ * Fire up the display manager, and the display processor.
+ *
+ */
+struct dm_internal *
+tk_open_dm(Tcl_Interp *interp, int argc, char **argv)
+{
+    static int count = 0;
+    int make_square = -1;
+    XGCValues gcv;
+
+    struct bu_vls str = BU_VLS_INIT_ZERO;
+    struct bu_vls init_proc_vls = BU_VLS_INIT_ZERO;
+    struct dm_internal *dmp = (struct dm_internal *)NULL;
+    Tk_Window tkwin;
+    Display *dpy = (Display *)NULL;
+    XColor fg, bg;
+
+    INIT_XCOLOR(&fg);
+    INIT_XCOLOR(&bg);
+
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
+
+    BU_ALLOC(dmp, struct dm_internal);
+
+    *dmp = dm_tk; /* struct copy */
+    dmp->dm_interp = interp;
+
+    BU_ALLOC(dmp->dm_vars.pub_vars, struct dm_xvars);
+    BU_ALLOC(dmp->dm_vars.priv_vars, struct tk_vars);
+
+    bu_vls_init(&dmp->dm_pathName);
+    bu_vls_init(&dmp->dm_tkName);
+    bu_vls_init(&dmp->dm_dName);
+
+    dm_processOptions(dmp, &init_proc_vls, --argc, ++argv);
+
+    if (bu_vls_strlen(&dmp->dm_pathName) == 0) {
+       bu_vls_printf(&dmp->dm_pathName, ".dm_tk%d", count);
+    }
+
+    ++count;
+    if (bu_vls_strlen(&dmp->dm_dName) == 0) {
+       char *dp;
+
+       dp = DisplayString(Tk_Display(tkwin));
+
+       if (dp)
+           bu_vls_strcpy(&dmp->dm_dName, dp);
+       else
+           bu_vls_strcpy(&dmp->dm_dName, ":0.0");
+    }
+    if (bu_vls_strlen(&init_proc_vls) == 0)
+       bu_vls_strcpy(&init_proc_vls, "bind_dm");
+
+    /* initialize dm specific variables */
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devmotionnotify = LASTEvent;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devbuttonpress = LASTEvent;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devbuttonrelease = LASTEvent;
+    dmp->dm_aspect = 1.0;
+
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->tkfontset = 0;
+
+    if (dmp->dm_top) {
+       /* Make xtkwin a toplevel window */
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin = 
Tk_CreateWindowFromPath(interp, tkwin,
+                                                                               
     bu_vls_addr(&dmp->dm_pathName),
+                                                                               
     bu_vls_addr(&dmp->dm_dName));
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->top = ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin;
+    } else {
+       char *cp;
+
+       cp = strrchr(bu_vls_addr(&dmp->dm_pathName), (int)'.');
+       if (cp == bu_vls_addr(&dmp->dm_pathName)) {
+           ((struct dm_xvars *)dmp->dm_vars.pub_vars)->top = tkwin;
+       } else {
+           struct bu_vls top_vls = BU_VLS_INIT_ZERO;
+
+           bu_vls_strncpy(&top_vls, (const char 
*)bu_vls_addr(&dmp->dm_pathName), cp - bu_vls_addr(&dmp->dm_pathName));
+
+           ((struct dm_xvars *)dmp->dm_vars.pub_vars)->top =
+               Tk_NameToWindow(interp, bu_vls_addr(&top_vls), tkwin);
+           bu_vls_free(&top_vls);
+       }
+
+       /* Make xtkwin an embedded window */
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin =
+           Tk_CreateWindow(interp, ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->top,
+                           cp + 1, (char *)NULL);
+    }
+
+    if (((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin == NULL) {
+       bu_log("tk_open: Failed to open %s\n", bu_vls_addr(&dmp->dm_pathName));
+       (void)tk_close(dmp);
+       return DM_NULL;
+    }
+
+    bu_vls_printf(&dmp->dm_tkName, "%s",
+                 (char *)Tk_Name(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin));
+
+    bu_vls_printf(&str, "_init_dm %s %s\n",
+                 bu_vls_addr(&init_proc_vls),
+                 bu_vls_addr(&dmp->dm_pathName));
+
+    if (Tcl_Eval(interp, bu_vls_addr(&str)) == BRLCAD_ERROR) {
+       bu_vls_free(&str);
+       (void)tk_close(dmp);
+
+       return DM_NULL;
+    }
+
+    bu_vls_free(&init_proc_vls);
+    bu_vls_free(&str);
+
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy =
+       Tk_Display(((struct dm_xvars *)dmp->dm_vars.pub_vars)->top);
+    dpy = ((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy;
+
+    /* make sure there really is a display before proceeding. */
+    if (!dpy) {
+       (void)tk_close(dmp);
+       return DM_NULL;
+    }
+
+    if (dmp->dm_width == 0) {
+       dmp->dm_width =
+           WidthOfScreen(Tk_Screen((
+                                       (struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin)) - 30;
+       ++make_square;
+    }
+
+    if (dmp->dm_height == 0) {
+       dmp->dm_height =
+           HeightOfScreen(Tk_Screen((
+                                        (struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin)) - 30;
+       ++make_square;
+    }
+
+    if (make_square > 0) {
+       /* Make window square */
+       if (dmp->dm_height <
+           dmp->dm_width)
+           dmp->dm_width = dmp->dm_height;
+       else
+           dmp->dm_height = dmp->dm_width;
+    }
+
+    Tk_GeometryRequest(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin,
+                      dmp->dm_width,
+                      dmp->dm_height);
+
+    Tk_MakeWindowExist(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win =
+       Tk_WindowId(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
+    dmp->dm_id = ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win;
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->pix =
+       Tk_GetPixmap(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                    DefaultRootWindow(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy),
+                    dmp->dm_width,
+                    dmp->dm_height,
+                    Tk_Depth(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin));
+
+    fg.red = 65535;
+    fg.green = fg.blue = 0;
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->fg =
+       Tk_GetColorByValue(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin,
+                          &fg)->pixel;
+
+    bg.red = bg.green = bg.blue = 3277;
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->bg =
+       Tk_GetColorByValue(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin,
+                          &bg)->pixel;
+
+    gcv.background = ((struct x_vars *)dmp->dm_vars.priv_vars)->bg;
+    gcv.foreground = ((struct x_vars *)dmp->dm_vars.priv_vars)->fg;
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->gc =
+       Tk_GetGC(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin,
+                (GCForeground|GCBackground), &gcv);
+
+    (void)tk_configureWin_guts(dmp, 1);
+
+    /*
+      Tk_SetWindowBackground(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->xtkwin,
+      ((struct x_vars *)dmp->dm_vars.priv_vars)->bg);
+    */
+    Tk_MapWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin);
+
+    MAT_IDN(((struct x_vars *)dmp->dm_vars.priv_vars)->mod_mat);
+    MAT_IDN(((struct x_vars *)dmp->dm_vars.priv_vars)->disp_mat);
+
+    ((struct x_vars *)dmp->dm_vars.priv_vars)->xmat = 
+        &(((struct x_vars *)dmp->dm_vars.priv_vars)->mod_mat[0]);
+
+    return dmp;
+}
+
+
+#endif /* DM_TK */
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/trunk/src/libdm/dm-tk.h (from rev 75269, 
brlcad/trunk/src/libdm/dm-tk.h)
===================================================================
--- brlcad/trunk/src/libdm/dm-tk.h                              (rev 0)
+++ brlcad/trunk/src/libdm/dm-tk.h      2020-04-09 18:02:59 UTC (rev 75324)
@@ -0,0 +1,56 @@
+/*                          D M - T K . H
+ * BRL-CAD
+ *
+ * Copyright (c) 1993-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @addtogroup libdm */
+/** @{ */
+/** @file dm-tk.h
+ *
+ */
+
+#ifndef DM_TK_H
+#define DM_TK_H
+
+#define CMAP_BASE 40
+#define CUBE_DIMENSION 6
+#define NUM_PIXELS 216    /* CUBE_DIMENSION * CUBE_DIMENSION * CUBE_DIMENSION 
*/
+#define ColormapNull (Colormap *)NULL
+
+struct tk_vars {
+    GC gc;
+    Pixmap pix;
+    fastf_t *xmat;
+    mat_t mod_mat;             /* default model transformation matrix */
+    mat_t disp_mat;            /* display transformation matrix */
+    int is_trueColor;
+    unsigned long bd, bg, fg;   /* color of border, background, foreground */
+    unsigned long pixels[NUM_PIXELS];
+};
+
+#endif /* DM_TK_H */
+
+/** @} */
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Modified: brlcad/trunk/src/libdm/dm-txt.c
===================================================================
--- brlcad/trunk/src/libdm/dm-txt.c     2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-txt.c     2020-04-09 18:02:59 UTC (rev 75324)
@@ -53,7 +53,7 @@
 
 
 HIDDEN int
-txt_close(dm *UNUSED(dmp), struct dm_context *UNUSED(context))
+txt_close(dm *UNUSED(dmp))
 {
     bu_log("close called\n");
     return 0;
@@ -205,7 +205,7 @@
 
 
 HIDDEN int
-txt_configureWin(dm *UNUSED(dmp), struct dm_context *UNUSED(context), int 
UNUSED(force))
+txt_configureWin(dm *UNUSED(dmp), int UNUSED(force))
 {
     bu_log("configureWin called\n");
     return 0;

Modified: brlcad/trunk/src/libdm/dm-wgl.c
===================================================================
--- brlcad/trunk/src/libdm/dm-wgl.c     2020-04-09 17:21:45 UTC (rev 75323)
+++ brlcad/trunk/src/libdm/dm-wgl.c     2020-04-09 18:02:59 UTC (rev 75324)
@@ -191,12 +191,23 @@
     return BRLCAD_OK;
 }
 
+HIDDEN void
+WGLEventProc(ClientData clientData, XEvent *UNUSED(eventPtr))
+{
+       dm *dmp = (dm *)clientData;
+       /* Need to make things visible after a Window minimization, but don't
+       want the out-of-date visual - for now, do two swaps.  If there's some
+       way to trigger a Window re-draw without doing buffer swaps, that would
+       be preferable... */
+       SwapBuffers(((struct dm_xvars *)dmp->dm_vars.pub_vars)->hdc);
+       SwapBuffers(((struct dm_xvars *)dmp->dm_vars.pub_vars)->hdc);
+}
 /*
  * Fire up the display manager, and the display processor.
  *
  */
 dm *
-wgl_open(Tcl_Interp *interp, struct dm_context *context, int argc, char 
*argv[])
+wgl_open(Tcl_Interp *interp, int argc, char *argv[])
 {
     static int count = 0;
     GLfloat backgnd[4];
@@ -208,10 +219,11 @@
     Tk_Window tkwin;
     HWND hwnd;
     HDC hdc;
-    int gotvisual;
+       int gotvisual;
 
-    struct dm_xvars *pubvars = NULL;
-    struct wgl_vars *privvars = NULL;
+    if ((tkwin = Tk_MainWindow(interp)) == NULL) {
+       return DM_NULL;
+    }
 
     BU_ALLOC(dmp, struct dm_internal);
 
@@ -220,9 +232,7 @@
     dmp->dm_light = 1;
 
     BU_ALLOC(dmp->dm_vars.pub_vars, struct dm_xvars);
-    pubvars = (struct dm_xvars *)dmp->dm_vars.pub_vars;
     BU_ALLOC(dmp->dm_vars.priv_vars, struct wgl_vars);
-    privvars = (struct wgl_vars *)dmp->dm_vars.priv_vars;
 
     dmp->dm_get_internal(dmp);
     mvars = (struct modifiable_ogl_vars *)dmp->m_vars;
@@ -229,13 +239,6 @@
 
     dmp->dm_vp = &default_viewscale;
 
-    if ((tkwin = (*context->dm_window_main)(dmp)) == NULL) {
-       bu_free((void *)privvars, "privvars");
-       bu_free((void *)pubvars, "pubvars");
-       bu_free((void *)dmp, "dmp");
-       return DM_NULL;
-    }
-
     bu_vls_init(&dmp->dm_pathName);
     bu_vls_init(&dmp->dm_tkName);
     bu_vls_init(&dmp->dm_dName);
@@ -259,9 +262,9 @@
        bu_vls_strcpy(&init_proc_vls, "bind_dm");
 
     /* initialize dm specific variables */
-    pubvars->devmotionnotify = LASTEvent;
-    pubvars->devbuttonpress = LASTEvent;
-    pubvars->devbuttonrelease = LASTEvent;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devmotionnotify = LASTEvent;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devbuttonpress = LASTEvent;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->devbuttonrelease = LASTEvent;
     dmp->dm_aspect = 1.0;
 
     /* initialize modifiable variables */
@@ -277,7 +280,7 @@
     mvars->boundFlag = dmp->dm_boundFlag;
 
     /* this is important so that wgl_configureWin knows to set the font */
-    pubvars->fontstruct = NULL;
+    ((struct dm_xvars *)dmp->dm_vars.pub_vars)->fontstruct = NULL;
 
     if (dmp->dm_width == 0) {
        dmp->dm_width = GetSystemMetrics(SM_CXSCREEN)- 30;
@@ -302,6 +305,7 @@
     if (dmp->dm_top) {
        /* Make xtkwin a toplevel window */
        Tcl_DString ds;
+
        Tcl_DStringInit(&ds);
        Tcl_DStringAppend(&ds, "toplevel ", -1);
        Tcl_DStringAppend(&ds, bu_vls_addr(&dmp->dm_pathName), -1);
@@ -311,45 +315,51 @@
            Tcl_DStringFree(&ds);
            return DM_NULL;
        }
+       ((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin =
+           Tk_NameToWindow(interp, bu_vls_addr(&dmp->dm_pathName), tkwin);
        Tcl_DStringFree(&ds);

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to