1 /*- 2 * Copyright (c) 1996 3 * Rob Zimmermann. All rights reserved. 4 * Copyright (c) 1996 5 * Keith Bostic. All rights reserved. 6 * 7 * See the LICENSE file for redistribution information. 8 */ 9 10 #include "config.h" 11 12 #include <sys/cdefs.h> 13 #if 0 14 #ifndef lint 15 static const char sccsid[] = "Id: m_ruler.c,v 8.6 2003/11/05 17:10:00 skimo Exp (Berkeley) Date: 2003/11/05 17:10:00 "; 16 #endif /* not lint */ 17 #else 18 __RCSID("$NetBSD: m_ruler.c,v 1.3 2014/01/26 21:43:45 christos Exp $"); 19 #endif 20 21 /* This module implements a dialog for the text ruler 22 * 23 * Interface: 24 * void __vi_show_text_ruler_dialog( Widget parent, String title ) 25 * Pops up a text ruler dialog. 26 * We allow one per session. It is not modal. 27 * 28 * void __vi_clear_text_ruler_dialog( Widget parent, String title ) 29 * Pops down the text ruler dialog. 30 * 31 * void __vi_set_text_ruler( int row, int col ) 32 * Changes the displayed position 33 */ 34 35 #include <sys/types.h> 36 #include <sys/queue.h> 37 38 #include <X11/X.h> 39 #include <X11/Intrinsic.h> 40 #include <X11/Shell.h> 41 #include <Xm/DrawingA.h> 42 #include <Xm/RowColumn.h> 43 #include <Xm/PushBG.h> 44 45 #include <bitstring.h> 46 #include <stdio.h> 47 48 #undef LOCK_SUCCESS 49 #include "../common/common.h" 50 #include "../ipc/ip.h" 51 #include "m_motif.h" 52 #include "vi_mextern.h" 53 54 55 /* globals */ 56 57 static Widget db_ruler = NULL; 58 59 static Boolean active = False; 60 61 static int ruler_border = 5, 62 ruler_asc; 63 64 static GC gc_ruler; 65 66 static XFontStruct *ruler_font; 67 68 static char text[256]; 69 70 #if ! defined(SelfTest) 71 static XutResource resource[] = { 72 { "rulerFont", XutRKfont, &ruler_font }, 73 { "rulerBorder", XutRKinteger, &ruler_border }, 74 }; 75 #endif 76 77 78 /* change the displayed position */ 79 80 static void 81 set_ruler_text(int row, int col, int *h, int *w, int *asc) 82 { 83 int dir, des; 84 XCharStruct over; 85 86 /* format the data */ 87 sprintf( text, "%9.d,%-9.d", row+1, col+1 ); 88 89 /* how big will it be? */ 90 XTextExtents( ruler_font, text, strlen(text), &dir, asc, &des, &over ); 91 92 /* how big a window will we need? */ 93 *h = 2*ruler_border + over.ascent + over.descent; 94 *w = 2*ruler_border + over.width; 95 } 96 97 98 static void 99 redraw_text(void) 100 { 101 XClearArea( XtDisplay(db_ruler), XtWindow(db_ruler), 0, 0, 0, 0, False ); 102 XDrawString( XtDisplay(db_ruler), 103 XtWindow(db_ruler), 104 gc_ruler, 105 ruler_border, ruler_border + ruler_asc, 106 text, 107 strlen(text) 108 ); 109 } 110 111 112 /* 113 * PUBLIC: void __vi_set_text_ruler __P((int, int)); 114 */ 115 void 116 __vi_set_text_ruler(int row, int col) 117 { 118 int h, w; 119 120 if ( ! active ) return; 121 122 set_ruler_text( row, col, &h, &w, &ruler_asc ); 123 124 redraw_text(); 125 } 126 127 128 /* callbacks */ 129 130 static void 131 cancel_cb(void) 132 { 133 #if defined(SelfTest) 134 puts( "cancelled" ); 135 #endif 136 active = False; 137 } 138 139 140 static void destroyed(void) 141 { 142 #if defined(SelfTest) 143 puts( "destroyed" ); 144 #endif 145 146 /* some window managers destroy us upon popdown */ 147 db_ruler = NULL; 148 active = False; 149 } 150 151 152 153 /* Draw and display a dialog the describes nvi options */ 154 155 #if defined(__STDC__) 156 static Widget create_text_ruler_dialog( Widget parent, String title ) 157 #else 158 static Widget create_text_ruler_dialog( parent, title ) 159 Widget parent; 160 String title; 161 #endif 162 { 163 Widget box; 164 int h, w, asc; 165 Pixel fg, bg; 166 167 /* already built? */ 168 if ( db_ruler != NULL ) return db_ruler; 169 170 #if defined(SelfTest) 171 ruler_font = XLoadQueryFont( XtDisplay(parent), "9x15" ); 172 #else 173 /* check the resource database for interesting resources */ 174 __XutConvertResources( parent, 175 vi_progname, 176 resource, 177 XtNumber(resource) 178 ); 179 #endif 180 181 gc_ruler = XCreateGC( XtDisplay(parent), XtWindow(parent), 0, NULL ); 182 XSetFont( XtDisplay(parent), gc_ruler, ruler_font->fid ); 183 184 box = XtVaCreatePopupShell( title, 185 transientShellWidgetClass, 186 parent, 187 XmNallowShellResize, False, 188 0 189 ); 190 XtAddCallback( box, XmNpopdownCallback, cancel_cb, 0 ); 191 XtAddCallback( box, XmNdestroyCallback, destroyed, 0 ); 192 193 /* should be ok to use the font now */ 194 active = True; 195 196 /* how big a window? */ 197 set_ruler_text( 0, 0, &h, &w, &asc ); 198 199 /* keep this global, we might destroy it later */ 200 db_ruler = XtVaCreateManagedWidget( "Ruler", 201 xmDrawingAreaWidgetClass, 202 box, 203 XmNheight, h, 204 XmNwidth, w, 205 0 206 ); 207 /* this callback is for when the drawing area is exposed */ 208 XtAddCallback( db_ruler, 209 XmNexposeCallback, 210 redraw_text, 211 0 212 ); 213 214 /* what colors are selected for the drawing area? */ 215 XtVaGetValues( db_ruler, 216 XmNbackground, &bg, 217 XmNforeground, &fg, 218 0 219 ); 220 XSetForeground( XtDisplay(db_ruler), gc_ruler, fg ); 221 XSetBackground( XtDisplay(db_ruler), gc_ruler, bg ); 222 223 /* done */ 224 return db_ruler; 225 } 226 227 228 229 /* module entry point 230 * __vi_show_text_ruler_dialog( parent, title ) 231 * __vi_clear_text_ruler_dialog( parent, title ) 232 */ 233 234 #if defined(__STDC__) 235 void __vi_show_text_ruler_dialog( Widget parent, String title ) 236 #else 237 void __vi_show_text_ruler_dialog( parent, title ) 238 Widget parent; 239 String title; 240 #endif 241 { 242 Widget db = create_text_ruler_dialog( parent, title ), 243 shell = XtParent(db); 244 Dimension height, width; 245 246 /* this guy does not resize */ 247 XtVaGetValues( db, 248 XmNheight, &height, 249 XmNwidth, &width, 250 0 251 ); 252 XtVaSetValues( shell, 253 XmNmaxWidth, width, 254 XmNminWidth, width, 255 XmNmaxHeight, height, 256 XmNminHeight, height, 257 0 258 ); 259 260 XtManageChild( db ); 261 262 /* leave this guy up */ 263 XtPopup( shell, XtGrabNone ); 264 265 active = True; 266 267 /* ask vi core for the current r,c now */ 268 #if ! defined(SelfTest) 269 __vi_set_text_ruler( __vi_screen->cury, __vi_screen->curx ); 270 #else 271 __vi_set_text_ruler( rand(), rand() ); 272 #endif 273 } 274 275 276 #if defined(__STDC__) 277 void __vi_clear_text_ruler_dialog() 278 #else 279 void __vi_clear_text_ruler_dialog(void) 280 #endif 281 { 282 if ( active ) 283 XtPopdown( XtParent(db_ruler) ); 284 } 285 286 287 #if defined(SelfTest) 288 289 #if XtSpecificationRelease == 4 290 #define ArgcType Cardinal * 291 #else 292 #define ArgcType int * 293 #endif 294 295 static void change_pos( Widget w ) 296 { 297 __vi_set_text_ruler( rand(), rand() ); 298 } 299 300 #if defined(__STDC__) 301 static void show_text_ruler( Widget w, XtPointer data, XtPointer cbs ) 302 #else 303 static void show_text_ruler( w, data, cbs ) 304 Widget w; 305 XtPointer data; 306 XtPointer cbs; 307 #endif 308 { 309 __vi_show_text_ruler_dialog( data, "Ruler" ); 310 } 311 312 main( int argc, char *argv[] ) 313 { 314 XtAppContext ctx; 315 Widget top_level, rc, button; 316 317 /* create a top-level shell for the window manager */ 318 top_level = XtVaAppInitialize( &ctx, 319 argv[0], 320 NULL, 0, /* options */ 321 (ArgcType) &argc, 322 argv, /* might get modified */ 323 NULL, 324 NULL 325 ); 326 327 rc = XtVaCreateManagedWidget( "rc", 328 xmRowColumnWidgetClass, 329 top_level, 330 0 331 ); 332 333 button = XtVaCreateManagedWidget( "Pop up text ruler dialog", 334 xmPushButtonGadgetClass, 335 rc, 336 0 337 ); 338 XtAddCallback( button, XmNactivateCallback, show_text_ruler, rc ); 339 340 button = XtVaCreateManagedWidget( "Change Position", 341 xmPushButtonGadgetClass, 342 rc, 343 0 344 ); 345 XtAddCallback( button, XmNactivateCallback, change_pos, rc ); 346 347 button = XtVaCreateManagedWidget( "Quit", 348 xmPushButtonGadgetClass, 349 rc, 350 0 351 ); 352 XtAddCallback( button, XmNactivateCallback, exit, 0 ); 353 354 XtRealizeWidget(top_level); 355 XtAppMainLoop(ctx); 356 } 357 #endif 358