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
set_ruler_text(int row,int col,int * h,int * w,int * asc)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
redraw_text(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
__vi_set_text_ruler(int row,int col)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
cancel_cb(void)131 cancel_cb(void)
132 {
133 #if defined(SelfTest)
134     puts( "cancelled" );
135 #endif
136     active = False;
137 }
138 
139 
destroyed(void)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__)
create_text_ruler_dialog(Widget parent,String title)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__)
__vi_show_text_ruler_dialog(Widget parent,String title)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__)
__vi_clear_text_ruler_dialog()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 
change_pos(Widget w)295 static    void      change_pos( Widget w )
296 {
297     __vi_set_text_ruler( rand(), rand() );
298 }
299 
300 #if defined(__STDC__)
show_text_ruler(Widget w,XtPointer data,XtPointer cbs)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 
main(int argc,char * argv[])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