libsx-2.05/0000755000175000017500000000000011252443776013726 5ustar amckinstryamckinstrylibsx-2.05/docs/0000755000175000017500000000000011252443541014644 5ustar amckinstryamckinstrylibsx-2.05/docs/html/0000755000175000017500000000000011252443541015610 5ustar amckinstryamckinstrylibsx-2.05/docs/html/string_entry.html0000644000175000017500000001146411252443541021233 0ustar amckinstryamckinstry String Entry

String Entry

A string entry widget is a widget that lets a user enter a single line of ASCII text. When the user presses return in the widget, a callback is made to your application with a pointer to the new text. Support routines also exist to Set and Get the text in the widget.

If you want multiple lines of text, see the text edit widget documentation.


Widget MakeStringEntry(char *txt, int size, StringCB func, void *data);

This function makes a string input widget. A string input widget is a widget that lets a user enter/edit a single line string value such as a filename.

The first argument is any default text you would like in the string entry widget. You can specify NULL or "" if you don't want anything to appear.

The next argument is the width in pixels of the string entry area. Be careful in specifying the width since the default font used by the widget may not be wide enough to contain the text you want. It is best if you call GetWidgetFont() and then call TextWidth() on a string of reasonable length and use the value returned by TextWidth() to be the width of the widget. If you're lazy, a value of 150-200 is usually pretty good.

The next argument is a callback function that is called whenever the user presses return in the string entry widget. The callback function should be declared as follows:

     void func(Widget w, char *string, void *data)
     {
     }

The first argument to the callback is the widget where the user pressed return. For the most part you can ignore this (unless you want to change the text). The second argument is a pointer to the string of text the user entered. The final argument is the user data pointer you passed in to MakeStringEntry() .

The string of text passed to your callback function should be copied elsewhere (using strdup() if necessary) because it is internal to the widget. The string passed to your callback function should never be modified directly. Also, do not just store the value of the pointer in some global variable. The memory pointed to by the string is private to the widget and should be copied if you want to preserve it.

SEE ALSO : SetStringEntry() , GetStringEntry() , SetWidgetPos() , GetWidgetFont() , TextWidth() , SetWidgetFont() , SetFgColor() , SetBgColor() , SetBorderColor()


void SetStringEntry(Widget w, char *new_text);

This function allows you to change the string of text displayed in a string entry widget.

The first argument is the widget in which you would like to change the string (this widget should be a string entry widget). The second argument is a pointer to the new text you would like displayed in the string entry area.

After calling this function, the new text is displayed in the string entry area and any old strings are gone.

SEE ALSO : GetStringEntry() , MakeStringEntry() ,


char *GetStringEntry(Widget w)

This function lets you retrieve the text a user entered in a string widget. The widget argument, w, should be a string entry widget.

The return value of this function is a char pointer to a null-terminated string that is the contents of the string entry widget. This pointer is valid until the next time you call GetStringEntry() or the string widget callback is called. Do not save the pointer returned by this function as it points to widget internal data. You should make a copy of the string with strdup() if you want to save the value.

If there is a problem, the function returns NULL.

NOTE: You should not free the string returned to you by this function. If you need to modify the string or otherwise use, you should make a copy with strdup() or some other method.

SEE ALSO : SetStringEntry() , MakeStringEntry() , libsx-2.05/docs/html/form.html0000644000175000017500000001543511252443541017451 0ustar amckinstryamckinstry Forms


Widget MakeForm(Widget parent, int where1, Widget from1 int where2, Widget from2)

This function lets you create a new "form" widget in which to put child widgets. A form widget is a container that holds other widgets. Normally there is no need to call this function, but if you want to have separate "groups" of widgets in your display and you can't lay them out that way with SetWidgetPos() , then using multiple form widgets may be the right thing. In addition, a nifty little box gets drawn around the form widget (and all the children) and this can be a nice visual cue in your interface indicating what groups of widgets belong together. A form widget creates a box that surrounds all the widgets contained inside of it (but the form widget itself is inactive and can't be clicked on by the user).

If you use multiple form widgets in your display, the basic logic of how you create the display is a little different. You can think of form widgets as miniature windows inside a larger window.

Once you create a form widget, any other widgets you create with calls like MakeButton() and MakeLabel() become children of this form widget. Before you create another form widget, you must lay out all the children of the current form widget with calls to SetWidgetPos() . After you lay out all the children of the current widget, then you can create another form widget, and repeat the process (or call SetForm() ).

Form widgets are layed out in a manner similar to regular widgets, except that usually their placement is relative to other form widgets. When you create a new form widget (after the first one), you specify where it should be placed relative to other form widgets that you created. The first form widget is always placed in the top left corner of the window.

The `parent' argument to MakeForm() specifies at what level the new form should be created. If you specify TOP_LEVEL_FORM (which is the usual thing to do) the new form is created at the top level of the window. If you pass another form widget for `parent', then this new form widget will be a child of the other form widget. This lets you create hierarchical "boxes" in your display.

The arguments where1, from1, where2, from2 are the same as in SetWidgetPos() . That is, you specify either NO_CARE, PLACE_UNDER, or PLACE_RIGHT for where1 and where2 and the from1/from2 arguments are the widgets you would like to place something to the right of or under (or they are NULL if you specified NO_CARE). See SetWidgetPos() for more documentation.

Now for an example: Let's say we want a display something like this:

      +------------+   +-----------------------+ 
      | +--------+ |   | +-------------------+ |  
      | |  Btn1  | |   | |                   | |   
      | +--------+ |   | |                   | |  
      |            |   | |                   | |  
      | +--------+ |   | |                   | |  
      | |  Btn2  | |   | |                   | |  
      | +--------+ |   | |                   | |   
      +------------+   | |                   | |  
                       | |                   | |  
                       | |                   | |  
                       | +-------------------+ |  
                       +-----------------------+  

We have two rectangles (forms) which contain other widgets. Inside the leftmost form are two buttons. The form on the right has a single drawing area. Skipping some of the unnecessary details, we could accomplish the above display with the following code:

  form1 = MakeForm(TOP_LEVEL_FORM, NO_CARE, NULL, NO_CARE, NULL);
  w[0]  = MakeButton("Btn1", NULL, NULL);
  w[1]  = MakeButton("Btn2", NULL, NULL);
  
  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
  
  form2 = MakeForm(TOP_LEVEL_FORM, PLACE_RIGHT, form1, NO_CARE, NULL); 
  w[2]  = MakeDrawArea(200, 200, NULL, NULL);

As you can see, we create the first form and specify that we don't care where it goes (the first form widget is always placed in the top left corner of the window). Then we create some widgets to place inside of our new form. Next, and this is important, we layout all the widgets inside of the first form. In this case we only need to make one call to SetWidgetPos() . Then we create the next form, and specify that we want to place it to the right of form1. Finally we create a drawing area widget, which is placed inside of form2.

If you want to create hiearchies of form widgets, you would specify the form widget that should be the parent for the first argument to MakeForm() . This can get quite complicted, so you should make sure you know what you're doing if you want to create big hierarchies.

NOTE: It is important that you layout all your widgets before you create a new form (unless you're creating a child form).

SEE ALSO: SetForm() , MakeWindow()


void SetForm(Widget w)

The SetForm() function allows you to change what is considered the current form. Normally you only use this function to set the current form to be TOP_LEVEL_FORM. You can cause your program to crash if you are not careful about what you set as the current form.

The main purpose of this function is to let you create displays that have both form widgets and other "normal" widgets at the same level. Mainly you would want to do this if you wanted a large drawing area (or some other type of widget) but didn't want to bother creating an form widget just to hold that one widget.

After calling this function, you can position any new widgets relative to other widgets (usually form widgets) created at the top level of the window.

The normal calling sequence is: SetForm(TOP_LEVEL_FORM), although you can specify any other form widget you like. Be careful, as it is possible to confuse the X layout routines and cause your program to crash.

NOTE: Before you call SetForm() and start creating new widgets and positioning them, any previous form widgets should be completely layed out (i.e. you called SetWidgetPos() for all child widgets of any previously created form widgets).

SEE ALSO: MakeForm() libsx-2.05/docs/html/general.libsx.html0000644000175000017500000001336311252443541021241 0ustar amckinstryamckinstry How to Use libsx

General Information on Using Libsx

Using libsx is pretty simple. At the minimum, you #include "libsx.h" and link with libsx.a. To actually have X windows pop open and such, you need to do the following:

  1. To get everything started, you should call OpenDisplay() ). If OpenDisplay() ) returns a non-zero value, it's ok to go on. OpenDisplay() ) creates what will eventually be your first window.
  2. After calling OpenDisplay() ), you can go on to create all sorts of widgets with the MakeXXX() calls. You can lay them out with calls to SetWidgetPos() .
  3. When you are done creating the user interface, call ShowDisplay() . This causes the window and components you've created to be displayed on the workstation screen.

    Until you call ShowDisplay() , the user can NOT see your window, and drawing into drawing areas has NO effect.

  4. If you need to, you can call any of the color allocation functions such as GetStandardColors() , etc.
  5. Finally, once the window is displayed and you've done all the initializations you wish, you must then call MainLoop() . After you call MainLoop() , events get processed as they come in and your callback functions are called as necessary.

    After calling MainLoop() , the correct way for your program to exit is to have one of your callback routines call exit() when appropriate (like after the user clicks on a "Quit" button).

  6. There is a predefined procedure CloseProcedure() , with a single argument
             CloseProcedure(Widget w)
    
    which is called each time the user presses the "Delete Window" slot of the window bar. Its default action is to close the active window, and to exit the application if that window is the original main window. You can redefine it to do whatever you like before closing (or to prevent the window being closed).

That's all you need to do. Even though that may look like a lot to do, it's really pretty simple in practice. For example, here is a hello world program with libsx:

#include "libsx.h"

main()
{
  MakeLabel("Hello World!");
  MainLoop();
}

Granted it's one more line than a standard printf() type of hello world program, but it's not all that bad.

Hello world programs are nice, but you don't tend to write very many of them. Real applications need to be able to do much more. Even these "real" programs aren't all that bad in libsx.

Here is a simple program that opens a window with a quit button and a drawing area that you could use to draw whatever graphics you wanted:

#include <stdio.h>
#include "libsx.h"

void quit(Widget w, void *data)
{
  exit(0);
}


void draw_stuff(Widget w, int width, int height, void *data)
{
  ClearDrawArea();
  DrawLine(0,0, width, height);   /* just draw a diagonal line */
}
  
int main(int argc, char **argv)
{
  Widget w[2];


  argc = OpenDisplay(argc, argv);
  if (argc == 0)                   /* woops, couldn't get started */
    exit(5);
  
  
  w[0] = MakeButton("Quit", quit, NULL);
  w[1] = MakeDrawArea(300,300, draw_stuff, NULL);

  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);

  ShowDisplay();
  GetStandardColors();

  MainLoop();   /* off we go! */
}

Here is how one would redefine the CloseProcedure to make it do some further stuff before closing.

void CloseProcedure(Widget w)
{
  if(w == GetTopWidget(a_widget_in_the_main_window)))
    {
    printf("Main window closed by user\n");
    exit(0);
    }
  else
    {
    printf("Auxilliary window closed by user\n");
    SetCurrentWindow(w);
    CloseWindow(); /* This actually closes the window */
    }

  /* Don't include exit(0) or CloseWindow() if you want to prevent the
     window from closing */
}

The code above is the basic skeleton for a libsx program, even complicated ones. First you open the display with OpenDisplay(). Then you build your interface by creating a bunch of widgets with the MakeXXX() calls. Next you layout the display by specifying the relative positions of the widgets to each other. Then you would get any fonts or colors you may need, and finally you just enter the main loop.

In libsx, your callback functions are where all the real work happens. The program above has two callback functions, quit() and draw_stuff(). They are tied to events that happen in the interface. When the user clicks on the "Quit" button, your quit() function is called. When the drawing area gets resized or needs to be redrawn, your draw_stuff() function gets called.

Usually the process of creating the interface would get separated into a separate function that is easy to modify (instead of cluttering up main). However, the basic outline is the same as above. The only real difference with more complicated interfaces is that they usually have a lot more calls to the MakeXXX() functions and they tend to make use of the extra void pointer argument in the callback routines.

If you'd like more examples, take a look at the provided source code. There are several reasonable examples of varying complexity that you can take and modify as you like. Each of the demos tries to demonstrate a certain group of features, so take a look at each to find the one that most closely matches what you want to do and start hacking from there! libsx-2.05/docs/html/misc.html0000644000175000017500000003744511252443541017446 0ustar amckinstryamckinstry Miscellaneous Functions


Miscellaneous

The following function allows you to specify how the display should be layed out. It lets you logically position the components you created with the MakeXXX() functions. You will use this function to layout the arrangement of your buttons, labels and drawing area(s).


void SetWidgetPos(Widget w, int where1, Widget from1, int where2,Widget from2);

This function lets you position a Widget in your window. The idea is that you specify logical placement of the Widget (i.e. place it to the right of this widget, and under that widget). Many layouts are possible, and you can even specify that you don't care where a specific widget is placed.

There are three types of placement. You can place a widget to the right of another widget with PLACE_RIGHT. If the argument "where1" is PLACE_RIGHT, then the Widget "w" will be placed to the right of the Widget "from1". If "where1" is equal to PLACE_UNDER, "w" will be placed under the widget "from1". The same holds true for the argument "where2" and Widget "from2". Having two arguments is necessary to be able to unambiguously specify where you want components placed in the display. If you don't care about where a widget is placed, you can use NO_CARE for the `where' argument and a NULL value for the `from' argument.

Generally, the first widget created need not be specified, it will always be in the top left corner. Other widgets can the be placed relative to that widget. For example, if you created 4 widgets (w[0] through w[3]) and wanted to arrange them in a column, you would do the following :

     SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
     SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
     SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE, NULL);

Notice how the third argument changes; we are placing the next widget underneath the previous widget. The zero'th widget (w[0]) doesn't have to be placed because it is always in the top left corner (this can not be changed).

If you wanted to arrange things in a row, you would use PLACE_RIGHT instead of PLACE_UNDER.

As a more complicated example, supposed you want to create two rows of widgets, and a drawing area. You would do the following :

     /* first three across the top */
     SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL);
     SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL);
     SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL);

     /* next three underneath the top row */     
     SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL);
     SetWidgetPos(w[5], PLACE_UNDER, w[0], PLACE_RIGHT, w[4]);
     SetWidgetPos(w[6], PLACE_UNDER, w[0], PLACE_RIGHT, w[5]);

     /* put the drawing area under the second row */
     SetWidgetPos(w[7], PLACE_UNDER, w[4], NO_CARE, NULL);

It is useful to think of the window as a kind of grid in which you can put various pieces. Just draw a picture of what you want and then use SetWidgetPos() to indicate to the system what is next to/underneath of what.

Also, all imaginable layouts are not possible with SetWidgetPos() . For example, you cannot specify specific pixel offsets for a widget, or that it be centered in the display, or right justified. This limitaton is for the sake of simplicity. Generally this should not be a problem (if it is, you are probably getting beyond the scope of what libsx was intended to provide, i.e. you're becoming an X hacker :).

You can simulate more complicated layouts by cheating and creating label widgets whose label is just spaces and then placing other widget the left or underneath the label. This works but is kind of hackish. SEE ALSO: AttachEdge() ,


void AttachEdge(Widget w, int edge, int attach_to)

Attaches an edge of widget to an attach position. Possible values for edge and attach respectively are

  RIGHT_EDGE, LEFT_EDGE, TOP_EDGE, BOTTOM_EDGE, 
  ATTACH_RIGHT, ATTACH_LEFT, ATTACH_TOP, ATTACH_BOTTOM.
The result of the AttachEdge procedure is that the relative positions of the specified "edge" and "attach_to" objects remain fixed once for all, even when the window is resized.

SEE ALSO: SetWidgetPos() ,


void SetFgColor(Widget w, int color);

This function sets the foreground color of a widget. If the widget is a drawing area, all future primitives are drawn with the specified color. If the widget is some other type of widget, it sets the foreground color of the widget (such as its text) to be the specified color.

The argument "color" should be an integer that was returned from the colormap functions ( GetNamedColor() , GetRGBColor() , GetPrivateColor() or GetStandardColors() ).

SEE ALSO : SetColor() , SetBgColor() , SetBorderColor() , GetStandardColors() , GetNamedColor() , GetRGBColor()


void SetBgColor(Widget w, int color);

This function sets the background color of a widget. If the specified widget is a drawing area, the next call to ClearDrawArea() will clear the drawing area to the specified background color.

The argument "color" should be an integer that was returned from the colormap functions ( GetNamedColor() , GetRGBColor() , GetPrivateColor() or GetStandardColors() ).

SEE ALSO : SetBgColor() , SetBorderColor() , GetStandardColors() , GetNamedColor() , GetRGBColor()


void SetBorderColor(Widget w, int color);

This argument will set the border color that is drawn around a widget. The same effect happens for all of the different widgets -- the border is redrawn with the new color. This can be very useful for giving a nice visual offset to an important or dangerous button. Of course you should avoid garish combinations of colors that are hard to look at.

SEE ALSO : SetBgColor() , SetBorderColor() , GetStandardColors() , GetNamedColor() , GetRGBColor()


int GetFgColor(Widget w);

This routine is a convience function that will return the current foreground color of any kind of widget. This is mainly useful for drawing widgets to make sure that you draw things in the proper foreground color. This can arise as a problem if you assume that black is going to be the default foreground color (which it normally is). However, the user can change this default by using the -fg "color" option on the command line. This is an X command line option, and can not be overriden by your program. A real application would use this function to check the value and use it to draw in the user's preferred foreground color. Other programs can just ignore the problem and still work ok as long as the user doesn't change the program's colors.

This function returns the integer value of the foreground color that you can use in later calls to SetFgColor() or SetColor() . It returns -1 if you passed an invalid Widget to it.

SEE ALSO : GetBgColor() , SetColor() , SetFgColor()


int GetBgColor(Widget w);

This routine is a convience function that will return the current background color of any kind of widget. This is mainly useful for drawing widgets to make sure that you draw things in the proper background color. This can be a problem if you assume that white is going to be the default background color (which it normally is). However, the user can change this default by using the -bg "color" option on the command line. This is an X command line option, and can not be overriden by your program. A real application would use this function to check the value and use it to draw in the user's preferred background color. Other programs can just ignore the problem and still work ok as long as the user doesn't change the program's colors.

The other problem that crops up if you ignore the background color is that if you go to erase something by just drawing in white and white doesn't happen to be the actual background color, your program will look funny.

This function returns the integer value of the background color that you can use in later calls to SetBgColor() or SetColor() . It returns -1 if you passed an invalid Widget to it.

SEE ALSO : GetFgColor() , SetColor() , SetFgColor()


void AddTimeOut(unsigned long interval, void (*func)(), void *data);

If you would like to animate a display or do some periodic processing (such as an auto-save feature for an editor), you can use time-outs.

A time-out is a callback function that gets called when the specified amount of time has expired (or I should say more precisely, when at _least_ that much time has passed, Unix a'int no real time system).

The argument `interval' is an unsigned long and is specified in milliseconds. That is, a time out of 1 second would be an argument of 1000.

The function, func, declared as follows:

        void  func(void *data, XtIntervalId *id)
	{
	}

The second argument should be ignored by function's code, but it should appear in the function prototype.

The function is only called once, if you would like the function to be called repeatedly (to update an animation for example), the last thing the function should do is to call AddTimeOut() again.


void SetWidgetState(Widget w, int state);

This function lets you enable or disable particular widgets in an interface. If, for example, choosing one item from a menu should disable various other widgets, you can call this function.

The Widget argument is the widget in question. The state argument is a boolean, which indicates whether the widget should be active or not. A value of TRUE indicates that the widget should accept input, and a value of FALSE indicates that the widget should not accept input (it becomes greyed out).

When you disable a widget, the user can no longer interact with that widget in _any_ way (it becomes grey'ed out and just ignores all input).


int GetWidgetState(Widget w);

This function returns a boolean value indicating whether or not the specified widget is currently active.

If the widget is active and accepting input, the return is TRUE, if the widget is inactive, the return value is FALSE.


void Beep(void);

This function is real complicated. It beeps the workstation speaker.


void ReadLocale(char *language);

Reads the dialogs file (normally stored in /usr/share/libsx/dialogs.XX where XX is the two-letter code for the language). This function can be used to override the environment variable LANG.


void SetWidgetBitmap(Widget w, char *data, int width, int height);

This function lets you attach a bitmap to a widget instead of its default text. This function only works correctly on Button, Toggle and Label widgets. Using it on another type of widget yields undefined results.

The Widget, w, will display the bitmap data given by the argument, data, whose width and height are given as the last two arguments.

The bitmap data is only one bitplane deep, and is usually produced by a somewhat brain-dead X program called `bitmap'. The output of the bitmap program is a file you can directly #include in your source code. The contents of the file are a static array of characters and two #defines that give the width and height of the bitmap.

Thus, making a widget with a bitmap is a two step process. First you would edit a bitmap using the `bitmap' program, then you would do the following:

          #include  "file_bmap.h"

          Widget w;

	  w = MakeButton(NULL, func, some_data_ptr);
	  SetWidgetBitmap(w, file_bmap_bits,file_bmap_width,file_bmap_height);

Bits which are a one in the bitmap are drawn in the widget's current foreground color and zero bits are drawn in the current background color.

SEE ALSO : SetWidgetPixmap() , SetThumbBitmap()


void SetWidgetPixmap(Widget w, char **xpmdata);

This function lets you attach a pixmap to a widget instead of its default text. This function only works correctly on Button, Toggle and Label widgets. Using it on another type of widget yields undefined results.

The Widget, w, will display the pixmap data given by the argument xpmdata.

The pixmap data can be produced by the standard X program called `pixmap'. It can also be obtained with many other drawing tools, using the so called xpm format. An .xpm file is a file you can directly #include in your source code. The contents of the file is a static array of strings of the form

          static char * mypix_xpm[] = {
          "48 32 3 1",
          "o      c grey76",
          ".      c blue",
          "X      c LimeGreen",
          "o.XXX.ooooXXX...o.XXX.ooooXXX...o.XXX.ooooXXX...",
          ...
          };
to indicate width=48 height=32 num_colors=3 cpp=1 (1 character used per pixel), 'o' will code for grey76, '.' for blue and 'X' for LimeGreen. The remaining strings are strings representing the rows of pixels, e.g. "o.XXX.ooooXXX...o.XXX.ooooXXX...o.XXX.ooooXXX...", for the first row of 48 pixels.

Let us suppose that you want to set a pixmap on a button. You would first create the desired pixmap "mypix.xpm" with the pixmap program, then you would do the following:

          #include  "mypix.xpm"

          Widget w;

	  w = MakeButton(NULL, func, some_data_ptr);
	  SetWidgetPixmap(w, mypix_xpm);
SEE ALSO : SetWidgetBitmap() libsx-2.05/docs/html/toggle.html0000644000175000017500000001175711252443541017772 0ustar amckinstryamckinstry Toggle

Toggle Widget

A toggle widget is similar to a button widget except that it maintains state. That is, when a user clicks a toggle widget, it remains highlighted until it is clicked again. This is similar to an on/off switch.

Toggle widgets can also be used to create a group of "radio buttons". A radio button group is a set of toggle widgets in which at most one of them can be selected at any one time (it is possible for none of them to be selected).


Widget MakeToggle(char *txt, int state, Widget w, ToggleCB func, void *data);

This function makes a widget that will toggle between a highlighted `on' state and an unhighlighted `off' state.

The first argument is the text that will be displayed inside the widget. The `state' argument is a boolean value of the initial state of the toggle button (TRUE == on/highlighted, FALSE == off). The next argument, a Widget, is NULL if this widget is a simple toggle button by itself and not part of a radio group (described below).

If you plan to display a bitmap for the toggle button, you may specify a NULL for the txt argument (and then call SetWidgetBitmap()).

The func argument is a standard callback function, that should be declared as follows:

     void func(Widget w, void *data)
     {
     }

The last argument, data, is an arbitrary pointer you would like passed to your callback function (it becomes the second argument to the callback function.

Each time the widget changes state, your callback function is called. That is, each time the user clicks the toggle, your function is called.


Radio Groups

It is possible to connect toggle widgets together to form a group of widgets that are mutually exclusive. That is to say, with a radio group, you can have a set of widgets in which at most one of them will be highlighted at any given time. Therefore, if you had 3 widgets, A, B, and C, only one could be highlighted at any one time, and clicking on another unhighlights the current one and highlights the toggle clicked on. This is useful for selecting one choice of several (such as a size, which is either small, medium or large, but not two at the same time). Keep in mind that it is possible for none of them to be selected.

To build a radio group, you use the Widget argument of the MakeToggle() function. If you specify another valid toggle widget in the call to MakeToggle() , the new widget becomes connected to the widget you specified. All the widgets you connect together form a radio group. Any single widget can _only_ be in one radio group.

EXAMPLE:

   Widget widg1, widg2, widg3;

   widg1 = MakeToggleWidget("Thing 1", TRUE,  NULL,  func1, NULL);
   widg2 = MakeToggleWidget("Thing 2", FALSE, widg1, func2, NULL);
   widg3 = MakeToggleWidget("Thing 3", FALSE, widg1, func3, NULL);

Notice how widg2 and widg3 specify widg1 as their Widget argument. This connects all three into a radio group in which only one can be set at a time. We initialize widg1 to be initially set and the others off. If you specify more than one widget as `on', the results are undefined.

The callback functions are called whenever a widget is highlighted or unhighlighted. The callbacks to the widget being unhighlighted happen before the callbacks to widgets being highlighted.

SEE ALSO: SetToggleState() , GetToggleState() , SetWidgetBitmap() , SetFgColor() , SetBgColor() , SetBorderColor() , SetWidgetFont()


void SetToggleState(Widget w, int state);

SetToggleState() explicitly sets the state of a widget.

The `state' argument is either TRUE (set the toggle to its highlighted state), or FALSE (unhighlight the widget). The callback routine for the widget is only called if there is a change in state.

SEE ALSO: GetToggleState() , MakeToggle()


int GetToggleState(Widget w);

This function returns the current state of the toggle widget w. The return values are either TRUE (the widget is selected) or FALSE (the widget is not highlighted).

SEE ALSO: MakeToggle() , SetToggleState() libsx-2.05/docs/html/draw_area.html0000644000175000017500000002602511252443541020430 0ustar amckinstryamckinstry Drawing Area


Drawing Area

A drawing area is a rectangular area that supports drawing into, receiving input from (mouse clicks, mouse motion and keypresses) and redisplay requests from X. You can draw any sort of graphics into a drawing area as well as perform various types of interaction with mouse and keyboard input.

It is also useful to read the drawing.html file for more information on the actual drawing routines available.


Widget MakeDrawArea(int width, int height, RedisplayCB func, void *data);

The function MakeDrawArea() creates a drawing area which you can later use to draw graphics into and receive mouse and keyboard input from. The drawing are will have a width and height as you specify. The callback function, func, is called whenever the drawing area should be redisplayed (because it was obscured or resized). The argument "data" is a pointer to any arbitrary data you want, and it is passed directly to the resize callback (and the other callbacks as well).

The redisplay callback is where you should put all of your drawing code. It is called for you when the application opens the window for the first time (by calling MainLoop()). The redisplay callback function should be declared as follows:

    void  redisplay(Widget w, int width, int height, void *data)
    {
    }

The first argument, w, is the drawing area widget that needs to be redrawn. The second and third arguments are the new width and height of the drawing area (it may have been resized). The final argument is the void pointer passed to MakeDrawArea().

If you are interested in receiving other types of input, see the functions, SetButtonDownCB() , SetButtonUpCB() , SetKeypressCB() SetMouseMotionCB() , SetLeaveCB() . These functions will let you set callbacks for the other types of input.

Each drawing area you create has its own state (foreground and background colors, drawing mode, and line width). Only one drawing area can be active at any given time. When an event happens for a drawing area, that drawing area becomes the active drawing area. You can make other drawing areas active with SetDrawArea() .

If something goes wrong in creating the DrawArea, a NULL value is returned.

SEE ALSO : drawing.html, SetButtonDownCB() , SetButtonUpCB() , SetKeypressCB() , SetMouseMotionCB() , SetLeaveCB() , SetWidgetPos() , SetWidgetFont() , SetFgColor() , SetBgColor() , SetBorderColor()


void SetButtonDownCB(Widget w, MouseButtonCB func);

This function sets up a callback that will be called everytime the user presses a mouse button in the specified drawing area widget `w'.

The callback function should be declared as follows:

    void  func(Widget w, int which_button, int x, int y, void *data)
    {
    }

Then, whenever the user presses a mouse button in the drawing area, your callback is called. The first argument is the drawing area widget where the event happened. The next argument is an integer specifying which button was pressed. It is a small positive integer. A value of one is the left mouse button, two is the middle mouse button and three is the right mouse button. Technically, values of four and five are also possible though I've never seen a mouse with five buttons. The x and y arguments are the position of the mouse where the user pressed the mouse button. The final argument is the void pointer argument given to MakeDrawArea() .

You can specify a NULL for the function to turn off receiving button down events.


void SetButtonUpCB(Widget w, MouseButtonCB button_up);

This function sets up a callback that will be called everytime the user releases a mouse button in the specified drawing area widget `w'.

The callback function should be declared as follows:

    void  func(Widget w, int which_button, int x, int y, void *data)
    {
    }

Then, whenever the user releases a mouse button in the drawing area, your callback is called. The first argument is the drawing area widget where the event happened. The next argument is an integer specifying which button was released. It is a small positive integer. A value of one is the left mouse button, two is the middle mouse button and three is the right mouse button. Technically, values of four and five are also possible though I've never seen a mouse with five buttons. The x and y arguments are the position of the mouse where the user released the mouse button. The final argument is the void pointer argument given to MakeDrawArea() .

You can specify a NULL for the function to turn off receiving button up events.


void SetKeypressCB(Widget w, KeyCB func);

This function lets you set a callback so that you will receive keyboard input in the drawing area.

The callback function should be declared as follows:

      void  func(Widget w, char *input, int up_or_down, void *data)
      {
      }

Then, whenever the user presses keys in the drawing area, your callback function is called. The first argument is the drawing area widget where the event happened. The next argument is a character pointer to a null-terminated string that contains what was typed by the user. The up_or_down argument indicates whether the key was pressed released (a zero indicates a press, a 1 indicates a key release). The final argument is the void ponter argument given to MakeDrawArea().

It is useful to know that the string returned to your program is not necessarily a single ASCII character. You will get the usual ASCII characters, including control characters (such as ^C or ^H). But, the workstation's function keys will also be returned in a string such as "F11" or "F23". You will also get other longer strings such as "Control_L", "Alt_R", or "Shift_L". It is important to understand that even if you just press the shift key to get a capital letter, you will first receive the string "Shift_L" or "Shift_R", then you will receive a capital letter (say, "H"). You should probably ignore the "Shift_L" or "Shift_R" messages (but who knows, you may find some use for them).

The argument, up_or_down, tells you whether the given key was pressed or released. If the key was pressed down, up_or_down has a zero (0), if the key was released, up_or_down contains a 1. This is useful for doing things like shift-clicking with the mouse or handling control-key combinations in an editor or other program.

The arrow keys return strings such as "Left", "Up", "Right", or "Down". Other keys on the keyboard may return strings such as "Home", "Prior", "Next", "Undo", "Help", etc. Of course not all keyboards generate all of the strings (because they aren't set up to).

NOTE WELL: The string that is returned to you can NOT be modified by your program. If you want to munge with it, make a copy using strdup() or strcpy() into your own buffer space.

You can specify a NULL for the function to turn off receiving keypress events.


void SetMouseMotionCB(Widget w, MotionCB func);

This function sets a callback so that whenever the mouse moves in your drawing area, the specified function will be called. It is important to keep in mind that the function you specify is called _every_ time the mouse moves in the drawing area, even if it is just passing through. The callback function should be declared as follows:

    void  func(Widget w, int x, int y, void *data);
    {
    }

The first argument is (as usual) the Widget where the mouse was moved in. The next two arguments are the current X and Y values of the mouse. The final argument is the void pointer passed into MakeDrawArea() .

You should be very frugal with what happens in this function so as not to cause the application to lag behind the user too much. Calling functions like sleep() are definitely out of the question.

You can specify a NULL for the function to turn off receiving mouse motion events.


void SetEnterCB(Widget w, EnterCB func);

This function sets a callback so that whenever the mouse crosses the boundary of your drawing area from the outside in, the specified function will be called.

The callback function should be declared as follows:

    void  func(Widget w, int x, int y, void *data);
    {
    }

The first argument is (as usual) the Widget that the mouse entered. The next two arguments are the X and Y coordinates of the crossing point. The final argument is the void pointer passed into MakeDrawArea() .

The coordinates may be inaccurate if the mouse moved rapidly; they may even fall outside the widget's boundaries.

You can specify a NULL for the function to turn off receiving mouse enter events.


void SetLeaveCB(Widget w, EnterCB func);

This function sets a callback so that whenever the mouse crosses the boundary of your drawing area from the inside out, the specified function will be called.

The callback function should be declared as follows:

    void  func(Widget w, int x, int y, void *data);
    {
    }

The first argument is (as usual) the Widget that the mouse exited. The next two arguments are the X and Y coordinates of the crossing point. The final argument is the void pointer passed into MakeDrawArea() .

The coordinates may be inaccurate if the mouse moved rapidly; they may even fall outside the widget's boundaries.

You can specify a NULL for the function to turn off receiving mouse exit events.

libsx-2.05/docs/html/color.html0000644000175000017500000004367011252443541017626 0ustar amckinstryamckinstry Color


Color

This file describes the routines for managing colors in your window. For example if you want to change what the foreground color is, or need to get specific colors. To get specific colors you use the functions discussed in here. It is important to remember that you can not call any of these functions until you have called ShowDisplay() .

Colors are represented by integers. When you get a color, you are returned an integer that you can use in calls to SetFgColor() , SetBgColor() , and SetColor() . You should attach no meaning to the numbers, and just because green is 17 does not mean that 18 is a lighter or darker shade of green.

There are three ways to manipulate colors with libsx. The first way handles most of the common cases, and is done with GetNamedColor() or GetRGBColor() .

The next method, GetPrivateColor() , allows your application to modify the actual display color represented by a color number (something you cannot do with the the previous methods).

The final method gives you complete control in specifying the entire colormap. That is, you can determine exactly what integers map to what colors so you can obtain smooth gradients (so for example black is color 0, and white is 255). These routines work best on 8 bit displays but will work on 24 bit displays.

NOTE: You can NOT call any color function until you have called ShowDisplay() .

The way colors work for drawing is like this. There are usually 256 available colors on a workstation. This is called an 8-bit display because 2 to the 8'th power == 256. These colors are stored in a table (array) of 256 entries. If you allocate a color, and it is in entry 37, then to draw with the color that is stored there, you must use 37 as an argument to the SetColor() function. When you ask for a color, it may be taken from anywhere in the array of 256 entries, and there is NO guarantee that if you allocate a green color that the next color in the table will be a lighter or darker green. Even if you allocate many colors using GetNamedColor() or GetRGBColor() , you have NO assurances about where those colors are in the array (chances are they won't be contiguous). If you need to have a contiguous set of numbers, you must use GetAllColors() and then SetColorMap() or SetMyColorMap() to set up a custom colormap with a known set of values. When you get a private color, your application can specify what values that color index should have. This is useful when you want to interactively modify a color.

It is important to remember that `getting a color' really means getting an index into the color table where the actual color is stored.

If you actually want to pop up a window allowing selection of color by users, invoke the SelectColor() function. It doesn't permanently allocate a color, so you show just do it later with the other routines.


void GetStandardColors(void);

This function gets 6 standard colors, RED, GREEN, BLUE, YELLOW, BLACK, and WHITE. These 6 variables contain values which can be used in calls to SetColor(), SetFgColor(), SetBgColor(), etc.

Do not use the values in RED, GREEN, BLUE, YELLOW, BLACK or WHITE before calling GetStandardColors(). The results are undefined if you do this.

In addition to the above 6 standard colors, the library makes use of 3 further colors HILIGHT, BUTTONBG, INPUTBG, as follows:

HILIGHT is the color of hilighted text to be used in active input string entries, and INPUTBG the corresponding background color. BUTTONBG is the default color of buttons for internally defined widgets; By default, HILIGHT coincides with the foreground color, while INPUTBG and BUTTONBG coincide with the background color (fg/bg default themselves to black/white). They can be adjusted to any other color value, once such a color has been defined through the Get*Color routines.

NOTE: You can only call GetStandardColors() after calling the ShowDisplay() function.

SEE ALSO : GetNamedColor() , GetRGBColor() , GetAllColors() SetColor() , SetFgColor() , SetBgColor()


int GetNamedColor(char *name);

This function allocates an entry in the color table for the color given by the ascii string "name". You can view the list of available color names with the showrgb command in a shell (some nice ones are "peachpuff", "burlywood3", "aquamarine", and "paleturquoise3"). Color names can have spaces in them. The return value of the function is an integer that you can use in calls to SetColor() (or any of the other SetXXColor() calls). If an error occurred trying to allocate the color (very possible if you allocate a lot of colors), a -1 is returned.

NOTE: the return value of zero is valid, a -1 indicates an error NOT zero.

NOTE: You can only call GetNamedColor() after calling the ShowDisplay() function.

SEE ALSO : GetStandardColors() , GetRGBColor() , GetAllColors() SetColor() , SetFgColor() , SetBgColor()


int GetRGBColor(int r, int g, int b);

This function tries to allocate the color given by the red, green, blue triple r,g,b. The arguments r,g, and b should be between 0 and 255. Overflow is not checked for. The return value is an integer value usable in the SetColor() calls or a -1 if an error occurred.

NOTE: the return value of zero is valid, a -1 indicates an error NOT zero.

NOTE: You can only call GetRGBColor() after calling the ShowDisplay() function.

SEE ALSO : GetStandardColors() , GetNamedColor() , GetAllColors() SetColor() , SetFgColor() , SetBgColor()


int GetPrivateColor(void);

This function allocates a private color cell for use by the application. A private color cell is one which you can change what color it represents. For example, if you would like to let the user interactively manipulate some color, you would need to allocate a private color cell.

The integer returned by this function is a reference to a color cell whose values you can set with SetPrivateColor() . The intial contents of the private color cell are undefined and you should probably call SetPrivateColor() immediately to set it to some known value.

If an error occurs, a -1 is returned.

When you are done with a private color cell, you should free it with FreePrivateColor() .

SEE ALSO: SetPrivateColor() , FreePrivateColor() , GetRGBColor()


void SetPrivateColor(int which, int r, int g, int b);

This function sets the color cell referred to by `which' to have the r,g,b values specified. The r,g,b values are given in the range 0-255 (inclusive). Once this function is called, any thing drawn in the display with the color `which' will now have the new color determined by the r,g,b arguments.

SEE ALSO: GetPrivateColor() , FreePrivateColor() , SetFgColor() , SetBgColor() ,


void FreePrivateColor(int which);

This function returns the color associated with the private color cell `which' to the system. You should have allocated the color referred to by `which' with GetPrivateColor() .

SEE ALSO GetPrivateColor() , SetPrivateColor() .


int GetAllColors(void);

This function is rather drastic and should be used with caution. It immediately grabs an entire 256 entry colormap for private use. This has the unfortunate effect of (temporarily) wiping out the colors in all the other windows on the display. However this is necessary if you wish to get a smooth colormap to use in displaying a smooth-shaded or continuous tone picture. Once GetAllColors() is called, the entire colormap is free for manipulation by your program. The colormap remains allocated until you call FreeAllColors() , at which time everything goes back to normal.

If an error occurred (quite possible), this routine returns FALSE. If everything went ok and the colormap was successfully allocated, TRUE is returned.

If you can avoid using this function, try to. It is disconcerting for the user to have the colormap get wacked out and have most of their windows disappear (they don't really disappear of course, you just can see them usually). However it is sometimes necessary to do this as there is no other way to get a smoothly continuous color map.

Usually, you will want to call SetColorMap() or SetMyColorMap() right after this function.

NOTE: On machines with multiple hardware colormaps (e.g. lots of SGI machines), only the current drawing area gets the colormap, other widgets and windows are not affected.

NOTE: You can only call GetAllColors() after calling the ShowDisplay() function.

SEE ALSO : SetColorMap() , SetMyColorMap() , FreeAllColors() , GetStandardColors() , GetNamedColor() , GetRGBColor()


void FreeAllColors(void);

This function frees a private colormap that was allocated with GetAllColors() . It has the beneficial effect of immediately restoring the rest of the colors on the screen and in other windows to those that existed prior to the call to GetAllColors() . This function is useful if wish to let the user restore their original colors temporarily (although this will happen automatically when the mouse moves outside the window).


void SetColorMap(int num);

This function creates several predefined color maps that are very smoothly continuous. It saves you the hassle of writing them yourself (even though they are mostly easy). The "num" argument you pass in should be one of the following #define's :

#define GREY_SCALE_1    0
#define GREY_SCALE_2    1
#define RAINBOW_1       2
#define RAINBOW_2       3

The colormap GREY_SCALE_2 is a complete smooth color ramp from pure black (color 0) to pure white (color 255). The other grey scale, GREY_SCALE_1 is a nearly pure ramp from black (color 0) to white (color 252), but also has a few additional colors thrown in near the end of the colormap. The two RAINBOW_? colormaps have different types of smooth changing rainbows of color. This are really only useful for drawing pretty patterns or doing false coloring.

NOTE: You should call GetAllColors() before you call this routine. It is not necessary, but if you don't, and GetAllColors() fails, you will never know about it, and your application may not work very well.

SEE ALSO : SetMyColorMap() , GetAllColors() , GetNamedColor() , GetStandardColors() , GetRGBColor()


void SetMyColorMap(int n, unsigned char *r, unsigned char *g,unsigned char *b);

Occasionally it is necessary to have absolute control over your colormap, and this function lets you do that. This function lets you completely specify each and every color that will be in the colormap. The three arrays r,g, and b are simply the red, green, and blue components of each color. The values in the array range from 0 to 255, hence they are unsigned char's. You need not specify a full array of 256 colors, you can in fact only specify a few. The integer argument "n" indicates how many entries there are in the r,g, and b arrays. The argument "n" should be greater than 0 and less than 255.

NOTE: You should call GetAllColors() before you call this routine. It is not necessary, but if you don't and GetAllColors() fails, you will never know about it, and your application may not work very well.

SEE ALSO : SetMyColorMap() , GetAllColors() , GetNamedColor() , GetStandardColors() , GetRGBColor()


char *SelectColor(char *inicolor, int output, char *txt, CSelCB func, void *data);

This is a sophisticated popup which lets the user browse and select a color. The "mode" button cycles through 3 possible modes: RGB mode (red-green-blue), HSV mode (hue-saturation-value), CMYK mode (cyan-magenta-yellow-black). For each mode, the routine provides scrolls which the user can use to set the parameters. Meanwhile, a rectangular draw area shows the resulting color. The user can also browse in the RGB data file (litteral definitions of colors in /usr/lib/X11/rgb.txt). Finally, the "Grab color" button sets the color to be the color of any chosen pixel on the screen, and the "Best match" button selects the predefined standard color which best approximates the selected color.

The parameters have the following significance: char *inicolor is the color to be set when the popup opens. It can be in a variety of different formats, e.g.

      "#87CEEB"      "135,206,235"      "skyblue"      "SkyBlue"
which are viewed as equivalent denominations of the skyblue color, whose pixel values are red=135=0x87 green=206=0xce blue=235=0xeb The output parameter sets which of the three forms should be used as a return value for the char *SelectColor() procedure:
      if output=0, the returned string is in hexadecimal form "#87CEEB", 
      if output=1, the returned string is either hexadecimal or litteral,
                  and is litteral if there is an exact match 
      if output=2, the returned string is the litteral best match
The next three parameters (txt, func, data) can be used to let interactively the selection operate on a call-back function func. The function is activated when the user clicks on an extra button at the lower right corner, marked with the label char *txt. The parameter void *data can be passed to the function. The function func itself should be of the type
      void func(Widget w, CSelData *cdata)
where cdata is a pointer to a complex structure data set, the main components of which are
      cdata->r cdata->g cdata->b           RGB (float values)
      cdata->h cdata->s cdata->v           HSV values
      cdata->c cdata->m cdata->y cdata->k  CMYK values
      cdata->rgb_list[1000][60]            List of litteral color names
      cdata->match_list[1000][60]          List of ordered best matches
      char *rgb_ptr[1000];                 Null terminated pointers to rgb_list
      char *match_ptr[1000];               Null terminated pointers to match_list
Finally, the initial data pointer used when invoking SelectColor can be retrieved as cdata->data. libsx-2.05/docs/html/drawing.html0000644000175000017500000005116711252443541020143 0ustar amckinstryamckinstry Drawing Functions

Drawing Overview

This file contains documentation about the routines that let you draw in a drawing area.

The documentation for these functions is quite brief because they are not all that complicated (how much can one really say about DrawLine() ).

Keep in mind that for all the drawing functions, the top-left corner of a drawing area is considered to be 0,0.

Also, all primitives are drawn in the current foreground color (set either by SetColor() or SetFgColor() . Text is drawn with the current foreground color and the background color. Line, arc, and box primitives are drawn with the current line width (as set by SetLineWidth() ), and all primitives are drawn in the current draw mode (set by SetDrawMode() ).


void SetDrawArea(Widget w);

This sets the current drawing area to be that named by the Widget w. If `w' is not a drawing area widget, nothing happens.

You need to call this function when you want to switch between multiple drawing areas.

If you only have one drawing area you do not need to worry about this function at all.

Any callbacks for a drawing area already have the current drawing area set to be the one where the event happened (so it is not necessary to call this function in a callback for a drawing area).


void SetColor(int color);

This sets the foreground color to draw with in the current drawing area (each drawing area has its own foreground color). The argument "color" should be a valid color obtained with one of the color functions (such as GetNamedColor() or GetRGBColor(), etc).

To some extent this function duplicates the SetFgColor() function, but exists because it is faster than SetFgColor().

SEE ALSO : SetBgColor() , GetFgColor() , SetFgColor() , GetStandardColors()


void SetLineWidth(int width);

This functions sets the width of lines drawn in the current drawing area. Each drawing area has its own line width.

A width of zero is valid and tells the X server to draw lines as fast as it possibly can, possibly being a little inaccurate. Larger numbers of course draw wider lines.

SEE ALSO : SetDrawMode() , SetWidgetFont() , SetFgColor() , SetBgColor()


void SetDrawMode(int mode);

This function sets the drawing mode for the current drawing area. A drawing mode is one of:

GXcopy, GXxor, GXinvert, GXor, GXclear, GXand, GXandReverse, GXnoop, GXnor, GXequiv, GXinvert, GXorReverse, GXcopyInverted, GXorInverted, GXnand, and GXset

Most of these are stupid/useless modes defined by X (so ignore them).

The primary mode is GXcopy (the default mode). This causes all primitives to draw in the foreground color, overwriting any pixels already drawn.

Libsx also defines a special mode: SANE_XOR. The SANE_XOR mode will actually draw primitives in a true XOR mode so that you can draw things like rubber-band boxes that the user stretches with the mouse. You must use SANE_XOR if you want true XOR'ed primitives, GXxor will definitely NOT work as you expect.

When you are done using SANE_XOR, you would normally call SetDrawMode() with an argument of GXcopy to restore normal drawing.

SEE ALSO : SetLineWidth() , SetWidgetFont() , SetFgColor() , SetBgColor()


void GetDrawAreaSize(int *w, int *h);

This is a convience function that returns the size of the current drawing area. The window dimension are returned in the two variables. It is important to note that "w" and "h" are POINTERS to integers, not just regular integers.


void ClearDrawArea(void);

This function completely clears the current drawing area and sets it to the current background color (which may not be white).

Generally, when your redisplay callback is called, this is the first thing want to do.

SEE ALSO : SetDrawArea() , GetBgColor() , SetBgColor()


void DrawPixel(int x1, int y1);

This function draws a point in the current foreground color at the location x1, y1 in your current drawing area. The top left corner of the drawing area is considered 0,0.

SEE ALSO : GetPixel() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


int GetPixel(int x1, int y1);

This function retrieves the pixel value at the location x1, y1 in the current drawing area. The top left corner of the drawing area is considered 0,0.

The pixel value returned to you will be between 0 and 255 (inclusive). The value you get back should be treated as an index to a colormap. To find out what actual color is displayed at that location, you need to look up the color in the colormap (which you should be maintaining as there is no way to get it after you've set it).

NOTE: This function is NOT very high performance. It has to call GetImage() to do the bulk of the work. This is unfortunate, but unavoidable because X does not provide an easy way to read individual pixels.

SEE ALSO : GetImage() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawLine(int x1, int y1, int x2, int y2);

This function draws a line from x1,y1 to x2,y2 in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

SEE ALSO : DrawPolyline() , DrawPixel() , SetColor() , SetBgColor() , SetFgColor() , SetDrawArea() ,


void DrawPolyline(XPoint *points, int n);

This function accepts an array of points and draws them as a connected polyline on the display. The line is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

The `points' argument is an array of XPoint structures which are as follows:

   typedef struct XPoint
   {
      short x,y;
   }XPoint;

You do not need to define this structure yourself. It is defined for you already, it is just reprinted here so you can see what it is.

You should have an array of these structures with each entry holding a vertex of the polyline.

SEE ALSO : DrawLine() , DrawFilledPolygon() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawFilledPolygon (XPoint *points, int n);

This function takes an array of points and draws them as a filled polygon on the display. The polygon is filled with the current foreground color and is drawn in the current drawing area. The top left corner of the drawing area is considered 0,0.

The `points' argument is an array of XPoint structures which are as follows:

   typedef struct XPoint
   {
      short x,y;
   }XPoint;

You do not need to define this structure yourself. It is defined for you already, it is just reprinted here so you can see what it is.

You should have an array of these structures with each entry holding a vertex of the polygon to be filled.

SEE ALSO : DrawPolyline() , DrawBox() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawBox(int x, int y, int width, int height);

This function draws a rectangular box starting at x,y with a width and height as specified. If you make the call: DrawBox(50,50, 75,75), you will get a box that starts at position 50,50 and goes for 75 pixels in the X and Y directions (i.e the other extreme of the box would be at 125,125). The box is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

If the width and height are negative, the box is still drawn properly.

SEE ALSO : DrawFilledBox() , DrawPolyline() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawFilledBox(int x, int y, int width, int height);

This function draws a filled rectangular box starting at x,y with a width and height as specified. If you make the call: DrawFilledBox(50,50, 75,75), you will get a filled box that starts at position 50,50 and goes for 75 pixels in the X and Y directions (i.e the other extreme of the box would be at 125,125). The box is filled with the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

If the width and height are negative, the box is still drawn properly.

SEE ALSO : DrawBox() , DrawFilledPolygon() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawText(char *string, int x, int y);

This function prints the text string "string" starting at x,y. The text is drawn in the current foreground color. The background of the text is filled with current background color of the drawing area widget. The top left of the drawing area is 0,0. The X,Y position you specify is the bottom left corner of where the text is drawn.

SEE ALSO : GetFont() , FontHeight() , TextWidth() , SetColor() , SetDrawArea() , SetWidgetFont() , GetBgColor() , SetFgColor() , SetBgColor()


void DrawArc(int x, int y, int width, int height, int angle1, int angle2);

This function draws an arc/ellipse from the location x,y that is bounded by the box defined by the x,y, width and height. That is, the arc/ellipse will always be contained in the box defined by the x,y position and the width and height arguments. The X,Y arguments are not the center of the arc/circle.

The arc begines at angle1 degrees and continues for angle2 degrees around the circle. The arc is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

If you want a circle, you would specify angle1 as 0, and angle2 as 360.

If the width and height are negative, the arc is still drawn properly.

SEE ALSO : DrawPolyline() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawFilledArc(int x, int y, int width, int height, int angle1, int angle2);

This function draws a filled arc/ellipse from the location x,y that is bounded by the box defined by the x,y, width and height. That is, the arc/ellipse will always be contained in the box defined by the x,y position and the width and height arguments. The X,Y arguments are not the center of the arc/circle.

The arc begines at angle1 degrees and continues for angle2 degrees around the circle. The arc is filled with the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0.

If you want a circle, you would specify angle1 as 0, and angle2 as 360.

If the width and height are negative, the arc is still drawn properly.

SEE ALSO : DrawArc() , SetColor() , SetDrawArea() , SetBgColor() , SetFgColor()


void DrawImage(char *data, int x, int y, int width, int height);

This function draws a bitmap image that has a width and height as specified by the arguments. The image is drawn at location x,y in the current drawing area. The "data" argument should point to at least width*height bytes of data.

Each byte of the data is interpreted as a color value to draw the corresponding pixel with.

Normally you would use this function when you have taken over the colormap with GetAllColors() (so that you can be guaranteed certain colors are in a given range). If you have not taken over the colormap, you need to make sure that the bytes in the image data contain valid values that you've allocated with the color allocation functions ( GetNamedColor() , GetRGBColor() or GetPrivateColor() ).

The top left corner of the drawing area is considered 0,0.

SEE ALSO : GetImage() , SetColor() , SetDrawArea() , GetAllColors()


void DrawBitmap(char *data, int x, int y, int width, int height);

This function draws a bitmap that has a width and height as specified by the arguments. The bitmap is drawn at location x,y in the current drawing area. The "data" argument should point to at least width*height/8 bytes of data.

The difference between this function and DrawImage() is that the data is an actual bitmap with 1 bit per pixel (versus 1 byte per pixel for an Image).

Each byte of the data is interpreted as 8 pixels. If a bit in the byte is on, the corresponding pixel is drawn in the foreground color. If the bit is off, the corresponding color is drawn in the background color.

Normally you would use this function on a monochrome display (though it will still work on a color screen).

The top left corner of the drawing area is considered 0,0.

SEE ALSO : DrawImage() , GetImage() , SetColor() , SetDrawArea()


void GetImage(char *data, int x, int y, int width, int height);

This function retrieves a bitmap image from your drawing area that has a width and height as specified by the arguments. The image is taken from the starting location x,y in the current drawing area. The "data" argument should point to at least width*height bytes of data.

The area of memory pointed to by data will be filled with the 8-bit pixel values of the current drawing area. Note that the pixel values are not the actual color values. If you want the actual color values, you'll need to know what the current colormap is (which you would know if you've set the colormap) and then use the pixel values to index the colormap.

The memory pointed to by data is packed with width*height bytes, with no extra padding or filling. That is, the first width bytes correspond to line 0, the next width bytes correspond to line 1 of the image, etc.

It is important to keep in mind that if you plan to save the pixel data in an image file, you need to also keep track of the colormap so that you can save that as well. By themselves, the pixel values don't correspond to any particular color.

A serious drawback of this function arises from the way X operates. If the drawing area from which you are "getting" the image is obscured by another window, that part of the bitmap will be empty. The only way around this is to make sure that your window is in front of all the others before you call GetImage(). This is a serious limitation, but it's the way X operates.

The top left corner of the drawing area is considered 0,0. If you specify a starting x,y and width,height dimensions that are larger than your drawing area, you will get a BadMatch error and X will terminate your program (so be careful).

SEE ALSO : DrawImage() , SetColor() , SetDrawArea() , GetAllColors()


void ScrollDrawArea(int dx, int dy, int x1,int y1, int x2, int y2);

This function scrolls the box defined by (x1,y1) (x2,y2) by the amounts dx and dy in the X and Y directions respectively. This means that the box whose upper left corner is (x1,y1) and whose lower right corner is (x2,y2) are scrolled by dx and dy pixels in X and Y.

A positive value for dx causes the drawing area to scroll its contents to the left. That is, whatever is at the left edge gets pushed off and the dx columns of pixels on the right hand side are cleared to the background color. A negative value has the opposite effect.

A positive value for dy corresponds to scrolling upwards. That is, whatever is at the top of the drawing area is pushed up by dy pixels and the bottom dy rows of pixels are cleared to the background color. A negative value has the opposite effect.

This function is useful for scrolling the drawing area to draw new information (such as a text editor might do to scroll text up or down).

The new area exposed by the scroll is filled with the current background color of the drawing area.

SEE ALSO : SetWidgetFont() , SetColor() libsx-2.05/docs/html/scrollbar.html0000644000175000017500000002321611252443541020465 0ustar amckinstryamckinstry Scrollbars


Scrollbars

A scrollbar is a widget that allows a user to control some numeric quantity interactively by using the mouse to scroll a slider, similar to the volume slider on some radios. The slider is called the "thumb" or "thumb area" in X terminology.


Widget MakeHorizScrollbar(int length, ScrollCB scroll_func, void *data);

Widget MakeVertScrollbar(int height, ScrollCB scroll_func, void *data);

These two routines create scrollbars. Scrollbars allow the user to interactively control some numeric quantity with the mouse.

When the user presses the left mouse button, the value represented by the scrollbar increases. When the press the middle mouse button, they can interactively adjust the value. Clicking the right mouse button decreases the value represented by the scrollbar.

The arguments to create a scrollbar are its length or height in pixels, a callback function to call when the scrollbar changes value and an extra void pointer argument that is passed to the callback function.

If these routines fail, they return NULL.

To set what values a scrollbar represents, you must use SetScrollbar() . These two routines only make a scrollbar and do not set it to return useful values. You always have to call SetScrollbar() to set what a scrollbar represents (see the documentation for SetScrollbar() for more information).

Your callback routine is called everytime the scrollbar changes. Since the calculations are done in floating point, the value may not have changed enough to be interesting, but your routine is still called. You should take care to see that the value changed enough to be interesting to your applications (i.e. it is wasteful for a text editor to repaint the window when the new value is 0.003 different than the old value).

A scrollbar callback routine should be declared as follows:

      void scroll_func(Widget w, float new_val, void *data)
      {
      }

The first argument, w, is the scrollbar widget that the user is manipulating. The second argument is a floating point value that represents the new value of the scrollbar. The third argument is the void pointer argument that was passed to Make{Horiz,Vert}Scrollbar().

SEE ALSO : SetScrollbar() , SetThumbBitmap() , SetWidgetPos() , SetFgColor() , SetBgColor() , SetBorderColor()


void SetScrollbar(Widget w, float where, float max, float size_shown);

This function lets you set the values that a scrollbar represents. The first argument is a scrollbar widget. The next three arguments are floating point numbers that specify the parameters of the scrollbar.

Before discussing the details of the three float arguments, let us get some terms straight. When we refer to the `container' of a scrollbar, we mean the entire box that makes up the scrollbar. The `thumb' of a scrollbar is the gray area that the user can grab to manipulate. We refer to the size or length of the thumb area (the amount of grey) as the `size shown'. The total amount represented by the scrollbar is called `max'.

The arguments mean the following:

      where -- this floating point number specifies where in the
               container the top of the thumb area should start.  If
	       you have a maximum value of 100 and where is 50, the 
	       beginning of the thumb will be in the middle of the
	       container. 

        max -- The maximum value that the scroll bar can have.  You
	       will receive numbers in the range 0 to max (inclusive). 
	       Obviously max should be a positive, and is a float.

 size_shown -- This float value controls how big the grey area that
               the user can grab is.  This represents how much of
	       whatever it is you are representing is visible.  For
	       example, a text editor which shows 24 lines of text
	       would set size_shown to be 24 (out of whatever max
	       is).  If you want the scrollbar to represent a
	       percentage of something, where when it is 100%, the
	       grey area is also 100% of the box, then you should
	       set the size_shown to be equal to max.  If this is
	       confusing, there are examples below.

Now, some examples to clarify things (in the following, assume that the argument, w, represents a scrollbar widget created with the MakeHorizScrollbar() or MakeVertScrollbar() routines).

For the first example, let's assume you want a scrollbar to let you set a color value which can range between 0 and 255 with the initial value at 67. You sould set the scrollbar as follows:

       SetScrollbar(w, 67.0, 255.0, 1.0);

The first value, 67.0, is where we would like the beginning of the thumb area to appear. The next value, 255, is the maximum value the scrollbar can attain. The third value, 1, is the size of the thumb area (the amount represented by the thumb relative to the maximum size). This scrollbar will now return values in the range of 0 to 255 (inclusive). The thumb area will be small, and represents one value of the 255 possible divisions. The position of the thumb area in the container represents its value.

For the next example, suppose we wish to make a scrollbar represent some percentage of a value. That is, the size of the thumb area should be proportional to the value of the scrollbar relative to its maximum (so when the value is at it maximum, the thumb area is 100% of the scrollbar).

In this case we would like the size of the thumb area to represent the amount of the variable (note the difference from the above example). Let us suppose we want a scrollbar which can represent a percentage 0 to 100, with the initial value being 50.

       SetScrollbar(w, 50.0, 100.0, 100.0);

The first value, 50, is where the thumb area begins (in the middle of the container). The next number is 100, and represents the maximum value of the scrollbar. The next number, again 100, is the size shown. Making this value the same as the max value (in this case 100) causes the thumb area to vary according to the value the scrollbar represents.

As a final example, let us take a text editor which is displaying a file. In this case, let us assume the text file is 259 lines long, the window can display 47 lines, and the top line currently displayed is 72. To create the correct scrollbar, we would do the following:

       SetScrollbar(w, 72.0, 259.0, 47.0);

This creates a scrollbar which has a thumb area whose size is 47/259 of the entire container, and is positioned 72/259'ths of the way down the container.

SEE ALSO: MakeHorizScrollbar() , MakeVertScrollbar() , SetThumbBitmap() , SetWidgetPos()


void SetThumbBitmap(Widget w, char *black_bits, int width, int height);

Sets a bitmap for the thumb area in the scrollbar. This function is similar to SetWidgetBitmap(), which one can refer to for details. The default bitmap is a black & white combination of pixels. To get instead an entirely black thumb area, one can use

       static unsigned char black_bits[] = { 0xff };
       SetThumbBitmap(scroll_widget, black_bits, 8, 1); 
The default is equivalent to
       static unsigned char black_bits[] = { 0xaa, 0x55 };
       SetThumbBitmap(scroll_widget, black_bits, 8, 2);
SEE ALSO: MakeHorizScrollbar() , MakeVertScrollbar() , SetWidgetPos() SetWidgetBitmap()

void SetScrollbarStep(Widget w, float fact)

Sets the fraction of the scrollbar that gets increased or decreased when the left or right mouse buttons is pressed. The scrollbar thus moves faster as fact increases. The default value is fact = 0.1 . See also the explanations concerning the scrollbar callback functions.

SEE ALSO: MakeHorizScrollbar() , MakeVertScrollbar() ,


void SetScrollbarDirection(float dir)

The effect of this function is to possibly affect the scrollbar step by a signed factor dir (normally equal to +1 or -1). If dir = -1, the direction of the scrollbar moves are reversed with respect to mouse clicks. This function is useful to deal with the tricky behaviour of the standard libraries Xaw, Xaw3d, Xaw95 (Libsx can be linked with any of these). Actually Xaw3d, Xaw95 behave differently of Xaw with respect to the action of mouse clicks on scrollbars, and the SetScrollbarDirection() function can then be used to adjust that behaviour according to the needs.

SEE ALSO: SetScrollbarStep() , libsx-2.05/docs/html/menu.html0000644000175000017500000001017011252443541017441 0ustar amckinstryamckinstry Menus


Menus

Menus provide standard drop-down style menus that let the user select from a variety of choices. The Athena widgets do not support cascaded menus, so a menu is only a single list of items. A menu contains menu items that are tied to callback functions in the application. Menu items must be text and can not be bitmaps.


Widget MakeMenu(char *name);

This function creates a menu button that contains the text pointed to by the character string name. When the button is clicked, a menu pops up. The menu contains items created with MakeMenuItem() .

You need to save the return value of this function to be able to pass it to MakeMenuItem() so that menu items can be attached to a menu.

If this function fails, it returns NULL.

SEE ALSO: MakeMenuItem() , MakeButton() , SetWidgetPos()


Widget MakeMenuItem(Widget menu, char *name, ButtonCB func, void *arg);

This function adds a menu item to a menu. The menu item contains the text pointed to by the string name. Whenever the user selects this menu item, the callback function, func, is called. The final argument is an arbitrary void pointer that is passed to the callback function.

The first argument must be a widget returned by MakeMenu() (results are undefined if it is not).

If MakeMenuItem() fails for any reason, a NULL is returned.

The callback function for the menu item should be declared as follows:

       void  func(Widget w, void *data)
       {
       }

Whenever the user selects this menu item, the callback will be called.

Setting of widget attributes with SetFgColor() , SetBgColor() , etc work normally except that only one background color may be specified and it takes effect for the entire menu. You can set different fonts for each menu item.

NOTE: You do not need to call SetWidgetPos() for menu items. Successive menu items are placed below previous menu items.

SEE ALSO: SetMenuItemChecked() , GetMenuItemChecked() , MakeMenu() .


void SetMenuItemChecked(Widget w, int state);

This function sets the ``checked'' state of a menu item. If a menu item is in the checked state, a bitmap of a check mark appears to the left of the menu item text.

The first argument, w, is a menu item widget created with MakeMenuItem() . The second argument, state, is a boolean value of either TRUE (1) or FALSE (0) indicating whether or not the check mark should be drawn to the left of the menu item. If the state argument is TRUE, the check mark is drawn. If the state argument is FALSE, the check mark is removed.

SEE ALSO: GetMenuItemChecked() , MakeMenuItem()


int GetMenuItemChecked(Widget w);

This function returns a boolean result indicating whether the menu item referred to by the Widget w, is checked or not.

If the menu item referred to by `w' is checked, a value of TRUE (1) is returned. If the menu item does not currently have a check mark next to it, a value of FALSE (0) is returned.

SEE ALSO: SetMenuItemChecked() , MakeMenuItem() libsx-2.05/docs/html/functions.html0000644000175000017500000001542711252443541020517 0ustar amckinstryamckinstry Libsx Functions

Listing of Functions by Category

Alphabetical Listing of Functions

libsx-2.05/docs/html/font.html0000644000175000017500000000773111252443541017454 0ustar amckinstryamckinstry Fonts

Fonts

Fonts are different type styles that can be used in various widgets. You load a font by name and get a handle in return. The handle you get allows you to set the font in the various widgets and font information calls.


XFont GetFont(char *fontname);

This function loads the font named by fontname and returns a handle to the font or NULL if there is an error. The handle returned by this function is an XFontStruct pointer, but should be treated as an opaque data type.

After you've loaded a font, you can then set that font in any widget that displays text. You can also use the handle in calls to TextWidget() and FontHeight() .

When you are done with a font, you should free it with FreeFont() .

SEE ALSO: SetWidgetFont() , FreeFont() , GetWidgetFont() , FontHeight() , TextWidth()


void SetWidgetFont(Widget w, XFont f);

This functions sets the font used by the widget `w', to be the font referred to by the argument `f'. The argument f should have been obtained with GetFont() .

SEE ALSO: GetFont() , FreeFont() , FontHeight() , TextWidth()


XFont GetWidgetFont(Widget w);

This function returns a handle to the font currently used by the Widget w. If an error occurs or there is no default font for the widget, a NULL is returned.

You should NOT call FreeFont() on any value returned by this function unless you are sure that you allocated the font with GetFont().

SEE ALSO: GetFont() , SetWidgetFont() , FontHeight() , TextWidth()


void FreeFont(XFont f);

This function frees the resources associated with the font, f. You should call this function when your application is done using a particular font.

Of course you should make sure that no widget still uses the identified font.

SEE ALSO: SetWidgetFont() , GetFont()


int FontHeight(XFont f);

This function returns an integer value that is the height in pixels of the specified font. The height is defined to be the ascent of the characters (from the baseline to the top of a capital letter) plus the descent of the characters (the distance from the baseline to bottom of a descender character like `g' or `p').

SEE ALSO: TextWidth() , GetFont() , SetWidgetFont()


int TextWidth(XFont f, char *txt);

This functions returns the width in pixels used by the string pointed to by txt in the font f. The string should be null-terminated and the entire string is used to determine the width.

SEE ALSO: FontHeight() , GetFont() , GetWidgetFont() libsx-2.05/docs/html/text_edit.html0000644000175000017500000001064511252443541020475 0ustar amckinstryamckinstry Text Edit Widget


Text Edit Widget

A text edit widget is an area used to display and optionally edit multiple lines of text. You can specify the text to be displayed as either an in memory string or as a file name. The text edit area manages its scrollbars and internal affairs, you need not do anything (in fact there are no callbacks for the text edit widget).


Widget MakeTextWidget(char *txt, int is_file, int editable, int w, int h);

This functions lets you create a text edit widget that will display some text and optionally let the user edit and manipulate it. The first argument, txt, is a pointer to a string (NULL is ok). The second argument, is_file, is a boolean value indicating if the first argument should be interpreted as a file name or not. The next argument, editable, is a boolean value indicating whether or not the user is allowed to edit the text. The final two arguments specify the width and height of the drawing area box. If the area is too small to display the text, scrollbars will appear.

The txt argument can either contain the entire string (null terminated) that you would like the user to edit, or it can contain the name of a file to be loaded into the text edit widget. If the second argument is_file is TRUE (1), then the first argument gets interpreted as a file name. If is_file is FALSE (0), then the first argument contains the actual text to be displayed.

If the txt argument contains the actual text to be displayed, after calling MakeTextWidget() you can free the memory if necessary (the text edit widget makes an internal copy of the string).

The argument `editable' is a boolean value indicating whether or not to allow editing of the text in the widget. If you just wish to display some text (such as a help file), set the editable argument to FALSE (0) and the user will not be allowed to modify the text.

SEE ALSO: GetTextWidgetText() , SetTextWidgetText() , SetWidgetPos() , SetFgColor() , SetBgColor() , SetWidgetFont()


void SetTextWidgetText(Widget w, char *text, int is_file);

This argument lets you modify the text displayed in a text edit widget. The first argument identifies the text edit widget to change. The second argument is a null-terminated string that either contains the actual text to display or the name of a file to read in. If the is_file argument is TRUE (1), then the string pointed to by the argument, text, is interpreted as a file name. If is_file is FALSE, the string pointed to by text is directly displayed in the text edit widget.

After calling this function, you can free the string pointed to by text if necessary. The text edit widget makes an internal copy of the text. If you wish to update the displayed text again, you should call SetTextWidgetText() again.

BUGS: The function name is way too long.

SEE ALSO: GetTextWidgetText() , MakeTextWidget()


char *GetTextWidgetText(Widget w);

This function lets you retrieve the text contained in a text edit widget. The only argument, w, should be a text edit widget created with MakeTextWidget() .

The return from this function is a character pointer to a null-terminated string that contains the current text in the widget. If there is an error, a NULL is returned.

NOTE: You should not free or otherwise modify the text returned by this function. If you need to make modifications, make a copy of the buffer. Again, DO NOT MODIFY THE TEXT RETURNED BY THIS FUNCTION. Make a copy if you need to modify it.

BUGS: The function name is way too long.

SEE ALSO: SetTextWidgetText() , MakeTextWidget() libsx-2.05/docs/html/windows.html0000644000175000017500000002672111252443541020200 0ustar amckinstryamckinstry Windows

Windows

This file contains descriptions of the main high level startup and window creation functions.


int OpenDisplay(int argc, char **argv);

This function initiates everything with libsx. You should call this function before you call any of the other functions. A correctly written application will call OpenDisplay(), passing its command line arguments and count. The return value from this function is the new number of arguments (or zero if an error occurred). The X libraries accept various standard command line options such as -display or -font, and if your application passes the command line arguments to OpenDisplay() ), these will be handled properly. Any X options are removed from the argv array, therefore it is best if you do your command line processing _after_ calling OpenDisplay(). In case you want to predefine some X options to be passed to OpenDisplay (without having to type them on the command line), e.g. -bg gray76 to define the background pixel, you can set the PredefArgs variable as follows:

    static char *args[] = { "-bg", "gray76", NULL };

    PredefArgs = args;
    OpenDisplay(argc, argv);

You only need to call this function once to initialize the first window your program uses. Any other windows you need should be created with MakeWindow() .

Technically, calling OpenDisplay() is optional (the MakeXXX() routines will call it for you if you didn't), but it's usually a good idea to call it (since it is only one line of code and it's pretty straightforward.

This function returns FALSE (0) if something went wrong (like being unable to open the display, etc). If everything went ok, it returns the new number of arguments in argv.

SEE ALSO: MakeWindow()


void ShowDisplay(void);

This function displays the currently active window (user interface) you've created with the MakeXXX() calls. After this call completes, the interface will be visible on the display.

Until you call this function, your interface will not be visible and drawing into a draw area will have no effect.

Usually one calls ShowDisplay() , allocates some colors and then immediately calls MainLoop() . If you do not call ShowDisplay() , but just directly call MainLoop() , then MainLoop() implicitly calls ShowDisplay() .

SEE ALSO: MainLoop() , MakeWindow()


void MainLoop(void);

After calling this function, your program yields control to the user interface, and it is entirely driven by what the user does and the callbacks associated with the various widgets. For a single window application, the general flow of events is:

    OpenDisplay(argc, argv);   /* initialize the first window */

    MakeButton(....);          /* create widgets */

    ShowDisplay();             /* put the window on the screen */
                               /* optionally allocate colors */
    MainLoop();                /* start the main loop going */

When you call this after calling ShowDisplay() for your first window (created by OpenDisplay() )), the MainLoop() function never returns and your application should have some callback function that will exit() the program (such as a quit button or menu option).

If you did not call ShowDisplay() , MainLoop() will call it for you and then launch into the main loop.

You should not call MainLoop() for NONEXCLUSIVE mode windows created with MakeWindow() . Those type of windows have their callbacks handled by the MainLoop() function that is already executing (i.e. the one you called for your original window).

If the window is an EXCLUSIVE mode window, then MainLoop() keeps executing until CloseWindow() is called on the EXCLUSIVE mode window. That is, MainLoop() blocks until the EXCLUSIVE mode window is closed, and then it returns.

If you create a non-exclusive mode window, the general order of events is:

      MakeWindow(NONEXCLUSIVE_WINDOW, ....);
      MakeButton(...);
      ShowDisplay();

This creates a window, puts interface objects into it, and then puts that window on the screen. No other actions need to be taken, and when the callback that created this new window returns, all processing takes place normally, including the processing of the new window and its callbacks.

For a window of EXCLUSIVE_WINDOW mode (like a popup), the general order execution is:

      MakeWindow(NONEXCLUSIVE_WINDOW, ....);
      MakeButton(...);
      ShowDisplay();

      MainLoop();     /* blocks until CloseWindow() is called */

      /* do something with whatever values the popup got for us */

When MainLoop() returns for an EXCLUSIVE_WINDOW, the window has been closed.

SEE ALSO: MakeWindow() , ShowDisplay() .


void SyncDisplay(void);

This function synchronizes the display with all drawing requests you have made. Normally it is not necessary to call this function, but if you make many repeated function calls to draw graphics, they will be updated in a chunky fashion because X buffers drawing requests and sends a bunch of them at once.

After this function completes, all drawing requests you have made are visible on the screen.

NOTE: Normally you do not need to call this function because X ensures that everything you request gets drawn, but sometimes it is necessary to insure the synchronization of the display.


Widget MakeWindow(char *window_name, char *display_name, int exclusive);

NOTE: Do not call this function to open your first window. Your application's first window is opened for you by OpenDisplay() ). If your application only needs one window, do NOT call this function.

This function opens a new window, possibly on a different display (workstation). The new window has the name specified by the argument window_name and is opened on the display named by display_name (a string usually in the form of, "machine_name:0.0"). The final argument indicates whether the window should be an exclusive window or not (described below).

After this functions returns, the current window is the one you just created and you can begin adding widgets to it with the MakeXXX() calls. After have created and added any widgets you want, you should call ShowDisplay() , and if the window is an EXCLUSIVE_MODE window, then you should call MainLoop() (which blocks until the window is closed). If you opened the window with the NONEXCLUSIVE_WINDOW option, you should NOT call MainLoop() .

If you pass a NULL for the window_name, it receives a default title of "Untitled".

If you pass the #define, SAME_DISPLAY, for the display name, the window opens on the same display as the original window opened by OpenDisplay() ).

The argument, exclusive, indicates what type of window to open. A normal window is a NONEXCLUSIVE_WINDOW. That is, it will not block the user from interacting with your existing window. An EXCLUSIVE_WINDOW is a popup window that blocks input to your main window until the popup is closed with CloseWindow().

The EXCLUSIVE_WINDOW mode is useful for requestors that need an answer and the user should not be able to do other things in the application. Of course some user-interface folks don't think modal windows like this are good, but tough cookies for them because some times it's necessary.

SEE ALSO: SetCurrentWindow()


void SetCurrentWindow(Widget w);

This function sets the currently active window for other function calls such as CloseWindow() . If you have multiple windows open on several displays, you must call this function switch the currently active one when you wish to manipulate the various windows.

The argument, w, must be a valid value returned by MakeWindow(). If you would like to set the current window to be the original window opened by OpenDisplay() ), you can pass the #define, ORIGINAL_WINDOW.

When you change windows, the current drawing area is also changed to be the last current drawing area in the new window (if there is a drawing area in the new window).

SEE ALSO: MakeWindow() , CloseWindow()


void CloseWindow(void);

This function closes and removes from the display, the currently active window.

After calling this function, you should not refer to any of the widgets contained in the window as they are invalid (as is the window handle).

SEE ALSO: SetCurrentWindow() , MakeWindow()


Widget GetTopWidget(Widget w);

This function returns the ID value of the top widget containing Widget w. This can be useful in combination with the CloseProcedure() routine, or when direct calls to the Xt or Xlib libraries are to be performed on the top widget.

SEE ALSO: MakeWindow() , CloseWindow() CloseProcedure()


void CloseProcedure(Widget w);

This function redefines the closing procedure to be used when the user clicks on the "Close Window" slot of the window bar.

It should invoke CloseWindow() to actually close the window, but need not do so, in case one wants the "Close Window" slot to become ineffective. The value of w can be compared to any of the existing top window widgets by means of a call

          GetTopWidget(any_widget_in_that_window).

This can be used to check which window is invoked, and so introduce various closing procedures for various windows.

SEE ALSO: SetCurrentWindow() , CloseWindow() , GetTopWidget() libsx-2.05/docs/html/label.html0000644000175000017500000000475411252443541017567 0ustar amckinstryamckinstry Labels

Labels

A label widget is a widget that displays some text or bitmap but cannot be clicked on or interacted with by the user. In addition to "simple" label widgets, other widgets such as buttons or menus can as well carry labels. Generally a label is for informational purposes, such as saying what the program title is, or what the widget is supposed to be used for. Some widgets carry predefined labels; the list of predefined labels is:

char *SX_Dialog_Label[] = {"Yes", "Cancel", "No", "Okay", "Cancel", "Retry" };

The pointers to these labels can be reassigned to other string pointers, so as (e.g.) to provide translations into other languages.


Widget MakeLabel(char *txt);

This function creates a label that contains the text in the character string pointed to by "txt". The text will simply be displayed, with no fancy borders or special highlighting. If the text contains new line characters, they will be interpreted properly.

If the argument txt is NULL, then no label will be set for the widget. This is convienent if you plan to put a bitmap on this widget with the SetWidgetBitmap() function.

This widget is useful for displaying a piece of textual information like a filename or user name.

If this routine fails, a NULL is returned.

SEE ALSO : SetWidgetPos() , SetWidgetBitmap() , SetLabel(), SetWidgetFont() , SetFgColor() , SetBgColor() , SetBorderColor()


void SetLabel(Widget w, char *txt);

This function sets the widget's text to the character string pointed to by "txt". The widget makes a private copy, so the "txt" pointer may be freed afterwards.

The new string may be truncated to the right if it is longer than the original. The simplest workaround is to pad the initial string with blanks at creation time.

This function also works with widgets created by MakeButton() and MakeToggle().

SEE ALSO : MakeLabel() , MakeButton() , MakeToggle() , SetWidgetFont() libsx-2.05/docs/html/libsx.html0000644000175000017500000001351611252443541017625 0ustar amckinstryamckinstrylibsx

libsx - Simple X Library


Introduction to libsx

Welcome to libsx, the simple X library. Libsx is an attempt to simplify the vagaries of programming under X windows, making it simple to create user interfaces for programs. With libsx, 10 lines of code may be all you need to create a user-interface complete with many different types of widgets.

Libsx is layered on top of the Athena widget set and basically acts as a front end to all the Athena and Xlib garbage so that programming reasonable interfaces isn't so painful. For example, libsx has a simple to use one-line string entry widget that you can create with a single function call (it's based on the Athena text widget but hides all the gory details). Libsx encapsulates the common operations people usually want to perform in a window system and makes them easy to accomplish (at the loss of some flexibility).

If you've ever wanted to just open a window with a few buttons and draw some graphics, but were turned away by the complexity of trying to do that, then libsx may be your ticket. Libsx is capable of easily creating many types of user-interface components each with a single function call of a few arguments. The library supports the following Athena ``widgets'':

    - Labels
    - Buttons
    - Toggle buttons and Radio buttons
    - String Entry areas
    - Scrolling Lists
    - Menus
    - Scrollbars
    - Drawing Areas
    - Text Edit boxes

The goal of libsx was to make the creation and manipulation of each of these items as simple as possible. The standard simplicity litmus test is a "Hello World" program, which in libsx is:

#include "libsx.h"
main()
{
  MakeLabel("Hello World");
  MainLoop();
}

More complicated interfaces use a similar style of creation and complete applications usually require less than 30 lines of code to create an entire user interface complete with menus, buttons, string entry widgets, etc. For example, to create an application that opens a window with a drawing area and a ``Quit'' button, all one must do is:

#include "libsx.h"

main()
{
  Widget quit_button, draw_area;
	      
  quit_button = MakeButton("Quit",     quit,       NULL);
  draw_area   = MakeDrawArea(500, 500, draw_stuff, NULL);

  SetWidgetPos(draw_area, PLACE_UNDER, quit_button, NO_CARE, NULL);

  MainLoop();
}

So in only a handful of lines of code, we created a simple X application that would have required inordinate amounts of code using traditional methods. All that is required now is for the user to write the routines ``quit'' and ``draw_stuff''.


Acknowledgements

Libsx was developed by Dominic Giampaolo. Quoting from the author:

"I developed libsx over the course of about 2 years while in graduate school at Worcester Polytech (in good ole Worcester, Mass.) It all started when I took the grad course in Computer Graphics. I wanted a nice library of routines to deal with all the X crap so I could concentrate on my graphics code. Soon the library started evolving into a much more sophisticated thing and when I became the TA for the graphics course, I beefed it up a lot. When you have 65 undergrads beating on a library you've written, it's got to be solid. The next time that I was TA, I polished up some more rough edges in the library (the stuff the students complained about) and it went through the ringer a second time with about 45 more students. Finally, during the summer of 1993 I added a ton of more functionality to the library so a friend of mine could write his 3-D editor the way it should be written and so I could do some stuff I wanted to do. In September of 1993 I was hired at SGI and I've done a little bit more work on libsx since I've been here (mainly little cleanups and the rudimentary OpenGL support). That is effectively what you see today."

"I've spent a lot of time deciding how to structure libsx so it would be easy to use but still be open ended. Libsx doesn't try to hide all of X, it just tries to make it more digestable. The library has gotten pretty big at this point, but it should be sufficient to write most types of GUI programs without lots of fuss."

"I've also spent a lot of time deciding what should and shouldn't be in libsx. It's too easy to throw in everything just because it's easy to do so. Unfortunately that's almost never the right reason to include something. I've tried to pare the design down to the essentials needed to write a useful application. Comments and critiques of the design/approach are welcome (I'd like to hear what others have to say about it or how they would have done it)."

In the past year (1994) I've received quite a bit of e-mail regarding libsx. I've received all kinds of comments, suggestions, and bug-fixes from a large number of people out there. If I had kept better track of everything I'd launch into a big spiel thanking all the individuals. Alas, I didn't keep track of everything, so I'll just have to offer a general thanks to all the folks who sent me comments, asked for fixes, and offered replacement code, etc. Thanks folks, I do appreciate it.

      Dominic Giampaolo
      dbg@sgi.com

Libsx includes David Nedde's Athena drawing area widget and encapsulates it so that a simple program to open a window and draw some graphics is now reduced to only a few lines of code.

The HTML documentation was done by Winston Holmes (winston@nestor.engr.utk.edu) by adding the HTML formatting codes to the doc files shipped with libsx. libsx-2.05/docs/html/local.libsx.html0000644000175000017500000000404111252443541020707 0ustar amckinstryamckinstry Local Information on Libsx

Local Libsx Information

Access to libsx

Libsx is currently compiled only for the Sun workstations running either Sunos 4.1.3 or Solaris 2.3. The libsx library is in /usr/local/lib, and the include files are in /usr/local/include.

Compiling and Linking to libsx with C

SunOS 4.1.x

The include files for X11 and libsx are in the standard places, so no special options are needed when compiling and linking.

Solaris 2.3

The X11 libraries are not in a standard location. -L/usr/x11/lib must be used to specify the location of the libraries. -R/usr/x11/lib needs to be used so that the libraries are found when run-time linking is performed.

cc -I/usr/x11/include -I/usr/local/include -c file.c
cc -o file -L/usr/local/lib -lsx -L/usr/x11/lib -lXaw -lXmu -lXt -lX11 -lXext \\
 -R/usr/x11/lib -lsocket

Using C++ with libsx

Since the libsx functions were compiled with a C compiler, the libsx include file must be bracketed with an extern "C" declaration.

extern "C" {
#include "libsx.h"             
}

Sun Specific Instructions when using C++ (Solaris 2.3)

Due to a bug in the C++ compiler, the -R option appears to be ignored by the linker. Setting the environment variable LD_RUN_PATH should make run time linking work properly. This variable should be set during the compilation.

setenv LD_RUN_PATH /opt/SUNWspro/lib:/usr/x11/lib

Example Makefile for C++

CPLUS = CC
 
LIBS = -L/usr/local/lib -lsx -L/usr/x11/lib -lXaw -lXmu -lXt -lX11 -lXext \
 -R/usr/x11/lib -lsocket 
 
CCFLAGS = -I/usr/local/include -I/usr/x11/include
#--------------------------------------------------------------------------
all: gr
 
gr: gr.o Graph.o
        $(CPLUS) -o gr gr.o Graph.o $(LIBS)
 
gr.o: gr.cc
        $(CPLUS) -c $(CCFLAGS) gr.cc
 
Graph.o: Graph.cc Graph.h
        $(CPLUS) -c $(CCFLAGS) Graph.cc
libsx-2.05/docs/html/button.html0000644000175000017500000000533311252443541020015 0ustar amckinstryamckinstry Buttons

Introduction to Buttons

A button widget is a button that a user can click on with the left mouse button to indicate an action. When a button is pressed, it is drawn in inverse video and some action takes place.

A button is connected to your code by a callback function which is called when the user clicks on the button widget with the left mouse button.


Widget MakeButton(char *label, ButtonCB func, void *data);

This function creates a small rectangular button which the user can click on. The character string pointed at by "label" will be printed inside the button. If the string has newline characters in it, they will be interpreted properly (i.e. you will get a multiline label). The next two arguments are a callback function, func, and an arbitrary data pointer, data, that will be passed to the function func.

If you plan to attach a bitmap to this widget, you can specify NULL for the label text (see the docs for SetWidgetBitmap() .

When the button is pressed, the function, "func" will be called. The function, func, will have two arguments. The first argument is the widget that user clicked on (which you can ignore if you do not need it). The second argument is the void pointer, 'data', specified in the call to MakeButton(). The function "func" should be declared as follows:

    void func(Widget w, void *data)
     {
          /* your code goes here */
     }

The last argument (called "data") is the same as the last argument to the MakeButton() function call. It is declared as a void pointer and you can cast to whatever type you need. Generally you'll have something like:

    MyProgram *me = (MyProgram *)data;

You use "buttons" to allow the user to indicate various actions (things like load, save, cut, copy, and paste operations are good examples). The mental model of how a button works is that when the user clicks on the button with the mouse, the function you specify is called.

If something goes wrong in creating the button, a NULL value is returned. This is a rare occurrence, but good code will still check for it.

SEE ALSO : SetWidgetPos() , SetWidgetBitmap() , SetLabel(), SetWidgetFont() , SetFgColor() , SetBgColor() , SetBorderColor() libsx-2.05/docs/html/popups.html0000644000175000017500000001375411252443541020036 0ustar amckinstryamckinstry Popup Windows


Popup Windows

Popup windows are simple dialog boxes that get a simple yes/no or string answer from the user. When these windows popup, they block input to the previously active window.


int GetYesNo(char *question);

This function allows you to prompt the user for the answer to a simple yes or no type of question. It simply pops up a dialog box with the text contained in the string question, and two okay/cancel buttons.

If the user clicks Okay, this function returns TRUE. If the user clicks Cancel, this function returns FALSE. The text in the question string can have embedded newlines (\n characters) to break things up or to add spacing.

SEE ALSO : GetOkay() , GetTriState() , GetString() , GetText()


int GetOkay(char *question);

This function is mainly for short informational displays. It pops up a dialog box with the text contained in the string question, and an okay button.

The text in the question string can have embedded newlines (\n characters) to break things up or to add spacing.

SEE ALSO : GetYesNo() , GetTriState() , GetString() , GetText()


int GetTriState(char *question);

This function allows you to prompt the user for the answer to a simple yes or no type of question, and in addition, the user has a Cancel option. The dialog box contains the string pointed to by the argument question and it also contains three buttons, Yes, No and Cancel.

If the user clicks the Yes button, this function returns TRUE. If the user clicks the No button, this function returns FALSE. If the user clicks the Cancel button, a -1 is returned. It is important to keep in mind that you can't just test for true/false as you can with GetYesNo() since a return of Cancel would test as true (since it is a non-zero value).

The text in the question string can have embedded newlines (\n characters) to break things up or to add spacing.

SEE ALSO : GetYesNo() , GetOkay() , GetString() , GetText()


char *GetString(char *msg, char *default);

This function allows you to prompt the user for a string of input. The first argument, msg, is a pointer to a string which will be displayed in the dialog box. The next argument, default, is the default string to place in the text string box (it can be NULL or "").

When you call this function, it pops up a small dialog box on the screen, and the user can enter the line of text. When the user clicks ok or cancel, the function returns a pointer to the string of text the user entered.

The string that is returned to your application is dynamically allocated with malloc(). It is the application's responsibility to free it when it is done.

If the user clicks cancel, you get a NULL return value.

SEE ALSO : GetYesNo() , GetText()


char *GetLongString(char *msg, char *default, int width);

Similar to GetString(), with an additional argument controlling the width of the input box (in pixels).

SEE ALSO : GetString() , GetText()


char *GetText(char *msg, char *default, int width, int height);

Similar to GetString(), but the dialog box is replaced by an editable window of dimensions width x height, which scrolls in both vertical and horizontal directions.

SEE ALSO : GetString() , GetLongString()


char *GetFile(char info_label, char file_or_dir_name, FreqCB func, void *data)

This is the API call to the File Requestor, which allows you to browse files from a directory or filesystem. The initial directory is set to be the directory file_or_dir_name -- or the directory containing that file if it is not a directory. The top information label is set to be info_label, usually some information to be passed to users. If the callback function (FreqCB) func is not NULL, a double click on an item in the scroll list allows 'func' to be executed without quitting the File Requestor. The syntax for the callback function is

      void func(Widget w, char *dir_name, char *file_name, void *data)
where dir_name and file_name are set to the values selected with the File Requestor.

SEE ALSO: SetFreqFilter()


void SetFreqFilter(char *filter)

Sets the "filter" to be used in the GetFile() procedure. The default filter is "*", which lets all files be listed in the file requestor. If filter is set to "*.txt", then only files possessing a .txt suffix will be listed. An arbitrary number of wild card characters '*' can be used. The length of filter cannot exceed 80 characters in total.

SEE ALSO: GetFile() libsx-2.05/docs/html/list.html0000644000175000017500000000770711252443541017464 0ustar amckinstryamckinstry List


List

A scroll list is a scrollable list of items organized in a veritical fashion. The user can scroll through the list of items using the mouse and select individual items in the list of available choices.


Widget MakeScrollList(char **item_list, int width, int height, ListCB func, void *data);

This function makes a scrollable list of items from which a user can select individual items. The list contains strings of text, pointed to by the table, item_list. The list, item_list, MUST contain a NULL entry as its last element (this is not optional). The area given to display the list is width and height pixels large. If the entire list will not fit, scrollbars appear that will let the user easily scroll through the list.

The callback function, func, should expect to be called with a Widget argument, the string of text the user clicked on, the string's index in your table, and whatever user data pointer you gave at widget creation time. The callback should be declared as follows:

   void func(Widget w, char *str, int index, void *data)
   {
   }

The list of strings passed in to MakeScrollList() must not be free()'d or otherwise deallocated for the entire lifetime of the widget (or until the list of strings is changed with ChangeScrollList() ).

SEE ALSO: GetCurrentListItem() , ChangeScrollList() , SetCurrentListItem() , SetFgColor() , SetBgColor() , SetWidgetFont()


int GetCurrentListItem(Widget w);

This function returns the index of the currently selected item in the list widget `w'. The index value returned is an index into the table displayed by the list (specified when the widget was created or with ChangeScrollList() ).

If no item is selected in the list widget, this routine will return a -1.

SEE ALSO: ChangeScrollList() , SetCurrentListItem() , MakeScrollList()


void ChangeScrollList(Widget w, char **new_list);

This function changes the list of strings displayed by the list widget `w'. The new list of items is taken from the argument `new_list'. After this function is called, the old list can be free()'d. Of course you can not free the new_list until the application is done or you change the list again.

You must remember to make the last entry of the new_list be NULL. This is very important.

SEE ALSO: GetCurrentListItem() , SetCurrentListItem() , MakeScrollList()


void SetCurrentListItem(Widget w, int list_index);

This function causes the item with index, `list_index', to be highlighted in the list widget `w'. You must make sure that list_index is a valid index into the currently displayed list, results are undefined otherwise.

After calling this function, the item with the index `list_index' is highlighted in the list widget.

SEE ALSO: GetCurrentListItem() , ChangeScrollList() , MakeScrollList() libsx-2.05/docs/text/0000755000175000017500000000000011252443541015630 5ustar amckinstryamckinstrylibsx-2.05/docs/text/misc.doc0000644000175000017500000003275711252443541017270 0ustar amckinstryamckinstry The following function allows you to specify how the display should be layed out. It lets you logically position the components you created with the MakeXXX() functions. You will use this function to layout the arrangement of your buttons, labels and drawing area(s). ----------------------------------------------------------- ----------------------------------------------------------- void SetWidgetPos(Widget w, int where1, Widget from1, int where2,Widget from2); This function lets you position a Widget in your window. The idea is that you specify logical placement of the Widget (i.e. place it to the right of this widget, and under that widget). Many layouts are possible, and you can even specify that you don't care where a specific widget is placed. There are three types of placement. You can place a widget to the right of another widget with PLACE_RIGHT. If the argument "where1" is PLACE_RIGHT, then the Widget "w" will be placed to the right of the Widget "from1". If "where1" is equal to PLACE_UNDER, "w" will be placed under the widget "from1". The same holds true for the argument "where2" and Widget "from2". Having two arguments is necessary to be able to unambiguously specify where you want components placed in the display. If you don't care about where a widget is placed, you can use NO_CARE for the `where' argument and a NULL value for the `from' argument. Generally, the first widget created need not be specified, it will always be in the top left corner. Other widgets can the be placed relative to that widget. For example, if you created 4 widgets (w[0] through w[3]) and wanted to arrange them in a column, you would do the following : SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE, NULL); Notice how the third argument changes; we are placing the next widget underneath the previous widget. The zero'th widget (w[0]) doesn't have to be placed because it is always in the top left corner (this can not be changed). If you wanted to arrange things in a row, you would use PLACE_RIGHT instead of PLACE_UNDER. As a more complicated example, supposed you want to create two rows of widgets, and a drawing area. You would do the following : /* first three across the top */ SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); /* next three underneath the top row */ SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[5], PLACE_UNDER, w[0], PLACE_RIGHT, w[4]); SetWidgetPos(w[6], PLACE_UNDER, w[0], PLACE_RIGHT, w[5]); /* put the drawing area under the second row */ SetWidgetPos(w[7], PLACE_UNDER, w[4], NO_CARE, NULL); It is useful to think of the window as a kind of grid in which you can put various pieces. Just draw a picture of what you want and then use SetWidgetPos() to indicate to the system what is next to/underneath of what. Also, all imaginable layouts are not possible with SetWidgetPos(). For example, you cannot specify specific pixel offsets for a widget, or that it be centered in the display, or right justified. This limitaton is for the sake of simplicity. Generally this should not be a problem (if it is, you are probably getting beyond the scope of what libsx was intended to provide, i.e. you're becoming an X hacker :). You can simulate more complicated layouts by cheating and creating label widgets whose label is just spaces and then placing other widget the left or underneath the label. This works but is kind of hackish. SEE ALSO: AttachEdge() ----------------------------------------------------------- void AttachEdge(Widget w, int edge, int attach_to) Attaches an edge of widget to an attach position. Possible values for edge and attach respectively are RIGHT_EDGE, LEFT_EDGE, TOP_EDGE, BOTTOM_EDGE, ATTACH_RIGHT, ATTACH_LEFT, ATTACH_TOP, ATTACH_BOTTOM. The result of the AttachEdge procedure is that the relative positions of the specified "edge" and "attach_to" objects remain fixed once for all, even when the window is resized. SEE ALSO: SetWidgetPos() ----------------------------------------------------------- void SetFgColor(Widget w, int color); This function sets the foreground color of a widget. If the widget is a drawing area, all future primitives are drawn with the specified color. If the widget is some other type of widget, it sets the foreground color of the widget (such as its text) to be the specified color. The argument "color" should be an integer that was returned from the colormap functions (GetNamedColor(), GetRGBColor(), GetPrivateColor() or GetStandardColors()). SEE ALSO : SetColor(), SetBgColor(), SetBorderColor(), GetStandardColors(), GetNamedColor(), GetRGBColor() ----------------------------------------------------------- void SetBgColor(Widget w, int color); This function sets the background color of a widget. If the specified widget is a drawing area, the next call to ClearDisplay() will clear the drawing area to the specified background color. The argument "color" should be an integer that was returned from the colormap functions (GetNamedColor(), GetRGBColor(), GetPrivateColor() or GetStandardColors()). SEE ALSO : SetBgColor(), SetBorderColor(), GetStandardColors(), GetNamedColor(), GetRGBColor() ----------------------------------------------------------- void SetBorderColor(Widget w, int color); This argument will set the border color that is drawn around a widget. The same effect happens for all of the different widgets -- the border is redrawn with the new color. This can be very useful for giving a nice visual offset to an important or dangerous button. Of course you should avoid garish combinations of colors that are hard to look at. SEE ALSO : SetBgColor(), SetBorderColor(), GetStandardColors(), GetNamedColor(), GetRGBColor() ----------------------------------------------------------- int GetFgColor(Widget w); This routine is a convience function that will return the current foreground color of any kind of widget. This is mainly useful for drawing widgets to make sure that you draw things in the proper foreground color. This can arise as a problem if you assume that black is going to be the default foreground color (which it normally is). However, the user can change this default by using the -fg "color" option on the command line. This is an X command line option, and can not be overriden by your program. A real application would use this function to check the value and use it to draw in the user's preferred foreground color. Other programs can just ignore the problem and still work ok as long as the user doesn't change the program's colors. This function returns the integer value of the foreground color that you can use in later calls to SetFgColor() or SetColor(). It returns -1 if you passed an invalid Widget to it. SEE ALSO : GetBgColor(), SetColor(), SetFgColor() ----------------------------------------------------------- int GetBgColor(Widget w); This routine is a convience function that will return the current background color of any kind of widget. This is mainly useful for drawing widgets to make sure that you draw things in the proper background color. This can be a problem if you assume that white is going to be the default background color (which it normally is). However, the user can change this default by using the -bg "color" option on the command line. This is an X command line option, and can not be overriden by your program. A real application would use this function to check the value and use it to draw in the user's preferred background color. Other programs can just ignore the problem and still work ok as long as the user doesn't change the program's colors. The other problem that crops up if you ignore the background color is that if you go to erase something by just drawing in white and white doesn't happen to be the actual background color, your program will look funny. This function returns the integer value of the background color that you can use in later calls to SetBgColor() or SetColor(). It returns -1 if you passed an invalid Widget to it. SEE ALSO : GetFgColor(), SetColor(), SetFgColor() ----------------------------------------------------------- void AddTimeOut(unsigned long interval, void (*func)(), void *data); If you would like to animate a display or do some periodic processing (such as an auto-save feature for an editor), you can use time-outs. A time-out is a callback function that gets called when the specified amount of time has expired (or I should say more precisely, when at _least_ that much time has passed, Unix a'int no real time system). The argument `interval' is an unsigned long and is specified in milliseconds. That is, a time out of 1 second would be an argument of 1000. The function, func, declared as follows: void func(void *data, XtIntervalId *id) { } The second argument should be ignored by function's code, but it should appear in the function prototype. The function is only called once, if you would like the function to be called repeatedly (to update an animation for example), the last thing the function should do is to call AddTimeOut() again. ----------------------------------------------------------- void SetWidgetState(Widget w, int state); This function lets you enable or disable particular widgets in an interface. If, for example, choosing one item from a menu should disable various other widgets, you can call this function. The Widget argument is the widget in question. The state argument is a boolean, which indicates whether the widget should be active or not. A value of TRUE indicates that the widget should accept input, and a value of FALSE indicates that the widget should not accept input (it becomes greyed out). When you disable a widget, the user can no longer interact with that widget in _any_ way (it becomes grey'ed out and just ignores all input). ----------------------------------------------------------- int GetWidgetState(Widget w); This function returns a boolean value indicating whether or not the specified widget is currently active. If the widget is active and accepting input, the return is TRUE, if the widget is inactive, the return value is FALSE. ----------------------------------------------------------- void Beep(void); This function is real complicated. It beeps the workstation speaker. ----------------------------------------------------------- void ReadLocale(char *language); Reads the dialogs file (normally stored in /usr/share/libsx/dialogs.XX where XX is the two-letter code for the language). This function can be used to override the environment variable LANG. ----------------------------------------------------------- void SetWidgetBitmap(Widget w, char *data, int width, int height); This function lets you attach a bitmap to a widget instead of its default text. This function only works correctly on Button, Toggle and Label widgets. Using it on another type of widget yields undefined results. The Widget, w, will display the bitmap data given by the argument, data, whose width and height are given as the last two arguments. The bitmap data is only one bitplane deep, and is usually produced by a somewhat brain-dead X program called `bitmap'. The output of the bitmap program is a file you can directly #include in your source code. The contents of the file are a static array of characters and two #defines that give the width and height of the bitmap. Thus, making a widget with a bitmap is a two step process. First you would edit a bitmap using the `bitmap' program, then you would do the following: #include "file_bmap.h" Widget w; w = MakeButton(NULL, func, some_data_ptr); SetWidgetBitmap(w, file_bmap_bits,file_bmap_width,file_bmap_height); Bits which are a one in the bitmap are drawn in the widget's current foreground color and zero bits are drawn in the current background color. SEE ALSO : SetWidgetPixmap(), SetThumbBitmap() ----------------------------------------------------------- void SetWidgetPixmap(Widget w, char **xpmdata); This function lets you attach a pixmap to a widget instead of its default text. This function only works correctly on Button, Toggle and Label widgets. Using it on another type of widget yields undefined results. The Widget, w, will display the pixmap data given by the argument xpmdata. The pixmap data can be produced by the standard X program called `pixmap'. It can also be obtained with many other drawing tools, using the so called xpm format. An .xpm file is a file you can directly #include in your source code. The contents of the file is a static array of strings of the form static char * mypix_xpm[] = { "48 32 3 1", "o c grey76", ". c blue", "X c LimeGreen", "o.XXX.ooooXXX...o.XXX.ooooXXX...o.XXX.ooooXXX...", ... }; to indicate width=48 height=32 num_colors=3 cpp=1 (1 character used per pixel), 'o' will code for grey76, '.' for blue and 'X' for LimeGreen. The remaining strings are strings representing the rows of pixels, e.g. "o.XXX.ooooXXX...o.XXX.ooooXXX...o.XXX.ooooXXX...", for the first row of 48 pixels. Let us suppose that you want to set a pixmap on a button. You would first create the desired pixmap "mypix.xpm" with the pixmap program, then you would do the following: #include "mypix.xpm" Widget w; w = MakeButton(NULL, func, some_data_ptr); SetWidgetPixmap(w, mypix_xpm); SEE ALSO : SetWidgetBitmap() libsx-2.05/docs/text/font.doc0000644000175000017500000000557311252443541017277 0ustar amckinstryamckinstryFonts are different type styles that can be used in various widgets. You load a font by name and get a handle in return. The handle you get allows you to set the font in the various widgets and font information calls. ------------------------------------------------------------------------ XFont GetFont(char *fontname); This function loads the font named by fontname and returns a handle to the font or NULL if there is an error. The handle returned by this function is an XFontStruct pointer, but should be treated as an opaque data type. After you've loaded a font, you can then set that font in any widget that displays text. You can also use the handle in calls to TextWidget() and FontHeight(). When you are done with a font, you should free it with FreeFont(). SEE ALSO: SetWidgetFont(), FreeFont(), GetWidgetFont(), FontHeight(), TextWidth() ------------------------------------------------------------------------ void SetWidgetFont(Widget w, XFont f); This functions sets the font used by the widget `w', to be the font referred to by the argument `f'. The argument f should have been obtained with GetFont(). SEE ALSO: GetFont(), FreeFont(), FontHeight(), TextWidth() ------------------------------------------------------------------------ XFont GetWidgetFont(Widget w); This function returns a handle to the font currently used by the Widget w. If an error occurs or there is no default font for the widget, a NULL is returned. You should NOT call FreeFont() on any value returned by this function unless you are sure that you allocated the font with GetFont(). SEE ALSO: GetFont(), SetWidgetFont(), FontHeight(), TextWidth() ------------------------------------------------------------------------ void FreeFont(XFont f); This function frees the resources associated with the font, f. You should call this function when your application is done using a particular font. Of course you should make sure that no widget still uses the identified font. SEE ALSO: SetWidgetFont(), GetFont() ------------------------------------------------------------------------ int FontHeight(XFont f); This function returns an integer value that is the height in pixels of the specified font. The height is defined to be the ascent of the characters (from the baseline to the top of a capital letter) plus the descent of the characters (the distance from the baseline to bottom of a descender character like `g' or `p'). SEE ALSO: TextWidth(), GetFont(), SetWidgetFont() ------------------------------------------------------------------------ int TextWidth(XFont f, char *txt); This functions returns the width in pixels used by the string pointed to by txt in the font f. The string should be null-terminated and the entire string is used to determine the width. SEE ALSO: FontHeight(), GetFont(), GetWidgetFont() ------------------------------------------------------------------------ libsx-2.05/docs/text/functions.doc0000644000175000017500000000614611252443541020336 0ustar amckinstryamckinstryLibsx Functions Listing of various Categories of Functions Buttons button.doc Color color.doc Drawing Area draw_area.doc Drawing drawing.doc Fonts font.doc Forms form.doc Labels label.doc Lists list.doc Menus menu.doc Miscellaneous Functions misc.doc Popup Windows popups.doc Scrollbar scrollbar.doc String Entry string_entry.doc Text Editing text_edit.doc Toggles toggle.doc Windows windows.doc Alphabetical Listing of Functions AddTimeOut misc.doc AttachEdge misc.doc Beep misc.doc ChangeScrollList list.doc ClearDisplay drawing.doc CloseProcedure windows.doc CloseWindow windows.doc DrawPixel drawing.doc DrawLine drawing.doc DrawPolyline drawing.doc DrawFilledPolygon drawing.doc DrawBox drawing.doc DrawFilledBox drawing.doc DrawText drawing.doc DrawArc drawing.doc DrawFilledArc drawing.doc DrawImage drawing.doc FontHeight font.doc FreeAllColors color.doc FreeFont font.doc FreePrivateColor color.doc GetAllColors color.doc GetBgColor misc.doc GetCurrentListItem list.doc GetDrawAreaSize drawing.doc GetFgColor misc.doc GetFile popups.doc GetFont font.doc GetImage drawing.doc GetLongString popups.doc GetMenuItemChecked menu.doc GetNamedColor color.doc GetOkay popups.doc GetPixel drawing.doc GetRGBColor color.doc GetPrivateColor color.doc GetStandardColors color.doc GetString popups.doc GetStringEntry string_entry.doc GetText popups.doc GetTextWidgetText text_edit.doc GetToggleState toggle.doc GetTopWidget windows.doc GetTriState popups.doc GetWidgetFont font.doc GetWidgetState misc.doc GetYesNo popups.doc MainLoop windows.doc MakeButton button.doc MakeDrawArea draw_area.doc MakeForm form.doc MakeHorizScrollbar scrollbar.doc MakeLabel label.doc MakeMenu menu.doc MakeMenuItem menu.doc MakeScrollList list.doc MakeStringEntry string_entry.doc MakeTextWidget text_edit.doc MakeToggle toggle.doc MakeVertScrollbar scrollbar.doc MakeWindow windows.doc OpenDisplay windows.doc ReadLocale misc.doc ScrollDrawArea drawing.doc SelectColor color.doc SetBgColor misc.doc SetBorderColor misc.doc SetButtonDownCB draw_area.doc SetButtonUpCB draw_area.doc SetColor drawing.doc SetColorMap color.doc SetCurrentListItem list.doc SetCurrentWindow windows.doc SetDrawArea drawing.doc SetDrawMode drawing.doc SetEnterCB draw_area.doc SetFgColor misc.doc SetForm form.doc SetFreqFilter popups.doc SetKeypressCB draw_area.doc SetLabel label.doc SetLeaveCB draw_area.doc SetLineWidth drawing.doc SetMenuItemChecked menu.doc SetMouseMotionCB draw_area.doc SetMyColorMap color.doc SetPrivateColor color.doc SetScrollbar scrollbar.doc SetScrollbarDirection scrollbar.doc SetScrollbarStep scrollbar.doc SetStringEntry string_entry.doc SetTextWidgetText text_edit.doc SetThumbBitmap scrollbar.doc SetToggleState toggle.doc SetWidgetFont font.doc SetWidgetBitmap misc.doc SetWidgetPixmap misc.doc SetWidgetPos misc.doc SetWidgetState misc.doc ShowDisplay windows.doc SyncDisplay windows.doc TextWidth font.doc libsx-2.05/docs/text/form.doc0000644000175000017500000001422711252443541017270 0ustar amckinstryamckinstry----------------------------------------------------------- Widget MakeForm(Widget parent, int where1, Widget from1 int where2, Widget from2) This function lets you create a new "form" widget in which to put child widgets. A form widget is a container that holds other widgets. Normally there is no need to call this function, but if you want to have separate "groups" of widgets in your display and you can't lay them out that way with SetWidgetPos(), then using multiple form widgets may be the right thing. In addition, a nifty little box gets drawn around the form widget (and all the children) and this can be a nice visual cue in your interface indicating what groups of widgets belong together. A form widget creates a box that surrounds all the widgets contained inside of it (but the form widget itself is inactive and can't be clicked on by the user). If you use multiple form widgets in your display, the basic logic of how you create the display is a little different. You can think of form widgets as miniature windows inside a larger window. Once you create a form widget, any other widgets you create with calls like MakeButton() and MakeLabel() become children of this form widget. Before you create another form widget, you must lay out all the children of the current form widget with calls to SetWidgetPos(). After you lay out all the children of the current widget, then you can create another form widget, and repeat the process (or call SetForm()). Form widgets are layed out in a manner similar to regular widgets, except that usually their placement is relative to other form widgets. When you create a new form widget (after the first one), you specify where it should be placed relative to other form widgets that you created. The first form widget is always placed in the top left corner of the window. The `parent' argument to MakeForm() specifies at what level the new form should be created. If you specify TOP_LEVEL_FORM (which is the usual thing to do) the new form is created at the top level of the window. If you pass another form widget for `parent', then this new form widget will be a child of the other form widget. This lets you create hierarchical "boxes" in your display. The arguments where1, from1, where2, from2 are the same as in SetWidgetPos(). That is, you specify either NO_CARE, PLACE_UNDER, or PLACE_RIGHT for where1 and where2 and the from1/from2 arguments are the widgets you would like to place something to the right of or under (or they are NULL if you specified NO_CARE). See SetWidgetPos() for more documentation. Now for an example: Let's say we want a display something like this: +------------+ +-----------------------+ | +--------+ | | +-------------------+ | | | Btn1 | | | | | | | +--------+ | | | | | | | | | | | | +--------+ | | | | | | | Btn2 | | | | | | | +--------+ | | | | | +------------+ | | | | | | | | | | | | | +-------------------+ | +-----------------------+ We have two rectangles (forms) which contain other widgets. Inside the leftmost form are two buttons. The form on the right has a single drawing area. Skipping some of the unnecessary details, we could accomplish the above display with the following code: form1 = MakeForm(TOP_LEVEL_FORM, NO_CARE, NULL, NO_CARE, NULL); w[0] = MakeButton("Btn1", NULL, NULL); w[1] = MakeButton("Btn2", NULL, NULL); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); form2 = MakeForm(TOP_LEVEL_FORM, PLACE_RIGHT, form1, NO_CARE, NULL); w[2] = MakeDrawArea(200, 200, NULL, NULL); As you can see, we create the first form and specify that we don't care where it goes (the first form widget is always placed in the top left corner of the window). Then we create some widgets to place inside of our new form. Next, and this is important, we layout all the widgets inside of the first form. In this case we only need to make one call to SetWidgetPos(). Then we create the next form, and specify that we want to place it to the right of form1. Finally we create a drawing area widget, which is placed inside of form2. If you want to create hiearchies of form widgets, you would specify the form widget that should be the parent for the first argument to MakeForm(). This can get quite complicted, so you should make sure you know what you're doing if you want to create big hierarchies. NOTE: It is important that you layout all your widgets before you create a new form (unless you're creating a child form). SEE ALSO: SetForm(), MakeWindow() ----------------------------------------------------------- void SetForm(Widget w) The SetForm() function allows you to change what is considered the current form. Normally you only use this function to set the current form to be TOP_LEVEL_FORM. You can cause your program to crash if you are not careful about what you set as the current form. The main purpose of this function is to let you create displays that have both form widgets and other "normal" widgets at the same level. Mainly you would want to do this if you wanted a large drawing area (or some other type of widget) but didn't want to bother creating an form widget just to hold that one widget. After calling this function, you can position any new widgets relative to other widgets (usually form widgets) created at the top level of the window. The normal calling sequence is: SetForm(TOP_LEVEL_FORM), although you can specify any other form widget you like. Be careful, as it is possible to confuse the X layout routines and cause your program to crash. NOTE: Before you call SetForm() and start creating new widgets and positioning them, any previous form widgets should be completely layed out (i.e. you called SetWidgetPos() for all child widgets of any previously created form widgets). SEE ALSO: MakeForm() ----------------------------------------------------------- libsx-2.05/docs/text/general.libsx.doc0000644000175000017500000001316611252443541021063 0ustar amckinstryamckinstry -- How to Use libsx -- Using libsx is pretty simple. At the minimum, you #include "libsx.h" and link with libsx.a. To actually have X windows pop open and such, you need to do the following: 1) To get everything started, you should call OpenDisplay(). If OpenDisplay() returns a non-zero value, it's ok to go on. OpenDisplay() creates what will eventually be your first window. 2) After calling OpenDisplay(), you can go on to create all sorts of widgets with the MakeXXX() calls. You can lay them out with calls to SetWidgetPos(). 3) When you are done creating the user interface, call ShowDisplay(). This causes the window and components you've created to be displayed on the workstation screen. Until you call ShowDisplay(), the user can _NOT_ see your window, and drawing into drawing areas has _NO_ effect. 3.5) If you need to, you can call any of the color allocation functions such as GetStandardColors(), etc. 4) Finally, once the window is displayed and you've done all the initializations you wish, you must then call MainLoop(). After you call MainLoop(), events get processed as they come in and your callback functions are called as necessary. After calling MainLoop(), the correct way for your program to exit is to have one of your callback routines call exit() when appropriate (like after the user clicks on a "Quit" button). 5) There is a predefined procedure CloseProcedure(Widget w) which is called each time the user presses the "Delete Window" slot of the window bar. Its default action is to close the active window, and to exit the application if that window is the original main window. You can redefine it to do whatever you like before closing (or to prevent the window being closed). That's all you need to do. Even though that may look like a lot to do, it's really pretty simple in practice. For example, here is a hello world program with libsx: ------------------------------------------------------------------ #include "libsx.h" main() { MakeLabel("Hello World!"); MainLoop(); } ------------------------------------------------------------------ Granted it's one more line than a standard printf() type of hello world program, but it's not all that bad. Hello world programs are nice, but you don't tend to write very many of them. Real applications need to be able to do much more. Even these "real" programs aren't all that bad in libsx. Here is a simple program that opens a window with a quit button and a drawing area that you could use to draw whatever graphics you wanted: ------------------------------------------------------------------ #include #include "libsx.h" void quit(Widget w, void *data) { exit(0); } void draw_stuff(Widget w, int width, int height, void *data) { ClearDrawArea(); DrawLine(0,0, width, height); /* just draw a diagonal line */ } int main(int argc, char **argv) { Widget w[2]; argc = OpenDisplay(argc, argv); if (argc == 0) /* woops, couldn't get started */ exit(5); w[0] = MakeButton("Quit", quit, NULL); w[1] = MakeDrawArea(300,300, draw_stuff, NULL); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); ShowDisplay(); GetStandardColors(); MainLoop(); /* off we go! */ } ------------------------------------------------------------------ Here is how one would redefine the CloseProcedure to make it do some further stuff before closing. ------------------------------------------------------------------ void CloseProcedure(Widget w) { if(w == GetTopWidget(a_widget_in_the_main_window)) { printf("Main window closed by user\n"); exit(0); } else { printf("Auxilliary window closed by user\n"); SetCurrentWindow(w); CloseWindow(); /* This actually closes the window */ } /* Don't include exit(0) or CloseWindow() if you want to prevent the window from closing */ } ------------------------------------------------------------------ The code above is the basic skeleton for a libsx program, even complicated ones. First you open the display with OpenDisplay(). Then you build your interface by creating a bunch of widgets with the MakeXXX() calls. Next you layout the display by specifying the relative positions of the widgets to each other. Then you would get any fonts or colors you may need, and finally you just enter the main loop. In libsx, your callback functions are where all the real work happens. The program above has two callback functions, quit() and draw_stuff(). They are tied to events that happen in the interface. When the user clicks on the "Quit" button, your quit() function is called. When the drawing area gets resized or needs to be redrawn, your draw_stuff() function gets called. Usually the process of creating the interface would get separated into a separate function that is easy to modify (instead of cluttering up main). However, the basic outline is the same as above. The only real difference with more complicated interfaces is that they usually have a lot more calls to the MakeXXX() functions and they tend to make use of the extra void pointer argument in the callback routines. If you'd like more examples, take a look at the provided source code. There are several reasonable examples of varying complexity that you can take and modify as you like. Each of the demos tries to demonstrate a certain group of features, so take a look at each to find the one that most closely matches what you want to do and start hacking from there! Have fun. Dominic Giampaolo dbg@sgi.com libsx-2.05/docs/text/color.doc0000644000175000017500000003441511252443541017444 0ustar amckinstryamckinstryThis file describes the routines for managing colors in your window. For example if you want to change what the foreground color is, or need to get specific colors. To get specific colors you use the functions discussed in here. It is important to remember that you can not call any of these functions until you have called ShowDisplay(). Colors are represented by integers. When you get a color, you are returned an integer that you can use in calls to SetFgColor(), SetBgColor(), and SetColor(). You should attach no meaning to the numbers, and just because green is 17 does not mean that 18 is a lighter or darker shade of green. There are three ways to manipulate colors with libsx. The first way handles most of the common cases, and is done with GetNamedColor() or GetRGBColor(). The next method, GetPrivateColor(), allows your application to modify the actual display color represented by a color number (something you cannot do with the the previous methods). The final method gives you complete control in specifying the entire colormap. That is, you can determine exactly what integers map to what colors so you can obtain smooth gradients (so for example black is color 0, and white is 255). These routines work best on 8 bit displays but will work on 24 bit displays. NOTE: You can NOT call any color function until you have called ShowDisplay(). ----------------------------------------------------------- The way colors work for drawing is like this. There are usually 256 available colors on a workstation. This is called an 8-bit display because 2 to the 8'th power == 256. These colors are stored in a table (array) of 256 entries. If you allocate a color, and it is in entry 37, then to draw with the color that is stored there, you must use 37 as an argument to the SetColor() function. When you ask for a color, it may be taken from anywhere in the array of 256 entries, and there is _NO_ guarantee that if you allocate a green color that the next color in the table will be a lighter or darker green. Even if you allocate many colors using GetNamedColor() or GetRGBColor(), you have _NO_ assurances about where those colors are in the array (chances are they won't be contiguous). If you need to have a contiguous set of numbers, you must use GetAllColors() and then SetColorMap() or SetMyColorMap() to set up a custom colormap with a known set of values. When you get a private color, your application can specify what values that color index should have. This is useful when you want to interactively modify a color. It is important to remember that `getting a color' really means getting an index into the color table where the actual color is stored. If you actually want to pop up a window allowing selection of color by users, invoke the SelectColor function. It doesn't permanently allocate a color, so you show just do it with the other routines. ----------------------------------------------------------- ----------------------------------------------------------- void GetStandardColors(void); This function gets 6 standard colors, RED, GREEN, BLUE, YELLOW, BLACK, and WHITE. These 6 variables contain values which can be used in calls to SetColor(), SetFgColor(), SetBgColor(), etc. Do not use the values in RED, GREEN, BLUE, YELLOW, BLACK or WHITE before calling GetStandardColors(). The results are undefined if you do this. In addition to the above 6 standard colors, the library makes use of 3 further colors HILIGHT, BUTTONBG, INPUTBG, as follows: HILIGHT is the color of hilighted text to be used in active input string entries, and INPUTBG the corresponding background color. BUTTONBG is the default color of buttons for internally defined widgets; By default, HILIGHT coincides with the foreground color, while INPUTBG and BUTTONBG coincide with the background color (fg/bg default themselves to black/white). They can be adjusted to any other color value, once such a color has been defined through the Get*Color routines. NOTE: You can only call GetStandardColors() after calling the ShowDisplay() function. SEE ALSO : GetNamedColor(), GetRGBColor(), GetAllColors() SetColor(), SetFgColor(), SetBgColor() ----------------------------------------------------------- int GetNamedColor(char *name); This function allocates an entry in the color table for the color given by the ascii string "name". You can view the list of available color names with the showrgb command in a shell (some nice ones are "peachpuff", "burlywood3", "aquamarine", and "paleturquoise3"). Color names can have spaces in them. The return value of the function is an integer that you can use in calls to SetColor() (or any of the other SetXXColor() calls). If an error occurred trying to allocate the color (very possible if you allocate a lot of colors), a -1 is returned. NOTE: the return value of zero is valid, a -1 indicates an error _NOT_ zero. NOTE: You can only call GetNamedColor() after calling the ShowDisplay() function. SEE ALSO : GetStandardColor(), GetRGBColor(), GetAllColors() SetColor(), SetFgColor(), SetBgColor() ----------------------------------------------------------- int GetRGBColor(int r, int g, int b); This function tries to allocate the color given by the red, green, blue triple r,g,b. The arguments r,g, and b should be between 0 and 255. Overflow is not checked for. The return value is an integer value usable in the SetColor() calls or a -1 if an error occurred. NOTE: the return value of zero is valid, a -1 indicates an error _NOT_ zero. NOTE: You can only call GetRGBColor() after calling the ShowDisplay() function. SEE ALSO : GetStandardColor(), GetNamedColor(), GetAllColors() SetColor(), SetFgColor(), SetBgColor() ----------------------------------------------------------- int GetPrivateColor(void); This function allocates a private color cell for use by the application. A private color cell is one which you can change what color it represents. For example, if you would like to let the user interactively manipulate some color, you would need to allocate a private color cell. The integer returned by this function is a reference to a color cell whose values you can set with SetPrivateColor(). The intial contents of the private color cell are undefined and you should probably call SetPrivateColor() immediately to set it to some known value. If an error occurs, a -1 is returned. When you are done with a private color cell, you should free it with FreePrivateColor(). SEE ALSO: SetPrivateColor(), FreePrivateColor(), GetRGBColor() ----------------------------------------------------------- void SetPrivateColor(int which, int r, int g, int b); This function sets the color cell referred to by `which' to have the r,g,b values specified. The r,g,b values are given in the range 0-255 (inclusive). Once this function is called, any thing drawn in the display with the color `which' will now have the new color determined by the r,g,b arguments. SEE ALSO: GetPrivateColor(), FreePrivateColor(), SetFgColor(), SetBgColor(), ----------------------------------------------------------- void FreePrivateColor(int which); This function returns the color associated with the private color cell `which' to the system. You should have allocated the color referred to by `which' with GetPrivateColor(). SEE ALSO GetPrivatecolor(), SetPrivatecolor(). ----------------------------------------------------------- int GetAllColors(void); This function is rather drastic and should be used with caution. It immediately grabs an entire 256 entry colormap for private use. This has the unfortunate effect of (temporarily) wiping out the colors in all the other windows on the display. However this is necessary if you wish to get a smooth colormap to use in displaying a smooth-shaded or continuous tone picture. Once GetAllColors() is called, the entire colormap is free for manipulation by your program. The colormap remains allocated until you call FreeAllColors(), at which time everything goes back to normal. If an error occurred (quite possible), this routine returns FALSE. If everything went ok and the colormap was successfully allocated, TRUE is returned. If you can avoid using this function, try to. It is disconcerting for the user to have the colormap get wacked out and have most of their windows disappear (they don't really disappear of course, you just can see them usually). However it is sometimes necessary to do this as there is no other way to get a smoothly continuous color map. Usually, you will want to call SetColorMap() or SetMyColorMap() right after this function. NOTE: On a 24 bit machine (like the SGI Indigo Elan I tested this with), only current drawing area gets the colormap, other widgets and windows are not affected. NOTE: You can only call GetAllColors() after calling the ShowDisplay() function. SEE ALSO : SetColorMap(), SetMyColorMap(), FreeAllColors(), GetStandardColors(), GetNamedColor(), GetRGBColor() ----------------------------------------------------------- void FreeAllColors(void); This function frees a private colormap that was allocated with GetAllColors(). It has the beneficial effect of immediately restoring the rest of the colors on the screen and in other windows to those that existed prior to the call to GetAllColors(). This function is useful if wish to let the user restore their original colors temporarily (although this will happen automatically when the mouse moves outside the window). ----------------------------------------------------------- void SetColorMap(int num); This function creates several predefined color maps that are very smoothly continuous. It saves you the hassle of writing them yourself (even though they are mostly easy). The "num" argument you pass in should be one of the following #define's : #define GREY_SCALE_1 0 #define GREY_SCALE_2 1 #define RAINBOW_1 2 #define RAINBOW_2 3 The colormap GREY_SCALE_2 is a complete smooth color ramp from pure black (color 0) to pure white (color 255). The other grey scale, GREY_SCALE_1 is a nearly pure ramp from black (color 0) to white (color 252), but also has a few additional colors thrown in near the end of the colormap. The two RAINBOW_? colormaps have different types of smooth changing rainbows of color. This are really only useful for drawing pretty patterns or doing false coloring. NOTE: You should call GetAllColors() before you call this routine. It is not necessary, but if you don't, and GetAllColors() fails, you will never know about it, and your application may not work very well. SEE ALSO : SetMyColorMap(), GetAllColors(), GetNamedColor(), GetStandardColors(), GetRGBColor() ----------------------------------------------------------- void SetMyColorMap(int n, unsigned char *r, unsigned char *g,unsigned char *b); Occasionally it is necessary to have absolute control over your colormap, and this function lets you do that. This function lets you completely specify each and every color that will be in the colormap. The three arrays r,g, and b are simply the red, green, and blue components of each color. The values in the array range from 0 to 255, hence they are unsigned char's. You need not specify a full array of 256 colors, you can in fact only specify a few. The integer argument "n" indicates how many entries there are in the r,g, and b arrays. The argument "n" should be greater than 0 and less than 255. NOTE: You should call GetAllColors() before you call this routine. It is not necessary, but if you don't and GetAllColors() fails, you will never know about it, and your application may not work very well. SEE ALSO : SetMyColorMap(), GetAllColors(), GetNamedColor(), GetStandardColors(), GetRGBColor() ----------------------------------------------------------- char *SelectColor (char *inicolor, int output, char *txt, CSelCB func, void *data); This is a sophisticated popup which lets the user browse and select a color. The "mode" button cycles through 3 possible modes: RGB mode (red-green-blue), HSV mode (hue-saturation-value), CMYK mode (cyan-magenta-yellow-black). For each mode, the routine provides scrolls which the user can use to set the parameters. Meanwhile, a rectangular draw area shows the resulting color. The user can also browse in the RGB data file (litteral definitions of colors in /usr/lib/X11/rgb.txt). Finally, the "Grab color" button sets the color to be the color of any chosen pixel on the screen, and the "Best match" button selects the predefined standard color which best approximates the selected color. The parameters have the following significance: char *inicolor is the color to be set when the popup opens. It can be in a variety of different formats, e.g. "#87CEEB" "135,206,235" "skyblue" "SkyBlue" which are viewed as equivalent denominations of the skyblue color, whose pixel values are red=135=0x87 green=206=0xce blue=235=0xeb The output parameter sets which of the three forms should be used as a return value for the char *SelectColor() procedure: if output=0, the returned string is in hexadecimal form "#87CEEB", if output=1, the returned string is either hexadecimal or litteral, and is litteral if there is an exact match if output=2, the returned string is the litteral best match The next three parameters (txt, func, data) can be used to let interactively the selection operate on a call-back function func. The function is activated when the user clicks on an extra button at the lower right corner, marked with the label char *txt. The parameter void *data can be passed to the function. The function func itself should be of the type void func(Widget w, CSelData *cdata) where cdata is a pointer to a complex structure data set, the main components of which are cdata->r cdata->g cdata->b RGB (float values) cdata->h cdata->s cdata->v HSV values cdata->c cdata->m cdata->y cdata->k CMYK values cdata->rgb_list[1000][60] List of litteral color names cdata->match_list[1000][60] List of ordered best matches char *rgb_ptr[1000]; Null terminated pointers to rgb_list char *match_ptr[1000]; Null terminated pointers to match_list Finally, the initial data pointer used when invoking SelectColor can be retrieved as cdata->data. libsx-2.05/docs/text/menu.doc0000644000175000017500000000634411252443541017272 0ustar amckinstryamckinstryMenus provide standard drop-down style menus that let the user select from a variety of choices. The Athena widgets do not support cascaded menus, so a menu is only a single list of items. A menu contains menu items that are tied to callback functions in the application. Menu items must be text and can not be bitmaps. ---------------------------------------------------------------------- Widget MakeMenu(char *name); This function creates a menu button that contains the text pointed to by the character string name. When the button is clicked, a menu pops up. The menu contains items created with MakeMenuItem(). You need to save the return value of this function to be able to pass it to MakeMenuItem() so that menu items can attached to a menu. If this function fails, it returns NULL. SEE ALSO: MakeMenuItem(), MakeButton(), SetWidgetPos() ---------------------------------------------------------------------- Widget MakeMenuItem(Widget menu, char *name, ButtonCB func, void *arg); This function adds a menu item to a menu. The menu item contains the text pointed to by the string name. Whenever the user selects this menu item, the callback function, func, is called. The final argument is an arbitrary void pointer that is passed to the callback function. The first argument must be a widget returned by MakeMenu() (results are undefined if it is not). If MakeMenuItem() fails for any reason, a NULL is returned. The callback function for the menu item should be declared as follows: void func(Widget w, void *data) { } Whenever the user selects this menu item, the callback will be called. Setting of widget attributes with SetFgColor(), SetBgColor(), etc work normally except that only one background color may be specified and it takes effect for the entire menu. You can set different fonts for each menu item. NOTE: You do not need to call SetWidgetPos() for menu items. Successive menu items are placed below previous menu items. SEE ALSO: SetMenuItemChecked(), GetMenuItemChecked(), MakeMenu(). ---------------------------------------------------------------------- void SetMenuItemChecked(Widget w, int state); This function sets the ``checked'' state of a menu item. If a menu item is in the checked state, a bitmap of a check mark appears to the left of the menu item text. The first argument, w, is a menu item widget created with MakeMenuItem(). The second argument, state, is a boolean value of either TRUE (1) or FALSE (0) indicating whether or not the check mark should be drawn to the left of the menu item. If the state argument is TRUE, the check mark is drawn. If the state argument is FALSE, the check mark is removed. SEE ALSO: GetMenuItemChecked(), MakeMenuItem() ---------------------------------------------------------------------- int GetMenuItemChecked(Widget w); This function returns a boolean result indicating whether the menu item referred to by the Widget w, is checked or not. If the menu item referred to by `w' is checked, a value of TRUE (1) is returned. If the menu item does not currently have a check mark next to it, a value of FALSE (0) is returned. SEE ALSO: SetMenuItemChecked(), MakeMenuItem() ---------------------------------------------------------------------- libsx-2.05/docs/text/scrollbar.doc0000644000175000017500000002036311252443541020306 0ustar amckinstryamckinstryA scrollbar is a widget that allows a user to control some numeric quantity interactively by using the mouse to scroll a slider, similar to the volume slider on some radios. The slider is called the "thumb" or "thumb area" in X terminology. ---------------------------------------------------------------------- Widget MakeHorizScrollbar(int length, ScrollCB scroll_func, void *data); Widget MakeVertScrollbar(int height, ScrollCB scroll_func, void *data); These two routines create scrollbars. Scrollbars allow the user to interactively control some numeric quantity with the mouse. When the user presses the left mouse button, the value represented by the scrollbar increases. When the press the middle mouse button, they can interactively adjust the value. Clicking the right mouse button decreases the value represented by the scrollbar. The arguments to create a scrollbar are its length or height in pixels, a callback function to call when the scrollbar changes value and an extra void pointer argument that is passed to the callback function. If these routines fail, they return NULL. To set what values a scrollbar represents, you must use SetScrollbar(). These two routines only make a scrollbar and do not set it to return useful values. You always have to call SetScrollbar() to set what a scrollbar represents (see the documentation for SetScrollbar() for more information). Your callback routine is called everytime the scrollbar changes. Since the calculations are done in floating point, the value may not have changed enough to be interesting, but your routine is still called. You should take care to see that the value changed enough to be interesting to your applications (i.e. it is wasteful for a text editor to repaint the window when the new value is 0.003 different than the old value). A scrollbar callback routine should be declared as follows: void scroll_func(Widget w, float new_val, void *data) { } The first argument, w, is the scrollbar widget that the user is manipulating. The second argument is a floating point value that represents the new value of the scrollbar. The third argument is the void pointer argument that was passed to Make{Horiz,Vert}Scrollbar(). SEE ALSO : SetScrollbar(), SetWidgetPos(), SetFgColor(), SetBgColor(), SetBorderColor() ----------------------------------------------------------- void SetScrollbar(Widget w, float where, float max, float size_shown); This function lets you set the values that a scrollbar represents. The first argument is a scrollbar widget. The next three arguments are floating point numbers that specify the parameters of the scrollbar. Before discussing the details of the three float arguments, let us get some terms straight. When we refer to the `container' of a scrollbar, we mean the entire box that makes up the scrollbar. The `thumb' of a scrollbar is the gray area that the user can grab to manipulate. We refer to the size or length of the thumb area (the amount of grey) as the `size shown'. The total amount represented by the scrollbar is called `max'. The arguments mean the following: where -- this floating point number specifies where in the container the top of the thumb area should start. If you have a maximum value of 100 and where is 50, the beginning of the thumb will be in the middle of the container. max -- The maximum value that the scroll bar can have. You will receive numbers in the range 0 to max (inclusive). Obviously max should be a positive, and is a float. size_shown -- This float value controls how big the grey area that the user can grab is. This represents how much of whatever it is you are representing is visible. For example, a text editor which shows 24 lines of text would set size_shown to be 24 (out of whatever max is). If you want the scrollbar to represent a percentage of something, where when it is 100%, the grey area is also 100% of the box, then you should set the size_shown to be equal to max. If this is confusing, there are examples below. Now, some examples to clarify things (in the following, assume that the argument, w, represents a scrollbar widget created with the MakeHorizScrollbar or MakeVertScrollbar() routines). For the first example, let's assume you want a scrollbar to let you set a color value which can range between 0 and 255 with the initial value at 67. You sould set the scrollbar as follows: SetScrollbar(w, 67.0, 255.0, 1.0); The first value, 67.0, is where we would like the beginning of the thumb area to appear. The next value, 255, is the maximum value the scrollbar can attain. The third value, 1, is the size of the thumb area (the amount represented by the thumb relative to the maximum size). This scrollbar will now return values in the range of 0 to 255 (inclusive). The thumb area will be small, and represents one value of the 255 possible divisions. The position of the thumb area in the container represents its value. For the next example, suppose we wish to make a scrollbar represent some percentage of a value. That is, the size of the thumb area should be proportional to the value of the scrollbar relative to its maximum (so when the value is at it maximum, the thumb area is 100% of the scrollbar). In this case we would like the size of the thumb area to represent the amount of the variable (note the difference from the above example). Let us suppose we want a scrollbar which can represent a percentage 0 to 100, with the initial value being 50. SetScrollbar(w, 50.0, 100.0, 100.0); The first value, 50, is where the thumb area begins (in the middle of the container). The next number is 100, and represents the maximum value of the scrollbar. The next number, again 100, is the size shown. Making this value the same as the max value (in this case 100) causes the thumb area to vary according to the value the scrollbar represents. As a final example, let us take a text editor which is displaying a file. In this case, let us assume the text file is 259 lines long, the window can display 47 lines, and the top line currently displayed is 72. To create the correct scrollbar, we would do the following: SetScrollbar(w, 72.0, 259.0, 47.0); This creates a scrollbar which has a thumb area whose size is 47/259 of the entire container, and is positioned 72/259'ths of the way down the container. SEE ALSO: MakeHorizScrollbar(), MakeVertScrollbar(), SetWidgetPos() ----------------------------------------------------------- void SetThumbBitmap(Widget w, char *black_bits, int width, int height); Sets a bitmap for the thumb area in the scrollbar. This function is similar to SetWidgetBitmap(), which one can refer to for details. The default bitmap is a black & white combination of pixels. To get instead an entirely black thumb area, one can use static unsigned char black_bits[] = { 0xff }; SetThumbBitmap(scroll_widget, black_bits, 8, 1); The default is equivalent to static unsigned char black_bits[] = { 0xaa, 0x55 }; SetThumbBitmap(scroll_widget, black_bits, 8, 2); SEE ALSO: SetWidgetBitmap() ----------------------------------------------------------- void SetScrollbarStep(Widget w, float fact) Sets the fraction of the scrollbar that gets increased or decreased when the left or right mouse buttons is pressed. The scrollbar thus moves faster as fact increases. The default value is fact = 0.1 . See also the explanations concerning the scrollbar callback functions. SEE ALSO: MakeHorizScrollbar(), MakeVertScrollbar() ----------------------------------------------------------- void SetScrollbarDirection(float dir) The effect of this function is to possibly affect the scrollbar step by a signed factor dir (normally equal to +1 or -1). If dir = -1, the direction of the scrollbar moves are reversed with respect to mouse clicks. This function is useful to deal with the tricky behaviour of the standard libraries Xaw, Xaw3d, Xaw95 (Libsx can be linked with any of these). Actually Xaw3d, Xaw95 behave differently of Xaw with respect to the action of mouse clicks on scrollbars, and the SetScrollbarDirection() function can then be used to adjust that behaviour according to the needs. SEE ALSO: SetScrollbarStep() libsx-2.05/docs/text/string_entry.doc0000644000175000017500000000665511252443541021062 0ustar amckinstryamckinstryA string entry widget is a widget that lets a user enter a single line of ASCII text. When the user presses return in the widget, a callback is made to your application with a pointer to the new text. Support routines also exist to Set and Get the text in the widget. If you want multiple lines of text, see the text edit widget documentation. ----------------------------------------------------------------------- Widget MakeStringEntry(char *txt, int size, StringCB func, void *data); This function makes a string input widget. A string input widget is a widget that lets a user enter/edit a single line string value such as a filename. The first argument is any default text you would like in the string entry widget. You can specify NULL or "" if you don't want anything to appear. The next argument is the width in pixels of the string entry area. Be careful in specifying the width since the default font used by the widget may not be wide enough to contain the text you want. It is best if you call GetWidgetFont() and then call TextWidth() on a string of reasonable length and use the value returned by TextWidth() to be the width of the widget. If you're lazy, a value of 150-200 is usually pretty good. The next argument is a callback function that is called whenever the user presses return in the string entry widget. The callback function should be declared as follows: void func(Widget w, char *string, void *data) { } The first argument to the callback is the widget where the user pressed return. For the most part you can ignore this (unless you want to change the text). The second argument is a pointer to the string of text the user entered. The final argument is the user data pointer you passed in to MakeStringEntry(). The string of text passed to your callback function should be copied elsewhere (using strdup() if necessary) because it is internal to the widget. The string passed to your callback function should _never_ be modified directly. SEE ALSO : SetStringEntry(), GetStringEntry(), SetWidgetPos(), GetWidgetFont(), TextWidth(), SetWidgetFont(), SetFgColor(), SetBgColor(), SetBorderColor() ---------------------------------------------------------------------- void SetStringEntry(Widget w, char *new_text); This function allows you to change the string of text displayed in a string entry widget. The first argument is the widget in which you would like to change the string (this widget should be a string entry widget). The second argument is a pointer to the new text you would like displayed in the string entry area. After calling this function, the new text is displayed in the string entry area and any old strings are gone. SEE ALSO : GetStringEntry(), MakeStringEntry(), ----------------------------------------------------------- char *GetStringEntry(Widget w) This function lets you retrieve the text a user entered in a string widget. The widget argument, w, should be a string entry widget. The return value of this function is a char pointer to a null-terminated string that is the contents of the string entry widget. If there is a problem, the function returns NULL. NOTE: You should not free the string returned to you by this function. If you need to modify the string or otherwise use, you should make a copy with strdup() or some other method. SEE ALSO : SetStringEntry(), MakeStringEntry(), ----------------------------------------------------------- libsx-2.05/docs/text/list.doc0000644000175000017500000000603711252443541017300 0ustar amckinstryamckinstry A scroll list is a scrollable list of items organized in a veritical fashion. The user can scroll through the list of items using the mouse and select individual items in the list of available choices. --------------------------------------------------------------- Widget MakeScrollList(char **item_list, int width, int height, ListCB func, void *data); This function makes a scrollable list of items from which a user can select individual items. The list contains strings of text, pointed to by the table, item_list. The list, item_list, MUST contain a NULL entry as its last element (this is not optional). The area given to display the list is width and height pixels large. If the entire list will not fit, scrollbars appear that will let the user easily scroll through the list. The callback function, func, should expect to be called with a Widget argument, the string of text the user clicked on, the string's index in your table, and whatever user data pointer you gave at widget creation time. The callback should be declared as follows: void func(Widget w, char *str, int index, void *data) { } The list of strings passed in to MakeScrollList() must not be free()'d or otherwise deallocated for the entire lifetime of the widget (or until the list of strings is changed with ChangeScrollList()). SEE ALSO: GetCurrentListItem(), ChangeScrollList(), SetCurrentListItem(), SetFgColor(), SetBgColor(), SetWidgetFont() ----------------------------------------------------------- int GetCurrentListItem(Widget w); This function returns the index of the currently selected item in the list widget `w'. The index value returned is an index into the table displayed by the list (specified when the widget was created or with ChangeScrollList()). If no item is selected in the list widget, this routine will return a -1. SEE ALSO: ChangeScrollList(), SetCurrentListItem(), MakeScrollList() ----------------------------------------------------------- void ChangeScrollList(Widget w, char **new_list); This function changes the list of strings displayed by the list widget `w'. The new list of items is taken from the argument `new_list'. After this function is called, the old list can be free()'d. Of course you can not free the new_list until the application is done or you change the list again. You must remember to make the last entry of the new_list be NULL. This is very important. SEE ALSO: GetCurrentListItem(), SetCurrentListItem(), MakeScrollList() ----------------------------------------------------------- void SetCurrentListItem(Widget w, int list_index); This function causes the item with index, `list_index', to be highlighted in the list widget `w'. You must make sure that list_index is a valid index into the currently displayed list, results are undefined otherwise. After calling this function, the item with the index `list_index' is highlighted in the list widget. SEE ALSO: GetCurrentListItem(), ChangeScrollList(), MakeScrollList() ----------------------------------------------------------- libsx-2.05/docs/text/windows.doc0000644000175000017500000002303311252443541020012 0ustar amckinstryamckinstryThis file contains descriptions of the main high level startup and window creation functions. ----------------------------------------------------------- int OpenDisplay(int argc, char **argv); This function initiates everything with libsx. You should call this function before you call any of the other functions. A correctly written application will call OpenDisplay(), passing its command line arguments and count. The return value from this function is the new number of arguments (or zero if an error occurred). The X libraries accept various standard command line options such as -display or -font, and if your application passes the command line arguments to OpenDisplay(), these will be handled properly. Any X options are removed from the argv array, therefore it is best if you do your command line processing _after_ calling OpenDisplay(). In case you want to predefine some X options to be passed to OpenDisplay (without having to type them on the command line), e.g. -bg gray76 to define the background pixel, you can set the PredefArgs variable as follows: static char *args[] = { "-bg", "gray76", NULL }; PredefArgs = args; OpenDisplay(argc, argv); You only need to call this function once to initialize the first window your program uses. Any other windows you need should be created with MakeWindow(). Technically, calling OpenDisplay() is optional (the MakeXXX() routines will call it for you if you didn't), but it's usually a good idea to call it (since it is only one line of code and it's pretty straightforward. This function returns FALSE (0) if something went wrong (like being unable to open the display, etc). If everything went ok, it returns the new number of arguments in argv. SEE ALSO: MakeWindow() ----------------------------------------------------------- void ShowDisplay(void); This function displays the currently active window (user interface) you've created with the MakeXXX() calls. After this call completes, the interface will be visible on the display. Until you call this function, your interface will not be visible and drawing into a draw area will have no effect. Usually one calls ShowDisplay(), allocates some colors and then immediately calls MainLoop(). If you do not call ShowDisplay(), but just directly call MainLoop(), then MainLoop() implicitly calls ShowDisplay(). SEE ALSO: MainLoop(), MakeWindow() ----------------------------------------------------------- void MainLoop(void); After calling this function, your program yields control to the user interface, and it is entirely driven by what the user does and the callbacks associated with the various widgets. For a single window application, the general flow of events is: OpenDisplay(argc, argv); /* initialize the first window */ MakeButton(....); /* create widgets */ ShowDisplay(); /* put the window on the screen */ /* optionally allocate colors */ MainLoop(); /* start the main loop going */ When you call this after calling ShowDisplay() for your first window (created by OpenDisplay()), the MainLoop() function never returns and your application should have some callback function that will exit() the program (such as a quit button or menu option). If you did not call ShowDisplay(), MainLoop() will call it for you and then launch into the main loop. You should not call MainLoop() for NONEXCLUSIVE mode windows created with MakeWindow(). Those type of windows have their callbacks handled by the MainLoop() function that is already executing (i.e. the one you called for your original window). If the window is an EXCLUSIVE mode window, then MainLoop() keeps executing until CloseWindow() is called on the EXCLUSIVE mode window. That is, MainLoop() blocks until the EXCLUSIVE mode window is closed, and then it returns. If you create a non-exclusive mode window, the general order of events is: MakeWindow(NONEXCLUSIVE_WINDOW, ....); MakeButton(...); ShowDisplay(); This creates a window, puts interface objects into it, and then puts that window on the screen. No other actions need to be taken, and when the callback that created this new window returns, all processing takes place normally, including the processing of the new window and its callbacks. For a window of EXCLUSIVE_WINDOW mode (like a popup), the general order execution is: MakeWindow(EXCLUSIVE_WINDOW, ....); MakeButton(...); ShowDisplay(); MainLoop(); /* blocks until CloseWindow() is called */ /* do something with whatever values the popup got for us */ When MainLoop() returns for an EXCLUSIVE_WINDOW, the window has been closed. SEE ALSO: MakeWindow(), ShowDisplay(). ----------------------------------------------------------- void SyncDisplay(void); This function synchronizes the display with all drawing requests you have made. Normally it is not necessary to call this function, but if you make many repeated function calls to draw graphics, they will be updated in a chunky fashion because X buffers drawing requests and sends a bunch of them at once. After this function completes, all drawing requests you have made are visible on the screen. NOTE: Normally you do not need to call this function because X ensures that everything you request gets drawn, but sometimes it is necessary to insure the synchronization of the display. ----------------------------------------------------------- Widget MakeWindow(char *window_name, char *display_name, int exclusive); NOTE: Do not call this function to open your first window. Your application's first window is opened for you by OpenDisplay(). If your application only needs one window, do NOT call this function. This function opens a new window, possibly on a different display (workstation). The new window has the name specified by the argument window_name and is opened on the display named by display_name (a string usually in the form of, "machine_name:0.0"). The final argument indicates whether the window should be an exclusive window or not (described below). After this functions returns, the current window is the one you just created and you can begin adding widgets to it with the MakeXXX() calls. After have created and added any widgets you want, you should call ShowDisplay(), and if the window is an EXCLUSIVE_MODE window, then you should call MainLoop() (which blocks until the window is closed). If you opened the window with the NONEXCLUSIVE_WINDOW option, you should NOT call MainLoop(). If you pass a NULL for the window_name, it receives a default title of "Untitled". If you pass the #define, SAME_DISPLAY, for the display name, the window opens on the same display as the original window opened by OpenDisplay(). The argument, exclusive, indicates what type of window to open. A normal window is a NONEXCLUSIVE_WINDOW. That is, it will not block the user from interacting with your existing window. An EXCLUSIVE_WINDOW is a popup window that blocks input to your main window until the popup is closed with CloseWindow(). The EXCLUSIVE_WINDOW mode is useful for requestors that need an answer and the user should not be able to do other things in the application. Of course some user-interface folks don't think modal windows like this are good, but tough cookies for them because some times it's necessary. SEE ALSO: SetCurrentWindow() ----------------------------------------------------------- void SetCurrentWindow(Widget w); This function sets the currently active window for other function calls such as CloseWindow(). If you have multiple windows open on several displays, you must call this function switch the currently active one when you wish to manipulate the various windows. The argument, w, must be a valid value returned by MakeWindow(). If you would like to set the current window to be the original window opened by OpenDisplay(), you can pass the #define, ORIGINAL_WINDOW. When you change windows, the current drawing area is also changed to be the last current drawing area in the new window (if there is a drawing area in the new window). SEE ALSO: MakeWindow(), CloseWindow() ----------------------------------------------------------- void CloseWindow(void); This function closes and removes from the display, the currently active window. After calling this function, you should not refer to any of the widgets contained in the window as they are invalid (as is the window handle). SEE ALSO: SetCurrentWindow(), MakeWindow() ----------------------------------------------------------- Widget GetTopWidget(Widget w); This function returns the ID value of the top widget containing Widget w. This can be useful in combination with the CloseProcedure() routine, or when direct calls to the Xt or Xlib libraries are to be performed on the top widget. SEE ALSO: MakeWindow(), CloseWindow(), CloseProcedure() ----------------------------------------------------------- void CloseProcedure(Widget w); This function redefines the closing procedure to be used when the user clicks on the "Close Window" slot of the window bar. It should invoke CloseWindow() to actually close the window, but need not do so, in case one wants the "Close Window" slot to become ineffective. The value of w can be compared to any of the existing top window widgets by means of a call GetTopWidget(any_widget_in_that_window). This can be used to check which window is invoked, and so introduce various closing procedures for various windows. SEE ALSO: SetCurrentWindow(), CloseWindow(), GetTopWidget() ----------------------------------------------------------- libsx-2.05/docs/text/popups.doc0000644000175000017500000000652311252443541017653 0ustar amckinstryamckinstryPopup windows are simple dialog boxes that get a simple yes/no or string/text answer from the user. When these windows popup, they block input to the previously active window. ----------------------------------------------------------- int GetYesNo(char *question); This function allows you to prompt the user for the answer to a simple yes or no type of question. It simply pops up a dialog box with the text contained in the string question, and two okay/cancel buttons. If the user clicks Okay, this function returns TRUE. If the user clicks Cancel, this function returns FALSE. The text in the question string can have embedded newlines (\n characters) to break things up or to add spacing. SEE ALSO : GetString(), GetText() ----------------------------------------------------------- char *GetString(char *msg, char *default); This function allows you to prompt the user for a string of input. The first argument, msg, is a pointer to a string which will be displayed in the dialog box. The next argument, default, is the default string to place in the text string box (it can be NULL or ""). The last argument is the width of the dialog box. When you call this function, it pops up a small dialog box on the screen, and the user can enter the line of text. When the user clicks ok or cancel, the function returns a pointer to the string of text the user entered. If the user clicks cancel, you get a NULL return value. SEE ALSO : GetYesNo(), GetText() ----------------------------------------------------------- char *GetLongString(char *msg, char *default, int width); Similar to GetString(), but with an additional parameter width contolling the width of the input box. SEE ALSO : GetYesNo(), GetString(), GetText() ---------------------------------------------------------------- char *GetText(char *msg, char *default, int width, int height); Quite similar to GetString(), but the dialog box is replaced by an editable window of dimensions width x height, which scrolls in both vertical and horizontal directions. SEE ALSO : GetYesNo(), GetText() ----------------------------------------------------------- char *GetFile(char info_label, char file_or_dir_name, FreqCB func, void *data) This is the API call to the File Requestor, which allows you to browse files from a directory or filesystem. The initial directory is set to be the directory file_or_dir_name -- or the directory containing that file if it is not a directory. The top information label is set to be info_label, usually some information to be passed to users. If the callback function (FreqCB) func is not NULL, a double click on an item in the scroll list allows 'func' to be executed without quitting the File Requestor. The syntax for the callback function is void func(Widget w, char *dir_name, char *file_name, void *data) where dir_name and file_name are set to the values selected with the File Requestor. SEE ALSO: SetFreqFilter() ----------------------------------------------------------- void SetFreqFilter(char *filter) Sets the "filter" to be used in the GetFile() procedure. The default filter is "*", which lets all files be listed in the file requestor. If filter is set to "*.txt", then only files possessing a .txt suffix will be listed. An arbitrary number of wild card characters '*' can be used. The length of filter cannot exceed 80 characters in total. SEE ALSO: GetFile() libsx-2.05/docs/text/text_edit.doc0000644000175000017500000000735511252443541020322 0ustar amckinstryamckinstryA text edit widget is an area used to display and optionally edit multiple lines of text. You can specify the text to be displayed as either an in memory string or as a file name. The text edit area manages its scrollbars and internal affairs, you need not do anything (in fact there are no callbacks for the text edit widget). ---------------------------------------------------------------------- Widget MakeTextWidget(char *txt, int is_file, int editable, int w, int h); This functions lets you create a text edit widget that will display some text and optionally let the user edit and manipulate it. The first argument, txt, is a pointer to a string (NULL is ok). The second argument, is_file, is a boolean value indicating if the first argument should be interpreted as a file name or not. The next argument, editable, is a boolean value indicating whether or not the user is allowed to edit the text. The final two arguments specify the width and height of the drawing area box. If the area is too small to display the text, scrollbars will appear. The txt argument can either contain the entire string (null terminated) that you would like the user to edit, or it can contain the name of a file to be loaded into the text edit widget. If the second argument is_file is TRUE (1), then the first argument gets interpreted as a file name. If is_file is FALSE (0), then the first argument contains the actual text to be displayed. If the txt argument contains the actual text to be displayed, after calling MakeTextWidget() you can free the memory if necessary (the text edit widget makes an internal copy of the string). The argument `editable' is a boolean value indicating whether or not to allow editing of the text in the widget. If you just wish to display some text (such as a help file), set the editable argument to FALSE (0) and the user will not be allowed to modify the text. SEE ALSO: Set/GetTextWidgetText(), SetWidgetPos(), SetFgColor(), SetBgColor(), SetWidgetFont() ---------------------------------------------------------------------- void SetTextWidgetText(Widget w, char *text, int is_file); This argument lets you modify the text displayed in a text edit widget. The first argument identifies the text edit widget to change. The second argument is a null-terminated string that either contains the actual text to display or the name of a file to read in. If the is_file argument is TRUE (1), then the string pointed to by the argument, text, is interpreted as a file name. If is_file is FALSE, the string pointed to by text is directly displayed in the text edit widget. After calling this function, you can free the string pointed to by text if necessary. The text edit widget makes an internal copy of the text. If you wish to update the displayed text again, you should call SetTextWidgetText() again. BUGS: The function name is way too long. SEE ALSO: GetTextWidgetText(), MakeTextWidget() ---------------------------------------------------------------------- char *GetTextWidgetText(Widget w); This function lets you retrieve the text contained in a text edit widget. The only argument, w, should be a text edit widget created with MakeTextWidget(). The return from this function is a character pointer to a null-terminated string that contains the current text in the widget. If there is an error, a NULL is returned. NOTE: You should not free or otherwise modify the text returned by this function. If you need to make modifications, make a copy of the buffer. Again, DO NOT MODIFY THE TEXT RETURNED BY THIS FUNCTION. Make a copy if you need to modify it. BUGS: The function name is way too long. SEE ALSO: SetTextWidgetText(), MakeTextWidget() ---------------------------------------------------------------------- libsx-2.05/docs/text/libsx_intro0000644000175000017500000000517611252443541020120 0ustar amckinstryamckinstryWelcome to libsx, the simple X library. Libsx is an attempt to simplify the vagaries of programming under X windows, making it simple to create user interfaces for programs. With libsx, 10 lines of code may be all you need to create a user-interface complete with many different types of widgets. Libsx is layered on top of the Athena widget set and basically acts as a front end to all the Athena and Xlib garbage so that programming reasonable interfaces isn't so painful. For example, libsx has a simple to use one-line string entry widget that you can create with a single function call (it's based on the Athena text widget but hides all the gory details). Libsx encapsulates the common operations people usually want to perform in a window system and makes them easy to accomplish (at the loss of some flexibility). If you've ever wanted to just open a window with a few buttons and draw some graphics, but were turned away by the complexity of trying to do that, then libsx may be your ticket. Libsx is capable of easily creating many types of user-interface components each with a single function call of a few arguments. The library supports the following Athena ``widgets'': -- Labels -- Buttons -- Toggle buttons and Radio buttons -- String Entry areas -- Scrolling Lists -- Menus -- Scrollbars -- Drawing Areas -- Text Edit boxes The goal of libsx was to make the creation and manipulation of each of these items as simple as possible. The standard simplicity litmus test is a "Hello World" program, which in libsx is: #include "libsx.h" main() { MakeLabel("Hello World"); MainLoop(); } More complicated interfaces use a similar style of creation and complete applications usually require less than 30 lines of code to create an entire user interface complete with menus, buttons, string entry widgets, etc. For example, to create an application that opens a window with a drawing area and a ``Quit'' button, all one must do is: #include "libsx.h" main() { Widget quit_button, draw_area; quit_button = MakeButton("Quit", quit, NULL); draw_area = MakeDrawArea(500, 500, draw_stuff, NULL); SetWidgetPos(draw_area, PLACE_UNDER, quit_button, NO_CARE, NULL); MainLoop(); } So in only a handful of lines of code, we created a simple X application that would have required inordinate amounts of code using traditional methods. All that is required now is for the user to write the routines ``quit'' and ``draw_stuff''. libsx-2.05/docs/text/drawing.doc0000644000175000017500000003625311252443541017763 0ustar amckinstryamckinstryThis file contains documentation about the routines that let you draw in a drawing area. The documentation for these functions is quite brief because they are not all that complicated (how much can one really say about DrawLine()). Keep in mind that for all the drawing functions, the top-left corner of a drawing area is considered to be 0,0. Also, all primitives are drawn in the current foreground color (set either by SetColor() or SetFgColor(). Text is drawn with the current foreground color and the background color. Line, arc, and box primitives are drawn with the current line width (as set by SetLineWidth()), and all primitives are drawn in the current draw mode (set by SetDrawMode()). ------------------------------------------------------------------------ void SetDrawArea(Widget w); This sets the current drawing area to be that named by the Widget w. If `w' is not a drawing area widget, nothing happens. You need to call this function when you want to switch between multiple drawing areas. If you only have one drawing area you do not need to worry about this function at all. Any callbacks for a drawing area already have the current drawing area set to be the one where the event happened (so it is not necessary to call this function in a callback for a drawing area). ------------------------------------------------------------------------ void SetColor(int color); This sets the foreground color to draw with in the current drawing area (each drawing area has its own foreground color). The argument "color" should be a valid color obtained with one of the color functions (such as GetNamedColor() or GetRGBColor(), etc). To some extent this function duplicates the SetFgColor() function, but exists because it is faster than SetFgColor(). SEE ALSO : SetBgColor(), GetFgColor(), SetFgColor(), GetStadardColors() ------------------------------------------------------------------------ void SetLineWidth(int width); This functions sets the width of lines drawn in the current drawing area. Each drawing area has its own line width. A width of zero is valid and tells the X server to draw lines as fast as it possibly can, possibly being a little inaccurate. Larger numbers of course draw wider lines. SEE ALSO : SetDrawMode(), SetWidgetFont(), SetFgColor(), SetBgColor() ------------------------------------------------------------------------ void SetDrawMode(int mode); This function sets the drawing mode for the current drawing area. A drawing mode is one of: GXcopy, GXxor, GXinvert, GXor, GXclear, GXand, GXandReverse, GXnoop, GXnor, GXequiv, GXinvert, GXorReverse, GXcopyInverted, GXorInverted, GXnand, and GXset Most of these are stupid/useless modes defined by X (so ignore them). The primary mode is GXcopy (the default mode). This causes all primitives to draw in the foreground color, overwriting any pixels already drawn. Libsx also defines a special mode: SANE_XOR. The SANE_XOR mode will actually draw primitives in a true XOR mode so that you can draw things like rubber-band boxes that the user stretches with the mouse. You must use SANE_XOR if you want true XOR'ed primitives, GXxor will definitely NOT work as you expect. When you are done using SANE_XOR, you would normally call SetDrawMode() with an argument of GXcopy to restore normal drawing. SEE ALSO : SetLineWidth(), SetWidgetFont(), SetFgColor(), SetBgColor() ------------------------------------------------------------------------ void GetDrawAreaSize(int *w, int *h); This is a convience function that returns the size of the current drawing area. The window dimension are returned in the two variables. It is important to note that "w" and "h" are POINTERS to integers, not just regular integers. ------------------------------------------------------------------------ void ClearDrawArea(void); This function completely clears the current drawing area and sets it to the current background color (which may not be white). Generally, when your redisplay callback is called, this is the first thing want to do. SEE ALSO : SetDrawArea(), GetBgColor(), SetBgColor() ------------------------------------------------------------------------ void DrawPixel(int x1, int y1); This function draws a point in the current foreground color at the location x1, y1 in your current drawing area. The top left corner of the drawing area is considered 0,0. SEE ALSO : GetPixel(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- int GetPixel(int x1, int y1); This function retrieves the pixel value at the location x1, y1 in the current drawing area. The top left corner of the drawing area is considered 0,0. The pixel value returned to you will be between 0 and 255 (inclusive). The value you get back should be treated as an index to a colormap. To find out what actual color is displayed at that location, you need to look up the color in the colormap (which you should be maintaining as there is no way to get it after you've set it). NOTE: This function is _NOT_ very high performance. It has to call GetImage() to do the bulk of the work. This is unfortunate, but unavoidable because X does not provide an easy way to read individual pixels. SEE ALSO : GetImage(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawLine(int x1, int y1, int x2, int y2); This function draws a line from x1,y1 to x2,y2 in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. SEE ALSO : DrawPolyline(), DrawPixel(), SetColor(), SetBgColor(), SetFgColor(), SetDrawArea(), ----------------------------------------------------------- void DrawPolyline(XPoint *points, int n); This function accepts an array of points and draws them as a connected polyline on the display. The line is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. The `points' argument is an array of XPoint structures which are as follows: typedef struct XPoint { short x,y; }XPoint; You do not need to define this structure yourself. It is defined for you already, it is just reprinted here so you can see what it is. You should have an array of these structures with each entry holding a vertex of the polyline. SEE ALSO : DrawLine(), DrawFilledPolygon(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawFilledPolygon (XPoint *points, int n); This function takes an array of points and draws them as a filled polygon on the display. The polygon is filled with the current foreground color and is drawn in the current drawing area. The top left corner of the drawing area is considered 0,0. The `points' argument is an array of XPoint structures which are as follows: typedef struct XPoint { short x,y; }XPoint; You do not need to define this structure yourself. It is defined for you already, it is just reprinted here so you can see what it is. You should have an array of these structures with each entry holding a vertex of the polygon to be filled. SEE ALSO : DrawPolyline(), DrawBox(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawBox(int x, int y, int width, int height); This function draws a rectangular box starting at x,y with a width and height as specified. If you make the call: DrawBox(50,50, 75,75), you will get a box that starts at position 50,50 and goes for 75 pixels in the X and Y directions (i.e the other extreme of the box would be at 125,125). The box is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. If the width and height are negative, the box is still drawn properly. SEE ALSO : DrawFilledBox(), DrawPolygon(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawFilledBox(int x, int y, int width, int height); This function draws a filled rectangular box starting at x,y with a width and height as specified. If you make the call: DrawFilledBox(50,50, 75,75), you will get a filled box that starts at position 50,50 and goes for 75 pixels in the X and Y directions (i.e the other extreme of the box would be at 125,125). The box is filled with the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. If the width and height are negative, the box is still drawn properly. SEE ALSO : DrawBox(), DrawFilledPolygon(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawText(char *string, int x, int y); This function prints the text string "string" starting at x,y. The text is drawn in the current foreground color. The background of the text is filled with current background color of the drawing area widget. The top left of the drawing area is 0,0. The X,Y position you specify is the bottom left corner of where the text is drawn. SEE ALSO : GetFont(), FontHeight(), TextWidth(), SetColor(), SetDrawArea(), SetWidgetFont(), GetBgColor(), SetFgColor(), SetBgColor() ----------------------------------------------------------- void DrawArc(int x, int y, int width, int height, int angle1, int angle2); This function draws an arc/ellipse from the location x,y that is bounded by the box defined by the x,y, width and height. That is, the arc/ellipse will always be contained in the box defined by the x,y position and the width and height arguments. The X,Y arguments are not the center of the arc/circle. The arc begines at angle1 degrees and continues for angle2 degrees around the circle. The arc is drawn in the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. If you want a circle, you would specify angle1 as 0, and angle2 as 360. If the width and height are negative, the arc is still drawn properly. SEE ALSO : DrawPolyline(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawFilledArc(int x, int y, int width, int height, int angle1, int angle2); This function draws a filled arc/ellipse from the location x,y that is bounded by the box defined by the x,y, width and height. That is, the arc/ellipse will always be contained in the box defined by the x,y position and the width and height arguments. The X,Y arguments are not the center of the arc/circle. The arc begines at angle1 degrees and continues for angle2 degrees around the circle. The arc is filled with the current foreground color in the current drawing area. The top left corner of the drawing area is considered 0,0. If you want a circle, you would specify angle1 as 0, and angle2 as 360. If the width and height are negative, the arc is still drawn properly. SEE ALSO : DrawArc(), SetColor(), SetDrawArea(), SetBgColor(), SetFgColor() ----------------------------------------------------------- void DrawImage(char *data, int x, int y, int width, int height); This function draws a bitmap image that has a width and height as specified by the arguments. The image is drawn at location x,y in the current drawing area. The "data" argument should point to at least width*height bytes of data. Each byte of the data is interpreted as a color value to draw the corresponding pixel with. Normally you would use this function when you have taken over the colormap with GetAllColors() (so that you can be guaranteed certain colors are in a given range). If you have not taken over the colormap, you need to make sure that the bytes in the image data contain valid values that you've allocated with the color allocation functions (GetNamedColor(), GetRGBColor() or GetPrivateColor()). The top left corner of the drawing area is considered 0,0. SEE ALSO : GetImage(), SetColor(), SetDrawArea(), GetAllColors() ----------------------------------------------------------- void GetImage(char *data, int x, int y, int width, int height); This function retrieves a bitmap image from your drawing area that has a width and height as specified by the arguments. The image is taken from the starting location x,y in the current drawing area. The "data" argument should point to at least width*height bytes of data. The area of memory pointed to by data will be filled with the 8-bit pixel values of the current drawing area. Note that the pixel values are not the actual color values. If you want the actual color values, you'll need to know what the current colormap is (which you would know if you've set the colormap) and then use the pixel values to index the colormap. The memory pointed to by data is packed with width*height bytes, with no extra padding or filling. That is, the first width bytes correspond to line 0, the next width bytes correspond to line 1 of the image, etc. It is important to keep in mind that if you plan to save the pixel data in an image file, you need to also keep track of the colormap so that you can save that as well. By themselves, the pixel values don't correspond to any particular color. A serious drawback of this function arises from the way X operates. If the drawing area from which you are "getting" the image is obscured by another window, that part of the bitmap will be empty. The only way around this is to make sure that your window is in front of all the others before you call GetImage(). This is a serious limitation, but it's the way X operates. The top left corner of the drawing area is considered 0,0. If you specify a starting x,y and width,height dimensions that are larger than your drawing area, you will get a BadMatch error and X will terminate your program (so be careful). SEE ALSO : DrawImage(), SetColor(), SetDrawArea(), GetAllColors() ----------------------------------------------------------- void ScrollDrawArea(int dx, int dy, int x1,int y1, int x2, int y2); This function scrolls the box defined by (x1,y1) (x2,y2) by the amounts dx and dy in the X and Y directions respectively. This means that the box whose upper left corner is (x1,y1) and whose lower right corner is (x2,y2) are scrolled by dx and dy pixels in X and Y. A positive value for dx causes the drawing area to scroll its contents to the left. That is, whatever is at the left edge gets pushed off and the dx columns of pixels on the right hand side are cleared to the background color. A negative value has the opposite effect. A positive value for dy corresponds to scrolling upwards. That is, whatever is at the top of the drawing area is pushed up by dy pixels and the bottom dy rows of pixels are cleared to the background color. A negative value has the opposite effect. This function is useful for scrolling the drawing area to draw new information (such as a text editor might do to scroll text up or down). The new area exposed by the scroll is filled with the current background color of the drawing area. SEE ALSO : SetWidgetFont(), SetColor() ------------------------------------------------------------------------ libsx-2.05/docs/text/label.doc0000644000175000017500000000300211252443541017371 0ustar amckinstryamckinstryA label widget is a widget that displays some text or bitmap but cannot be clicked on or interacted with by the user. In addition to "simple" label widgets, other widgets such as buttons or menus can as well carry labels. Generally a label is for informational purposes, such as saying what the program title is, or what the widget is supposed to be used for. Some widgets carry predefined labels; the list of predefined labels is: char *SX_Dialog_Label[] = {"Yes", "Cancel", "No", "Okay", "Cancel", "Retry" }; The pointers to these labels can be reassigned to other string pointers, so as (e.g.) to provide translations into other languages. ------------------------------------------------------------------------ Widget MakeLabel(char *txt); This function creates a label that contains the text in the character string pointed to by "txt". The text will simply be displayed, with no fancy borders or special highlighting. If the text contains new line characters, they will be interpreted properly. If the argument txt is NULL, then no label will be set for the widget. This is convienent if you plan to put a bitmap on this widget with the SetWidgetBitmap() function. This widget is useful for displaying a piece of textual information like a filename or user name. If this routine fails, a NULL is returned. SEE ALSO : SetWidgetPos(), SetWidgetBitmap(), SetLabel(), SetWidgetFont(), SetFgColor(), SetBgColor(), SetBorderColor() ------------------------------------------------------------------------ libsx-2.05/docs/text/button.doc0000644000175000017500000000430711252443541017636 0ustar amckinstryamckinstryA button widget is a button that a user can click on with the left mouse button to indicate an action. When a button is pressed, it is drawn in inverse video and some action takes place. A button is connected to your code by a callback function which is called when the user clicks on the button widget with the left mouse button. ----------------------------------------------------------- Widget MakeButton(char *label, ButtonCB func, void *data); This function creates a small rectangular button which the user can click on. The character string pointed at by "label" will be printed inside the button. If the string has newline characters in it, they will be interpreted properly (i.e. you will get a multiline label). The next two arguments are a callback function, func, and an arbitrary data pointer, data, that will be passed to the function func. If you plan to attach a bitmap to this widget, you can specify NULL for the label text (see the docs for SetWidgetBitmap(). When the button is pressed, the function, "func" will be called. The function, func, will have two arguments. The first argument is the widget that user clicked on (which you can ignore if you do not need it). The second argument is the void pointer, 'data', specified in the call to MakeButton(). The function "func" should be declared as follows: void func(Widget w, void *data) { /* your code goes here */ } The last argument (called "data") is the same as the last argument to the MakeButton() function call. It is declared as a void pointer and you can cast to whatever type you need. Generally you'll have something like: MyProgram *me = (MyProgram *)data; You use "buttons" to allow the user to indicate various actions (things like load, save, cut, copy, and paste operations are good examples). The mental model of how a button works is that when the user clicks on the button with the mouse, the function you specify is called. If something goes wrong in creating the button, a NULL value is returned. This is a rare occurrence, but good code will still check for it. SEE ALSO : SetWidgetPos(), SetWidgetBitmap(), SetLabel(), SetWidgetFont(), SetFgColor(), SetBgColor(), SetBorderColor() libsx-2.05/docs/text/draw_area.doc0000644000175000017500000002001211252443541020237 0ustar amckinstryamckinstryA drawing area is a rectangular area that supports drawing into, receiving input from (mouse clicks, mouse motion and keypresses) and redisplay requests from X. You can draw any sort of graphics into a drawing area as well as perform various types of interaction with mouse and keyboard input. It is also useful to read the drawing.doc file for more information on the actual drawing routines available. ----------------------------------------------------------- Widget MakeDrawArea(int width, int height, RedisplayCB func, void *data); The function MakeDrawArea() creates a drawing area which you can later use to draw graphics into and receive mouse and keyboard input from. The drawing are will have a width and height as you specify. The callback function, func, is called whenever the drawing area should be redisplayed (because it was obscured or resized). The argument "data" is a pointer to any arbitrary data you want, and it is passed directly to the resize callback (and the other callbacks as well). The redisplay callback is where you should put all of your drawing code. It is called for you when the application opens the window for the first time (by calling MainLoop()). The redisplay callback function should be declared as follows: void redisplay(Widget w, int width, int height, void *data) { } The first argument, w, is the drawing area widget that needs to be redrawn. The second and third arguments are the new width and height of the drawing area (it may have been resized). The final argument is the void pointer passed to MakeDrawArea(). If you are interested in receiving other types of input, see the functions, SetButtonDownCB(), SetButtonUpCB(), SetKeypressCB() and SetMouseMotionCB(). These functions will let you set callbacks for the other types of input. Each drawing area you create has its own state (foreground and background colors, drawing mode, and line width). Only one drawing area can be active at any given time. When an event happens for a drawing area, that drawing area becomes the active drawing area. You can make other drawing areas active with SetDrawArea(). If something goes wrong in creating the DrawArea, a NULL value is returned. SEE ALSO : drawing.doc, SetButtonDownCB(), SetButtonUpCB(), SetKeypressCB(), SetMouseMotionCB(), SetWidgetPos(), SetWidgetFont(), SetFgColor(), SetBgColor(), SetBorderColor() ----------------------------------------------------------- void SetButtonDownCB(Widget w, MouseButtonCB func); This function sets up a callback that will be called everytime the user presses a mouse button in the specified drawing area widget `w'. The callback function should be declared as follows: void func(Widget w, int which_button, int x, int y, void *data) { } Then, whenever the user presses a mouse button in the drawing area, your callback is called. The first argument is the drawing area widget where the event happened. The next argument is an integer specifying which button was pressed. It is a small positive integer. A value of one is the left mouse button, two is the middle mouse button and three is the right mouse button. Technically, values of four and five are also possible though I've never seen a mouse with five buttons. The x and y arguments are the position of the mouse where the user pressed the mouse button. The final argument is the void pointer argument given to MakeDrawArea(). You can specify a NULL for the function to turn off receiving button down events. ----------------------------------------------------------- void SetButtonUpCB(Widget w, MouseButtonCB button_up); This function sets up a callback that will be called everytime the user releases a mouse button in the specified drawing area widget `w'. The callback function should be declared as follows: void func(Widget w, int which_button, int x, int y, void *data) { } Then, whenever the user releases a mouse button in the drawing area, your callback is called. The first argument is the drawing area widget where the event happened. The next argument is an integer specifying which button was released. It is a small positive integer. A value of one is the left mouse button, two is the middle mouse button and three is the right mouse button. Technically, values of four and five are also possible though I've never seen a mouse with five buttons. The x and y arguments are the position of the mouse where the user released the mouse button. The final argument is the void pointer argument given to MakeDrawArea(). You can specify a NULL for the function to turn off receiving button up events. ----------------------------------------------------------- void SetKeypressCB(Widget w, KeyCB func); This function lets you set a callback so that you will receive keyboard input in the drawing area. The callback function should be declared as follows: void func(Widget w, char *input, int up_or_down, void *data) { } Then, whenever the user presses keys in the drawing area, your callback function is called. The first argument is the drawing area widget where the event happened. The next argument is a character pointer to a null-terminated string that contains what was typed by the user. The up_or_down argument indicates whether the key was pressed released (a zero indicates a press, a 1 indicates a key release). The final argument is the void ponter argument given to MakeDrawArea(). It is useful to know that the string returned to your program is not necessarily a single ASCII character. You will get the usual ASCII characters, including control characters (such as ^C or ^H). But, the workstation's function keys will also be returned in a string such as "F11" or "F23". You will also get other longer strings such as "Control_L", "Alt_R", or "Shift_L". It is important to understand that even if you just press the shift key to get a capital letter, you will first receive the string "Shift_L" or "Shift_R", then you will receive a capital letter (say, "H"). You should probably ignore the "Shift_L" or "Shift_R" messages (but who knows, you may find some use for them). The argument, up_or_down, tells you whether the given key was pressed or released. If the key was pressed down, up_or_down has a zero (0), if the key was released, up_or_down contains a 1. This is useful for doing things like shift-clicking with the mouse or handling control-key combinations in an editor or other program. The arrow keys return strings such as "Left", "Up", "Right", or "Down". Other keys on the keyboard may return strings such as "Home", "Prior", "Next", "Undo", "Help", etc. Of course not all keyboards generate all of the strings (because they aren't set up to). NOTE WELL: The string that is returned to you can _NOT_ (I'll repeat that, can _NOT_) be modified by your program. Got it? Do _NOT_ modify the string. If you want to munge with it, make a copy using strdup() or strcpy() into your own buffer space. You can specify a NULL for the function to turn off receiving keypress events. ----------------------------------------------------------- void SetMouseMotionCB(Widget w, MotionCB func); This function sets a callback so that whenever the mouse moves in your drawing area, the specified function will be called. It is important to keep in mind that the function you specify is called _every_ time the mouse moves in the drawing area, even if it is just passing through. The callback function should be declared as follows: void func(Widget w, int x, int y, void *data); { } The first argument is (as usual) the Widget where the mouse was moved in. The next two arguments are the current X and Y values of the mouse. The final argument is the void pointer passed into MakeDrawArea(). You should be very frugal with what happens in this function so as not to cause the application to lag behind the user too much. Calling functions like sleep() are definitely out of the question. You can specify a NULL for the function to turn off receiving mouse motion events. ----------------------------------------------------------- libsx-2.05/docs/text/toggle.doc0000644000175000017500000001021511252443541017577 0ustar amckinstryamckinstryA toggle widget is similar to a button widget except that it maintains state. That is, when a user clicks a toggle widget, it remains highlighted until it is clicked again. This is similar to an on/off switch. Toggle widgets can also be used to create a group of "radio buttons". A radio button group is a set of toggle widgets in which at most one of them can be selected at any one time (it is possible for none of them to be selected). ------------------------------------------------------------------------ Widget MakeToggle(char *txt, int state, Widget w, ToggleCB func, void *data); This function makes a widget that will toggle between a highlighted `on' state and an unhighlighted `off' state. The first argument is the text that will be displayed inside the widget. The `state' argument is a boolean value of the initial state of the toggle button (TRUE == on/highlighted, FALSE == off). The next argument, a Widget, is NULL if this widget is a simple toggle button by itself and not part of a radio group (described below). If you plan to display a bitmap for the toggle button, you may specify a NULL for the txt argument (and then call SetWidgetBitmap()). The func argument is a standard callback function, that should be declared as follows: void func(Widget w, void *data) { } The last argument, data, is an arbitrary pointer you would like passed to your callback function (it becomes the second argument to the callback function. Each time the widget changes state, your callback function is called. That is, each time the user clicks the toggle, your function is called. Radio Groups: It is possible to connect toggle widgets together to form a group of widgets that are mutually exclusive. That is to say, with a radio group, you can have a set of widgets in which at most one of them will be highlighted at any given time. Therefore, if you had 3 widgets, A, B, and C, only one could be highlighted at any one time, and clicking on another unhighlights the current one and highlights the toggle clicked on. This is useful for selecting one choice of several (such as a size, which is either small, medium or large, but not two at the same time). Keep in mind that it is possible for none of them to be selected. To build a radio group, you use the Widget argument of the MakeToggle() function. If you specify another valid toggle widget in the call to MakeToggle(), the new widget becomes connected to the widget you specified. All the widgets you connect together form a radio group. Any single widget can _only_ be in one radio group. EXAMPLE: Widget widg1, widg2, widg3; widg1 = MakeToggleWidget("Thing 1", TRUE, NULL, func1, NULL); widg2 = MakeToggleWidget("Thing 2", FALSE, widg1, func2, NULL); widg3 = MakeToggleWidget("Thing 3", FALSE, widg1, func3, NULL); Notice how widg2 and widg3 specify widg1 as their Widget argument. This connects all three into a radio group in which only one can be set at a time. We initialize widg1 to be initially set and the others off. If you specify more than one widget as `on', the results are undefined. The callback functions are called whenever a widget is highlighted or unhighlighted. The callbacks to the widget being unhighlighted happen before the callbacks to widgets being highlighted. SEE ALSO: SetToggleState(), GetToggleState(), SetWidgetBitmap(), SetFgColor(), SetBgColor(), SetBorderColor(), SetWidgetFont() ----------------------------------------------------------- void SetToggleState(Widget w, int state); SetToggleState() explicitly sets the state of a widget. The `state' argument is either TRUE (set the toggle to its highlighted state), or FALSE (unhighlight the widget). The callback routine for the widget is only called if there is a change in state. SEE ALSO: GetToggleState(), MakeToggle() ----------------------------------------------------------- int GetToggleState(Widget w); This function returns the current state of the toggle widget w. The return values are either TRUE (the widget is selected) or FALSE (the widget is not highlighted). SEE ALSO: MakeToggle(), SetToggleState() ----------------------------------------------------------- libsx-2.05/freq/0000755000175000017500000000000011252443541014651 5ustar amckinstryamckinstrylibsx-2.05/freq/main.c0000644000175000017500000000412611252443541015744 0ustar amckinstryamckinstry/* * This is an example program for use with the libsx library. This * example shows how to implement a simple file requestor. The main * window has two button widgets: a load button and a quit button. The load * button will open a file requestor window where the user can select a * file from a scrollable list. The program will block until the user * has selected a file or cancelled the load at which point the appropriate * action can be taken. * * -Allen Martin (amartin@wpi.wpi.edu) */ #include #include #include #include "libsx.h" /* gets us in the door with libsx */ #include "freq.h" /* file requestor header */ int init_display(int argc, char **argv, void *data); /* callback protos */ void quit(Widget w, void *data); void load(Widget w, void *data); void main(int argc, char **argv) { argc = init_display(argc, argv, NULL); /* setup the display */ if (argc == 0) exit(0); MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ int init_display(int argc, char **argv, void *data) { Widget w[2]; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; w[0] = MakeButton("Load", load, data); w[1] = MakeButton("Quit!", quit, data); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); ShowDisplay(); GetStandardColors(); return argc; } /* * load() - Callback function for the load button. This just calls * SimpleGetFile() to get a file name */ void load(Widget w, void *data) { char *fname; fname = SimpleGetFile(NULL); if(fname) printf("The file \"%s\" was selected\n", fname); else printf("Load Cancelled\n"); } /* * quit() - Callback funtion for the quit button. */ void quit(Widget w, void *data) { exit(0); } libsx-2.05/freq/dirlist.c0000644000175000017500000000756311252443541016502 0ustar amckinstryamckinstry/* * This file contains a function, get_dir_list() that will get a directory * listing and put all the names into a table (an array of char *'s table) * and return it to you (along with the number of entries in the directory * if desired). The table is NULL terminated (i.e. the entry after the last * one is a NULL), and is just like an argv style array. * * If an error occurs (memory allocation, bad directory name, etc), you * will get a NULL back. * * Each entry of the returned table points to a NULL-terminated string * that contains the name of a file in the directory. If the name is * a directory, it has a slash appended to it. * * When you are done with the table, you should free it manually, or you * can call the function free_table() provided down below. * * See the sample main() down below for how to use it. Ignore (or steal * if you'd like) the other code that isn't particularly relevant (i.e. * the support functions). * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include #include #include void free_table(char **table, int n) { char **orig = table; for(; n > 0; n--, table++) { if (*table) free(*table); } free(orig); } void free_dirlist(char **table) { char **orig = table; while(*table) { free(*table); table++; } free(orig); } char *get_file_name(struct dirent *d) { struct stat s; char *name; if (d == NULL) { fprintf(stderr, "BUG BUG BUG (got a NULL in get_file_name()).\n"); return NULL; } if (stat(d->d_name, &s) < 0) { perror(d->d_name); return NULL; } if (S_ISDIR(s.st_mode)) { name = (char *)malloc(strlen(d->d_name)+2); if (name == NULL) return NULL; sprintf(name, "%s/", d->d_name); } else { name = (char *)strdup(d->d_name); } return name; } #define CHUNK 100 char **get_dir_list(char *dirname, int *num_entries) { int i,size=CHUNK; char **table, old_dir[MAXPATHLEN]; DIR *dir; struct dirent *dirent; getcwd(old_dir, MAXPATHLEN); if (dirname && chdir(dirname) < 0) return NULL; dir = opendir("."); if (dir == NULL) { chdir(old_dir); return NULL; } table = (char **)calloc(size, sizeof(char *)); if (table == NULL) { closedir(dir); chdir(old_dir); return NULL; } dirent = NULL; i = 0; for(dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { table[i] = get_file_name(dirent); if (table[i] == NULL) /* continue if there was an error */ { continue; } i++; if (i == size) { char **table2; size *= 2; table2 = (char **)realloc(table, size * sizeof(char *)); if (table2 == NULL) { free_table(table, i); closedir(dir); chdir(old_dir); return NULL; } table = table2; } } table[i] = NULL; /* make sure the table ends with a NULL */ if (num_entries) *num_entries = i; closedir(dir); chdir(old_dir); return table; } #ifdef TEST /* * This function is just a wrapper for strcmp(), and is called by qsort() * (if used) down below. */ int mystrcmp(char **a, char **b) { return strcmp(*a, *b); } main(int argc, char **argv) { int i, num_entries; char *dirname, **table; if (argv[1] == NULL) dirname = "."; else dirname = argv[1]; table = get_dir_list(dirname, &num_entries); if (table == NULL) printf("No such directory: %s\n", dirname); else { /* * If you want to sort the table, you would do it as follows: */ qsort(table, num_entries, sizeof(char *), mystrcmp); printf("Number of files == %d\n", num_entries); for(i=0; table[i] != NULL; i++) printf("%s\n", table[i]); free_table(table, num_entries); } exit(0); } #endif /* TEST */ libsx-2.05/freq/freq.c0000644000175000017500000002416011252443541015755 0ustar amckinstryamckinstry/* This file contains all routines for creating and managing a file * requestor. The programmer's only interface to the file requestor * is the function GetFile(). See the description for that function * for usage information (it's pretty trivial). * * Originally written by Allen Martin (amartin@cs.wpi.edu). * * Significant modifications by me (Dominic Giampaolo, dbg@sgi.com) * to clean up some bugs, do double-clicks correctly, and make * relative path browsing work better. */ #include #include #include #include #include #include #include "libsx.h" #ifndef CLK_TCK #include #define CLK_TCK sysconf(_SC_CLK_TCK) /* seems to work right */ #endif /* CLK_TCK */ /* * Some ugly hacks to make this work better under ultrix. */ #ifdef ultrix /* * Can you say "Let's be pinheaded and follow the letter of the spec without * regard for what might make sense"? I knew you could. And so can the * boys and girls at DEC. * * Which is why they don't provide strdup() in their libc. Gay or what? */ char *strdup(const char *str) { char *new; new = malloc(strlen(str)+1); if (new) strcpy(new, str); return new; } #endif /* ultrix */ /* * No one seems to have a prototype for strdup(). What a pain * in the butt. Why on earth isn't strdup() in the POSIX standard * but something completely useless like mbstowcs() is? */ char *strdup(const char *str); /* * Here's where the real code begins. */ typedef struct { Widget freq_window; Widget file_path; Widget file_name; Widget file_list; char **dirlist; /* used by the list widget */ char fpath[MAXPATHLEN]; char fname[MAXPATHLEN]; clock_t last_click; /* time of last click */ } FReqData; static void load_cancel(Widget w, FReqData *fdata); static void load_ok(Widget w, FReqData *fdata); static void load_list(Widget w, char *string, int index, FReqData *fdata); static void load_dir(Widget w, char *string, FReqData *fdata); static void load_name(Widget w, char *string, FReqData *fdata); static int mystrcmp(const void *a, const void *b); char **get_dir_list(char *pname, int *num); void free_dirlist(char **table); /* * GetFile() - This is the entry point to the file requestor. A single * argument is passed - the path name for the initial list. * If this path name is passed as NULL, the current directory * is used instead. The function returns a character string * that is the name of the selected file, path included. If * an error occurs, or the user selects CANCEL, NULL is returned. */ char *SimpleGetFile(char *_path) { FReqData fdata; Widget w[8]; int num_dir; char path[MAXPATHLEN]; if(!_path || strcmp(_path, ".") == 0 || strcmp(_path, "./") == 0) getcwd(path, MAXPATHLEN); else strcpy(path, _path); if(path[strlen(path)-1] != '/') strcat(path, "/"); if(!(fdata.dirlist = get_dir_list(path, &num_dir))) return(NULL); qsort(fdata.dirlist, num_dir, sizeof(char *), mystrcmp); fdata.freq_window = MakeWindow("File Requestor", SAME_DISPLAY, EXCLUSIVE_WINDOW); w[0] = MakeLabel("Path:"); w[1] = MakeStringEntry(path, 300, (void *)load_dir, &fdata); w[2] = MakeScrollList(fdata.dirlist, 350, 300, (void *)load_list, &fdata); w[3] = MakeLabel("File:"); w[4] = MakeStringEntry("", 300, (void *)load_name, &fdata); w[5] = MakeButton("Ok", (void *)load_ok, &fdata); w[6] = MakeLabel("Select a File from the List or Enter a Name"); w[7] = MakeButton("Cancel", (void *)load_cancel, &fdata); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[2], PLACE_RIGHT, w[3]); SetWidgetPos(w[5], PLACE_UNDER, w[3], NO_CARE, NULL); SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]); SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]); /* save the file name & file list widgets, so we can use them later */ fdata.file_path = w[1]; fdata.file_list = w[2]; fdata.file_name = w[4]; fdata.last_click = 0; /* set up the file path */ strcpy(fdata.fpath, path); ShowDisplay(); MainLoop(); /* free the directory list */ if (fdata.dirlist) free_dirlist(fdata.dirlist); SetCurrentWindow(ORIGINAL_WINDOW); if(fdata.fname[0] == '\0') return(NULL); else return(strdup(fdata.fname)); } /* * load_cancel() - Callback routine for CANCEL button */ static void load_cancel(Widget w, FReqData *fdata) { SetCurrentWindow(fdata->freq_window); CloseWindow(); strcpy(fdata->fname, ""); } /* * load_ok() - Callback routine for OK button */ static void load_ok(Widget w, FReqData *fdata) { char *fpath, *fname; char fullname[MAXPATHLEN]; fpath = GetStringEntry(fdata->file_path); fname = GetStringEntry(fdata->file_name); sprintf(fullname, "%s%s", fpath, fname); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); SetCurrentWindow(fdata->freq_window); CloseWindow(); } /* * load_list() - Callback routine for scrollable list widget */ static void load_list(Widget w, char *string, int index, FReqData *fdata) { char newpath[MAXPATHLEN], *cptr, *fpath, fullname[MAXPATHLEN]; char **old_dirlist=NULL; static char oldfile[MAXPATHLEN] = { '\0', }; clock_t cur_click; struct tms junk_tms; /* not used, but passed to times() */ int num_dir; float tdiff; /* difference in time between two clicks as % of a second */ /* * First we check fora double click. * * If the time between the last click and this click is greater than * 0.5 seconds or the last filename and the current file name * are different, then it's not a double click, so we just return. */ cur_click = times(&junk_tms); tdiff = ((float)(cur_click - fdata->last_click) / CLK_TCK); if(tdiff > 0.50 || strcmp(oldfile, string) != 0) { fdata->last_click = cur_click; strcpy(oldfile, string); SetStringEntry(fdata->file_name, string); return; } /* check if a directory was selected */ if(string[strlen(string)-1] != '/') /* a regular file double click */ { fpath = GetStringEntry(fdata->file_path); sprintf(fullname, "%s%s", fpath, string); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); SetCurrentWindow(fdata->freq_window); CloseWindow(); return; } /* * Else, we've got a directory name and should deal with it * as approrpriate. */ /* check for special cases "./" and "../" */ if(strcmp(string, "./") == 0) { if (fdata->fpath) strcpy(newpath, fdata->fpath); else strcpy(newpath, "./"); } else if(strcmp(string, "../") == 0) { strcpy(newpath, fdata->fpath); if (strcmp(newpath, "./") == 0) strcpy(newpath, string); else { /* * chop off the last path component and look at what it * is to determine what to do with the `..' we just got. */ cptr = strrchr(newpath, '/'); if (cptr) *cptr = '\0'; cptr = strrchr(newpath, '/'); if (cptr) *cptr = '\0'; if ( (cptr != NULL && strcmp(cptr+1, "..") == 0) ||(cptr == NULL && strcmp(newpath, "..") == 0)) { if (cptr) *cptr = '/'; strcat(newpath, "/"); /* put back the / we took out */ strcat(newpath, "../"); /* and append the new ../ */ } else { if(cptr == NULL && strcmp(fdata->fpath, "/") == 0) strcpy(newpath, "/"); else if (cptr == NULL) strcpy(newpath, "./"); if (newpath[strlen(newpath)-1] != '/') strcat(newpath, "/"); } } } else /* not a `./' or `../', so it's just a regular old directory name */ { if (fdata->fpath[strlen(fdata->fpath)-1] == '/') sprintf(newpath, "%s%s", fdata->fpath, string); else sprintf(newpath, "%s/%s", fdata->fpath, string); } old_dirlist = fdata->dirlist; if(!(fdata->dirlist = get_dir_list(newpath, &num_dir))) /* should beep the display or something here */ return; qsort(fdata->dirlist, num_dir, sizeof(char *), mystrcmp); strcpy(fdata->fpath, newpath); SetStringEntry(fdata->file_path, fdata->fpath); SetStringEntry(fdata->file_name, ""); strcpy(fdata->fpath, newpath); ChangeScrollList(fdata->file_list, fdata->dirlist); /* free the directory list */ if (old_dirlist) free_dirlist(old_dirlist); fdata->last_click = 0; /* re-init double-click time */ return; } /* * load_dir() - Callback routine for pathname string entry widget */ static void load_dir(Widget w, char *string, FReqData *fdata) { char **old_dirlist, temp[MAXPATHLEN]; int num_dir; /* make sure the name has a '/' at the end */ strcpy(temp, string); if(temp[strlen(temp)-1] != '/') strcat(temp, "/"); old_dirlist = fdata->dirlist; if(!(fdata->dirlist = get_dir_list(temp, &num_dir))) { /* bad path - reset the file path and return */ SetStringEntry(fdata->file_path, fdata->fpath); return; } qsort(fdata->dirlist, num_dir, sizeof(char *), mystrcmp); strcpy(fdata->fpath, temp); SetStringEntry(fdata->file_path, temp); ChangeScrollList(fdata->file_list, fdata->dirlist); /* free the directory list */ if (old_dirlist) free_dirlist(old_dirlist); } /* * load_name() - Callback routine for file name string entry widget */ static void load_name(Widget w, char *string, FReqData *fdata) { char *fpath, fullname[MAXPATHLEN]; fpath = GetStringEntry(fdata->file_path); sprintf(fullname, "%s%s", fpath, string); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); SetCurrentWindow(fdata->freq_window); CloseWindow(); return; } /* * This function is just a wrapper for mystrcmp(), and is called by qsort() * (if used) down below. */ static int mystrcmp(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } libsx-2.05/freq/freq.h0000644000175000017500000000004111252443541015752 0ustar amckinstryamckinstrychar *SimpleGetFile(char *path); libsx-2.05/freq/makefile0000644000175000017500000000055611252443541016357 0ustar amckinstryamckinstry# # include ../libsx_defs FREQ_OBJS = freq.o dirlist.o OBJS = main.o libfreq.a all : libfreq.a freq libfreq.a : $(FREQ_OBJS) rm -f libfreq.a ar rc libfreq.a $(FREQ_OBJS) $(RANLIB) libfreq.a freq : $(OBJS) $(CC) -o $@ $(OBJS) $(LIBS) main.o : main.c libsx.h freq.h freq.o : freq.c dirlist.o : dirlist.c clean: rm -f *.o *~ core freq libfreq.a libsx-2.05/freq/libsx.h0000777000175000017500000000000011252443766020445 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/frac/0000755000175000017500000000000011252443541014627 5ustar amckinstryamckinstrylibsx-2.05/frac/frac.c0000644000175000017500000001016111252443541015705 0ustar amckinstryamckinstry/* this program draw 2-d fractal mountains. It generates them using * a random midpoint displacement algorithim. * * it generates several screenfulls of mountains and scrolls them to try * and be interesting. * * This code is pretty mungy, but works * d.b.g. late summer 1990 * dbg@sgi.com */ #include #include #include #include #include #include "libsx.h" /* * Unfortunately some machines like Sun's don't have RAND_MAX defined * where it should be (can you say "Please be ANSI compliant?"), so * we will #define it if it isn't. */ #ifndef RAND_MAX #define RAND_MAX 0x7fff #endif /* forward declaration */ int fracline(int a, int b); void quit(Widget w, void *junk); void anim(Widget w, void *data); void draw_stuff(Widget w, int width, int height, void *junk); void set_scroll_val(Widget w, float val, void *junk); void set_timeout_val(Widget w, float val, void *junk); int max_random = RAND_MAX; #define MAX 2048 int line[MAX]; /* this is our global fractal "line" */ double rug = 0.6; /* ruggedness factor of the "terrain" */ int width,height,where; int scroll_amount=8; int timeout=250; int remove_timeout=FALSE; main(int argc, char **argv) { int a, b; Widget w[10]; if (OpenDisplay(argc, argv) == 0) exit(0); w[0] = MakeButton("Quit", quit, NULL); w[1] = MakeDrawArea(500, 500, draw_stuff, NULL); w[2] = MakeButton(" Animate ", anim, NULL); w[3] = MakeHorizScrollbar(100, set_scroll_val, NULL); w[4] = MakeHorizScrollbar(150,set_timeout_val,NULL); w[5] = MakeLabel("Scroll Amount:"); w[6] = MakeLabel("Timeout Val:"); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[5], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[5], NO_CARE, NULL); SetWidgetPos(w[6], PLACE_RIGHT, w[3], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_RIGHT, w[6], NO_CARE, NULL); SetScrollbar(w[3], (float)scroll_amount, 32.0, 1.0); SetScrollbar(w[4], (float)timeout, 500.0, 10.0); ShowDisplay(); GetStandardColors(); /* initialize */ srand((getpid()*time(NULL)) | 0x01); a = 0; b = MAX - 1; line[a] = line[b] = (rand() % 200) + 100; fracline(a, b); /* actually generate the fractal line. */ MainLoop(); } /* end of main */ void quit(Widget w, void *junk) { exit(0); } void set_scroll_val(Widget w, float val, void *junk) { scroll_amount = (int)val + 1; } void set_timeout_val(Widget w, float val, void *junk) { timeout = (int)val; } void draw_stuff(Widget w, int nwidth, int nheight, void *junk) { int i,x; width = nwidth; height = nheight; ClearDrawArea(); SetColor(BLACK); for(i=1; i < width; i++) DrawLine(i-1, line[i-1], i, line[i]); where = i; } /* void do_anim(void *data, XtIntervalId *foo) */ void do_anim(void *data) { int i; ScrollDrawArea(scroll_amount, 0, 0,0, width, height); SetColor(BLACK); for(i=0; i < scroll_amount; i++) { DrawLine(width-scroll_amount+i-1, line[(where+i-1)%MAX], width-scroll_amount+i, line[(where+i) %MAX]); } where += i; if (remove_timeout == FALSE) AddTimeOut(timeout, do_anim, NULL); else remove_timeout = FALSE; } void anim(Widget w, void *data) { static int toggle=0; toggle ^= 1; if (toggle) { SetLabel(w, "Stop Anim"); AddTimeOut(timeout, do_anim, NULL); } else { remove_timeout = TRUE; SetLabel(w, " Animate "); } } /* This is the "random midpoint displacement algorithim" It hasn't been * optimized, and I don't know why I used all the temporary variables.... */ fracline(int a, int b) { int mid; double temp, temp1, temp2; if ( (b - a) > 1){ mid = (a + b) / 2; temp1 = (line[a] + line[b])/2; temp = (double)(b - a); temp2 = (double)rand() / (double)max_random; temp2 = (temp2 * 2.0) - 1.0; line[mid] = (int)(temp1 + (temp2 * temp * rug)); if (line[mid] < 0) line[mid] = 0; else if (line[mid] > 500) line[mid] = 500; fracline(a, mid); fracline(mid, b); } } libsx-2.05/frac/makefile0000644000175000017500000000015011252443541016323 0ustar amckinstryamckinstry# # include ../libsx_defs frac : frac.o $(CC) -o frac frac.o $(LIBS) clean : rm -f *.o *~ core frac libsx-2.05/frac/libsx.h0000777000175000017500000000000011252443766020423 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/src/0000755000175000017500000000000011252443541014503 5ustar amckinstryamckinstrylibsx-2.05/src/colormap.c0000644000175000017500000003263111252443541016470 0ustar amckinstryamckinstry/* This file contains routines to manage colormaps. I've written all * of it except for the routines that generate the colormap data. That * was taken from some code by Jeff LeBlanc who took it from some other * nameless soul. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* internal prototypes */ static void grey_scale_plus(int ncells); static void grey_scale(int ncells); static void g_opt_2(int ncells); static void b_opt_2(int ncells); int WHITE = 0, /* Global indicies into the color map */ BLACK = 0, RED = 0, GREEN = 0, BLUE = 0, YELLOW = 0, HILIGHT= -1, BUTTONBG= -1, INPUTBG= -1; static XColor col[256]; static int ncells; /* number of color cells available */ #define X_MAX_COLOR 65535 /* static void get_color(Colormap cmap, char *name, int *var) */ void get_color(Colormap cmap, char *name, int *var) { XColor exact, pixel_color; if (XAllocNamedColor(lsx_curwin->display, cmap, name, &exact, &pixel_color)) { *var = pixel_color.pixel; lsx_curwin->named_colors[lsx_curwin->color_index++] = pixel_color.pixel; } } void GetStandardColors(void) { Colormap mycmap; if (lsx_curwin->display == NULL || lsx_curwin->has_standard_colors) return; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; get_color(mycmap, "black", &BLACK); get_color(mycmap, "white", &WHITE); get_color(mycmap, "red", &RED); get_color(mycmap, "green", &GREEN); get_color(mycmap, "blue", &BLUE); get_color(mycmap, "yellow",&YELLOW); lsx_curwin->has_standard_colors = TRUE; } int GetNamedColor(char *name) { Colormap mycmap; XColor exact, pixel_color; if (lsx_curwin->display == NULL) return -1; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; if (XAllocNamedColor(lsx_curwin->display, mycmap, name,&exact,&pixel_color)) { lsx_curwin->named_colors[lsx_curwin->color_index++] = pixel_color.pixel; return pixel_color.pixel; } else return -1; } int GetRGBColor(int r, int g, int b) { Colormap mycmap; XColor color; if (lsx_curwin->display == NULL) return -1; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; color.flags = DoRed | DoGreen | DoBlue; color.red = (unsigned short) ((r * X_MAX_COLOR) / 256); color.green = (unsigned short) ((g * X_MAX_COLOR) / 256); color.blue = (unsigned short) ((b * X_MAX_COLOR) / 256); if (XAllocColor(lsx_curwin->display, mycmap, &color)) { lsx_curwin->named_colors[lsx_curwin->color_index++] = color.pixel; return color.pixel; } else return -1; } void FreeStandardColors(void) { int i; Colormap mycmap; if (lsx_curwin->display == NULL) return; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; for(i=0; i < lsx_curwin->color_index; i++) XFreeColors(lsx_curwin->display, mycmap, (unsigned long *)&lsx_curwin->named_colors[i], 1, 0); lsx_curwin->color_index = 0; } int GetAllColors(void) { int i; int mydepth; Visual *xv; Window win; if (lsx_curwin->display == NULL) return FALSE; if (lsx_curwin->cmap) /* because we already have a custom cmap */ return TRUE; ncells = 256; mydepth = XDefaultDepth(lsx_curwin->display, lsx_curwin->screen); if (mydepth < 2) return FALSE; /* setup for colormap stuff */ xv = DefaultVisual(lsx_curwin->display, lsx_curwin->screen); lsx_curwin->cmap = XCreateColormap(lsx_curwin->display, lsx_curwin->window, xv,AllocAll); if (lsx_curwin->cmap == None) return FALSE; for (i=0; i < ncells; i++) { col[i].pixel = i; col[i].red = col[i].green = col[i].blue = 0; /* all black by default */ col[i].flags = DoRed | DoGreen | DoBlue; } /* * Supposedly this is the correct thing to do when setting a colormap. * * That is, it sets the window colormap for the top-level shell widget * then it calls XSetWMColormapWindows() for the top-level shell widget * and the drawing area widget. * * For kicks we also call XChangeWindowAttributes() because it seems * like it might be a good thing to do (isn't it fun when there's 5 or * 6 ways to do the same thing?). Remember that in X, form follows * malfunction. * * Unfortunately, the correct thing to do isn't always what works. * The code in the #ifdef section breaks twm rather horribly. What * seems to happen is that when I call XSetWMColormapWindows() with * more than one id (in the same call or split across multiple calls) * and one of those window id's is a child of another, then twm dies. * On an SGI & DECstation twm gets a seg fault and dies (every single * time). * * So in summary, it seems that just calling XSetWindowColormap() * for the top-level shell widget and the drawing widget is what * works the most reliably across the widest number of systems and * window managers. * * I have personally seen this code work properly on a Sparc 10 * w/OpenWindows version 3, a Solbourne running OpenWindows v2.0, * a whole schwack of SGI workstations running various versions of * IRIX and several different graphics systems (Elan, XS24, Reality * Engine, VGX, GT, and Entry Level graphics on Indigo). It also * worked on a DECstation 3100 w/twm and dxwm. I've also tested * this with mwm and 4Dwm on the SGI's. Another window manager, * ctwm also seems to work. That's a pretty wide range of platforms * (though HP is notably absent from the list and it probably doesn't * work there since I'm sure they're different than everyone else :^). */ win = lsx_curwin->window; XSetWindowColormap(lsx_curwin->display, win, lsx_curwin->cmap); if (lsx_curwin->last_draw_widget) { win = XtWindow(lsx_curwin->last_draw_widget); XSetWindowColormap(lsx_curwin->display, win, lsx_curwin->cmap); } #ifdef NO_BROKEN_WINDOW_MANAGERS winattr.colormap = lsx_curwin->cmap; XChangeWindowAttributes(lsx_curwin->display, win, CWColormap, &winattr); i = 0; win_ids[i] = lsx_curwin->window; if (lsx_curwin->last_draw_widget) { i++ win_ids[i] = XtWindow(lsx_curwin->last_draw_widget); } XSetWMColormapWindows(lsx_curwin->display, lsx_curwin->window, win_ids, i); #endif return TRUE; } void FreeAllColors(void) { if (lsx_curwin->display == NULL) return; if (lsx_curwin->cmap == None) /* woops, don't have a cmap to free */ return; XFreeColormap(lsx_curwin->display, lsx_curwin->cmap); lsx_curwin->cmap = None; } void SetMyColorMap(int n, unsigned char *r, unsigned char *g, unsigned char *b) { int i; if (lsx_curwin->display == NULL || n < 0 || n > 256) return; if (lsx_curwin->cmap == None) if (GetAllColors() == FALSE) return; for(i=0; i < n; i++) { col[i].flags = DoRed | DoGreen | DoBlue; col[i].red = (unsigned short)(r[i] * X_MAX_COLOR / 256); col[i].green = (unsigned short)(g[i] * X_MAX_COLOR / 256); col[i].blue = (unsigned short)(b[i] * X_MAX_COLOR / 256); } XStoreColors(lsx_curwin->display, lsx_curwin->cmap, col, n); } void SetColorMap(int num) { if (lsx_curwin->display == NULL) return; if (lsx_curwin->cmap == None) if (GetAllColors() == FALSE) return; switch (num) { case 0: grey_scale_plus(ncells); break; case 1: grey_scale(ncells); break; case 2: g_opt_2(ncells); break; case 3: b_opt_2(ncells); break; default: grey_scale_plus(ncells); break; } XStoreColors(lsx_curwin->display, lsx_curwin->cmap, col, ncells); } int GetPrivateColor(void) { Colormap mycmap; unsigned long pixels[1], plane_masks[1]; int result; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; result = XAllocColorCells(lsx_curwin->display, mycmap, FALSE, &plane_masks[0], 0, &pixels[0], 1); if (result != 0) return pixels[0]; else return -1; } void SetPrivateColor(int which, int r, int g, int b) { Colormap mycmap; XColor pcol; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; pcol.pixel = which; pcol.flags = DoRed|DoGreen|DoBlue; pcol.red = (short)(r * X_MAX_COLOR / 256); pcol.green = (short)(g * X_MAX_COLOR / 256); pcol.blue = (short)(b * X_MAX_COLOR / 256); pcol.pad = 0; XStoreColor(lsx_curwin->display, mycmap, &pcol); } void FreePrivateColor(int which) { Colormap mycmap; unsigned long pixels[1]; pixels[0] = which; if (lsx_curwin->cmap == None) mycmap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); else mycmap = lsx_curwin->cmap; XFreeColors(lsx_curwin->display, mycmap, &pixels[0], 1, 0); } /*****************************************************************************/ static void grey_scale_plus(int ncells) { int i; int num; num = ncells - 4; /* gray scale */ for(i = 0; i < num; i++) { col[i].flags = DoRed | DoGreen | DoBlue; col[i].red = (unsigned short)(i * X_MAX_COLOR / num); col[i].green = (unsigned short)(i * X_MAX_COLOR / num); col[i].blue = (unsigned short)(i * X_MAX_COLOR / num); } /* plus */ /* yellow */ col[num].flags = DoRed | DoGreen | DoBlue; col[num].red = (unsigned short)(X_MAX_COLOR); col[num].green = (unsigned short)(X_MAX_COLOR); col[num].blue = (unsigned short)(0); /* red */ col[num+1].flags = DoRed | DoGreen | DoBlue; col[num+1].red = (unsigned short)(X_MAX_COLOR); col[num+1].green = (unsigned short)(0); col[num+1].blue = (unsigned short)(0); /* blue */ col[num+2].flags = DoRed | DoGreen | DoBlue; col[num+2].red = (unsigned short)(0); col[num+2].green = (unsigned short)(X_MAX_COLOR); col[num+2].blue = (unsigned short)(0); /* green */ col[num+3].flags = DoRed | DoGreen | DoBlue; col[num+3].red = (unsigned short)(0); col[num+3].green = (unsigned short)(0); col[num+3].blue = (unsigned short)(X_MAX_COLOR); BLACK = col[0].pixel; WHITE = col[num-1].pixel; YELLOW = col[num].pixel; RED = col[num+1].pixel; BLUE = col[num+2].pixel; GREEN = col[num+3].pixel; } /*****************************************************************************/ static void grey_scale(int ncells) { int i; /* gray scale */ for(i = 0; i < ncells ; i++) { col[i].flags = DoRed | DoGreen | DoBlue; col[i].red = (unsigned short)(i * X_MAX_COLOR / ncells); col[i].green = (unsigned short)(i * X_MAX_COLOR / ncells); col[i].blue = (unsigned short)(i * X_MAX_COLOR / ncells); } WHITE = col[ncells-1].pixel; BLACK = col[0].pixel; RED = BLACK; GREEN = BLACK; BLUE = BLACK; YELLOW = BLACK; } /*****************************************************************************/ static void g_opt_2(int ncells) { int i; float con; float x,tmp; con = 1.0 / ( (1-0.3455)*(1-0.3455) * (1-0.90453)*(1-0.90453) ); for(i = 0; i < ncells ; i++) { col[i].flags = DoRed | DoGreen | DoBlue; /* ramp on red */ col[i].red = (unsigned short)(i * X_MAX_COLOR / ncells); x = (float)(i)/(float)(ncells); /* double hump on green */ tmp = con*x*(x - 0.3455)*(x - 0.3455)*(x - 0.90453)*(x - 0.90453); if (tmp > 1.0) tmp = 1.0; if (tmp < 0.0) tmp = 0.0; col[i].green = (unsigned short)((int)((float)(X_MAX_COLOR) * tmp)); /* single hump on blue */ tmp = x*(4*x - 3)*(4*x - 3); if (tmp > 1.0) tmp = 1.0; if (tmp < 0.0) tmp = 0.0; col[i].blue = (unsigned short)((int)((float)(X_MAX_COLOR) * tmp)); } WHITE = 0; BLACK = 256 - ncells; RED = BLACK; GREEN = BLACK; BLUE = BLACK; YELLOW = WHITE; } /*****************************************************************************/ static void b_opt_2(int ncells) { int i; float con; float x,tmp; con = 1.0 / ( (1-0.3455)*(1-0.3455) * (1-0.90453)*(1-0.90453) ); for(i = 0; i < ncells ; i++) { col[i].flags = DoRed | DoGreen | DoBlue; /* ramp on red */ col[i].red = (unsigned short)(i * X_MAX_COLOR / ncells); x = (float)(i)/(float)(ncells); /* single hump on green */ tmp = x*(4*x - 3)*(4*x - 3); if (tmp > 1.0) tmp = 1.0; if (tmp < 0.0) tmp = 0.0; col[i].green = (unsigned short)((int)((float)(X_MAX_COLOR) * tmp)); /* double hump on blue */ tmp = con*x*(x - 0.3455)*(x - 0.3455)*(x - 0.90453)*(x - 0.90453); if (tmp > 1.0) tmp = 1.0; if (tmp < 0.0) tmp = 0.0; col[i].blue = (unsigned short)((int)((float)(X_MAX_COLOR) * tmp)); } WHITE = 0; BLACK = 256 - ncells; RED = BLACK; GREEN = BLACK; BLUE = BLACK; YELLOW = WHITE; } /*****************************************************************************/ libsx-2.05/src/popups.c0000644000175000017500000000752111252443541016202 0ustar amckinstryamckinstry/* This file contains routines that handle popping up dialog boxes. * They use the routines in Dialog.c to do most of the work. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "dialog.h" #include "libsx.h" #include "libsx_private.h" static int do_popup(char *blurb, int buttons); extern XtAppContext lsx_app_con; /* * User input routines that take place through Dialog boxes (getting * a string and a simple yes/no answer). */ char *GetString(char *blurb, char *default_string) { char *string = default_string; Dialog dialog = NULL; if (blurb == NULL || (lsx_curwin->toplevel==NULL && OpenDisplay(0,NULL)==0)) return NULL; dialog = CreateDialog(lsx_curwin->toplevel, "InputString", Okay | Cancel); if (dialog == NULL) /* then there's an error */ return NULL; if (string == NULL) string = ""; switch(PopupDialog(lsx_app_con, dialog, blurb, string, &string, XtGrabExclusive)) { case Yes: case Okay: /* don't have to do anything, string is already set */ break; case Cancel: string = NULL; break; default: string = NULL; /* shouldn't happen, but just in case */ break; } /* end of switch */ FreeDialog(dialog); return string; } char *GetText(char *blurb, char *default_string, int width, int height) { Widget wid_gettext[6]; char *string; int i; void GetTextCancel(Widget ww, void* data) { string = NULL; SetCurrentWindow(ww); CloseWindow(); } void GetTextOkay(Widget ww, void* data) { char *ptr; ptr = GetStringEntry(wid_gettext[1]); if (ptr!=NULL) { string = (char *)malloc((strlen(ptr)+1)*sizeof(char)); strcpy(string, ptr); } SetCurrentWindow(ww); CloseWindow(); } MakeWindow("GetText",SAME_DISPLAY, EXCLUSIVE_WINDOW); string = NULL; wid_gettext[0] = MakeLabel(blurb); if(height>0) wid_gettext[1] = MakeTextWidget(default_string,0,1, width, height); else wid_gettext[1] = MakeStringEntry(default_string,width, NULL, NULL); SetWidgetPos(wid_gettext[1],PLACE_UNDER,wid_gettext[0],NO_CARE,NULL); wid_gettext[2] = MakeButton(SX_Dialog[POPUP_DIAL],GetTextOkay,NULL); wid_gettext[3] = MakeButton(SX_Dialog[POPUP_DIAL+1],GetTextCancel,NULL); for (i=2; i<=3 ; i++) SetWidgetPos(wid_gettext[i],PLACE_UNDER,wid_gettext[1],NO_CARE,NULL); SetWidgetPos(wid_gettext[3],PLACE_RIGHT,wid_gettext[2],NO_CARE,NULL); ShowDisplay(); if(INPUTBG>=0) SetBgColor(wid_gettext[1],INPUTBG); if(BUTTONBG>=0) for (i=2; i<=3 ; i++) SetBgColor(wid_gettext[i],BUTTONBG); MainLoop(); return string; } char *GetLongString(char *blurb, char *default_string, int width) { return GetText(blurb, default_string, width, 0); } int GetYesNo(char *blurb) { return do_popup(blurb, Yes|No); } int GetOkay(char *blurb) { return do_popup(blurb, Okay); } int GetTriState(char *blurb) { return do_popup(blurb, Yes|Abort|No); } static int do_popup(char *blurb, int buttons) { Dialog dialog = NULL; int ret; if (blurb == NULL || (lsx_curwin->toplevel==NULL && OpenDisplay(0,NULL)==0)) return FALSE; dialog = CreateDialog(lsx_curwin->toplevel,SX_Dialog[POPUP_DIAL+2],buttons); if (dialog == NULL) /* then there's an error */ return FALSE; switch(PopupDialog(lsx_app_con, dialog, blurb, NULL, NULL, XtGrabExclusive)) { case Okay: case Yes: ret = TRUE; break; case No: ret = FALSE; break; case Abort: ret = -1; break; default: ret = FALSE; /* unknown return from dialog, return an err */ break; } /* end of switch */ FreeDialog(dialog); return ret; } libsx-2.05/src/drawing.h0000644000175000017500000000327511252443541016316 0ustar amckinstryamckinstry/* DrawingA.h - Public Header file */ /* Copyright 1990, David Nedde * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ /* Define widget's class pointer and strings used to specify resources */ #ifndef _XawDrawingArea_h #define _XawDrawingArea_h #define XADCS XawDrawingAreaCallbackStruct /* Resources ADDED to label widget: Name Class RepType Default Value ---- ----- ------- ------------- exposeCallback Callback Pointer NULL inputCallback Callback Pointer NULL motionCallback Callback Pointer NULL resizeCallback Callback Pointer NULL enterCallback Callback Pointer NULL leaveCallback Callback Pointer NULL */ extern WidgetClass drawingAreaWidgetClass; typedef struct _DrawingAreaClassRec *DrawingAreaWidgetClass; typedef struct _DrawingAreaRec *DrawingAreaWidget; /* Resource strings */ #ifndef XtNvisual #define XtNvisual "visual" #endif #define XtNexposeCallback "exposeCallback" #define XtNinputCallback "inputCallback" #define XtNmotionCallback "motionCallback" #define XtNresizeCallback "resizeCallback" #define XtNenterCallback "enterCallback" #define XtNleaveCallback "leaveCallback" typedef struct _XawDrawingAreaCallbackStruct { int reason; XEvent *event; Window window; } XawDrawingAreaCallbackStruct; /* Reasons */ #define XawCR_EXPOSE 1 #define XawCR_INPUT 2 #define XawCR_MOTION 3 #define XawCR_RESIZE 4 #define XawCR_ENTER 5 #define XawCR_LEAVE 6 #endif /* _XawDrawingArea_h */ libsx-2.05/src/libsx.c0000644000175000017500000004222111252443541015771 0ustar amckinstryamckinstry/* This file contains the top level routines that manipulate whole * windows and what not. It's the main initialization stuff, etc. * * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" /* * Libsx Dialogs */ char *SX_Dialog[NUM_DIAL]; /* * Predefined Args; */ static char *_PredefArgs[] = { NULL } ; char **PredefArgs = _PredefArgs ; /* * External prototypes. */ extern void PositionPopup(Widget w); /* from Dialog.c */ extern void libsx_set_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms);/* from string_entry.c */ extern void libsx_set_text_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms); extern void libsx_done_with_text(Widget w, XEvent *xev, String *parms, Cardinal *num_parms);/* from string_entry.c */ /* internal protos */ static Bool is_expose_event(Display *d, XEvent *xev, char *blorg); /* * Private static variables. */ static WindowState *lsx_windows = NULL, empty_window = { 0, 0, 0, NULL, NULL, NULL, NULL, 0,}, *orig_window = NULL; static int window_opened=0; static char *app_name=""; static Display *base_display=NULL; char _FreqFilter[80] = "*"; /* * Global Variables for all of libsx (but not for user applications). * * We initialize lsx_curwin to point to the static empty_window so that * if other functions get called before OpenDisplay(), they won't core * dump, and will fail gracefully instead. */ volatile WindowState *lsx_curwin = &empty_window; XtAppContext lsx_app_con; Widget w_prev = 0, win_prev = 0; int color_prev = -1; static String fallback_resources[] = { "*font: 7x13", "*vertical*borderWidth: 0", "*horizontal*borderWidth: 0", "*vertical*shadowWidth: 1", "*horizontal*shadowWidth: 1", "*valueBar*shadowWidth: 1", "*scrollbar*shadowWidth: 1", "*Text*shadowWidth: 1", "*SimpleMenu.shadowWidth: 1", "*SimpleMenu*SmeBSB*shadowWidth: 0", "*Dialog*label.resizable: True", "*Dialog*Text.resizable: True", "*Dialog.Text.translations: #override Return: set-okay()\\n\ Linefeed: set-okay()", NULL }; /* * Read dialogs as needed by environment variable LANG */ void ReadLocale(char *language) { char locale_file[128]; char line[128]; char *ptr; FILE *fd; int i, j; if (language==NULL) language=getenv("LANG"); if (language==NULL) language="en"; sprintf(locale_file, SX_SHAREDIR"/dialogs.%c%c", language[0], language[1]); fd = fopen(locale_file, "r"); if (fd==NULL) strcpy(locale_file, SX_SHAREDIR"/dialogs.en"), fd = fopen(locale_file, "r"); if (fd==NULL) fprintf(stderr, "Cannot open dialogs %s !!", locale_file); else { i=0; while((ptr=fgets(line,120,fd))!=NULL) { j=strlen(line)-1; if (line[j]=='\n') line[j]='\0'; if (itoplevel = XtAppInitialize(&lsx_app_con, argv[0], NULL, 0, &argc, new_argv, fallback_resources, wargs, arg_cnt); if (*PredefArgs) for (i=1; i<=argc; i++) argv[i] = new_argv[i]; } else lsx_curwin->toplevel = XtAppCreateShell (argv[0], argv[0], applicationShellWidgetClass, dpy, wargs, arg_cnt); if (lsx_curwin->toplevel == NULL) { free((void *)lsx_curwin); return FALSE; } app_name = argv[0]; /* save this for later */ lsx_curwin->form_widget = XtCreateManagedWidget("form", formWidgetClass, lsx_curwin->toplevel,NULL,0); if (lsx_curwin->form_widget == NULL) { XtDestroyWidget(lsx_curwin->toplevel); free((void *)lsx_curwin); lsx_curwin = &empty_window; return FALSE; } lsx_curwin->toplevel_form = lsx_curwin->form_widget; lsx_curwin->next = lsx_windows; /* link it in to the list */ lsx_windows = (WindowState *)lsx_curwin; /* save these values for later */ lsx_curwin->display = (Display *)XtDisplay(lsx_curwin->toplevel); lsx_curwin->screen = DefaultScreen(lsx_curwin->display); orig_window = (WindowState *)lsx_curwin; base_display = lsx_curwin->display; window_opened = 1; return argc; } /* end of _OpenDisplay() */ int OpenDisplay(int argc, char **argv) { return _OpenDisplay(argc, argv, NULL, NULL, 0); } #ifdef OPENGL_SUPPORT int OpenGLDisplay(int argc, char **argv, int *attributes) { int xargc, i, retval, count, tmp_depth; char **new_argv, **xargv; Display *dpy; XVisualInfo *xvi; GLXContext cx; XVisualInfo vinfo; XVisualInfo *vinfo_list; /* returned list of visuals */ Colormap colormap; /* created colormap */ Widget top; extern char *strdup(char *str); /* Parse additional predefined args */ if (PredefArgs) { int i = 0, j; while (PredefArgs[i]!=NULL) ++i; new_argv = (char**) malloc((argc+i+1)*sizeof(char *)); new_argv[0] = argv[0]; i = 0; while (PredefArgs[i]!=NULL) { new_argv[i+1] = PredefArgs[i]; ++i; } for (j=1; j<=argc; j++) new_argv[i+j] = argv[j]; argc += i; argv = new_argv; } /* * First we copy the command line arguments */ xargc = argc; xargv = (char **)malloc(argc * sizeof (char *)); for(i=0; i < xargc; i++) xargv[i] = strdup(argv[i]); /* * The following creates a _dummy_ toplevel widget so we can * retrieve the appropriate visual resource. */ top = XtAppInitialize(&lsx_app_con, xargv[0], NULL, 0, &xargc, xargv, (String *)NULL, NULL, 0); if (top == NULL) return 0; dpy = XtDisplay(top); /* * Check if the server supports GLX. If not, crap out. */ if (glXQueryExtension(dpy, NULL, NULL) == GL_FALSE) { XtDestroyWidget(top); return FALSE; } xvi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes); if (xvi == NULL) { XtDestroyWidget(top); return 0; } cx = glXCreateContext(dpy, xvi, 0, GL_TRUE); if (cx == NULL) { XtDestroyWidget(top); return 0; } /* * Now we create an appropriate colormap. We could * use a default colormap based on the class of the * visual; we could examine some property on the * rootwindow to find the right colormap; we could * do all sorts of things... */ colormap = XCreateColormap (dpy, RootWindowOfScreen(XtScreen (top)), xvi->visual, AllocNone); /* * Now find some information about the visual. */ vinfo.visualid = XVisualIDFromVisual(xvi->visual); vinfo_list = XGetVisualInfo(dpy, VisualIDMask, &vinfo, &count); if (vinfo_list && count > 0) { tmp_depth = vinfo_list[0].depth; XFree((XPointer) vinfo_list); } XtDestroyWidget(top); /* * Free up the copied version of the command line arguments */ for(i=0; i < xargc; i++) if (xargv[i]) free(xargv[i]); free(xargv); retval = _OpenDisplay(argc, argv, dpy, NULL, 0); if (retval > 0) { lsx_curwin->xvi = xvi; lsx_curwin->gl_context = cx; lsx_curwin->draw_area_cmap = colormap; lsx_curwin->draw_area_depth = tmp_depth; } return retval; } #endif /* OPENGL_SUPPORT */ void CloseProcedure(Widget w) { volatile WindowState *worig; SetCurrentWindow(ORIGINAL_WINDOW); worig = lsx_curwin; SetCurrentWindow(w); if (lsx_curwin->window == worig->window && lsx_curwin->display == worig->display) exit(0); CloseWindow(); } static XtActionsRec close_action[] = { /* action_name routine */ { "Quit", (XtActionProc)CloseProcedure }, /* quit application */ }; void ShowDisplay(void) { XEvent xev; Display *display; static Atom wm_delete_window; XWMHints *hints; if (lsx_curwin->toplevel == NULL || lsx_curwin->window_shown == TRUE) return; XtRealizeWidget(lsx_curwin->toplevel); display = XtDisplay(lsx_curwin->toplevel); XtAppAddActions(lsx_app_con, close_action, XtNumber(close_action)); XtOverrideTranslations(lsx_curwin->toplevel, XtParseTranslationTable("WM_PROTOCOLS:Quit()") ); wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); (void) XSetWMProtocols(display, XtWindow(lsx_curwin->toplevel), &wm_delete_window, 1); hints = XGetWMHints(display, XtWindow(lsx_curwin->toplevel)); hints->flags=AllHints; hints->input=True; XSetWMHints(display, XtWindow(lsx_curwin->toplevel), hints); if (XtIsTransientShell(lsx_curwin->toplevel)) /* do popups differently */ { PositionPopup(lsx_curwin->toplevel); XtPopup(lsx_curwin->toplevel, XtGrabExclusive); lsx_curwin->window = (Window )XtWindow(lsx_curwin->toplevel); lsx_curwin->window_shown = TRUE; return; } /* * wait until the window is _really_ on screen */ while(!XtIsRealized(lsx_curwin->toplevel)) ; /* * Now make sure it is really on the screen. */ XPeekIfEvent(XtDisplay(lsx_curwin->toplevel), &xev, is_expose_event, NULL); SetDrawArea(lsx_curwin->last_draw_widget); lsx_curwin->window = (Window )XtWindow(lsx_curwin->toplevel); lsx_curwin->window_shown = TRUE; } /* end of ShowDisplay() */ static Bool is_expose_event(Display *d, XEvent *xev, char *blorg) { if (xev->type == Expose) return TRUE; else return FALSE; } static int libsx_exit_main_loop=0; void ExitMainLoop(void) { libsx_exit_main_loop = 1; } void MainLoop(void) { int transient; WindowState *curwin; if (lsx_curwin->toplevel == NULL) return; /* in case the user forgot to map the display, do it for them */ if (lsx_curwin->window_shown == FALSE) { ShowDisplay(); GetStandardColors(); } curwin = (WindowState *)lsx_curwin; transient = XtIsTransientShell(lsx_curwin->toplevel); while (lsx_curwin != &empty_window && libsx_exit_main_loop == 0) { XEvent event; XtAppNextEvent(lsx_app_con, &event); XtDispatchEvent(&event); if (curwin != lsx_curwin) /* hmmm, something changed... */ { if (transient) /* just break out for transient windows */ break; curwin = (WindowState *)lsx_curwin; } } if (libsx_exit_main_loop) /* if this was set, reset it back */ libsx_exit_main_loop = 0; return; } void CheckForEvent(void) { XEvent event; if (XtAppPending(lsx_app_con) == 0) return; XtAppNextEvent(lsx_app_con, &event); XtDispatchEvent(&event); } void SyncDisplay(void) { if (lsx_curwin->display) XSync(lsx_curwin->display, FALSE); } void AddTimeOut(unsigned long interval, void (*func)(), void *data) { if (lsx_curwin->toplevel && func) XtAppAddTimeOut(lsx_app_con, interval, (XtTimerCallbackProc)func, data); } void AddReadCallback(int fd, IOCallback func, void *data) { XtInputMask mask = XtInputReadMask; XtAppAddInput(lsx_app_con, fd, (XtPointer)mask, (XtInputCallbackProc)func, data); } void AddWriteCallback(int fd, IOCallback func, void *data) { XtInputMask mask = XtInputWriteMask; XtAppAddInput(lsx_app_con, fd, (XtPointer)mask, (XtInputCallbackProc)func, data); } Widget MakeWindow(char *window_name, char *display_name, int exclusive) { WindowState *win=NULL; Display *d=NULL; Arg wargs[20]; int n=0; Visual *vis; Colormap cmap; char *argv[5]; int argc; if (window_opened == 0) /* must call OpenDisplay() for first window */ return NULL; win = (WindowState *)calloc(sizeof(WindowState), 1); if (win == NULL) return NULL; /* * Setup a phony argv/argc to appease XtOpenDisplay(). */ if (window_name) argv[0] = window_name; else argv[0] = app_name; argv[1] = NULL; argc = 1; if (display_name != NULL) d = XtOpenDisplay(lsx_app_con, display_name, app_name, app_name, NULL, 0, &argc, argv); else d = base_display; if (d == NULL) { free(win); return NULL; } win->display = d; cmap = DefaultColormap(d, DefaultScreen(d)); vis = DefaultVisual(d, DefaultScreen(d)); n=0; XtSetArg(wargs[n], XtNtitle, window_name); n++; XtSetArg(wargs[n], XtNiconName, window_name); n++; XtSetArg(wargs[n], XtNcolormap, cmap); n++; XtSetArg(wargs[n], XtNvisual, vis); n++; if (HILIGHT>=0 && w_prev != 0 && lsx_curwin->toplevel == win_prev ) { SetFgColor(w_prev, color_prev); w_prev=0; } if (exclusive == FALSE) { win->toplevel = XtAppCreateShell(argv[0], app_name, topLevelShellWidgetClass, d, wargs, n); } else { win->toplevel = XtCreatePopupShell(argv[0], transientShellWidgetClass, lsx_curwin->toplevel, NULL, 0); } if (win->toplevel == NULL) { if (d != base_display) XtCloseDisplay(d); free(win); return NULL; } win->form_widget = XtCreateManagedWidget("form", formWidgetClass, win->toplevel, NULL, 0); if (win->form_widget == NULL) { XtDestroyWidget(win->toplevel); if (d != base_display) XtCloseDisplay(d); free(win); return NULL; } win->toplevel_form = win->form_widget; win->screen = DefaultScreen(win->display); /* * Now link in the new window into the window list and make it * the current window. */ win->next = lsx_windows; lsx_windows = win; lsx_curwin = win; return win->toplevel; /* return a handle to the user */ } Widget GetTopWidget(Widget w) { return XtParent(XtParent(w)); } Widget MakeForm(Widget parent) { int n; Arg wargs[5]; Widget form; if (lsx_curwin->toplevel == NULL) return NULL; if (parent == TOP_LEVEL_FORM) parent = lsx_curwin->toplevel_form; else if (strcmp(XtName(parent), "form") != 0) /* parent not a form widget */ return NULL; n=0; XtSetArg(wargs[n], XtNwidth, 100); n++; XtSetArg(wargs[n], XtNheight, 100); n++; XtSetArg(wargs[n], XtNresizable, 1); n++; form = XtCreateManagedWidget("form", formWidgetClass, parent, wargs, n); if (form == NULL) return NULL; lsx_curwin->form_widget = form; return form; } void SetForm(Widget form) { if (lsx_curwin->toplevel == NULL) return; if (form == TOP_LEVEL_FORM) lsx_curwin->form_widget = lsx_curwin->toplevel_form; else lsx_curwin->form_widget = form; } Widget GetForm(void) { if (lsx_curwin->toplevel == NULL) return NULL; return lsx_curwin->form_widget; } void SetCurrentWindow(Widget w) { WindowState *win; if (w == ORIGINAL_WINDOW) { if (orig_window) lsx_curwin = orig_window; else if (lsx_windows) /* hmm, don't have orig_window */ lsx_curwin = lsx_windows; else lsx_curwin = &empty_window; /* hmm, don't have anything left */ SetDrawArea(lsx_curwin->last_draw_widget); return; } for(win=lsx_windows; win; win=win->next) if (win->toplevel == w && win->display == XtDisplay(w)) break; if (win == NULL) return; lsx_curwin = win; SetDrawArea(lsx_curwin->last_draw_widget); } void CloseWindow(void) { WindowState *tmp; if (lsx_curwin->toplevel == NULL) return; XtDestroyWidget(lsx_curwin->toplevel); if (lsx_curwin->display != base_display) { FreeFont(lsx_curwin->font); XtCloseDisplay(lsx_curwin->display); } /* * if the window to delete is not at the head of the list, find * it in the list of available windows and delete it. */ if (lsx_curwin == lsx_windows) lsx_windows = lsx_curwin->next; else { for(tmp=lsx_windows; tmp && tmp->next != lsx_curwin; tmp=tmp->next) /* nothing */; if (tmp == NULL) /* didn't find it. must be bogus. just return */ return; tmp->next = lsx_curwin->next; } if (lsx_curwin == orig_window) orig_window = NULL; free((void *)lsx_curwin); if (lsx_windows == NULL) lsx_windows = &empty_window; lsx_curwin = (volatile WindowState *)lsx_windows; } void Beep(void) { XBell(lsx_curwin->display, 100); } libsx-2.05/src/drawingP.h0000644000175000017500000000303611252443541016431 0ustar amckinstryamckinstry/* DrawingArea Private header file */ /* Copyright 1990, David Nedde * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ #ifndef _XawDrawingAreaP_h #define _XawDrawingAreaP_h #include "drawing.h" #ifdef X11_R3 #include #else #include #endif /* The drawing area's contribution to the class record */ typedef struct _DrawingAreaClassPart { int ignore; } DrawingAreaClassPart; /* Drawing area's full class record */ typedef struct _DrawingAreaClassRec { CoreClassPart core_class; SimpleClassPart simple_class; DrawingAreaClassPart drawing_area; } DrawingAreaClassRec; extern DrawingAreaClassRec drawingAreaClassRec; #ifndef XtCVisual #define XtCVisual "Visual" #endif #ifndef XtRVisual #define XtRVisual "Visual" #endif /* Resources added and status of drawing area widget */ typedef struct _XsDrawingAreaPart { /* Resources */ Visual *vis; XtCallbackList expose_callback; XtCallbackList input_callback; XtCallbackList motion_callback; XtCallbackList resize_callback; XtCallbackList enter_callback; XtCallbackList leave_callback; } DrawingAreaPart; /* Drawing area's instance record */ typedef struct _DrawingAreaRec { CorePart core; SimplePart simple; DrawingAreaPart drawing_area; } DrawingAreaRec; #endif /* _XawDrawingAreaP_h */ libsx-2.05/src/dirlist.c0000644000175000017500000001135411252443541016325 0ustar amckinstryamckinstry/* * This file contains a function, get_dir_list() that will get a directory * listing and put all the names into a table (an array of char *'s table) * and return it to you (along with the number of entries in the directory * if desired). The table is NULL terminated (i.e. the entry after the last * one is a NULL), and is just like an argv style array. * * If an error occurs (memory allocation, bad directory name, etc), you * will get a NULL back. * * Each entry of the returned table points to a NULL-terminated string * that contains the name of a file in the directory. If the name is * a directory, it has a slash appended to it. * * When you are done with the table, you should free it manually, or you * can call the function free_table() provided down below. * * See the sample main() down below for how to use it. Ignore (or steal * if you'd like) the other code that isn't particularly relevant (i.e. * the support functions). * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include #include #include #include extern char *strdup(char *str); extern char _FreqFilter[84]; extern int view_dir, view_pt; void free_table(char **table, int n) { char **orig = table; for(; n > 0; n--, table++) { if (*table) free(*table); } free(orig); } void free_dirlist(char **table) { char **orig = table; while(*table) { free(*table); table++; } free(orig); } int freq_filter_check(char *scanit) { char *ptp, *pts, *ptr, *ptn; char needle[84]; struct stat buf; if (scanit == NULL) return 1; if (!strcmp(scanit, "./")) return 1; stat(scanit, &buf); if (S_ISDIR(buf.st_mode)) return view_dir; if (view_pt && *scanit == '.') return 1; pts = scanit; ptr = _FreqFilter; iter: while (*ptr == '*') ++ptr; if (*ptr == '\0') return 0; strcpy(needle, ptr); ptn = needle; while (*ptn != '\0' && *ptn != '*') ++ptn; *ptn = '\0'; if ((ptp = strstr(pts, needle)) == NULL) return 1; if (ptr == _FreqFilter && ptp > scanit) return 1; ptr = ptr + (ptn-needle); pts = ptp + (ptn-needle); if (*ptr == '\0' && *pts != '\0' && *pts != '/') return 1; goto iter; } char *get_file_name(struct dirent *d) { struct stat s; char *name; if (d == NULL) { fprintf(stderr, "BUG BUG BUG (got a NULL in get_file_name()).\n"); return NULL; } if (stat(d->d_name, &s) < 0) { perror(d->d_name); return NULL; } if (S_ISDIR(s.st_mode)) { name = (char *)malloc(strlen(d->d_name)+2); if (name == NULL) return NULL; sprintf(name, "%s/", d->d_name); } else { name = (char *)strdup(d->d_name); } return name; } #define CHUNK 100 char **get_dir_list(char *dirname, int *num_entries) { int i,size=CHUNK; char **table, old_dir[MAXPATHLEN]; DIR *dir; struct dirent *dirent; getcwd(old_dir, MAXPATHLEN); if (dirname && chdir(dirname) < 0) return NULL; dir = opendir("."); if (dir == NULL) { chdir(old_dir); return NULL; } table = (char **)calloc(size, sizeof(char *)); if (table == NULL) { closedir(dir); chdir(old_dir); return NULL; } dirent = NULL; i = 0; for(dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { table[i] = get_file_name(dirent); if (freq_filter_check(table[i])) continue; /* continue if table[i] is void or doesn't match the filter */ i++; if (i == size) { char **table2; size *= 2; table2 = (char **)realloc(table, size * sizeof(char *)); if (table2 == NULL) { free_table(table, i); closedir(dir); chdir(old_dir); return NULL; } table = table2; } } table[i] = NULL; /* make sure the table ends with a NULL */ if (num_entries) *num_entries = i; closedir(dir); chdir(old_dir); return table; } #ifdef TEST /* * This function is just a wrapper for strcmp(), and is called by qsort() * (if used) down below. */ int mystrcmp(char **a, char **b) { return strcmp(*a, *b); } main(int argc, char **argv) { int i, num_entries; char *dirname, **table; if (argv[1] == NULL) dirname = "."; else dirname = argv[1]; table = get_dir_list(dirname, &num_entries); if (table == NULL) printf("No such directory: %s\n", dirname); else { /* * If you want to sort the table, you would do it as follows: */ qsort(table, num_entries, sizeof(char *), mystrcmp); printf("Number of files == %d\n", num_entries); for(i=0; table[i] != NULL; i++) printf("%s\n", table[i]); free_table(table, num_entries); } exit(0); } #endif /* TEST */ libsx-2.05/src/freq.c0000644000175000017500000003263111252443541015611 0ustar amckinstryamckinstry/* This file contains all routines for creating and managing a file * requestor. The programmer's only interface to the file requestor * is the function GetFile(). * * Originally written by Allen Martin (amartin@cs.wpi.edu). * * Significant modifications by me (Dominic Giampaolo, dbg@sgi.com) * to clean up some bugs, do double-clicks correctly, and make * relative path browsing work better. */ #include #include #include #include #include #include #include #include #include "libsx.h" #ifndef CLK_TCK #define CLK_TCK sysconf(_SC_CLK_TCK) /* seems to work right */ #endif /* CLK_TCK */ extern char _FreqFilter[84]; int view_dir = 0; int view_pt = 0; /* * Some ugly hacks to make this work better under ultrix. */ #ifdef ultrix /* * Can you say "Let's be pinheaded and follow the letter of the spec without * regard for what might make sense"? I knew you could. And so can the * boys and girls at DEC. * * Which is why they don't provide strdup() in their libc. Gay or what? */ char *strdup(const char *str) { char *new; new = malloc(strlen(str)+1); if (new) strcpy(new, str); return new; } #endif /* ultrix */ /* * No one seems to have a prototype for strdup(). What a pain * in the butt. Why on earth isn't strdup() in the POSIX standard * but something completely useless like mbstowcs() is? */ char *strdup(const char *str); /* * Here's where the real code begins. */ typedef struct { Widget freq_window; Widget file_path; Widget file_filter; Widget file_name; Widget file_list; char **dirlist; /* used by the list widget */ char fpath[MAXPATHLEN]; char fname[MAXPATHLEN]; FreqCB list_CB; void *data; clock_t last_click; /* time of last click */ } FReqData; static void load_cancel(Widget w, FReqData *fdata); static void load_ok(Widget w, FReqData *fdata); static void load_list(Widget w, char *string, int index, FReqData *fdata); static void load_dir(Widget w, char *string, FReqData *fdata); static void load_filter(Widget w, char *string, FReqData *fdata); static void load_name(Widget w, char *string, FReqData *fdata); static void home_dir(Widget w, FReqData *fdata); static void current_dir(Widget w, FReqData *fdata); static void root_dir(Widget w, FReqData *fdata); static void refresh_dir(Widget w, FReqData *fdata); static void viewornot_dir(Widget w, FReqData *fdata); static void viewornot_pt(Widget w, FReqData *fdata); static int mystrcmp(const void *a, const void *b); char **get_dir_list(char *pname, int *num); void free_dirlist(char **table); void SetFreqFilter(char *filter) { if (filter) strncpy(_FreqFilter, filter, 80); else strcpy(_FreqFilter, "*"); } /* * GetFile() - This is the entry point to the file requestor. A single * argument is passed - the path name for the initial list. * If this path name is passed as NULL, the current directory * is used instead. The function returns a character string * that is the name of the selected file, path included. If * an error occurs, or the user selects CANCEL, NULL is returned. */ char *GetFile (char *_label, char *_path, FreqCB _func, void *_data) { FReqData fdata; Widget w[19]; int num_dir, i; char path[MAXPATHLEN]; char filename[MAXPATHLEN]=""; char *ptr; struct stat buf; int fields[] = {2,4,5,8}; int separ[] = {13,14,17}; if(!_path || !*_path || strcmp(_path, ".") == 0 || strcmp(_path, "./") == 0) getcwd(path, MAXPATHLEN); else strcpy(path, _path); stat(path, &buf); if(S_ISDIR(buf.st_mode)) { if(path[strlen(path)-1] != '/') strcat(path, "/"); } else { ptr = path+strlen(path)-1; while (ptr > path && *ptr != '/') --ptr; if (*ptr=='/') { ++ptr; strcpy(filename,ptr); *ptr='\0'; } } stat(path, &buf); if(!S_ISDIR(buf.st_mode)) getcwd(path, MAXPATHLEN); if(!(fdata.dirlist = get_dir_list(path, &num_dir))) return(NULL); qsort(fdata.dirlist, num_dir, sizeof(char *), mystrcmp); fdata.freq_window = MakeWindow("FileRequestor", SAME_DISPLAY, EXCLUSIVE_WINDOW); w[0] = MakeLabel(_label); w[1] = MakeLabel(SX_Dialog[FREQ_DIAL]); w[2] = MakeStringEntry(path, 406, (void *)load_dir, &fdata); w[3] = MakeLabel(SX_Dialog[FREQ_DIAL+1]); w[4] = MakeStringEntry(_FreqFilter, 406, (void *)load_filter, &fdata); w[5] = MakeScrollList(fdata.dirlist, 468, 300, (void *)load_list, &fdata); w[6] = MakeLabel(SX_Dialog[FREQ_DIAL+2]); w[7] = MakeLabel(SX_Dialog[FREQ_DIAL+3]); w[8] = MakeStringEntry(filename, 406, (void *)load_name, &fdata); w[9] = MakeLabel(SX_Dialog[FREQ_DIAL+4]); w[10] = MakeButton(SX_Dialog[FREQ_DIAL+5], (void *)home_dir, &fdata); w[11] = MakeButton(SX_Dialog[FREQ_DIAL+6], (void *)current_dir, &fdata); w[12] = MakeButton("/", (void *)root_dir, &fdata); w[13] = MakeButton(SX_Dialog[FREQ_DIAL+7], (void *)refresh_dir, &fdata); w[14] = MakeLabel(SX_Dialog[FREQ_DIAL+8]); w[15] = MakeToggle("/", view_dir, NULL, (void *)viewornot_dir, &fdata); w[16] = MakeToggle(".", view_pt, NULL, (void *)viewornot_pt, &fdata); w[17] = MakeButton(SX_Dialog[FREQ_DIAL+9], (void *)load_cancel, &fdata); w[18] = MakeButton(SX_Dialog[FREQ_DIAL+10], (void *)load_ok, &fdata); for(i=1; i<=8; i++) SetWidgetPos(w[i], PLACE_UNDER, w[i-1-(i==2)-(i==4)-(i==8)], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_RIGHT, w[3], NO_CARE, NULL); SetWidgetPos(w[8], PLACE_RIGHT, w[7], NO_CARE, NULL); for(i=9; i<=18; i++) { SetWidgetPos(w[i], PLACE_UNDER, w[8], NO_CARE, NULL); if(i>9) SetWidgetPos(w[i], PLACE_RIGHT, w[i-1], NO_CARE, NULL); } for(i=0; i<=2; i++) XtVaSetValues(w[separ[i]], "horizDistance", 31+(i==2), NULL); if (BUTTONBG >= 0) for (i=10; i<=18; i++) if (i!=14) SetBgColor(w[i], BUTTONBG); if (INPUTBG >= 0) for (i=0; i<=3; i++) SetBgColor(w[fields[i]],INPUTBG); /* save the file name & file list widgets, so we can use them later */ fdata.file_path = w[2]; fdata.file_filter = w[4]; fdata.file_list = w[5]; fdata.file_name = w[8]; fdata.fname[0] = '\0'; fdata.last_click = 0; fdata.list_CB = _func; fdata.data = _data; /* set up the file path */ strcpy(fdata.fpath, path); ShowDisplay(); MainLoop(); /* free the directory list */ if (fdata.dirlist) free_dirlist(fdata.dirlist); SetCurrentWindow(ORIGINAL_WINDOW); if(fdata.fname[0] == '\0') return(NULL); else return(strdup(fdata.fname)); } /* * load_cancel() - Callback routine for CANCEL button */ static void load_cancel(Widget w, FReqData *fdata) { SetCurrentWindow(fdata->freq_window); CloseWindow(); strcpy(fdata->fname, ""); } /* * load_ok() - Callback routine for OK button */ static void load_ok(Widget w, FReqData *fdata) { char *fpath, *fname; char fullname[MAXPATHLEN]; fpath = GetStringEntry(fdata->file_path); fname = GetStringEntry(fdata->file_name); strncpy(_FreqFilter, GetStringEntry(fdata->file_filter), 80); sprintf(fullname, "%s%s", fpath, fname); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); SetCurrentWindow(fdata->freq_window); CloseWindow(); } /* * load_list() - Callback routine for scrollable list widget */ static void load_list(Widget w, char *string, int index, FReqData *fdata) { char newpath[MAXPATHLEN], *cptr, *fpath, fullname[MAXPATHLEN]; char **old_dirlist=NULL; static char oldfile[MAXPATHLEN] = { '\0', }; clock_t cur_click; struct tms junk_tms; /* not used, but passed to times() */ int num_dir; float tdiff; /* difference in time between two clicks as % of a second */ /* * First we check for a double click. * * If the time between the last click and this click is greater than * 0.5 seconds or the last filename and the current file name * are different, then it's not a double click, so we just return. */ cur_click = times(&junk_tms); tdiff = ((float)(cur_click - fdata->last_click) / CLK_TCK); if(tdiff > 0.50 || strcmp(oldfile, string) != 0) { fdata->last_click = cur_click; strcpy(oldfile, string); SetStringEntry(fdata->file_name, string); return; } /* check if a directory was selected */ if(string[strlen(string)-1] != '/') /* a regular file double click */ { fpath = GetStringEntry(fdata->file_path); sprintf(fullname, "%s%s", fpath, string); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); if (fdata->list_CB) fdata->list_CB(fdata->file_list, fdata->fpath, fdata->fname, fdata->data); else { SetCurrentWindow(fdata->freq_window); CloseWindow(); } return; } /* * Else, we've got a directory name and should deal with it * as approrpriate. */ /* check for special cases "./" and "../" */ if(strcmp(string, "./") == 0) { if (fdata->fpath) strcpy(newpath, fdata->fpath); else strcpy(newpath, "./"); } else if(strcmp(string, "../") == 0) { strcpy(newpath, fdata->fpath); if (strcmp(newpath, "./") == 0) strcpy(newpath, string); else { /* * chop off the last path component and look at what it * is to determine what to do with the `..' we just got. */ cptr = strrchr(newpath, '/'); if (cptr) *cptr = '\0'; cptr = strrchr(newpath, '/'); if (cptr) *cptr = '\0'; if ( (cptr != NULL && strcmp(cptr+1, "..") == 0) ||(cptr == NULL && strcmp(newpath, "..") == 0)) { if (cptr) *cptr = '/'; strcat(newpath, "/"); /* put back the / we took out */ strcat(newpath, "../"); /* and append the new ../ */ } else { if(cptr == NULL && strcmp(fdata->fpath, "/") == 0) strcpy(newpath, "/"); else if (cptr == NULL) strcpy(newpath, "./"); if (newpath[strlen(newpath)-1] != '/') strcat(newpath, "/"); } } } else /* not a `./' or `../', so it's just a regular old directory name */ { if (fdata->fpath[strlen(fdata->fpath)-1] == '/') sprintf(newpath, "%s%s", fdata->fpath, string); else sprintf(newpath, "%s/%s", fdata->fpath, string); } old_dirlist = fdata->dirlist; if(!(fdata->dirlist = get_dir_list(newpath, &num_dir))) /* should beep the display or something here */ return; qsort(fdata->dirlist, num_dir, sizeof(char *), mystrcmp); strcpy(fdata->fpath, newpath); SetStringEntry(fdata->file_path, fdata->fpath); SetStringEntry(fdata->file_name, ""); strcpy(fdata->fpath, newpath); ChangeScrollList(fdata->file_list, fdata->dirlist); /* free the directory list */ if (old_dirlist) free_dirlist(old_dirlist); fdata->last_click = 0; /* re-init double-click time */ return; } /* * load_dir() - Callback routine for pathname string entry widget */ static void load_dir(Widget w, char *string, FReqData *fdata) { char **old_dirlist, temp[MAXPATHLEN]; int num_dir; strncpy(_FreqFilter, GetStringEntry(fdata->file_filter), 80); /* make sure the name has a '/' at the end */ strcpy(temp, string); if(temp[strlen(temp)-1] != '/') strcat(temp, "/"); old_dirlist = fdata->dirlist; if(!(fdata->dirlist = get_dir_list(temp, &num_dir))) { /* bad path - reset the file path and return */ SetStringEntry(fdata->file_path, fdata->fpath); return; } qsort(fdata->dirlist, num_dir, sizeof(char *), mystrcmp); strcpy(fdata->fpath, temp); SetStringEntry(fdata->file_path, temp); ChangeScrollList(fdata->file_list, fdata->dirlist); /* free the directory list */ if (old_dirlist) free_dirlist(old_dirlist); } static void load_filter(Widget w, char *string, FReqData *fdata) { load_dir(w, (char *)GetStringEntry(fdata->file_path), (FReqData *)fdata); } static void refresh_dir(Widget w, FReqData *fdata) { load_dir(w, (char *)GetStringEntry(fdata->file_path), (FReqData *)fdata); } static void viewornot_dir(Widget w, FReqData *fdata) { view_dir = 1 - view_dir; load_dir(w, (char *)GetStringEntry(fdata->file_path), (FReqData *)fdata); } static void viewornot_pt(Widget w, FReqData *fdata) { view_pt = 1 - view_pt; load_dir(w, (char *)GetStringEntry(fdata->file_path), (FReqData *)fdata); } static void home_dir(Widget w, FReqData *fdata) { load_dir(w, getenv("HOME"), (FReqData *)fdata); } static void current_dir(Widget w, FReqData *fdata) { char *ptr; load_dir(w, ptr=getcwd(NULL,1024), (FReqData *)fdata); free(ptr); } static void root_dir(Widget w, FReqData *fdata) { load_dir(w, "/", (FReqData *)fdata); } /* * load_name() - Callback routine for file name string entry widget */ static void load_name(Widget w, char *string, FReqData *fdata) { char *fpath, fullname[MAXPATHLEN]; fpath = GetStringEntry(fdata->file_path); sprintf(fullname, "%s%s", fpath, string); /* right here we should check the validity of the file name */ /* and abort if invalid */ strcpy(fdata->fname, fullname); SetCurrentWindow(fdata->freq_window); CloseWindow(); return; } /* * This function is just a wrapper for mystrcmp(), and is called by qsort() * (if used) down below. */ static int mystrcmp(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } libsx-2.05/src/misc.c0000644000175000017500000002253611252443541015612 0ustar amckinstryamckinstry/* This file contains miscellaneous routines that apply to all kinds * of widgets. Things like setting and getting the color of a widget, * its font, position, etc. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" /* * Miscellaneous functions that allow customization of widgets and * other sundry things. */ void SetWindowTitle(char *title) { XTextProperty xtxt; if (lsx_curwin->toplevel == NULL || title == NULL) return; XStringListToTextProperty(&title, 1, &xtxt); XSetWMName(lsx_curwin->display, XtWindow(lsx_curwin->toplevel), &xtxt); } void SetIconTitle(char *title) { XTextProperty xtxt; if (lsx_curwin->toplevel == NULL || title == NULL) return; XStringListToTextProperty(&title, 1, &xtxt); XSetWMIconName(lsx_curwin->display, XtWindow(lsx_curwin->toplevel), &xtxt); } void SetFgColor(Widget w, int color) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return; if ((di=libsx_find_draw_info(w)) != NULL) { Display *d=XtDisplay(w); di->foreground = color; if (di->mask != 0xffffffff) XSetPlaneMask(d, di->drawgc, di->foreground ^ di->background); else XSetForeground(d, di->drawgc, color); return; } n = 0; XtSetArg(wargs[n], XtNforeground, color); n++; XtSetValues(w, wargs, n); } void SetBgColor(Widget w, int color) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ Widget tmp; DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return; if ((di=libsx_find_draw_info(w)) != NULL) { Display *d=XtDisplay(w); XSetBackground(d, di->drawgc, color); XSetWindowBackground(d, XtWindow(w), color); di->background = color; if (di->mask != 0xffffffff) XSetPlaneMask(d, di->drawgc, di->foreground ^ di->background); return; } tmp = XtParent(w); if (tmp != lsx_curwin->form_widget) { if (XtNameToWidget(tmp, "menu_item")) w = tmp; } n = 0; XtSetArg(wargs[n], XtNbackground, color); n++; XtSetValues(w, wargs, n); } int GetFgColor(Widget w) { Pixel color; int n = 0; Arg wargs[1]; /* Used to set widget resources */ DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return -1; if ((di=libsx_find_draw_info(w)) != NULL) { return di->foreground; } n = 0; XtSetArg(wargs[n], XtNforeground, &color); n++; XtGetValues(w, wargs, n); return color; } int GetBgColor(Widget w) { Pixel color; int n = 0; Arg wargs[1]; /* Used to set widget resources */ Widget tmp; DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return -1; if ((di=libsx_find_draw_info(w)) != NULL) { return di->background; } tmp = XtParent(w); if (tmp != lsx_curwin->form_widget) { if (XtNameToWidget(tmp, "menu_item")) w = tmp; } n = 0; XtSetArg(wargs[n], XtNbackground, &color); n++; XtGetValues(w, wargs, n); return color; } void SetBorderColor(Widget w, int color) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ if (lsx_curwin->toplevel == NULL || w == NULL) return; n = 0; XtSetArg(wargs[n], XtNborder, color); n++; XtSetValues(w, wargs, n); } void SetWidgetState(Widget w, int state) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ if (lsx_curwin->toplevel == NULL || w == NULL) return; n = 0; XtSetArg(wargs[n], XtNsensitive, state); n++; XtSetValues(w, wargs, n); } int GetWidgetState(Widget w) { int n = 0, state; Arg wargs[1]; /* Used to set widget resources */ if (lsx_curwin->toplevel == NULL || w == NULL) return 0; n = 0; XtSetArg(wargs[n], XtNsensitive, &state); n++; XtGetValues(w, wargs, n); return state; } void SetWidgetBitmap(Widget w, char *data, int width, int height) { Pixmap pm; Display *d; Arg wargs[3]; int n=0; if (lsx_curwin->display == NULL || w == NULL) return; d = XtDisplay(w); pm = XCreateBitmapFromData(d, DefaultRootWindow(d), data, width, height); if (pm == None) return; n=0; XtSetArg(wargs[n], XtNbitmap, pm); n++; XtSetValues(w, wargs, n); } #ifdef XPM_SUPPORT void SetWidgetPixmap(Widget w, char **xpmdata) { Pixmap xpm; XpmAttributes xpma; Arg wargs[4]; /* Used to set widget resources */ int n = 0; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return; xpma.colormap = DefaultColormap(lsx_curwin->display, DefaultScreen(lsx_curwin->display)); xpma.valuemask = XpmColormap; XpmCreatePixmapFromData(lsx_curwin->display, DefaultRootWindow(lsx_curwin->display), xpmdata, &xpm, NULL, &xpma); n = 0; XtSetArg(wargs[n], XtNwidth, xpma.width); n++; XtSetArg(wargs[n], XtNheight, xpma.height); n++; XtSetArg(wargs[n], XtNbackgroundPixmap, xpm); n++; XtSetValues(w, wargs, n); } #endif void AttachEdge(Widget w, int edge, int attach_to) { char *edge_name; static char *edges[] = { XtNleft, XtNright, XtNtop, XtNbottom }; static int attached[] = { XtChainLeft, XtChainRight, XtChainTop, XtChainBottom }; int a; Arg wargs[5]; int n=0; if (w == NULL || edge < 0 || edge > BOTTOM_EDGE || attach_to < 0 || attach_to > ATTACH_BOTTOM) return; edge_name = edges[edge]; a = attached[attach_to]; n=0; XtSetArg(wargs[n], edge_name, a); n++; XtSetValues(w, wargs, n); } void SetWidgetPos(Widget w, int where1, Widget from1, int where2, Widget from2) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ char *name; if (lsx_curwin->toplevel == NULL || w == NULL) return; /* * Don't want to do this for menu item widgets */ if ((name = XtName(w)) && strcmp(name, "menu_item") == 0) return; /* * In the case that the widget we were passed is a list widget, we * have to play a few games. We can't set the position of a list * widget directly because it is a composite widget. We want to * set the position of the parent of the list widget (a viewport * widget) instead. Normally the parent of a widget will be the * current lsx_curwin->form_widget, so if that isn't the case, * we have a composite list widget and really want its parent. * * The extra check for the name of the widget not being "form" is to * allow proper setting of multiple form widgets. In the case that * we are setting the position of multiple form widgets, the parent of * the widget we are setting will not be lsx_curwin->form_widget. When * this is the case, we just want to set the widget itself, not the * parent. Basically this is an exception to the previous paragraph * (and it should be the only one, I think). * * Kind of hackish. Oh well... */ if (XtParent(w) != lsx_curwin->form_widget && strcmp(XtName(w), "form") != 0) w = XtParent(w); /* * If we're placing this new widget (w) relative to a list widget, * and the parent of the list widget is not the form_widget, then * we should grab the parent of the list widget and use that for * doing relative placement (because the list widget is composite). */ if (where1 != NO_CARE) { name = XtName(from1); if (strcmp(name, "list") == 0 && XtParent(from1) != lsx_curwin->form_widget) from1 = XtParent(from1); } if (where2 != NO_CARE) { name = XtName(from2); if (strcmp(name, "list") == 0 && XtParent(from2) != lsx_curwin->form_widget) from2 = XtParent(from2); } /* * Here we do the first half of the positioning. */ if (where1 == PLACE_RIGHT && from1) { XtSetArg(wargs[n], XtNfromHoriz, from1); n++; } else if (where1 == PLACE_UNDER && from1) { XtSetArg(wargs[n], XtNfromVert, from1); n++; } /* * Now do the second half of the positioning */ if (where2 == PLACE_RIGHT && from2) { XtSetArg(wargs[n], XtNfromHoriz, from2); n++; } else if (where2 == PLACE_UNDER && from2) { XtSetArg(wargs[n], XtNfromVert, from2); n++; } if (n) /* if any values were actually set */ XtSetValues(w, wargs, n); } void SetWidgetSize(Widget w, int width, int height) { int n = 0; Arg wargs[2]; if (width > 0) { printf("setting widget width: %d\n", width); XtSetArg(wargs[0], XtNwidth, width); n++; } if (height > 0) { printf("setting widget height: %d\n", height); XtSetArg(wargs[0], XtNheight, height); n++; } if (n > 0 && w != NULL) XtSetValues(w, wargs, n); } /* void SetIconBitmap(unsigned char *bits, int width, int height) { Pixmap pix; XWMHints *xwmh; #if 0 if (lsx_curwin == NULL || lsx_curwin->display == NULL) return; pix = XCreatePixmapFromBitmapData(lsx_curwin->display, lsx_curwin->window, bits, width, height, cur_di->foreground, cur_di->background, DefaultDepth(display,lsx_curwin->screen)); if (pix == NULL) return; #endif } void SetIconImage(unsigned char *bitmap, int width, int height) { } */ libsx-2.05/src/menu.c0000644000175000017500000000712611252443541015621 0ustar amckinstryamckinstry/* This file contains routines that create menus and menu items within * those menus. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include #include #include #include "libsx.h" #include "libsx_private.h" #include "check_mark.h" /* * Menu functions. */ Widget MakeMenu(char *name) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ Widget button, menu=NULL; if (lsx_curwin->toplevel == NULL && OpenDisplay(0,NULL) == 0) return NULL; if (name == NULL) return NULL; n = 0; XtSetArg(wargs[n], XtNlabel, name); n++; XtSetArg(wargs[n], XtNborderWidth, 1); n++; /* * We create two widgets, the simpleMenu widget is a child of the menu button * widget. We return the reference to the button widget however so that * way the SetXXColor() and SetWidgetFont() functions work as expect * (that is they change the menu button). * * The MakeMenuItem() function is aware of this, and gets the child of * the menu button for creation of the actual menu items. * */ button = XtCreateManagedWidget("menuButton", menuButtonWidgetClass, lsx_curwin->form_widget, wargs, n); if (button) menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, button, NULL, 0); if (menu == NULL) { XtDestroyWidget(button); button = NULL; } return button; } Widget MakeMenuItem(Widget parent, char *name, ButtonCB func, void *arg) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ Widget item, menu; if (lsx_curwin->toplevel == NULL && OpenDisplay(0,NULL) == 0) return NULL; if (parent == NULL) return NULL; /* * We get the "menu" widget child of the parent widget because the * parent is really a reference to the menu button widget, not the * popup-shell widget we really want. See the above comment in * MakeMenu(). */ if ((menu = XtNameToWidget(parent, "menu")) == NULL) return NULL; n = 0; XtSetArg(wargs[n], XtNlabel, name); n++; XtSetArg(wargs[n], XtNleftMargin, check_mark_width); n++; item = XtCreateManagedWidget("menu_item", smeBSBObjectClass, menu, wargs, n); if (item == NULL) return NULL; if (func) XtAddCallback(item, XtNcallback, (XtCallbackProc)func, arg); return item; } void SetMenuItemChecked(Widget w, int state) { int n=0; Arg wargs[5]; Pixmap mark; if (lsx_curwin->toplevel == NULL || w == NULL) return; if (lsx_curwin->check_mark == None) /* create the check mark bitmap */ { Display *d=XtDisplay(XtParent(w)); mark = XCreateBitmapFromData(d, DefaultRootWindow(d), (char *)check_mark_bits, check_mark_width, check_mark_height); if (mark == None) return; lsx_curwin->check_mark = mark; } else mark = lsx_curwin->check_mark; /* * Now set the check mark. */ n=0; XtSetArg(wargs[n], XtNleftMargin, 16); n++; if (state) { XtSetArg(wargs[n], XtNleftBitmap, mark); n++; } /* checkmark on */ else { XtSetArg(wargs[n], XtNleftBitmap, None); n++; } /* checkmark off */ XtSetValues(w, wargs, n); } int GetMenuItemChecked(Widget w) { int n=0; Arg wargs[5]; Pixmap mark; if (lsx_curwin->toplevel == NULL || w == NULL) return FALSE; n=0; XtSetArg(wargs[n], XtNleftBitmap, &mark); n++; XtGetValues(w, wargs, n); if (mark == None) return FALSE; else return TRUE; } libsx-2.05/src/scrollbar.c0000644000175000017500000001554711252443541016646 0ustar amckinstryamckinstry/* This file contains routines to manipulate scrollbar widgets (either * horizontal or vertical ones). * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include "xstuff.h" #ifdef sgi /* * little fixes for the botched up SGI Xaw/Scrollbar.h header file... */ #define NeedFunctionPrototypes 1 /* Make DAMN sure we pick up prototypes */ #undef NeedWidePrototypes #endif #ifdef __linux__ #define NeedFunctionPrototypes 1 /* Make DAMN sure we pick up prototypes */ #undef NeedWidePrototypes #endif #include #include "libsx.h" #include "libsx_private.h" /* * this structure maintains some internal state information about each * scrollbar. */ typedef struct ScrollInfo { Widget scroll_widget; void (*func)(Widget widg, float val, void *data); float max; float where_is; float size_shown; float val; float fraction; void *user_data; struct ScrollInfo *next; }ScrollInfo; static ScrollInfo *scroll_bars = NULL; /* * This is called when the user interactively uses the middle mouse * button to move the slider. */ static void my_jump_proc(Widget scroll_widget, XtPointer client_data, XtPointer percent) { ScrollInfo *si = (ScrollInfo *)client_data; float old_val = si->val; /* We want the scrollbar to be at 100% when the right edge of the slider * hits the end of the scrollbar, not the left edge. When the right edge * is at 1.0, the left edge is at 1.0 - size_shown. Normalize * accordingly. */ si->val = (*(float *) percent) * si->max; if ((si->val + si->size_shown > si->max) && fabs((double)(si->size_shown - si->max)) > 0.01) { si->val = si->max - si->size_shown; XawScrollbarSetThumb(scroll_widget, si->val/si->max, si->size_shown / si->max); } else if (si->val <= 0) si->val = 0; si->where_is = si->val; if (si->func && old_val != si->val) (*si->func)(si->scroll_widget, si->val, si->user_data); } /* * This is called whenever the user uses the left or right mouse buttons */ static void my_scroll_proc(Widget scroll_widget, XtPointer client_data, XtPointer position) { int pos; ScrollInfo *si = (ScrollInfo *)client_data; float old_val = si->val; pos = (int)position; if (pos < 0) /* button 3 pressed, go up */ { si->val += (si->fraction * si->max); /* go up ten percent at a time */ } else /* button 2 pressed, go down */ { si->val -= (si->fraction * si->max); /* go down ten percent at a time */ } if (si->size_shown != si->max && (si->val + si->size_shown) >= si->max) si->val = si->max - si->size_shown; else if (si->val >= si->max) si->val = si->max; else if (si->val <= 0.0) si->val = 0.0; XawScrollbarSetThumb(scroll_widget,si->val/si->max, si->size_shown/si->max); si->where_is = si->val; if (si->func && old_val != si->val) (*si->func)(si->scroll_widget, si->val, si->user_data); } /* static void destroy_scroll_info(Widget w, void *data, void *junk) { ScrollInfo *si = (ScrollInfo *)data; ScrollInfo *curr; if (si == scroll_bars) scroll_bars = si->next; else { for(curr=scroll_bars; curr && curr->next != si; curr=curr->next) if (curr == NULL) return; curr->next = si->next; } free(si); } */ void SetScrollbar(Widget w, float where, float max, float size_shown) { ScrollInfo *si; if (lsx_curwin->toplevel == NULL || w == NULL) return; /* * Here we have to search for the correct ScrollInfo structure. * This is kind of hackish, but is the easiest way to make the * interfaces to all this easy and consistent with the other * routines. */ for(si=scroll_bars; si; si=si->next) { if (si->scroll_widget == w && XtDisplay(si->scroll_widget) == XtDisplay(w)) break; } if (si == NULL) return; si->where_is = where; if (max > -0.0001 && max < 0.0001) max = 0.0001; si->max = max; if (fabs((double)max - size_shown) > 0.01) si->max += size_shown; si->size_shown = size_shown; si->val = si->where_is; XawScrollbarSetThumb(w, si->where_is/si->max, si->size_shown/si->max); } /* * Scrollbar Creation/Manipulation routines. * */ static Widget MakeScrollbar(int length, ScrollCB scroll_func, void *data, int orientation) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ Widget scroll_widget; ScrollInfo *si; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; si = (ScrollInfo *)calloc(sizeof(ScrollInfo),1); if (si == NULL) return NULL; si->func = scroll_func; si->user_data = data; si->size_shown = si->max = 1.0; si->val = si->where_is = 0.0; si->fraction = 0.1; n = 0; XtSetArg(wargs[n], XtNorientation, orientation); n++; XtSetArg(wargs[n], XtNlength, length); n++; XtSetArg(wargs[n], (orientation==XtorientHorizontal)? XtNwidth:XtNheight, length); n++; scroll_widget = XtCreateManagedWidget("scrollbar", scrollbarWidgetClass, lsx_curwin->form_widget, wargs,n); if (scroll_widget == NULL) { free(si); return NULL; } si->scroll_widget = scroll_widget; si->next = scroll_bars; scroll_bars = si; XtAddCallback(scroll_widget, XtNjumpProc, my_jump_proc, si); XtAddCallback(scroll_widget, XtNscrollProc, my_scroll_proc, si); return scroll_widget; } Widget MakeVertScrollbar(int height, ScrollCB scroll_func, void *data) { return MakeScrollbar(height, scroll_func, data, XtorientVertical); } Widget MakeHorizScrollbar(int length, ScrollCB scroll_func, void *data) { return MakeScrollbar(length, scroll_func, data, XtorientHorizontal); } float __dir__ = 1.0; void SetScrollbarDirection(float dir) { __dir__ = dir; } void SetScrollbarStep(Widget w, float fact) { ScrollInfo *si; if (lsx_curwin->toplevel == NULL || w == NULL) return; /* * Here we have to search for the correct ScrollInfo structure. * This is kind of hackish, but is the easiest way to make the * interfaces to all this easy and consistent with the other * routines. */ for(si=scroll_bars; si; si=si->next) { if (si->scroll_widget == w && XtDisplay(si->scroll_widget) == XtDisplay(w)) break; } if (si == NULL) return; si->fraction = fact * __dir__; } void SetThumbBitmap(Widget w, char *black_bits, int width, int height) { Display *d; Pixmap thumb_pm; Arg wargs[5]; /* Used to set widget resources */ d = XtDisplay (lsx_curwin->toplevel); thumb_pm = XCreateBitmapFromData (d, DefaultRootWindow(d), black_bits, width, height); if (thumb_pm) { XtSetArg(wargs[0], XtNthumb, thumb_pm); } else printf ("\nError, can't make thumb pixmap !!\n"); XtSetValues(w, wargs, 1); } libsx-2.05/src/grabpix.c0000644000175000017500000001675011252443541016314 0ustar amckinstryamckinstry/* $XConsortium: grabpix.c,v 1.29 94/04/17 20:25:02 rws Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" typedef struct _RootWindowClassRec* RootWindowWidgetClass; typedef struct _RootWindowRec* RootWindowWidget; extern WidgetClass rootWindowWidgetClass; typedef struct { int empty; } RootWindowClassPart; typedef struct _RootWindowClassRec { CoreClassPart core_class; RootWindowClassPart root_class; } RootWindowClassRec; extern RootWindowClassRec rootClassRec; typedef struct { /* resources */ char* resource; /* private state */ } RootWindowPart; typedef struct _RootWindowRec { CorePart core; RootWindowPart root; } RootWindowRec; static void Realize(); RootWindowClassRec rootWindowClassRec = { { /* core fields */ /* superclass */ (WidgetClass) &widgetClassRec, /* class_name */ "RootWindow", /* widget_size */ sizeof(RootWindowRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ NULL, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ NULL, /* num_actions */ 0, /* resources */ NULL, /* num_resources */ 0, /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ NULL, /* resize */ NULL, /* expose */ NULL, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, { /* rootWindow fields */ /* empty */ 0 } }; WidgetClass rootWindowWidgetClass = (WidgetClass)&rootWindowClassRec; typedef struct { GC gc; XWindowAttributes win_info; XImage *image; Position homeX, homeY, x, y; Dimension width, height; } hlStruct, *hlPtr; /*ARGSUSED*/ static void Realize(w, value_mask, attributes) Widget w; XtValueMask *value_mask; XSetWindowAttributes *attributes; { w->core.window = RootWindowOfScreen(w->core.screen); } char *GrabPixel(char *format) { static Cursor newcursor; static Display *dpy; static int scr; static GC selectGC; static XGCValues selectGCV; static Widget toplevel, root; static int sec = 2; /* security border strip */ static unsigned int srcWidth=1, srcHeight=1; /* static char formatstr[256]="Pixel at (%x,%y) colored [%r,%g,%b]\n\ Window object 0x%w, colormap entry %c, button %m\n"; */ static char output[256]; #define lens_width 16 #define lens_height 16 #define lens_x_hot 5 #define lens_y_hot 5 #define lensMask_width 16 #define lensMask_height 16 #define lensMask_x_hot 5 #define lensMask_y_hot 5 static char lens_bits[] = { 0x00, 0x00, 0xf8, 0x00, 0x24, 0x01, 0x22, 0x02, 0x02, 0x02, 0x8e, 0x03, 0x02, 0x02, 0x22, 0x02, 0x24, 0x07, 0xf8, 0x0d, 0x00, 0x13, 0x00, 0x22, 0x00, 0x44, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00}; static char lensMask_bits[] = { 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0x77, 0x07, 0x8f, 0x07, 0x8f, 0x07, 0x8f, 0x07, 0x77, 0x07, 0xfe, 0x0f, 0xfc, 0x1f, 0xf8, 0x3f, 0x00, 0x7f, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10}; static void InitCursors() { Pixmap cursor,mask; XColor cfor,cbak; cbak.red=0xffff; cbak.green=0xffff; cbak.blue=0xffff; cfor.red=0; cfor.green=0; cfor.blue=0; cursor = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), lens_bits,lens_width,lens_height); mask = XCreateBitmapFromData(dpy,DefaultRootWindow(dpy), lensMask_bits,lensMask_width, lensMask_height); newcursor = XCreatePixmapCursor(dpy, cursor, mask, &cfor, &cbak, lens_x_hot,lens_y_hot); } static void SetupGC() { selectGCV.function = GXxor; selectGCV.foreground = 1L; selectGCV.subwindow_mode = IncludeInferiors; selectGC = XtGetGC(toplevel, GCFunction|GCForeground|GCSubwindowMode, &selectGCV); } static Window FindWindow(x, y) int x, y; { XWindowAttributes wa; Window findW = DefaultRootWindow(dpy), stopW, childW; XTranslateCoordinates(dpy, findW, findW, x, y, &x, &y, &stopW); while (stopW) { XTranslateCoordinates(dpy, findW, stopW, x, y, &x, &y, &childW); findW = stopW; if (childW && XGetWindowAttributes(dpy, childW, &wa) && wa.class != InputOutput) break; stopW = childW; } return findW; } static void CreateRoot() { root = XtCreateWidget("root", rootWindowWidgetClass, toplevel, NULL, 0); XtRealizeWidget(root); } static void StartRootPtrGrab() { Window rootR, childR, window; int rootX, rootY, winX, winY; unsigned int mask; hlPtr data; XColor color; int x, y, i; Pixel pixel; static XEvent event; char addstr[20]; XtGrabPointer (root, False, PointerMotionMask|ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, newcursor, CurrentTime); XQueryPointer(dpy, DefaultRootWindow(dpy), &rootR, &childR, &rootX, &rootY, &winX, &winY, &mask); data = (hlPtr)XtMalloc(sizeof(hlStruct)); data->x = rootX; data->y = rootY; data->gc = selectGC; data->width = srcWidth; data->height = srcHeight; restart: XNextEvent(dpy, &event); if (event.type == ButtonRelease) { x = event.xmotion.x_root; y = event.xmotion.y_root; if (x DisplayWidth(dpy,scr)-sec) x = DisplayWidth(dpy,scr) - srcWidth-sec; if (y+srcHeight> DisplayHeight(dpy,scr)-sec) y = DisplayHeight(dpy,scr)- srcHeight-sec; data->x = x; data->y = y; window = FindWindow(x,y); XGetWindowAttributes(dpy, window, &data->win_info); data->image = XGetImage (dpy, RootWindow(dpy, scr), x, y, srcWidth, srcHeight, AllPlanes, ZPixmap); pixel = XGetPixel(data->image, 0, 0); color.pixel = pixel; XQueryColor(dpy, data->win_info.colormap, &color); *output = '\0'; for(i=0; ix); break; case 'y': sprintf(addstr, "%d", data->y); break; case 'r': sprintf(addstr, "%d", color.red/256); break; case 'g': sprintf(addstr, "%d", color.green/256); break; case 'b': sprintf(addstr, "%d", color.blue/256); break; case 'c': sprintf(addstr, "%d", (unsigned int)pixel); break; case 'm': sprintf(addstr, "%d", event.xbutton.button); break; case 'w': sprintf(addstr, "%x", (unsigned int)window); break; } } else sprintf(addstr,"%c", format[i]); strcat(output,addstr); } XtUngrabPointer(root,CurrentTime); return ; } goto restart; } dpy = lsx_curwin->display; scr = DefaultScreen(dpy); toplevel = lsx_curwin->toplevel; InitCursors(); SetupGC(); CreateRoot(); StartRootPtrGrab(); return(output); } libsx-2.05/src/dialog.c0000644000175000017500000001531011252443541016106 0ustar amckinstryamckinstry/* * [ This file is blatantly borrowed from the pixmap distribution. ] * [ It was written by the fellows below, and they disclaim all ] * [ warranties, expressed or implied, in this software. ] * [ As if anyone cares about that... ] * * Copyright 1991 Lionel Mallet * * Author: Davor Matic, MIT X Consortium */ #include #include #include #include #include #include #include #include #include #include #include "libsx.h" #include "dialog.h" #define min(x, y) (((x) < (y)) ? (x) : (y)) #define max(x, y) (((x) > (y)) ? (x) : (y)) extern int HILIGHT; extern int BUTTONBG; extern int INPUTBG; extern void SetBgColor(Widget w, int color); extern void SetFgColor(Widget w, int color); static void libsx_set_text_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms); static int selected; static int button_flags[] = { Yes, Abort, No, Okay, Cancel, Retry}; static void SetSelected(Widget w, XtPointer client_data, XtPointer call_data) { selected = (long)client_data; } /* * Can't make this static because we need to be able to access the * name over in display.c to properly set the resources we want. */ void SetOkay(Widget w, XEvent *xev, String *parms, Cardinal *numparams) { SetSelected(w, (XtPointer)(Okay | Yes), NULL); } /* * This action table sets up an action so that the return key can * be used to pop-down a popup. The translation is setup in libsx.c * We do it there instead of here because the resources need to be * setup at XtAppInitialize time (well strictly that's not entirely * true, but we'll pretend it is). */ static XtActionsRec popup_actions_table[] = { { "set_text_focus", libsx_set_text_focus }, { "set-okay", SetOkay } }; static int added_popup_actions = 0; Dialog CreateDialog(Widget top_widget, char *name, int options) { int i; Dialog popup; Widget button; if ((popup = (Dialog) XtMalloc(sizeof(_Dialog))) == NULL) return NULL; if (added_popup_actions == 0) { extern XtAppContext lsx_app_con; added_popup_actions = 1; XtAppAddActions(lsx_app_con, popup_actions_table, XtNumber(popup_actions_table)); } popup->top_widget = top_widget; popup->shell_widget = XtCreatePopupShell(name, transientShellWidgetClass, top_widget, NULL, 0); popup->dialog_widget = XtCreateManagedWidget("dialog", dialogWidgetClass, popup->shell_widget, NULL, 0); for (i = 0; i < XtNumber(button_flags); i++) if (options & button_flags[i]) { XawDialogAddButton(popup->dialog_widget, SX_Dialog[i], SetSelected, (XtPointer)button_flags[i]); button = XtNameToWidget(popup->dialog_widget, SX_Dialog[i]); if (BUTTONBG>=0) SetBgColor(button, BUTTONBG); } popup->options = options; return popup; } void FreeDialog(Dialog dialog) { if (dialog == NULL) return; XtDestroyWidget(dialog->shell_widget); XtFree((char *)dialog); } void PositionPopup(Widget shell_widget) { int n; Arg wargs[10]; Position popup_x, popup_y, top_x, top_y; Dimension popup_width, popup_height, top_width, top_height, border_width; n = 0; XtSetArg(wargs[n], XtNx, &top_x); n++; XtSetArg(wargs[n], XtNy, &top_y); n++; XtSetArg(wargs[n], XtNwidth, &top_width); n++; XtSetArg(wargs[n], XtNheight, &top_height); n++; XtGetValues(XtParent(shell_widget), wargs, n); n = 0; XtSetArg(wargs[n], XtNwidth, &popup_width); n++; XtSetArg(wargs[n], XtNheight, &popup_height); n++; XtSetArg(wargs[n], XtNborderWidth, &border_width); n++; XtGetValues(shell_widget, wargs, n); popup_x = max(0, min(top_x + ((Position)top_width - (Position)popup_width) / 2, (Position)DisplayWidth(XtDisplay(shell_widget), DefaultScreen(XtDisplay(shell_widget))) - (Position)popup_width - 2 * (Position)border_width)); popup_y = max(0, min(top_y+((Position)top_height - (Position)popup_height) / 2, (Position)DisplayHeight(XtDisplay(shell_widget), DefaultScreen(XtDisplay(shell_widget))) - (Position)popup_height - 2 * (Position)border_width)); n = 0; XtSetArg(wargs[n], XtNx, popup_x); n++; XtSetArg(wargs[n], XtNy, popup_y); n++; XtSetValues(shell_widget, wargs, n); } void libsx_set_text_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms) { if(HILIGHT>=0) SetFgColor(w, HILIGHT); XSetInputFocus(XtDisplay(w),XtWindow(w),RevertToNone,CurrentTime); } int PopupDialog(XtAppContext app_con, Dialog popup, char *message, char *suggestion, char **answer, XtGrabKind grab) { int n, height = 35; Arg wargs[10]; Widget value; static int already_done = FALSE; static XtTranslations trans; if (already_done == FALSE) { already_done = TRUE; trans = XtParseTranslationTable("#override\n" " : set_text_focus()\n"); } n = 0; XtSetArg(wargs[n], XtNlabel, message); n++; if (suggestion) { XtSetArg(wargs[n], XtNvalue, suggestion); n++; } XtSetValues(popup->dialog_widget, wargs, n); /* * Here we get ahold of the ascii text widget for the dialog box (if it * exists) and we set some useful resources in it. */ value = XtNameToWidget(popup->dialog_widget, "value"); n = 0; XtSetArg(wargs[n], XtNeditType, "edit"); n++; XtSetArg(wargs[n], XtNresizable, True); n++; XtSetArg(wargs[n], XtNheight, height); n++; XtSetArg(wargs[n], XtNwidth, 350); n++; XtSetArg(wargs[n], XtNresize, XawtextResizeHeight); n++; XtSetArg(wargs[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++; if (suggestion) { XtSetArg(wargs[n], XtNinsertPosition, strlen(suggestion));n++; } XtSetArg(wargs[n], XtNtranslations, trans); n++; if (value) XtSetValues(value, wargs, n); XtRealizeWidget(popup->shell_widget); if(INPUTBG>=0) SetBgColor(value, INPUTBG); PositionPopup(popup->shell_widget); selected = Empty; XtPopup(popup->shell_widget, grab); while ((selected & popup->options) == Empty) { XEvent event; XtAppNextEvent(app_con, &event); XtDispatchEvent(&event); } PopdownDialog(popup, answer); return (selected & popup->options); } void PopdownDialog(Dialog popup, char **answer) { char *tmp; extern char *strdup(char *str); if (answer) { tmp = XawDialogGetValueString(popup->dialog_widget); *answer = tmp ? strdup(tmp) : NULL; } XtPopdown(popup->shell_widget); } libsx-2.05/src/resize.c0000644000175000017500000000127411252443541016154 0ustar amckinstryamckinstry#include #include "libsx.h" void cb1(Widget w, void *junk) { printf("Inside callback #1\n"); } void cb2(Widget w, void *junk) { printf("Inside callback #2\n"); } void cb3(Widget w, void *junk) { printf("Inside callback #3\n"); } void quit(Widget w, void *junk) { exit(0); } main() { Widget w1, w2, w3, w4; w1 = MakeButton("Button 1", cb1, NULL); w2 = MakeButton("Button 2", cb2, NULL); w3 = MakeButton("Button 3", cb3, NULL); w4 = MakeButton("Quit", quit, NULL); SetWidgetPos(w2, PLACE_RIGHT, w1, NO_CARE, NULL); SetWidgetPos(w3, PLACE_RIGHT, w2, NO_CARE, NULL); SetWidgetPos(w4, PLACE_RIGHT, w3, NO_CARE, NULL); MainLoop(); } libsx-2.05/src/drawing.c0000644000175000017500000002116711252443541016311 0ustar amckinstryamckinstry/* DrawingA.c: The DrawingArea Widget Methods */ /* Copyright 1990, David Nedde * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ #include #include #include #include #include #include "drawingP.h" #ifndef caddr_t extern char *caddr_t; #endif static void Initialize(); static void MyRealize(); /* So we can do our own visual */ static void Destroy(); static void Redisplay(); static void input_draw(); static void motion_draw(); static void resize_draw(); static void enter_draw(); static void leave_draw(); static char defaultTranslations[] = ": input() \n : input() \n : input() \n : input() \n : motion() \n : resize() \n : enter() \n : leave()"; static XtActionsRec actionsList[] = { { "input", (XtActionProc)input_draw }, { "motion", (XtActionProc)motion_draw }, { "resize", (XtActionProc)resize_draw }, { "enter", (XtActionProc)enter_draw }, { "leave", (XtActionProc)leave_draw }, }; /* Default instance record values */ static XtResource resources[] = { {XtNvisual, XtCVisual, XtRVisual, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.vis), XtRVisual, NULL }, {XtNexposeCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.expose_callback), XtRCallback, NULL }, {XtNinputCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.input_callback), XtRCallback, NULL }, {XtNmotionCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.motion_callback), XtRCallback, NULL }, {XtNresizeCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.resize_callback), XtRCallback, NULL }, {XtNenterCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.enter_callback), XtRCallback, NULL }, {XtNleaveCallback, XtCCallback, XtRCallback, sizeof(caddr_t), XtOffset(DrawingAreaWidget, drawing_area.leave_callback), XtRCallback, NULL }, }; DrawingAreaClassRec drawingAreaClassRec = { /* CoreClassPart */ { (WidgetClass) &simpleClassRec, /* superclass */ "DrawingArea", /* class_name */ sizeof(DrawingAreaRec), /* size */ NULL, /* class_initialize */ NULL, /* class_part_initialize */ FALSE, /* class_inited */ Initialize, /* initialize */ NULL, /* initialize_hook */ MyRealize, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ resources, /* resources */ XtNumber(resources), /* resource_count */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ Destroy, /* destroy */ NULL, /* resize */ Redisplay, /* expose */ NULL, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_private */ defaultTranslations, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display_accelerator */ NULL /* extension */ }, /* CoreClass fields initialization */ { /* change_sensitive */ XtInheritChangeSensitive }, /* SimpleClass fields initialization */ { 0, /* field not used */ }, /* DrawingAreaClass fields initialization */ }; WidgetClass drawingAreaWidgetClass = (WidgetClass)&drawingAreaClassRec; static void Initialize( request, new) DrawingAreaWidget request, new; { if (request->core.width == 0) new->core.width = 100; if (request->core.height == 0) new->core.height = 100; } /* Function Name: ConvertCursor * Description: Converts a name to a new cursor. * Arguments: w - the simple widget. * Returns: none. */ static void ConvertCursor(Widget w) { SimpleWidget simple = (SimpleWidget) w; XrmValue from, to; Cursor cursor; if (simple->simple.cursor_name == NULL) return; from.addr = (XPointer) simple->simple.cursor_name; from.size = strlen((char *) from.addr) + 1; to.size = sizeof(Cursor); to.addr = (XPointer) &cursor; if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to)) { if ( cursor != None) simple->simple.cursor = cursor; } else { XtAppErrorMsg(XtWidgetToApplicationContext(w), "convertFailed","ConvertCursor","XawError", "Simple: ConvertCursor failed.", (String *)NULL, (Cardinal *)NULL); } } static void MyRealize(w, valueMask, attributes) DrawingAreaWidget w; Mask *valueMask; XSetWindowAttributes *attributes; { Pixmap border_pixmap = 0; if (!XtIsSensitive((Widget)w)) { /* change border to gray; have to remember the old one, * so XtDestroyWidget deletes the proper one */ if (((SimpleWidget)w)->simple.insensitive_border == None) ((SimpleWidget)w)->simple.insensitive_border = XmuCreateStippledPixmap(XtScreen(w), w->core.border_pixel, w->core.background_pixel, w->core.depth); border_pixmap = w->core.border_pixmap; attributes->border_pixmap = w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border; *valueMask |= CWBorderPixmap; *valueMask &= ~CWBorderPixel; } ConvertCursor((Widget)w); if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None) *valueMask |= CWCursor; XtCreateWindow((Widget)w, (unsigned int)InputOutput, (Visual *)w->drawing_area.vis, *valueMask, attributes ); if (!XtIsSensitive((Widget)w)) w->core.border_pixmap = border_pixmap; } static void Destroy( w) DrawingAreaWidget w; { XtRemoveAllCallbacks((Widget)w, XtNexposeCallback); XtRemoveAllCallbacks((Widget)w, XtNinputCallback); XtRemoveAllCallbacks((Widget)w, XtNmotionCallback); XtRemoveAllCallbacks((Widget)w, XtNresizeCallback); XtRemoveAllCallbacks((Widget)w, XtNenterCallback); XtRemoveAllCallbacks((Widget)w, XtNleaveCallback); } /* Invoke expose callbacks */ static void Redisplay(w, event, region) DrawingAreaWidget w; XEvent *event; Region region; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_EXPOSE; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNexposeCallback, (char *)&cb); } /* Invoke resize callbacks */ static void resize_draw(w, event, args, n_args) DrawingAreaWidget w; XEvent *event; char *args[]; int n_args; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_RESIZE; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNresizeCallback, (char *)&cb); } /* Invoke input callbacks */ static void input_draw(w, event, args, n_args) DrawingAreaWidget w; XEvent *event; char *args[]; int n_args; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_INPUT; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNinputCallback, (char *)&cb); } /* Invoke motion callbacks */ static void motion_draw(w, event, args, n_args) DrawingAreaWidget w; XEvent *event; char *args[]; int n_args; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_MOTION; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNmotionCallback, (char *)&cb); } /* Invoke enter callbacks */ static void enter_draw(w, event, args, n_args) DrawingAreaWidget w; XEvent *event; char *args[]; int n_args; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_ENTER; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNenterCallback, (char *)&cb); } /* Invoke leave callbacks */ static void leave_draw(w, event, args, n_args) DrawingAreaWidget w; XEvent *event; char *args[]; int n_args; { XawDrawingAreaCallbackStruct cb; cb.reason = XawCR_LEAVE; cb.event = event; cb.window = XtWindow(w); XtCallCallbacks((Widget)w, XtNleaveCallback, (char *)&cb); } libsx-2.05/src/list.c0000644000175000017500000000677011252443541015634 0ustar amckinstryamckinstry/* This file contains routines to manipulate a scrolling list widget. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include #include #include "libsx.h" #include "libsx_private.h" /* * this structure maintains some internal state information about each * scrolled list widget. */ typedef struct ListInfo { Widget w; void (*func)(Widget w, char *str, int index, void *data); void *data; struct ListInfo *next; }ListInfo; static ListInfo *scroll_lists = NULL; /* * List Widget Creation Routines and stuff. */ static void list_callback(Widget w, XtPointer data, XtPointer call_data) { ListInfo *li = (ListInfo *)data; XawListReturnStruct *list = (XawListReturnStruct *)call_data; if (li->func) li->func(w, list->string, list->list_index, li->data); } static void destroy_list(Widget w, void *data, void *junk) { ListInfo *li=(ListInfo *)data, *curr; if (li == scroll_lists) scroll_lists = li->next; else { for(curr=scroll_lists; curr && curr->next != li; curr=curr->next) /* nothing */; curr->next = li->next; } free(li); } Widget MakeScrollList(char **item_list, int width, int height, ListCB func, void *data) { int n = 0; Arg wargs[10]; /* Used to set widget resources */ Widget list, vport; ListInfo *li; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; n = 0; XtSetArg(wargs[n], XtNwidth, width); n++; XtSetArg(wargs[n], XtNheight, height); n++; XtSetArg(wargs[n], XtNallowVert, True); n++; XtSetArg(wargs[n], XtNallowHoriz, True); n++; XtSetArg(wargs[n], XtNuseBottom, True); n++; vport = XtCreateManagedWidget("vport", viewportWidgetClass, lsx_curwin->form_widget,wargs,n); if (vport == NULL) return NULL; n = 0; XtSetArg(wargs[n], XtNlist, item_list); n++; XtSetArg(wargs[n], XtNverticalList, True); n++; XtSetArg(wargs[n], XtNforceColumns, True); n++; XtSetArg(wargs[n], XtNdefaultColumns, 1); n++; XtSetArg(wargs[n], XtNborderWidth, 1); n++; /* * Here we create the list widget and make it the child of the * viewport widget so that the viewport will properly handle scrolling * it and all that jazz. */ list = XtCreateManagedWidget("list", listWidgetClass, vport,wargs,n); if (list == NULL) { XtDestroyWidget(vport); return NULL; } li = (ListInfo *)malloc(sizeof(ListInfo)); if (li == NULL) { XtDestroyWidget(list); XtDestroyWidget(vport); return NULL; } XtAddCallback(list, XtNdestroyCallback, (XtCallbackProc)destroy_list, li); li->func = func; li->data = data; li->w = list; li->next = scroll_lists; scroll_lists = li; if (func) XtAddCallback(list, XtNcallback, list_callback, li); return list; } /* end of MakeScrollList() */ void SetCurrentListItem(Widget w, int list_index) { if (w && list_index >= 0) XawListHighlight(w, list_index); } int GetCurrentListItem(Widget w) { XawListReturnStruct *item; if (lsx_curwin->toplevel == NULL || w == NULL) return -1; item = XawListShowCurrent(w); if (item == NULL) return -1; return item->list_index; } void ChangeScrollList(Widget w, char **new_list) { if (lsx_curwin->toplevel && w && new_list) XawListChange(w, new_list, -1, -1, TRUE); } libsx-2.05/src/Makefile0000644000175000017500000000402411252443541016143 0ustar amckinstryamckinstry# # Makefile for the libsx library # # # If you have trouble building, edit the file ../libsx_defs and # change stuff there. That file gets included everywhere else, so # you only need to change things there once. # include ../libsx_defs LIBDIR=/usr/X11R6/lib INCLUDEDIR=/usr/X11R6/include/X11/SX SHAREDIR=/usr/share/libsx CC=gcc # # You shouldn't need to modify anything below here. # # LIBSXOBJS = draw.o toggle.o button.o string_entry.o libsx.o misc.o list.o\ font.o scrollbar.o menu.o popups.o colormap.o drawing.o\ dialog.o dirlist.o freq.o grabpix.o colorsel.o version.o OBJS = main.o callbacks.o all : libsx.a libsx.so libsx.a : $(LIBSXOBJS) rm -f libsx.a ar rc libsx.a $(LIBSXOBJS) $(RANLIB) libsx.a libsx.so : $(LIBSXOBJS) rm -f libsx.so $(CC) -shared -Wl,-soname,libsx.so draw.o toggle.o \ button.o string_entry.o libsx.o misc.o list.o font.o scrollbar.o \ menu.o popups.o colormap.o drawing.o dialog.o dirlist.o freq.o \ grabpix.o colorsel.o version.o -o libsx.so draw.o : draw.c libsx.h libsx_private.h toggle.o : toggle.c libsx.h libsx_private.h button.o : button.c libsx.h libsx_private.h string_entry.o : string_entry.c libsx.h libsx_private.h libsx.o : libsx.c libsx.h libsx_private.h misc.o : misc.c libsx.h libsx_private.h list.o : list.c libsx.h libsx_private.h scrollbar.o : scrollbar.c libsx.h libsx_private.h menu.o : menu.c libsx.h libsx_private.h check_mark.h popups.o : popups.c libsx.h libsx_private.h dialog.h colormap.o : colormap.c libsx.h libsx_private.h font.o : font.c libsx.h libsx_private.h dialog.o : dialog.c dialog.h dirlist.o : dirlist.c freq.o : freq.c grabpix.o : grabpix.c colorsel.o : colorsel.c version.o : version.c # # Demo program objects. # main.o : main.c main.h libsx.h callbacks.h callbacks.o : libsx.h callbacks.c install: mkdirhier $(LIBDIR) cp -f libsx.a libsx.so $(LIBDIR) mkdirhier $(INCLUDEDIR) cp -f libsx.h $(INCLUDEDIR) mkdirhier $(SHAREDIR) cp -f dialogs/dialogs* $(SHAREDIR) clean: rm -f *.o *~ dialogs/*~ core libsx.a libsx.so libsx-2.05/src/dialogs/0000755000175000017500000000000011252443541016125 5ustar amckinstryamckinstrylibsx-2.05/src/dialogs/dialogs.fr0000644000175000017500000000061311252443541020100 0ustar amckinstryamckinstry#define MAIN_DIAL 0 Oui Annuler Non Okay Annuler Reitérer #define POPUP_DIAL 6 Ok Annuler Question #define COLSEL_DIAL 9 [couleur initiale] [pourcent] Couleur : Mode Liste des valeurs RGB Saisie Approx Accepter Annuler #define FREQ_DIAL 17 Chemin Filtre Choisir dans la liste ou entrer un nom de fichier Fichier Aller à Home CWD Liste Cacher Annul Ok #define NUM_DIAL 28 libsx-2.05/src/dialogs/dialogs.de0000644000175000017500000000060011252443541020055 0ustar amckinstryamckinstry#define MAIN_DIAL 0 Ja Abbrech Nein OK Abbrech Wieder #define POPUP_DIAL 6 OK Abbrech Frage #define COLSEL_DIAL 9 [Initiale Farbe] [Annäherung] Setz Farbe Modus Liste RGB Werten Grab Farbe Annäherung Akzept Abbrech #define FREQ_DIAL 17 Suchpad Filter Wählen Datei aus Liste oder schreiben Zeichenfolge Datei Geh zu Home CWD Such Raus Abbrech OK #define NUM_DIAL 28 libsx-2.05/src/dialogs/Makefile0000644000175000017500000000021711252443541017565 0ustar amckinstryamckinstry# # Makefile for the libsx dialogs # SHAREDIR=/usr/share/libsx install: mkdirhier $(SHAREDIR) cp -f dialogs* $(SHAREDIR) clean: rm -f *~ libsx-2.05/src/dialogs/dialogs.en0000644000175000017500000000057711252443541020104 0ustar amckinstryamckinstry#define MAIN_DIAL 0 Yes Cancel No Okay Cancel Retry #define POPUP_DIAL 6 Okay Cancel Question #define COLSEL_DIAL 9 [initial color] [match] Set Color Mode List of RGB values Grab color Best match Accept Cancel #define FREQ_DIAL 17 Path Filter Select a File from the List or Enter a Name File Goto Home CWD Rescan Hide Cancel Ok #define NUM_DIAL 28 libsx-2.05/src/font.c0000644000175000017500000000313411252443541015616 0ustar amckinstryamckinstry/* This file contains routines that manipulate fonts. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" XFont GetFont(char *fontname) { XFontStruct *xfs; if (lsx_curwin->display == NULL || fontname == NULL) return NULL; xfs = XLoadQueryFont(lsx_curwin->display, fontname); return xfs; } void SetWidgetFont(Widget w, XFont f) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL || f == NULL) return; if ((di=libsx_find_draw_info(w)) != NULL) { XSetFont(lsx_curwin->display, di->drawgc, f->fid); di->font = f; return; } n = 0; XtSetArg(wargs[n], XtNfont, f); n++; XtSetValues(w, wargs, n); return; } XFont GetWidgetFont(Widget w) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ XFont f=NULL; DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return NULL; if ((di=libsx_find_draw_info(w)) != NULL) { return di->font; } n = 0; XtSetArg(wargs[n], XtNfont, &f); n++; XtGetValues(w, wargs, n); return f; } void FreeFont(XFont f) { if (lsx_curwin->display && f) XFreeFont(lsx_curwin->display, f); } int FontHeight(XFont f) { if (f) return (f->ascent+f->descent); else return -1; } int TextWidth(XFont f, char *txt) { if (f && txt) return XTextWidth(f, txt, strlen(txt)); else return -1; } libsx-2.05/src/draw.c0000644000175000017500000004356311252443541015617 0ustar amckinstryamckinstry/* This file contains routines that encapsulate a drawing area widget. * It is slightly different in format than the other files because it * also has some callback wrappers that extract relevant information and * then pass that to the user callback functions for redisplaying, * keyboard input and mouse clicks/motion. * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include "libsx.h" #include "libsx_private.h" #include #include "drawing.h" /* * Internal prototypes that massage the data into something more * digestable by regular humans. */ static void _redisplay(Widget w, void *data, XADCS *call_data); static void _resize(Widget w, void *data, XADCS *call_data); static void _do_input(Widget w, void *data, XADCS *call_data); static void _do_motion(Widget w, void *data, XADCS *call_data); static void _do_enter(Widget w, void *data, XADCS *call_data); static void _do_leave(Widget w, void *data, XADCS *call_data); static void _do_destroy(Widget w,void *data, XADCS *call_data); static char *TranslateKeyCode(XEvent * ev); static GC setup_gc(Widget w); static DrawInfo *draw_info_head = NULL; static DrawInfo *cur_di = NULL; /* current drawing area info structure */ static Window window; /* only used below by the drawing functions. */ static GC drawgc; static Display *display = NULL; /* * Drawing Area Creation Routine. */ Widget MakeDrawArea(int width, int height, RedisplayCB redisplay, void *data) { int n = 0; Arg wargs[8]; /* Used to set widget resources */ Widget draw_widget; DrawInfo *di; Cursor cross = XCreateFontCursor(lsx_curwin->display, XC_crosshair); if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; di = (DrawInfo *) calloc(sizeof(DrawInfo), 1); if (di == NULL) return NULL; n = 0; XtSetArg(wargs[n], XtNwidth, width); n++; XtSetArg(wargs[n], XtNheight, height); n++; XtSetArg(wargs[n], XtNcursor, cross); n++; #ifdef OPENGL_SUPPORT if (lsx_curwin->xvi) { XtSetArg(wargs[n], XtNvisual, lsx_curwin->xvi->visual); n++; XtSetArg(wargs[n], XtNcolormap, lsx_curwin->draw_area_cmap); n++; XtSetArg(wargs[n], XtNdepth, lsx_curwin->draw_area_depth); n++; } #endif /* OPENGL_SUPPORT */ draw_widget = XtCreateManagedWidget("drawing_area", drawingAreaWidgetClass, lsx_curwin->form_widget, wargs, n); if (draw_widget == NULL) { free(di); return NULL; } di->drawgc = setup_gc(draw_widget); di->foreground = BlackPixel(lsx_curwin->display, lsx_curwin->screen); di->background = WhitePixel(lsx_curwin->display, lsx_curwin->screen); di->mask = 0xffffffff; di->user_data = data; di->redisplay = redisplay; XtAddCallback(draw_widget, XtNexposeCallback, (XtCallbackProc)_redisplay,di); XtAddCallback(draw_widget, XtNresizeCallback, (XtCallbackProc)_resize, di); XtAddCallback(draw_widget, XtNinputCallback, (XtCallbackProc)_do_input, di); XtAddCallback(draw_widget, XtNmotionCallback, (XtCallbackProc)_do_motion,di); XtAddCallback(draw_widget, XtNenterCallback, (XtCallbackProc)_do_enter, di); XtAddCallback(draw_widget, XtNleaveCallback, (XtCallbackProc)_do_leave, di); XtAddCallback(draw_widget,XtNdestroyCallback,(XtCallbackProc)_do_destroy,di); lsx_curwin->last_draw_widget = draw_widget; di->widget = draw_widget; di->next = draw_info_head; draw_info_head = di; cur_di = di; /* * Make sure the font is set to something sane. */ if (lsx_curwin->font == NULL) lsx_curwin->font = GetFont("fixed"); SetWidgetFont(draw_widget, lsx_curwin->font); return draw_widget; } /* * Internal function for getting a graphics context so we can draw. */ static GC setup_gc(Widget w) { int fore_g, back_g; /* Fore and back ground pixels */ GC drawgc; back_g = WhitePixel(XtDisplay(w), DefaultScreen(XtDisplay(w))); fore_g = BlackPixel(XtDisplay(w), DefaultScreen(XtDisplay(w))); /* Create drawing GC */ drawgc = XCreateGC(XtDisplay(w), DefaultRootWindow(XtDisplay(w)), 0, 0); XSetBackground(XtDisplay(w), drawgc, back_g); XSetForeground(XtDisplay(w), drawgc, fore_g); XSetFunction(XtDisplay(w), drawgc, GXcopy); return drawgc; } /* end of setup_gc() */ /* * This function searches through our list of drawing area info structures * and returns the one that matches the specified widget. We have to be * careful and make sure that the DrawInfo structure we match is for the * right display. */ DrawInfo * libsx_find_draw_info(Widget w) { DrawInfo *di; if (w == NULL) return NULL; for (di = draw_info_head; di; di = di->next) { if (di->widget == w && XtDisplay(di->widget) == XtDisplay(w)) break; /* then we've found it */ } return di; } int TurnOnBackingStore(Widget w) { XSetWindowAttributes xswa; if (w == NULL || DoesBackingStore(XtScreen(w)) == 0) return FALSE; xswa.backing_store = Always; XChangeWindowAttributes(XtDisplay(w), XtWindow(w), CWBackingStore, &xswa); return TRUE; } void SetButtonDownCB(Widget w, MouseButtonCB button_down) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->button_down = button_down; } void SetButtonUpCB(Widget w, MouseButtonCB button_up) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->button_up = button_up; } void SetKeypressCB(Widget w, KeyCB keypress) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->keypress = keypress; } void SetMouseMotionCB(Widget w, MotionCB motion) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->motion = motion; } void SetEnterCB(Widget w, EnterCB enter) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->enter = enter; } void SetLeaveCB(Widget w, EnterCB leave) { DrawInfo *di; if ((di = libsx_find_draw_info(w)) == NULL) return; di->leave = leave; } void SetDrawMode(int mode) { if (display == NULL) return; if (mode == SANE_XOR) { cur_di->mask = cur_di->foreground ^ cur_di->background; XSetForeground(display, drawgc, 0xffffffff); XSetBackground(display, drawgc, cur_di->background); XSetFunction(display, drawgc, GXxor); XSetPlaneMask(display, drawgc, cur_di->mask); } else { XSetForeground(display, drawgc, cur_di->foreground); XSetBackground(display, drawgc, cur_di->background); XSetFunction(display, drawgc, mode); XSetPlaneMask(display, drawgc, 0xffffffff); cur_di->mask = 0xffffffff; } } void SetLineWidth(int width) { if (display == NULL || cur_di == NULL || width < 0) return; XSetLineAttributes(display, drawgc, width, cur_di->line_style, CapButt, JoinMiter); cur_di->width = width; } void SetLineStyle(int line_style) { if (display == NULL || cur_di == NULL) return; XSetLineAttributes(display, drawgc, cur_di->width, line_style, CapButt, JoinMiter); cur_di->line_style = line_style; } void SetDrawArea(Widget w) { DrawInfo *di; if (lsx_curwin->toplevel == NULL || w == NULL) return; if ((di = libsx_find_draw_info(w)) == NULL)/* w isn't really a draw area */ return; window = (Window) XtWindow(w); drawgc = di->drawgc; display = XtDisplay(w); cur_di = di; lsx_curwin->last_draw_widget = w; #ifdef OPENGL_SUPPORT if (lsx_curwin->gl_context) glXMakeCurrent(display, XtWindow(w), lsx_curwin->gl_context); #endif /* OPENGL_SUPPORT */ } #ifdef OPENGL_SUPPORT void SwapBuffers(void) { if (lsx_curwin == NULL || lsx_curwin->last_draw_widget == NULL) return; glXSwapBuffers(display, window); } #endif /* OPENGL_SUPPORT */ void GetDrawAreaSize(int *w, int *h) { int n; Arg wargs[2]; Dimension nwidth, nheight; if (lsx_curwin->toplevel == NULL || lsx_curwin->last_draw_widget == NULL || w == NULL || h == NULL) return; *w = *h = 0; n = 0; XtSetArg(wargs[n], XtNwidth, &nwidth); n++; XtSetArg(wargs[n], XtNheight, &nheight); n++; XtGetValues(lsx_curwin->last_draw_widget, wargs, n); *w = nwidth; *h = nheight; } /* * These are the drawing area "draw" functions. You use these functions * to draw into a DrawingArea widget. */ void ClearDrawArea(void) { XClearWindow(display, window); } void SetColor(int color) { if (cur_di == NULL || display == NULL) return; cur_di->foreground = color; if (cur_di->mask != 0xffffffff) XSetPlaneMask(display, drawgc, cur_di->foreground ^ cur_di->background); else XSetForeground(display, drawgc, color); } void DrawPixel(int x1, int y1) { XDrawPoint(display, window, drawgc, x1, y1); } int GetPixel(int x1, int y1) { char ch; GetImage(&ch, x1, y1, 1, 1); /* gag! no other easy way to do it */ return (int) ch; } void DrawLine(int x1, int y1, int x2, int y2) { XDrawLine(display, window, drawgc, x1, y1, x2, y2); } void DrawPolyline(XPoint * points, int n) { XDrawLines(display, window, drawgc, points, n, CoordModeOrigin); } void DrawFilledPolygon(XPoint * points, int n) { XFillPolygon(display, window, drawgc, points, n, Complex, CoordModeOrigin); } void DrawFilledBox(int x, int y, int fwidth, int fheight) { if (fwidth < 0) { fwidth *= -1; x -= fwidth; } if (fheight < 0) { fheight *= -1; y -= fheight; } XFillRectangle(display, window, drawgc, x, y, fwidth, fheight); } void DrawBox(int x, int y, int bwidth, int bheight) { if (bwidth < 0) { bwidth *= -1; x -= bwidth; } if (bheight < 0) { bheight *= -1; y -= bheight; } XDrawRectangle(display, window, drawgc, x, y, bwidth, bheight); } void DrawText(char *string, int x, int y) { XDrawImageString(display, window, drawgc, x, y, string, strlen(string)); } void DrawTextOver(char *string, int x, int y) { XDrawString(display, window, drawgc, x, y, string, strlen(string)); } void DrawArc(int x, int y, int awidth, int aheight, int angle1, int angle2) { angle1 = angle1 * 64; /* multiply by 64 because X works in 64'ths of a */ angle2 = angle2 * 64; /* a degree and we just want to work in degrees */ if (awidth < 0) { awidth *= -1; x -= awidth; } if (aheight < 0) { aheight *= -1; y -= aheight; } XDrawArc(display, window, drawgc, x, y, awidth, aheight, angle1, angle2); } void DrawFilledArc(int x, int y, int awidth, int aheight, int angle1, int angle2) { angle1 = angle1 * 64; /* multiply by 64 because X works in 64'ths of a */ angle2 = angle2 * 64; /* a degree and we just want to work in degrees */ if (awidth < 0) { awidth *= -1; x -= awidth; } if (aheight < 0) { aheight *= -1; y -= aheight; } XFillArc(display, window, drawgc, x, y, awidth, aheight, angle1, angle2); } void DrawImage(char *data, int x, int y, int width, int height) { XImage *xi; if (lsx_curwin->toplevel == NULL || data == NULL) return; xi = XCreateImage(display, DefaultVisual(display, DefaultScreen(display)), DefaultDepth(display,DefaultScreen(display)), ZPixmap, 0, data, width, height, XBitmapPad(display), width); if (xi == NULL) return; XPutImage(display, window, drawgc, xi, 0, 0, x, y, xi->width, xi->height); XFree((char *) xi); } void DrawBitmap(char *data, int x, int y, int width, int height) { Pixmap pix; if (lsx_curwin->toplevel == NULL || data == NULL) return; pix = XCreatePixmapFromBitmapData(display, window, data, width, height, cur_di->foreground, cur_di->background, DefaultDepth(display, lsx_curwin->screen)); if (pix == None) return; XCopyArea(display, pix, window, drawgc, 0, 0, width, height, x, y); XFreePixmap(display, pix); } /* * This function is kind of gaggy in some respects because it * winds up requiring twice the amount of memory really needed. * It would be possible to return the XImage structure directly, * but that kind of defeats the whole purpose of libsx in addition * to the fact that X packs the data in ways that might not be * what the user wants. So we unpack the data and just put the * raw bytes of the image in the user's buffer. */ void GetImage(char *data, int x, int y, int width, int height) { XImage *xi; int i, j; char *xi_data; if (lsx_curwin->toplevel == NULL || data == NULL) return; xi = XGetImage(display, window, x, y, width, height, ~0, ZPixmap); xi_data = xi->data; for (i = 0; i < height; i++) { char *line_start = xi_data; for (j = 0; j < width; j++, xi_data++, data++) *data = *xi_data; while ((xi_data - line_start) < xi->bytes_per_line) xi_data++; } XFree((char *) xi); } /* * Below are internal callbacks that the drawing area calls. They in * turn call the user callback functions. */ /* * Internal callback routines for the drawing areas that massage * all the X garbage into a more digestable form. */ static void _redisplay(Widget w, void *data, XADCS * call_data) { int new_width, new_height; DrawInfo *di = data; if (call_data->event->xexpose.count != 0) /* Wait until last expose event */ return; SetDrawArea(w); GetDrawAreaSize(&new_width, &new_height); /* get the draw area size */ if (di->redisplay) di->redisplay(w, new_width, new_height, di->user_data); } /* Called when a DrawingArea is resized. */ static void _resize(Widget w, void *data, XADCS * call_data) { int new_width, new_height; DrawInfo *di = data; if (call_data->event->xexpose.count != 0) /* Wait until last expose event */ return; SetDrawArea(w); GetDrawAreaSize(&new_width, &new_height); /* get the new draw area size */ if (di->redisplay) di->redisplay(w, new_width, new_height, di->user_data); } /* Called when the pointer enter a DrawingArea. */ static void _do_enter(Widget w, void *data, XADCS * call_data) { DrawInfo *di = data; XEnterWindowEvent *event = (XEnterWindowEvent *) call_data->event; if (di->enter) di->enter(w, event->x, event->y, di->user_data); } /* Called when the pointer leaves a DrawingArea. */ static void _do_leave(Widget w, void *data, XADCS * call_data) { DrawInfo *di = data; XLeaveWindowEvent *event = (XLeaveWindowEvent *) call_data->event; if (di->leave) di->leave(w, event->x, event->y, di->user_data); } void _do_destroy(Widget w, void *data, XADCS *call_data) { DrawInfo *di = (DrawInfo *)data; DrawInfo *curr; if (di == draw_info_head) draw_info_head = di->next; else { for(curr=draw_info_head; curr && curr->next != di; curr=curr->next) /* nothing */; if (curr == NULL) /* hmmm, that's odd -- we didn't find it */ return; curr->next = di->next; /* unlink this guy from the list */ } free(di); } /* Called when a DrawingArea has input (either mouse or keyboard). */ static void _do_input(Widget w, void *data, XADCS * call_data) { char *input; DrawInfo *di = data; SetDrawArea(w); if (call_data->event->type == ButtonPress) { if (di->button_down) di->button_down(w, call_data->event->xbutton.button, call_data->event->xbutton.x, call_data->event->xbutton.y, di->user_data); } else if (call_data->event->type == ButtonRelease) { if (di->button_up) di->button_up(w, call_data->event->xbutton.button, call_data->event->xbutton.x, call_data->event->xbutton.y, di->user_data); } else if (call_data->event->type == KeyPress) { input = TranslateKeyCode(call_data->event); if (input && di->keypress) di->keypress(w, input, 0, di->user_data); } else if (call_data->event->type == KeyRelease) { input = TranslateKeyCode(call_data->event); if (input && di->keypress) di->keypress(w, input, 1, di->user_data); } } static void _do_motion(Widget w, void *data, XADCS * call_data) { DrawInfo *di = data; SetDrawArea(w); if (di->motion) di->motion(w, call_data->event->xmotion.x, call_data->event->xmotion.y, di->user_data); } #define KEY_BUFF_SIZE 256 static char key_buff[KEY_BUFF_SIZE]; static char * TranslateKeyCode(XEvent * ev) { int count; char *tmp; KeySym ks; if (ev) { count = XLookupString((XKeyEvent *) ev, key_buff, KEY_BUFF_SIZE, &ks, NULL); key_buff[count] = '\0'; if (count == 0) { tmp = XKeysymToString(ks); if (tmp) strcpy(key_buff, tmp); else strcpy(key_buff, ""); } return key_buff; } else return NULL; } #define ABS(x) ((x < 0) ? -x : x) #define SWAP(a,b) { a ^= b; b ^= a; a ^= b; } void ScrollDrawArea(int dx, int dy, int x1, int y1, int x2, int y2) { int w, h, x3, y3, x4, y4, _dx_, _dy_; Window win = window; /* window is a static global */ if (dx == 0 && dy == 0) return; if (display == NULL) return; if (x2 < x1) SWAP(x1, x2); if (y2 < y1) SWAP(y1, y2); _dx_ = ABS(dx); _dy_ = ABS(dy); x3 = x1 + _dx_; y3 = y1 + _dy_; x4 = x2 - _dx_ + 1; y4 = y2 - _dy_ + 1; w = x2 - x3 + 1; h = y2 - y3 + 1; if (dx <= 0) { if (dy <= 0) { XCopyArea(display, win, win, drawgc, x1, y1, w, h, x3, y3); if (_dy_) XClearArea(display, win, x1, y1, w + _dx_, _dy_, FALSE); if (_dx_) XClearArea(display, win, x1, y1, _dx_, h, FALSE); } else /* dy > 0 */ { XCopyArea(display, win, win, drawgc, x1, y3, w, h, x3, y1); XClearArea(display, win, x1, y4, w + _dx_, _dy_, FALSE); if (_dx_) XClearArea(display, win, x1, y1, _dx_, h, FALSE); } } else /* dx > 0 */ { if (dy <= 0) { XCopyArea(display, win, win, drawgc, x3, y1, w, h, x1, y3); if (_dy_) XClearArea(display, win, x1, y1, w + _dx_, _dy_, FALSE); XClearArea(display, win, x4, y3, _dx_, h, FALSE); } else /* dy > 0 */ { XCopyArea(display, win, win, drawgc, x3, y3, w, h, x1, y1); XClearArea(display, win, x1, y4, w + _dx_, _dy_, FALSE); XClearArea(display, win, x4, y1, _dx_, h, FALSE); } } } libsx-2.05/src/libsx.h0000644000175000017500000002553511252443541016007 0ustar amckinstryamckinstry/* This file contains all the header definitions for working with this * library of functions that make X stuff a lot easier to swallow. * * -- This code under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #ifndef _LIBSX_H_ /* prevent accidental re-inclusions */ #define _LIBSX_H_ #ifdef __cplusplus /* be friendly to people using C++ */ extern "C" { #endif #include #define SX_SHAREDIR "/usr/share/libsx" /* * Predefined Args */ extern char **PredefArgs; /* * Version and author information */ char *LibVersion(); char *Author(); /* * General prototypes for the setup functions */ void ReadLocale(char *language); int OpenDisplay(int argc, char **argv); int GLOpenDisplay(int argc, char **argv, int *attributes); void ShowDisplay(void); void MainLoop(void); void CheckForEvent(void); void SyncDisplay(void); Widget MakeWindow(char *window_name, char *display_name, int exclusive); void SetCurrentWindow(Widget w); void CloseWindow(void); void ExitMainLoop(void); /* only call after CloseWindow() */ /* #define's for use with MakeWindow() */ #define SAME_DISPLAY NULL #define NONEXCLUSIVE_WINDOW 0 #define EXCLUSIVE_WINDOW 1 /* #define for use with SetCurrentWindow() */ #define ORIGINAL_WINDOW NULL Widget GetTopWidget(Widget w); Widget MakeForm(Widget parent); Widget GetForm(void); void SetForm(Widget form); /* for use w/MakeForm() and SetForm() */ #define TOP_LEVEL_FORM NULL /* * These are typedef's for the various styles of callback functions. */ typedef void (*ButtonCB)(Widget w, void *data); typedef void (*StringCB)(Widget w, char *string, void *data); typedef void (*ScrollCB)(Widget w, float new_val, void *data); typedef void (*ListCB)(Widget w, char *string, int index, void *data); typedef void (*FreqCB)(Widget w, char *dir_name, char *file_name, void *data); /* * These typedef's are for drawing area callbacks only. */ typedef void (*RedisplayCB)(Widget w, int new_width, int new_height, void *d); typedef void (*MouseButtonCB)(Widget w, int button, int x, int y, void *dat); typedef void (*KeyCB)(Widget w, char *input, int up_or_down, void *data); typedef void (*MotionCB)(Widget w, int x, int y, void *data); typedef void (*EnterCB)(Widget w, int x, int y, void *data); typedef void (*LeaveCB)(Widget w, int x, int y, void *data); /* * Prototypes for the widget creation functions. General functions * that apply to any widget (such as setting its color or position) follow * after these. */ /* * Button and Label Widget routines. */ Widget MakeButton(char *label, ButtonCB function, void *data); Widget MakeLabel(char *txt); /* * Toggle Widget routines. */ Widget MakeToggle(char *txt, int state, Widget w, ButtonCB func, void *d); void SetToggleState(Widget w, int state); int GetToggleState(Widget w); /* * Drawing Area and drawing functions. */ Widget MakeDrawArea(int width, int height, RedisplayCB redisplay, void *data); void SetButtonDownCB(Widget w, MouseButtonCB button_down); void SetButtonUpCB(Widget w, MouseButtonCB button_up); void SetKeypressCB(Widget w, KeyCB keypress); void SetMouseMotionCB(Widget w, MotionCB motion); void SetEnterCB(Widget w, EnterCB enter); void SetLeaveCB(Widget w, LeaveCB leave); int TurnOnBackingStore(Widget w); void SetColor(int color); void SetDrawMode(int mode); #define SANE_XOR 0x7f /* A sane mode for drawing XOR lines and stuff */ void SetLineStyle(int style); /* LineSolid, LineOnOffDash, LineDoubleDash */ void SetLineWidth(int width); void SetDrawArea(Widget w); void GetDrawAreaSize(int *w, int *h); void ClearDrawArea(void); void DrawPixel(int x1, int y1); int GetPixel(int x1, int y1); void DrawLine(int x1, int y1, int x2, int y2); void DrawPolyline(XPoint *points, int n); void DrawFilledPolygon (XPoint *points, int n); void DrawFilledBox(int x, int y, int width, int height); void DrawBox(int x, int y, int width, int height); void DrawText(char *string, int x, int y); void DrawArc(int x, int y, int width, int height, int angle1, int angle2); void DrawFilledArc(int x, int y, int w, int h, int angle1, int angle2); void DrawImage(char *data, int x, int y, int width, int height); void DrawBitmap(char *data, int x, int y, int width, int height); void GetImage(char *data, int x, int y, int width, int height); void ScrollDrawArea(int dx, int dy, int x1,int y1, int x2, int y2); void SwapBuffers(void); /* only if libsx compiled with -DOPENGL_SUPPORT */ char *GrabPixel(char *format); /* * String Entry routines. */ Widget MakeStringEntry(char *txt, int size, StringCB func, void *data); void SetStringEntry(Widget w, char *new_text); char *GetStringEntry(Widget w); /* * Ascii Text display widget routines. */ Widget MakeTextWidget(char *txt, int is_file, int editable, int w, int h); void SetTextEditable(Widget w, int can_edit); void SetTextWidgetText(Widget w, char *text, int is_file); char *GetTextWidgetText(Widget w); void SetTextWidgetPosition(Widget w, int text_pos); /* * File requestor */ char *GetFile(char *_label, char *_path, FreqCB _func, void *_data); void SetFreqFilter(char *filter); /* defines for the is_file argument */ #define EDIT_FILE 1 #define EDIT_STRING 0 /* defines for the editable argument to MakeTextWidget() */ #define CAN_MODIFY 1 #define NO_MODIFY 0 /* * Scrollbar routines. */ Widget MakeHorizScrollbar(int len, ScrollCB scroll_func, void *data); Widget MakeVertScrollbar( int height, ScrollCB scroll_func, void *data); void SetScrollbar(Widget w, float where, float max, float size_shown); void SetScrollbarStep(Widget w, float fact); void SetThumbBitmap(Widget w, char *black_bits, int width, int height); void SetScrollbarDirection(float dir); /* * Scrolled list routines. */ Widget MakeScrollList(char **list, int width, int height, ListCB func,void *d); void SetCurrentListItem(Widget w, int list_index); int GetCurrentListItem(Widget w); void ChangeScrollList(Widget w, char **new_list); /* * Menu and MenuItem routines. */ Widget MakeMenu(char *name); Widget MakeMenuItem(Widget menu, char *name, ButtonCB func, void *arg); void SetMenuItemChecked(Widget w, int state); int GetMenuItemChecked(Widget w); /* * Widget position setting functions (used to do algorithmic layout). */ void SetWidgetPos(Widget w, int where1, Widget from1,int where2,Widget from2); /* * define's for button/gadget placement, used to call SetWidgetPos() */ #define NO_CARE 0x00 /* don't care where the gadget is placed */ #define PLACE_RIGHT 0x01 /* place me to the right of specified gadget */ #define PLACE_UNDER 0x02 /* place me under the specified gadget */ void AttachEdge(Widget w, int edge, int attach_to); #define LEFT_EDGE 0x00 /* These #define's specify which edge we want */ #define RIGHT_EDGE 0x01 #define TOP_EDGE 0x02 #define BOTTOM_EDGE 0x03 #define ATTACH_LEFT 0x00 /* attach given edge to the left side of form */ #define ATTACH_RIGHT 0x01 /* attach given edge to the right side of form */ #define ATTACH_TOP 0x02 /* attach given edge to the top of the form */ #define ATTACH_BOTTOM 0x03 /* attach given edge to the bottom of the form */ /* * General Setting/Getting of Widget attributes. These apply to any * type of widget. */ void SetWindowTitle(char *title); void SetIconTitle(char *title); void SetFgColor(Widget w, int color); void SetBgColor(Widget w, int color); void SetBorderColor(Widget w, int color); int GetFgColor(Widget w); int GetBgColor(Widget w); void SetLabel(Widget w, char *txt); void SetWidgetState(Widget w, int state); /* turn widgets on and off */ int GetWidgetState(Widget w); void SetWidgetBitmap(Widget w, char *data, int width, int height); #define XPM_SUPPORT #ifdef XPM_SUPPORT void SetWidgetPixmap(Widget w, char **xpmdata); #endif void SetWidgetSize(Widget w, int width, int height); void Beep(void); /* * Font things. */ typedef XFontStruct *XFont; /* make it a little easier to read */ XFont GetFont(char *fontname); void SetWidgetFont(Widget w, XFont f); XFont GetWidgetFont(Widget w); void FreeFont(XFont f); int FontHeight(XFont f); int TextWidth(XFont f, char *txt); /* * Miscellaneous functions. */ typedef void (*GeneralCB)(void *data); typedef void (*IOCallback)(void *data, int *fd); void AddTimeOut(unsigned long interval, GeneralCB func, void *data); void AddReadCallback(int fd, IOCallback func, void *data); void AddWriteCallback(int fd, IOCallback func, void *data); /* * User-input functions */ char *GetString(char *blurb, char *default_string); char *GetLongString(char *blurb, char *default_string, int width); char *GetText(char *blurb, char *default_string, int width, int height); int GetYesNo(char *question); int GetOkay(char *blurb); int GetTriState(char *blurb); /* * Labels */ #define NUM_DIAL 28 extern char *SX_Dialog[NUM_DIAL]; #define MAIN_DIAL 0 #define POPUP_DIAL 6 #define COLSEL_DIAL 9 #define FREQ_DIAL 17 /* * Colormap things. */ extern int WHITE, /* Global color values to use for drawing in color */ BLACK, RED, GREEN, BLUE, YELLOW, HILIGHT, BUTTONBG, INPUTBG; /* * Getting/Setting/Freeing Color and Colormap function prototypes */ void GetStandardColors(void); int GetNamedColor(char *name); int GetRGBColor(int r, int g, int b); void FreeStandardColors(void); int GetPrivateColor(void); void SetPrivateColor(int which, int r, int g, int b); void FreePrivateColor(int which); /* * The following functions completely take over the display colormap. * ** Use with caution ** */ int GetAllColors(void); void SetColorMap(int num); void SetMyColorMap(int n, unsigned char *r, unsigned char *g,unsigned char *b); void FreeAllColors(void); /* * Prototype of data for color selector widget */ typedef struct { void *data; Widget csel_window; Widget lmode, lcolor, draw, scroll_list; Widget red_label, red_string, red_scroll; Widget green_label, green_string, green_scroll; Widget blue_label, blue_string, blue_scroll; Widget black_label, black_string, black_scroll; int color; int mode; int cancelled; int output; float r, g, b; float h, s, v; float c, m, y, k; char rgb_list[1000][60]; char *rgb_ptr[1000]; char match_list[1000][80]; char *match_ptr[1000]; char save[40]; } CSelData; typedef void (*CSelCB)(Widget w, CSelData *data); char * SelectColor(char *inicolor, int output, char *txt, CSelCB func, void *data); /* * define's for use in calling SetColorMap() */ #define GREY_SCALE_1 0 /* grey-scale with a few other colors */ #define GREY_SCALE_2 1 /* pure grey-scale (0-255) */ #define RAINBOW_1 2 /* different types of rainbows/bands of colors */ #define RAINBOW_2 3 #ifdef __cplusplus } #endif #endif /* _LIBSX_H_ */ libsx-2.05/src/check_mark.h0000644000175000017500000000045611252443541016750 0ustar amckinstryamckinstry#define check_mark_width 16 #define check_mark_height 16 static unsigned char check_mark_bits[] = { 0x00, 0xc0, 0x00, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0x83, 0x03, 0xcf, 0x01, 0xdf, 0x01, 0xfc, 0x01, 0xf8, 0x00, 0xf0, 0x00, 0xe0, 0x00}; libsx-2.05/src/version.c0000644000175000017500000000035111252443541016333 0ustar amckinstryamckinstrystatic char libsx_version[] = "Libsx version 2.05"; static char libsx_blurb[] = "Originally written by Dominic Giampaolo dbg@sgi.com"; char *LibVersion() { return libsx_version; } char *Author() { return libsx_blurb; } libsx-2.05/src/libsx_private.h0000644000175000017500000000250111252443541017525 0ustar amckinstryamckinstry/* * Structures and variables private to libsx. */ typedef struct WindowState { int screen; int window_shown; Window window; Display *display; Widget toplevel, toplevel_form, form_widget, last_draw_widget; int has_standard_colors; int named_colors[256]; int color_index; Colormap cmap; Pixmap check_mark; XFontStruct *font; #ifdef OPENGL_SUPPORT XVisualInfo *xvi; GLXContext gl_context; Colormap draw_area_cmap; int draw_area_depth; #endif /* OPENGL_SUPPORT */ struct WindowState *next; }WindowState; /* global list of open windows. defined in libsx.c, used everywhere */ extern volatile WindowState *lsx_curwin; typedef struct DrawInfo { RedisplayCB redisplay; MouseButtonCB button_down; MouseButtonCB button_up; KeyCB keypress; MotionCB motion; EnterCB enter; LeaveCB leave; GC drawgc; /* Graphic Context for drawing in this widget */ int foreground; /* need to save these so we know what they are */ int background; int width; int line_style; unsigned long mask; XFontStruct *font; void *user_data; Widget widget; struct DrawInfo *next; }DrawInfo; DrawInfo *libsx_find_draw_info(Widget w); /* private internal function */ libsx-2.05/src/xstuff.h0000644000175000017500000000050011252443541016166 0ustar amckinstryamckinstry#include #include #include #include #include #include #ifdef OPENGL_SUPPORT #include #include #endif /* OPENGL_SUPPORT */ #define XPM_SUPPORT #ifdef XPM_SUPPORT #include #endif libsx-2.05/src/toggle.c0000644000175000017500000000732111252443541016133 0ustar amckinstryamckinstry/* This file contains routines that manage creating toggle widgets (that * is, widgets that have state, either on or off) and radio group widgets * (radio groups are a set of mutually exclusive toggles). * * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include #include "libsx.h" #include "libsx_private.h" /* * Toggle Button Creation/Manipulation routines. */ Widget MakeToggle(char *txt, int state, Widget w, ButtonCB func, void *d) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ Widget toggle; char *name = "toggle"; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; n = 0; if (txt) { XtSetArg(wargs[n], XtNlabel, txt); n++; } XtSetArg(wargs[n], XtNstate, (Boolean)state); n++; if (w) { char *s = XtName(w); /* * If the widget we were given is not part of a radio group, the * user obviously is screwed up, so just dump out. */ if (s==NULL || (strcmp(s,"toggle") != 0 && strcmp(s,"radio_group") != 0)) return NULL; XtSetArg(wargs[n], XtNradioGroup, w); n++; name = "radio_group"; } toggle = XtCreateManagedWidget(name, toggleWidgetClass, lsx_curwin->form_widget,wargs,n); if (toggle == NULL) return NULL; if (w) { void *data; n = 0; XtSetArg(wargs[n], XtNradioData, toggle); n++; XtSetValues(toggle, wargs, n); /* * Check if the radioData resource is set for the widget w. If * it isn't, set it here, so it is set for all widgets that * are part of the radioGroup. This only gets executed to * patch up the first toggle of a radio group that never had * its radioData resource set. */ n=0; XtSetArg(wargs[n], XtNradioData, &data); n++; XtGetValues(w, wargs, n); if (data != w) /* if we already set the radioData field, then data == w */ { n=0; XtSetArg(wargs[n], XtNradioData, w); n++; XtSetValues(w, wargs, n); } } if (func) XtAddCallback(toggle, XtNcallback, (XtCallbackProc)func, d); return toggle; } /* end of MakeToggle() */ void SetToggleState(Widget w, int state) { int n=0; Arg wargs[5]; void *data; if (lsx_curwin->toplevel == NULL || w == NULL) return; n=0; XtSetArg(wargs[n], XtNradioData, &data); n++; XtGetValues(w, wargs, n); if (data != w) /* only happens if we're not in a radio group */ { Boolean old_state; n=0; XtSetArg(wargs[n], XtNstate, &old_state); n++; XtGetValues(w, wargs, n); if (old_state == state) /* no state change */ return; n=0; XtSetArg(wargs[n], XtNstate, (Boolean)state); n++; XtSetValues(w, wargs, n); /* make sure callbacks get called since we changed state */ XtCallCallbacks(w, XtNcallback, NULL); } else /* widget is part of a radio group, so do things right */ { Widget cur_widg; cur_widg = (Widget)XawToggleGetCurrent(w); if ((cur_widg != w && state == FALSE) || (cur_widg == w && state == TRUE)) return; /* early out because there is no state change */ if (state == TRUE) XawToggleSetCurrent(w, w); else if (state == FALSE) /* current widget is on, turn it off */ XawToggleUnsetCurrent(w); } } int GetToggleState(Widget w) { Boolean state=0; int n=0; Arg wargs[2]; if (w == NULL) return FALSE; n=0; XtSetArg(wargs[n], XtNstate, &state); n++; XtGetValues(w, wargs, n); return (int)state; } libsx-2.05/src/dialog.h0000644000175000017500000000172311252443541016116 0ustar amckinstryamckinstry/* * $Id: Dialog.c,v 1.3.1.4 1991/10/14 16:41:56 mallet Exp $ * * [ This file is blatantly borrowed from the pixmap distribution. ] * [ It was written by the fellows below, and they disclaim all ] * [ warranties, expressed or implied, in this software. ] * [ As if anyone cares about that... ] * * Copyright 1991 Lionel Mallet * * Author: Davor Matic, MIT X Consortium */ #define Yes 16 #define No 32 #define Empty 0 #define Okay 1 #define Abort 2 #define Cancel 4 #define Retry 8 typedef struct { Widget top_widget, shell_widget, dialog_widget; int options; } _Dialog, *Dialog; Dialog CreateDialog(Widget top_widget, char *name, int options); void FreeDialog(Dialog dialog); void PositionPopup(Widget shell_widget); int PopupDialog(XtAppContext app_con, Dialog popup, char *message, char *suggestion, char **answer, XtGrabKind grab); void PopdownDialog(Dialog popup, char **answer); libsx-2.05/src/colorsel.c0000644000175000017500000005465711252443541016512 0ustar amckinstryamckinstry/* * Color selector widget. The function SelectColor() pops up a modal window * that lets a user interactively play with a color in either RGB or * HSV or CMYK space and then returns the chosen value to your program. * * Written by Allen Martin (amartin@cs.wpi.edu) * Improved by J.-P. Demailly (demailly@ujf-grenoble.fr) * SelectColor() now accesses the RGB data file and has a Grab color button * */ char *SX_ColorSelector_Label[] = { }; #define RGBTXT "/usr/lib/X11/rgb.txt" #include #include #include #include #include #include #include #include #include "libsx.h" #include "libsx_private.h" #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #define BOX_WIDTH 85 #define BOX_HEIGHT 85 extern int strcasecmp __P ((__const char *__s1, __const char *__s2)); extern int lstat __P ((__const char *__file, struct stat *__buf)); extern float __dir__; static int whichdir; static int CYAN=0, MAGENTA=0; static int w_mode, w_r, w_g, w_b, w_h, w_s, w_v, w_c, w_m, w_y, w_k; static int mydepth; /* Static (private) procedures static void color_cancel(Widget w, CSelData *cdata); static void grab_color(Widget w, CSelData *cdata); static void color_ok(Widget w, CSelData *cdata); static void color_byname(Widget w, char *string, CSelData *cdata); static void color_string(Widget w, char *string, CSelData *cdata); static void color_scroll(Widget w, float val, CSelData *cdata); static void color_redisplay(Widget w, int width, int height, CSelData *cdata); static void rgb_hsv_cmyk(Widget w, CSelData *cdata); static void rgb2hsv(CSelData *cdata); static void hsv2rgb(CSelData *cdata); static void rgb2cmyk(CSelData *cdata); static void cmyk2rgb(CSelData *cdata); static void set_rgb_data(int r, int g, int b, CSelData *cdata); static void set_widgets(int reset, CSelData *cdata); static void load_list(char *filename, CSelData *cdata); static void list_click(Widget w, char *string, int index, CSelData *fdata); static void reset_list(Widget w, CSelData *cdata); static void best_match(int mode, CSelData *cdata); static void show_best_match(Widget w, CSelData *cdata); */ int trunc(float v) { return (int)(0.5+v); } float my_sqrt(float v) { int i; float x = 50; if (v<=0) return 0.0; for (i=0; i<=20; i++) x = 0.5*(x+v/x); return x; } static void rgb2cmyk(CSelData *cdata) { float r = 100.0-(cdata->r/2.55) ; float g = 100.0-(cdata->g/2.55) ; float b = 100.0-(cdata->b/2.55) ; cdata->k = MIN(r, MIN(g, b)); if ( cdata->k<0 ) cdata->k = 0; cdata->c = r - cdata->k; cdata->m = g - cdata->k; cdata->y = b - cdata->k; } static void cmyk2rgb(CSelData *cdata) { cdata->r = 255.0 - (cdata->k+cdata->c)*2.55; if (cdata->r<0) cdata->r=0; cdata->g = 255.0 - (cdata->k+cdata->m)*2.55; if (cdata->g<0) cdata->g=0; cdata->b = 255.0 - (cdata->k+cdata->y)*2.55; if (cdata->b<0) cdata->b=0; } static void rgb2hsv(CSelData *cdata) { float max = MAX(cdata->r,MAX(cdata->g,cdata->b)); float min = MIN(cdata->r,MIN(cdata->g,cdata->b)); float delta; cdata->v = max; if (max != 0.0) cdata->s = (max - min) / max; else cdata->s = 0.0; if (cdata->s == 0) cdata->h = 0; else { delta = max - min; if (cdata->r == max) cdata->h = (cdata->g - cdata->b) / delta; else if (cdata->g == max) cdata->h = 2 + (cdata->b - cdata->r) / delta; else if (cdata->b == max) cdata->h = 4 + (cdata->r - cdata->g) / delta; cdata->h *= 60; if (cdata->h < 0.0) cdata->h += 360; } cdata->s *= 100.0; } static void hsv2rgb(CSelData *cdata) { int i; float f,h,p,q,t; float s=cdata->s; s /= 100.0; if (s == 0 && cdata->h == 0) { cdata->r = cdata->g = cdata->b = cdata->v; } else { if (cdata->h > 360.499) cdata->h = 0.0; h = cdata->h / 60.0; i = h; f = h - i; p = cdata->v * (1 - s); q = cdata->v * (1 - (s * f)); t = cdata->v * (1 - (s * (1 - f))); switch (i) { case 0: cdata->r = cdata->v; cdata->g = t; cdata->b = p; break; case 1: cdata->r = q; cdata->g = cdata->v; cdata->b = p; break; case 2: cdata->r = p; cdata->g = cdata->v; cdata->b = t; break; case 3: cdata->r = p; cdata->g = q; cdata->b = cdata->v; break; case 4: cdata->r = t; cdata->g = p; cdata->b = cdata->v; break; case 5: cdata->r = cdata->v; cdata->g = p; cdata->b = q; break; } } } /* * Update color widgets: labels, strings, scrolls and draw_area */ static void set_widgets(int reset, CSelData *cdata) { char cvalue[80]; if(cdata->mode == 0) { if (!reset) { rgb2hsv(cdata); rgb2cmyk(cdata); } if (w_mode != cdata->mode) { SetLabel(cdata->lmode, "RGB "); SetLabel(cdata->red_label, "R"); SetLabel(cdata->green_label, "G"); SetLabel(cdata->blue_label, "B"); SetBgColor((whichdir)?cdata->red_scroll:cdata->red_string, RED); SetBgColor((whichdir)?cdata->green_scroll:cdata->green_string, GREEN); SetBgColor((whichdir)?cdata->blue_scroll:cdata->blue_string, BLUE); XtVaSetValues(cdata->black_label, XtNmappedWhenManaged, False, NULL); XtVaSetValues(cdata->black_string, XtNmappedWhenManaged, False, NULL); XtVaSetValues(cdata->black_scroll, XtNmappedWhenManaged, False, NULL); w_mode = cdata->mode; reset = True; } if (reset || trunc(cdata->r) != w_r) { w_r = trunc(cdata->r); sprintf(cvalue, "%d", w_r); SetScrollbar(cdata->red_scroll, (float)cdata->r, 255.0, 1.0); SetStringEntry(cdata->red_string, cvalue); } if (reset || trunc(cdata->g) != w_g) { w_g = trunc(cdata->g); sprintf(cvalue, "%d", w_g); SetScrollbar(cdata->green_scroll, (float)cdata->g, 255.0, 1.0); SetStringEntry(cdata->green_string, cvalue); } if (reset || trunc(cdata->b) != w_b) { w_b = trunc(cdata->b); sprintf(cvalue, "%d", w_b); SetScrollbar(cdata->blue_scroll, (float)cdata->b, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); } } if(cdata->mode == 1) { if (!reset) { hsv2rgb(cdata); rgb2cmyk(cdata); } if (w_mode != cdata->mode) { SetLabel(cdata->lmode, "HSV "); SetLabel(cdata->red_label, "H"); SetLabel(cdata->green_label, "S"); SetLabel(cdata->blue_label, "V"); SetBgColor((whichdir)?cdata->red_scroll:cdata->red_string, WHITE); SetBgColor((whichdir)?cdata->green_scroll:cdata->green_string, WHITE); SetBgColor((whichdir)?cdata->blue_scroll:cdata->blue_string, WHITE); XtVaSetValues(cdata->black_label, XtNmappedWhenManaged, False, NULL); XtVaSetValues(cdata->black_string, XtNmappedWhenManaged, False, NULL); XtVaSetValues(cdata->black_scroll, XtNmappedWhenManaged, False, NULL); w_mode = cdata->mode; reset = True; } if (reset || trunc(cdata->h) != w_h) { w_h = trunc(cdata->h); sprintf(cvalue, "%d", w_h); SetScrollbar(cdata->red_scroll, (float)cdata->h, 360.0, 1.0); SetStringEntry(cdata->red_string, cvalue); } if (reset || trunc(cdata->s) != w_s) { w_s = trunc(cdata->s); sprintf(cvalue, "%d", w_s); SetScrollbar(cdata->green_scroll, (float)cdata->s, 100.0, 1.0); SetStringEntry(cdata->green_string, cvalue); } if (reset || trunc(cdata->v) != w_v) { w_v = trunc(cdata->v); sprintf(cvalue, "%d", w_v); SetScrollbar(cdata->blue_scroll, (float)cdata->v, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); } } if(cdata->mode == 2) { if (!reset) { cmyk2rgb(cdata); rgb2hsv(cdata); } if (w_mode != cdata->mode) { SetLabel(cdata->lmode, "CMYK"); SetLabel(cdata->red_label, "C"); SetLabel(cdata->green_label, "M"); SetLabel(cdata->blue_label, "Y"); SetLabel(cdata->black_label, "K"); SetBgColor((whichdir)?cdata->red_scroll:cdata->red_string, CYAN); SetBgColor((whichdir)?cdata->green_scroll:cdata->green_string,MAGENTA); SetBgColor((whichdir)?cdata->blue_scroll:cdata->blue_string, YELLOW); XtVaSetValues(cdata->black_label, XtNmappedWhenManaged, True, NULL); XtVaSetValues(cdata->black_string, XtNmappedWhenManaged, True, NULL); XtVaSetValues(cdata->black_scroll, XtNmappedWhenManaged, True, NULL); w_mode = cdata->mode; reset = True; } if (reset || trunc(cdata->c) != w_c) { w_c = trunc(cdata->c); sprintf(cvalue, "%d", w_c); SetScrollbar(cdata->red_scroll, (float)cdata->c, 100.0, 1.0); SetStringEntry(cdata->red_string, cvalue); } if (reset || trunc(cdata->m) != w_m) { w_m = trunc(cdata->m); sprintf(cvalue, "%d", w_m); SetScrollbar(cdata->green_scroll, (float)cdata->m, 100.0, 1.0); SetStringEntry(cdata->green_string, cvalue); } if (reset || trunc(cdata->y) != w_y) { w_y = trunc(cdata->y); sprintf(cvalue, "%d", w_y); SetScrollbar(cdata->blue_scroll, (float)cdata->y, 100.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); } if (reset || trunc(cdata->k) != w_k) { w_k = trunc(cdata->k); sprintf(cvalue, "%d", w_k); SetScrollbar(cdata->black_scroll, (float)cdata->k, 100.0, 1.0); SetStringEntry(cdata->black_string, cvalue); } } if (mydepth<16) SetPrivateColor(cdata->color, (int)cdata->r, (int)cdata->g, (int)cdata->b); else { cdata->color = GetRGBColor((int)cdata->r, (int)cdata->g, (int)cdata->b); --lsx_curwin->color_index; SetDrawArea(cdata->draw); SetFgColor(cdata->draw, cdata->color); SetBgColor(cdata->draw, cdata->color); ClearDrawArea(); } } static void rgb_hsv_cmyk(Widget w, CSelData *cdata) { cdata->mode = (1+cdata->mode) % 3; set_widgets(True, cdata); } void set_rgb_data(int r, int g, int b, CSelData *cdata) { cdata->r = r; cdata->g = g; cdata->b = b; rgb2hsv(cdata); rgb2cmyk(cdata); set_widgets(False, cdata); } /* * grab_color() - Callback for color grab button */ static void grab_color(Widget w, CSelData *cdata) { char col_str[80]; int r, g, b; strcpy(col_str, GrabPixel("%r %g %b")); sscanf(col_str, "%d %d %d", &r, &g, &b); set_rgb_data(r, g, b, cdata); } static void best_match(int mode, CSelData *cdata) { int num=0, i, j, k; int r, g, b; int rank[1000]; float fr=cdata->r, fg=cdata->g, fb=cdata->b; float d[1000]; float perc; char format[30]; while(cdata->rgb_ptr[num]) { sscanf(cdata->rgb_ptr[num], "%d %d %d", &r, &g, &b); d[num] = (fr-r)*(fr-r)+(fg-g)*(fg-g)+(fb-b)*(fb-b); num++; } rank[0] = 0; for(i=1; i=d[rank[j]])) j++; if (j==i) rank[i] = i; else { for(k=i; k>j; k--) rank[k] = rank[k-1]; rank[j] = i; } } sprintf(cdata->match_list[0], " %3d %3d %3d %s", trunc(fr), trunc(fg), trunc(fb), SX_Dialog[COLSEL_DIAL]); cdata->match_ptr[0] = cdata->match_list[0]; if (mode) { for(i=1; i<=num; i++) { sprintf(format, "%%s%%%ds %%s%%2.2f %%%%", 50-strlen(cdata->rgb_ptr[rank[i-1]])); perc = my_sqrt((d[rank[i-1]]/19.5075)); sprintf(cdata->match_list[i], format, cdata->rgb_ptr[rank[i-1]], "", (perc==0)?"":" ",100-perc); cdata->match_ptr[i] = cdata->match_list[i]; } cdata->match_ptr[num] = NULL; } else cdata->match_ptr[0]=cdata->rgb_ptr[rank[0]]; } static void show_best_match(Widget w, CSelData *cdata) { best_match(1, cdata); ChangeScrollList(cdata->scroll_list, cdata->match_ptr); } /* * color_ok() - Callback for color requestor OK button */ static void color_ok(Widget w, CSelData *cdata) { int r, g, b; cdata->cancelled = 0; if(cdata->output==0) { numerical: sprintf(cdata->save, "#%02X%02X%02X", trunc(cdata->r), trunc(cdata->g), trunc(cdata->b)); } else { best_match(0, cdata); sscanf(cdata->match_ptr[0], "%d %d %d %s", &r, &g, &b, cdata->save); if (cdata->output==1) { if (r!=trunc(cdata->r) || g!=trunc(cdata->g) || b!=trunc(cdata->b)) goto numerical; } } if (mydepth<16) FreePrivateColor(cdata->color); SetCurrentWindow(cdata->csel_window); CloseWindow(); } /* * color_cancel() - Callback for color requestor CANCEL button */ static void color_cancel(Widget w, CSelData *cdata) { cdata->cancelled = 1; SetCurrentWindow(cdata->csel_window); if (mydepth<16) FreePrivateColor(cdata->color); CloseWindow(); } static void set_color_values(int i, float val, CSelData *cdata) { val = MAX(val, 0); if(cdata->mode == 0) { /* range the value */ val = MIN(255, val); if(i==0) cdata->r = val; else if(i==1) cdata->g = val; else if(i==2) cdata->b = val; } if(cdata->mode == 1) { if(i==0) { val = MIN(360, val); cdata->h = val; } else if(i==1) { val = MIN(100, val); cdata->s = val; } else if(i==2) { val = MIN(255, val); cdata->v = val; } } if(cdata->mode == 2) { if(i==0) { val = MIN(100, val); cdata->c = val; } else if(i==1) { val = MIN(100, val); cdata->m = val; } else if(i==2) { val = MIN(100, val); cdata->y = val; } else if(i==3) { val = MIN(100, val); cdata->k = val; } } set_widgets(False, cdata); } static void color_byname(Widget w, char *string, CSelData *cdata) { int r, g, b, i; char name[40], col_str[40]; if (string[0]>='0' && string[0]<='9') { if (sscanf(string, "%d,%d,%d", &r, &g, &b)<3) sscanf(string, "%d %d %d", &r, &g, &b); } else if (string[0]=='#') sscanf(string, "#%02X%02X%02X", &r, &g, &b); else if (isalpha(string[0])) { sscanf(string, "%s", name); i = 0; iterate: if (cdata->rgb_ptr[i] == NULL) return; sscanf(cdata->rgb_ptr[i], "%d %d %d %s", &r, &g, &b, col_str); ++i; if (strcasecmp(name,col_str)) goto iterate; } else return; set_rgb_data(r, g, b, cdata); } static void color_string(Widget w, char *string, CSelData *cdata) { float val; int i = 0; sscanf(string, "%f", &val); if (w==cdata->red_string) { i = 0; w_r = w_h = w_c = -1; } else if (w==cdata->green_string) { i = 1; w_g = w_s = w_m = -1; } else if (w==cdata->blue_string) { i = 2; w_b = w_v = w_y = -1; } else if (w==cdata->black_string) { i = 3; w_k = -1; } set_color_values(i, val, cdata); } static void color_scroll(Widget w, float val, CSelData *cdata) { int i = 0; if (w==cdata->red_scroll) i = 0; else if (w==cdata->green_scroll) i = 1; else if (w==cdata->blue_scroll) i = 2; else if (w==cdata->black_scroll) i = 3; set_color_values(i, val, cdata); } /* * color_redisplay() - Redisplay callback for the color draw area */ static void color_redisplay(Widget w, int width, int height, CSelData *cdata) { DrawFilledBox(0, 0, width, height); } static void load_list(char *filename, CSelData *cdata) { struct stat st; char *pline; char rgb_line[256]; FILE *fd; int i; int r, g, b; char name[40], comp1[20], comp2[20], comp3[20]; pline = (char *)1; if(lstat(RGBTXT,&st)!=0) { fprintf(stderr, "The RGB colors data file %s does not exist !!\n", RGBTXT); return; } fd=fopen(RGBTXT, "r"); i = 0; while(pline!=NULL) { pline=fgets(rgb_line,76,fd); if((pline!=NULL) && (rgb_line[0]!='!')) { *comp1 = '\0'; sscanf(pline, "%d %d %d %s %s %s %s", &r, &g, &b, name, comp1, comp2, comp3); if (!*comp1) { name[0] = toupper(name[0]); sprintf(cdata->rgb_list[i], " %3d %3d %3d %s", r, g, b, name); cdata->rgb_ptr[i] = cdata->rgb_list[i]; ++i; } } } strcpy(cdata->rgb_list[i], ""); cdata->rgb_ptr[i] = NULL; fclose(fd); ChangeScrollList(cdata->scroll_list, cdata->rgb_ptr); } static void reset_list(Widget w, CSelData *cdata) { ChangeScrollList(cdata->scroll_list, cdata->rgb_ptr); } static void list_click(Widget w, char *string, int index, CSelData *cdata) { int r, g, b; char name[40], color_line[80]; sscanf(string, "%d %d %d %s\n", &r, &g, &b, name); set_rgb_data(r, g, b, cdata); sprintf(color_line, "%s = #%02X%02X%02X", name, r, g, b); SetStringEntry(cdata->lcolor, color_line); } /* * SelectColor() */ char * SelectColor(char *inicolor, int output, char *txt, CSelCB func, void *data) { CSelData cdata; Widget w[30]; int width, i; static unsigned char black_bits[] = { 0xff }; static char col_str[80]; /* initialize the color values */ cdata.mode = 0; cdata.output = output; cdata.data = data; data = 0; w_mode=-1, w_r=-1, w_g=-1, w_b=-1, w_h=-1, w_s=-1, w_v=-1, w_c=-1, w_m=-1, w_y=-1, w_k=-1; cdata.csel_window = MakeWindow("ColorSelector", SAME_DISPLAY, EXCLUSIVE_WINDOW); mydepth = DefaultDepth(lsx_curwin->display,lsx_curwin->screen); whichdir = (__dir__>0); w[0] = MakeLabel(txt); w[1] = MakeLabel(SX_Dialog[COLSEL_DIAL+1]); w[2] = MakeStringEntry(NULL, 284, (void *)color_byname, &cdata); w[3] = MakeLabel(SX_Dialog[COLSEL_DIAL+2]); w[4] = MakeButton("CMYK", (void *)rgb_hsv_cmyk, &cdata); /* determine the width to make the string widgets with */ width = TextWidth(GetWidgetFont(w[0]), "8888888"); w[5] = MakeLabel("R"); w[6] = MakeStringEntry(NULL, width, (void *)color_string, &cdata); w[7] = MakeHorizScrollbar(284, (void *)color_scroll, &cdata); SetScrollbarStep(w[7], 0.03); w[8] = MakeLabel("G"); w[9] = MakeStringEntry(NULL, width, (void *)color_string, &cdata); w[10] = MakeHorizScrollbar(284, (void *)color_scroll, &cdata); SetScrollbarStep(w[10], 0.03); w[11] = MakeLabel("B"); w[12] = MakeStringEntry(NULL, width, (void *)color_string, &cdata); w[13] = MakeHorizScrollbar(284, (void *)color_scroll, &cdata); SetScrollbarStep(w[13], 0.03); w[14] = MakeLabel("K"); w[15] = MakeStringEntry(NULL, width, (void *)color_string, &cdata); w[16] = MakeHorizScrollbar(284, (void *)color_scroll, &cdata); SetScrollbarStep(w[16], 0.03); w[17] = MakeDrawArea(BOX_WIDTH, BOX_HEIGHT, (void *)color_redisplay, &cdata); w[18] = MakeButton(SX_Dialog[COLSEL_DIAL+3], (void *)reset_list, &cdata); cdata.rgb_ptr[0] = NULL; w[19] = MakeScrollList(cdata.rgb_ptr, 466, 274, (void *)list_click,&cdata); w[20] = MakeButton(SX_Dialog[COLSEL_DIAL+4],(void *)grab_color, &cdata); w[21] = MakeButton(SX_Dialog[COLSEL_DIAL+5],(void *)show_best_match,&cdata); w[22] = MakeButton(SX_Dialog[COLSEL_DIAL+6],(void *)color_ok, &cdata); w[23] = MakeButton(SX_Dialog[COLSEL_DIAL+7],(void *)color_cancel, &cdata); if (func) { w[24] = MakeButton(txt, (ButtonCB)func, &cdata); XtVaSetValues(w[24], "horizDistance", 126, NULL); SetWidgetPos(w[24], PLACE_UNDER, w[19], PLACE_RIGHT, w[22]); if (BUTTONBG>=0) SetBgColor(w[24], BUTTONBG); } SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], PLACE_UNDER, w[0]); SetWidgetPos(w[3], PLACE_RIGHT, w[2], PLACE_UNDER, w[0]); SetWidgetPos(w[4], PLACE_RIGHT, w[3], PLACE_UNDER, w[0]); SetWidgetPos(w[5], PLACE_UNDER, w[2], NO_CARE, NULL); SetWidgetPos(w[6], PLACE_UNDER, w[2], PLACE_RIGHT, w[5]); SetWidgetPos(w[7], PLACE_UNDER, w[2], PLACE_RIGHT, w[6]); SetWidgetPos(w[8], PLACE_UNDER, w[5], NO_CARE, NULL); SetWidgetPos(w[9], PLACE_UNDER, w[5], PLACE_RIGHT, w[8]); SetWidgetPos(w[10], PLACE_UNDER, w[5], PLACE_RIGHT, w[9]); SetWidgetPos(w[11], PLACE_UNDER, w[8], NO_CARE, NULL); SetWidgetPos(w[12], PLACE_UNDER, w[8], PLACE_RIGHT, w[11]); SetWidgetPos(w[13], PLACE_UNDER, w[8], PLACE_RIGHT, w[12]); SetWidgetPos(w[14], PLACE_UNDER, w[11], NO_CARE, NULL); SetWidgetPos(w[15], PLACE_UNDER, w[11], PLACE_RIGHT, w[14]); SetWidgetPos(w[16], PLACE_UNDER, w[11], PLACE_RIGHT, w[15]); SetWidgetPos(w[17], PLACE_UNDER, w[2], PLACE_RIGHT, w[7]); SetWidgetPos(w[18], PLACE_UNDER, w[17], NO_CARE, NULL); SetWidgetPos(w[19], PLACE_UNDER, w[18], NO_CARE, NULL); SetWidgetPos(w[20], PLACE_UNDER, w[19], NO_CARE, NULL); SetWidgetPos(w[21], PLACE_UNDER, w[19], PLACE_RIGHT, w[20]); SetWidgetPos(w[22], PLACE_UNDER, w[19], PLACE_RIGHT, w[21]); SetWidgetPos(w[23], PLACE_UNDER, w[19], PLACE_RIGHT, w[22]); XtVaSetValues(w[18], "vertDistance", 8, NULL); /* save important widgets */ cdata.lcolor = w[2]; cdata.lmode = w[4]; cdata.red_label = w[5]; cdata.red_string = w[6]; cdata.red_scroll = w[7]; cdata.green_label = w[8]; cdata.green_string = w[9]; cdata.green_scroll = w[10]; cdata.blue_label = w[11]; cdata.blue_string = w[12]; cdata.blue_scroll = w[13]; cdata.black_label = w[14]; cdata.black_string = w[15]; cdata.black_scroll = w[16]; cdata.draw = w[17]; cdata.scroll_list = w[19]; XtVaSetValues(cdata.red_label, "vertDistance", 12, NULL); XtVaSetValues(cdata.red_string, "vertDistance", 12, NULL); XtVaSetValues(cdata.red_scroll, "vertDistance", 12, NULL); XtVaSetValues(cdata.draw, "horizDistance", 19, "vertDistance", 11, NULL); ShowDisplay(); load_list(RGBTXT, &cdata); /* allocate the custom color */ SetDrawArea(cdata.draw); if (mydepth<16) { cdata.color = GetPrivateColor(); SetColor(cdata.color); } SetThumbBitmap(cdata.red_scroll, black_bits, 8, 1); SetThumbBitmap(cdata.green_scroll, black_bits, 8, 1); SetThumbBitmap(cdata.blue_scroll, black_bits, 8, 1); SetThumbBitmap(cdata.black_scroll, black_bits, 8, 1); if (INPUTBG) { SetBgColor(w[2], INPUTBG); for(i=5; i<=17; i++) if (i%3 != 2 || i>=15) SetBgColor(w[i], INPUTBG); SetBgColor(w[19], INPUTBG); } if (BUTTONBG) { SetBgColor(w[4], BUTTONBG); SetBgColor(w[18], BUTTONBG); for(i=20; i<=23; i++) SetBgColor(w[i], BUTTONBG); } if (CYAN==0) CYAN = GetNamedColor("cyan"); if (MAGENTA==0) MAGENTA = GetNamedColor("magenta"); SetBgColor(cdata.black_scroll, INPUTBG); if (inicolor) color_byname(w[2], inicolor, &cdata); else { cdata.r = 0; cdata.g = 0; cdata.b = 0; set_widgets(False, &cdata); } MainLoop(); data = cdata.data; if (cdata.cancelled) return NULL; else { strcpy(col_str,cdata.save); return col_str; } } libsx-2.05/src/string_entry.c0000644000175000017500000002635111252443541017405 0ustar amckinstryamckinstry/* This file contains routines that manipulate single and multi-line * text entry widgets. * * G.Raschetti (jimi@settimo.italtel.it) added the code for * MakeFiniteStringEntry() and created the code of CreateStringEntry() * from what used to be in MakeStringEntry(). * * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include #include "libsx.h" #include "libsx_private.h" extern Widget w_prev, win_prev; extern int color_prev; static void libsx_set_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms); static void libsx_done_with_text(Widget w, XEvent *xev, String *parms, Cardinal *num_parms); static void destroy_string_entry(Widget *w, void *data, void *junk); /* * This setups up an action that we'll then setup a transaltion to * map to. That is, we tell X about the action "done_with_text" and * then later map the return key so that it is translated into a call * to this action. */ static XtActionsRec string_actions_table[] = { { "set_focus", libsx_set_focus }, { "done_with_text", libsx_done_with_text } }; static int added_string_actions=0; /* * this structure maintains some internal state information about each * string entry widget. */ typedef struct StringInfo { Widget str_widget; void (*func)(Widget w, char *txt, void *data); void *user_data; struct StringInfo *next; }StringInfo; static StringInfo *string_widgets = NULL; /* * String Entry Widget Creation stuff. */ Widget CreateStringEntry(char *txt, int size, StringCB func, void *data, int maxlen) { static int already_done = FALSE; static XtTranslations trans; int n = 0; /* jimi: da 10 a 12 */ Arg wargs[12]; /* Used to set widget resources */ Widget str_entry; StringInfo *stri; if (added_string_actions == 0) { extern XtAppContext lsx_app_con; added_string_actions = 1; XtAppAddActions(lsx_app_con, string_actions_table, XtNumber(string_actions_table)); } if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; if (already_done == FALSE) { already_done = TRUE; trans = XtParseTranslationTable("#override\n\ : set_focus()\n\ Return: done_with_text()\n\ Linefeed: done_with_text()\n\ CtrlM: done_with_text()\n\ CtrlJ: done_with_text()\n"); } stri = (StringInfo *)malloc(sizeof(*stri)); if (stri == NULL) return NULL; stri->func = func; stri->user_data = data; n = 0; XtSetArg(wargs[n], XtNeditType, XawtextEdit); n++; XtSetArg(wargs[n], XtNwrap, XawtextWrapNever); n++; XtSetArg(wargs[n], XtNresize, XawtextResizeWidth); n++; XtSetArg(wargs[n], XtNtranslations, trans); n++; XtSetArg(wargs[n], XtNwidth, size); n++; if(maxlen) { XtSetArg(wargs[n], XtNlength, maxlen); n++; XtSetArg(wargs[n], XtNuseStringInPlace, True); n++; } if (txt) { XtSetArg(wargs[n], XtNstring, txt); n++; XtSetArg(wargs[n], XtNinsertPosition, strlen(txt)); n++; } str_entry = XtCreateManagedWidget("string", asciiTextWidgetClass, lsx_curwin->form_widget,wargs,n); if (str_entry) /* only if we got a real widget do we bother */ { stri->str_widget = str_entry; stri->next = string_widgets; string_widgets = stri; XtAddCallback(str_entry,XtNdestroyCallback, (XtCallbackProc)destroy_string_entry, stri); } else free(stri); return str_entry; } /* end of CreateStringEntry() */ /* * String Entry Widget Creation stuff. */ Widget MakeStringEntry(char *txt, int size, StringCB func, void *data) { return(CreateStringEntry(txt, size, func, data, 0)); } /* end of MakeStringEntry() */ /* * Finite String Entry Widget Creation stuff. */ Widget MakeFiniteStringEntry(char *txt, int size, int maxstrlen, StringCB func, void *data, int maxlen) { return(CreateStringEntry(txt, size, func, data, maxlen)); } /* end of MakeFiniteStringEntry() */ /* * Private internal callback for string entry widgets. */ void libsx_set_focus(Widget w, XEvent *xev, String *parms, Cardinal *num_parms) { if (HILIGHT>=0) { if (w != w_prev && w_prev != 0 && lsx_curwin->toplevel == win_prev ) SetFgColor(w_prev,color_prev); if (w != w_prev) color_prev = GetFgColor(w); w_prev = w; win_prev = lsx_curwin->toplevel; SetFgColor(w,HILIGHT); } XSetInputFocus(XtDisplay(w),XtWindow(w),RevertToNone,CurrentTime); } /* * Private internal callback for string entry widgets. */ void libsx_done_with_text(Widget w, XEvent *xev, String *parms, Cardinal *num_parms) { int n = 0; Arg wargs[10]; /* Used to get widget resources */ char *txt; StringInfo *stri; n = 0; XtSetArg(wargs[n], XtNstring, &txt); n++; XtGetValues(w, wargs, n); /* * Find the correct ScrollInfo structure. */ for(stri=string_widgets; stri; stri=stri->next) { if (stri->str_widget == w && XtDisplay(stri->str_widget) == XtDisplay(w)) /* did find it */ break; } if (stri == NULL) return; if (stri->func) stri->func(w, txt, stri->user_data); /* call the user's function */ } /* * internal callback called when the widget is destroyed. We need * to free up some data at this point. */ static void destroy_string_entry(Widget *w, void *data, void *junk) { StringInfo *si=(StringInfo *)data, *curr; if (si == string_widgets) string_widgets = si->next; else { for(curr=string_widgets; curr && curr->next != si; curr=curr->next) /* nothing */; if (curr == NULL) /* oddly enough we didn't find it... */ return; curr->next = si->next; } free(si); } void SetStringEntry(Widget w, char *new_text) { int n = 0; Arg wargs[2]; /* Used to set widget resources */ if (lsx_curwin->toplevel == NULL || w == NULL || new_text == NULL) return; n = 0; XtSetArg(wargs[n], XtNstring, new_text); n++; XtSetValues(w, wargs, n); /* * Have to set this resource separately or else it doesn't get * updated in the display. Isn't X a pain in the ass? * * (remember that with X windows, form follows malfunction) */ n = 0; XtSetArg(wargs[n], XtNinsertPosition, strlen(new_text)); n++; XtSetValues(w, wargs, n); } char *GetStringEntry(Widget w) { int n = 0; Arg wargs[2]; /* Used to set widget resources */ char *text; if (lsx_curwin->toplevel == NULL || w == NULL) return NULL; n = 0; XtSetArg(wargs[n], XtNstring, &text); n++; XtGetValues(w, wargs, n); return text; } /* * Full Text Widget creation and support routines. */ /* forward prototype */ char *slurp_file(char *fname); Widget MakeTextWidget(char *txt, int is_file, int editable, int w, int h) { int n; Arg wargs[10]; Widget text; char *real_txt; static int already_done = FALSE; static XtTranslations trans; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; if (added_string_actions == 0) { extern XtAppContext lsx_app_con; added_string_actions = 1; XtAppAddActions(lsx_app_con, string_actions_table, XtNumber(string_actions_table)); } if (already_done == FALSE) { already_done = TRUE; trans = XtParseTranslationTable("#override\n\ : set_focus()\n\ Prior: previous-page()\n\ Next: next-page()\n\ Home: beginning-of-file()\n\ End: end-of-file()\n\ CtrlUp: beginning-of-file()\n\ CtrlDown: end-of-file()\n\ ShiftUp: previous-page()\n\ ShiftDown: next-page()\n"); } n=0; XtSetArg(wargs[n], XtNwidth, w); n++; XtSetArg(wargs[n], XtNheight, h); n++; XtSetArg(wargs[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++; XtSetArg(wargs[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++; XtSetArg(wargs[n], XtNautoFill, TRUE); n++; XtSetArg(wargs[n], XtNtranslations, trans); n++; if (is_file && txt) { real_txt = slurp_file(txt); } else real_txt = txt; if (real_txt) { XtSetArg(wargs[n], XtNstring, real_txt); n++; } if (editable) { XtSetArg(wargs[n], XtNeditType, XawtextEdit); n++; } text = XtCreateManagedWidget("text", asciiTextWidgetClass, lsx_curwin->form_widget,wargs,n); if (real_txt != txt && real_txt != NULL) free(real_txt); /* we're done with the buffer */ return text; } void SetTextWidgetText(Widget w, char *txt, int is_file) { int n; Arg wargs[2]; char *real_txt; Widget source; if (lsx_curwin->toplevel == NULL || w == NULL || txt == NULL) return; source = XawTextGetSource(w); if (source == NULL) return; if (is_file) { real_txt = slurp_file(txt); } else real_txt = txt; n=0; XtSetArg(wargs[n], XtNstring, real_txt); n++; XtSetValues(source, wargs, n); if (real_txt != txt && real_txt != NULL) free(real_txt); /* we're done with the buffer */ } char *GetTextWidgetText(Widget w) { int n; Arg wargs[4]; char *text=NULL; Widget source; if (lsx_curwin->toplevel == NULL || w == NULL) return NULL; source = XawTextGetSource(w); if (source == NULL) return NULL; n=0; XtSetArg(wargs[n], XtNstring, &text); n++; XtGetValues(source, wargs, n); return text; } #include #include #include char *slurp_file(char *fname) { struct stat st; char *buff; int fd, count; if (stat(fname, &st) < 0) return NULL; if (S_ISDIR(st.st_mode) == TRUE) /* don't want to edit directories */ return NULL; buff = (char *)malloc(sizeof(char)*(st.st_size+1)); if (buff == NULL) return NULL; fd = open(fname, O_RDONLY); if (fd < 0) { free(buff); return NULL; } count = read(fd, buff, st.st_size); buff[count] = '\0'; /* null terminate */ close(fd); return (buff); } void SetTextWidgetPosition(Widget w, int text_pos) { int n; Arg wargs[5]; n = 0; XtSetArg(wargs[n], XtNinsertPosition, text_pos); n++; XtSetValues(w, wargs, n); } void SetTextEditable(Widget w, int can_edit) /* ugly function name... */ { int n; Arg wargs[5]; n = 0; if (can_edit) { XtSetArg(wargs[n], XtNeditType, XawtextEdit); n++; } else { XtSetArg(wargs[n], XtNeditType, XawtextRead); n++; } XtSetValues(w, wargs, n); } libsx-2.05/src/button.c0000644000175000017500000000430011252443541016157 0ustar amckinstryamckinstry/* This file contains routines that manage creating and manipulating * button and label widgets. Button widgets can be clicked on, label * widgets just display some text. * * * This code is under the GNU Copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include "xstuff.h" #include #include "libsx.h" #include "libsx_private.h" /* * Command Button Creation routine. */ Widget MakeButton(char *txt, ButtonCB func, void *data) { int n = 0; Arg wargs[5]; /* Used to set widget resources */ Widget button; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; n = 0; if (txt) { XtSetArg(wargs[n], XtNlabel, txt); n++; } button = XtCreateManagedWidget("button", commandWidgetClass, lsx_curwin->form_widget,wargs,n); if (button == NULL) return NULL; if (func) XtAddCallback(button, XtNcallback, (XtCallbackProc)func, data); return button; } /* end of MakeButton() */ /* * Text Label Creation. */ Widget MakeLabel(char *txt) { int n = 0; Pixel bg_color = ~0; Arg wargs[5]; /* Used to set widget resources */ Widget label; if (lsx_curwin->toplevel == NULL && OpenDisplay(0, NULL) == 0) return NULL; n = 0; if (txt) { XtSetArg(wargs[n], XtNlabel, txt); n++; } label = XtCreateManagedWidget("label", labelWidgetClass, lsx_curwin->form_widget,wargs,n); if (label == NULL) return NULL; /* this little contortion here is to make sure there is no * border around the label (else it looks exactly like a command * button, and that's confusing) */ n = 0; XtSetArg(wargs[n], XtNbackground, &bg_color); n++; XtGetValues(label, wargs, n); n = 0; XtSetArg(wargs[n], XtNborder, bg_color); n++; XtSetValues(label, wargs, n); return label; } /* end of MakeLabel() */ void SetLabel(Widget w, char *txt) { int n = 0; Arg wargs[1]; /* Used to set widget resources */ if (lsx_curwin->toplevel == NULL || w == NULL) return; n = 0; XtSetArg(wargs[n], XtNlabel, txt); n++; XtSetValues(w, wargs, n); } libsx-2.05/creq/0000755000175000017500000000000011252443541014646 5ustar amckinstryamckinstrylibsx-2.05/creq/creq.c0000644000175000017500000002507011252443541015750 0ustar amckinstryamckinstry/* * A color chooser. The function GetColor() pops up a modal window * that lets a user interactively play with a color in either RGB or * HSV space and then returns the chosen value to your program. * * Written by Allen Martin (amartin@cs.wpi.edu) */ #include #include #include #include "libsx.h" #ifdef __linux__ #define NeedFunctionPrototypes 1 #undef NeedWidePrototypes #endif #include #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) typedef struct { Widget creq_window; Widget red_label, red_string, red_scroll; Widget green_label, green_string, green_scroll; Widget blue_label, blue_string, blue_scroll; int color; int rgb; float r, g, b; float h, s, v; int cancelled; } CReqData; #define BOX_WIDTH 85 #define BOX_HEIGHT 85 static void color_cancel(Widget w, CReqData *cdata); static void color_ok(Widget w, CReqData *cdata); static void color_string(Widget w, char *string, CReqData *cdata); static void color_scroll(Widget w, float val, CReqData *cdata); static void color_redisplay(Widget w, int width, int height, CReqData *cdata); static void rgb_hsv(Widget w, CReqData *cdata); static void rgb2hsv(float r, float g, float b, float *h, float *s, float *v); static void hsv2rgb(float h, float s, float v, float *r, float *g, float *b); /* * GetColor() */ int GetColor(unsigned char *r, unsigned char *g, unsigned char *b) { CReqData cdata; Widget w[14]; char cvalue[4]; int width; static unsigned char black_bits[] = { 0xff }; /* initialize the color values */ cdata.r = (float)*r; cdata.g = (float)*g; cdata.b = (float)*b; rgb2hsv(cdata.r, cdata.g, cdata.b, &cdata.h, &cdata.s, &cdata.v); cdata.rgb=TRUE; cdata.creq_window = MakeWindow("Color Requestor", SAME_DISPLAY, EXCLUSIVE_WINDOW); w[0] = MakeButton("RGB/HSV", (void *)rgb_hsv, &cdata); /* determine the width to make the string widgets with */ width = TextWidth(GetWidgetFont(w[0]), "88888"); w[1] = MakeLabel("R"); sprintf(cvalue, "%d", *r); w[2] = MakeStringEntry(cvalue, width, (void *)color_string, &cdata); w[3] = MakeHorizScrollbar(250, (void *)color_scroll, &cdata); w[4] = MakeLabel("G"); sprintf(cvalue, "%d", *g); w[5] = MakeStringEntry(cvalue, width, (void *)color_string, &cdata); w[6] = MakeHorizScrollbar(250, (void *)color_scroll, &cdata); w[7] = MakeLabel("B"); sprintf(cvalue, "%d", *b); w[8] = MakeStringEntry(cvalue, width, (void *)color_string, &cdata); w[9] = MakeHorizScrollbar(250, (void *)color_scroll, &cdata); w[10] = MakeDrawArea(BOX_WIDTH, BOX_HEIGHT, (void *)color_redisplay, &cdata); w[11] = MakeButton("Ok", (void *)color_ok, &cdata); w[12] = MakeLabel("Please Edit the Color Above"); w[13] = MakeButton("Cancel", (void *)color_cancel, &cdata); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_UNDER, w[0], PLACE_RIGHT, w[1]); SetWidgetPos(w[3], PLACE_UNDER, w[0], PLACE_RIGHT, w[2]); SetWidgetPos(w[4], PLACE_UNDER, w[1], NO_CARE, NULL); SetWidgetPos(w[5], PLACE_UNDER, w[1], PLACE_RIGHT, w[4]); SetWidgetPos(w[6], PLACE_UNDER, w[1], PLACE_RIGHT, w[5]); SetWidgetPos(w[7], PLACE_UNDER, w[4], NO_CARE, NULL); SetWidgetPos(w[8], PLACE_UNDER, w[4], PLACE_RIGHT, w[7]); SetWidgetPos(w[9], PLACE_UNDER, w[4], PLACE_RIGHT, w[8]); SetWidgetPos(w[10], PLACE_RIGHT, w[3], NO_CARE, NULL); SetWidgetPos(w[11], PLACE_UNDER, w[7], NO_CARE, NULL); SetWidgetPos(w[12], PLACE_UNDER, w[7], PLACE_RIGHT, w[11]); SetWidgetPos(w[13], PLACE_UNDER, w[7], PLACE_RIGHT, w[12]); /* save important widgets */ cdata.red_label = w[1]; cdata.red_string = w[2]; cdata.red_scroll = w[3]; cdata.green_label = w[4]; cdata.green_string = w[5]; cdata.green_scroll = w[6]; cdata.blue_label = w[7]; cdata.blue_string = w[8]; cdata.blue_scroll = w[9]; ShowDisplay(); /* allocate the custom color */ cdata.color = GetPrivateColor(); SetPrivateColor(cdata.color, cdata.r, cdata.g, cdata.b); SetDrawArea(w[10]); SetColor(cdata.color); SetBgColor(w[3], RED); SetThumbBitmap(w[3], black_bits, 8, 1); SetScrollbar(w[3], (float)*r, 255.0, 1.0); SetBgColor(w[6], GREEN); SetThumbBitmap(w[6], black_bits, 8, 1); SetScrollbar(w[6], (float)*g, 255.0, 1.0); SetBgColor(w[9], BLUE); SetThumbBitmap(w[9], black_bits, 8, 1); SetScrollbar(w[9], (float)*b, 255.0, 1.0); MainLoop(); SetCurrentWindow(ORIGINAL_WINDOW); /* check for cancel */ if(cdata.cancelled) return(TRUE); *r = (unsigned char)cdata.r; *g = (unsigned char)cdata.g; *b = (unsigned char)cdata.b; return(FALSE); } /* * rgb_hsv() - Callback for the RGB/HSV button */ static void rgb_hsv(Widget w, CReqData *cdata) { char cvalue[4]; cdata->rgb = !cdata->rgb; if(cdata->rgb) { SetLabel(cdata->red_label, "R"); SetLabel(cdata->green_label, "G"); SetLabel(cdata->blue_label, "B"); sprintf(cvalue, "%d", (int)cdata->r); SetScrollbar(cdata->red_scroll, (float)cdata->r, 255.0, 1.0); SetStringEntry(cdata->red_string, cvalue); sprintf(cvalue, "%d", (int)cdata->g); SetScrollbar(cdata->green_scroll, (float)cdata->g, 255.0, 1.0); SetStringEntry(cdata->green_string, cvalue); sprintf(cvalue, "%d", (int)cdata->b); SetScrollbar(cdata->blue_scroll, (float)cdata->b, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); } else { SetLabel(cdata->red_label, "H"); SetLabel(cdata->green_label, "S"); SetLabel(cdata->blue_label, "V"); sprintf(cvalue, "%d", (int)cdata->h); SetScrollbar(cdata->red_scroll, (float)cdata->h, 360.0, 1.0); SetStringEntry(cdata->red_string, cvalue); sprintf(cvalue, "%d", (int)cdata->s); SetScrollbar(cdata->green_scroll, (float)cdata->s, 100.0, 1.0); SetStringEntry(cdata->green_string, cvalue); sprintf(cvalue, "%d", (int)cdata->v); SetScrollbar(cdata->blue_scroll, (float)cdata->v, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); } } /* * color_ok() - Callback for color requestor OK button */ static void color_ok(Widget w, CReqData *cdata) { cdata->cancelled = FALSE; SetCurrentWindow(cdata->creq_window); CloseWindow(); } /* * color_cancel() - Callback for color requestor CANCEL button */ static void color_cancel(Widget w, CReqData *cdata) { cdata->cancelled = TRUE; SetCurrentWindow(cdata->creq_window); CloseWindow(); } static void color_string(Widget w, char *string, CReqData *cdata) { char cvalue[4]; float val; sscanf(string, "%f", &val); val = MAX(0, val); if(cdata->rgb) { /* range the value */ val = MIN(255, val); sprintf(cvalue, "%d", (int)val); if(w==cdata->red_string) { SetScrollbar(cdata->red_scroll, val, 255.0, 1.0); SetStringEntry(cdata->red_string, cvalue); cdata->r = val; } else if(w==cdata->green_string) { SetScrollbar(cdata->green_scroll, val, 255.0, 1.0); SetStringEntry(cdata->green_string, cvalue); cdata->g = val; } else if(w==cdata->blue_string) { SetScrollbar(cdata->blue_scroll, val, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); cdata->b = val; } rgb2hsv(cdata->r, cdata->g, cdata->b, &cdata->h, &cdata->s, &cdata->v); } else { if(w==cdata->red_string) { val = MIN(360, val); sprintf(cvalue, "%d", (int)val); SetScrollbar(cdata->red_scroll, val, 360.0, 1.0); SetStringEntry(cdata->red_string, cvalue); cdata->h = val; } else if(w==cdata->green_string) { val = MIN(100, val); sprintf(cvalue, "%d", (int)val); SetScrollbar(cdata->green_scroll, val, 100.0, 1.0); SetStringEntry(cdata->green_string, cvalue); cdata->s = val; } else if(w==cdata->blue_string) { val = MIN(255, val); sprintf(cvalue, "%d", (int)val); SetScrollbar(cdata->blue_scroll, val, 255.0, 1.0); SetStringEntry(cdata->blue_string, cvalue); cdata->v = val; } hsv2rgb(cdata->h, cdata->s, cdata->v, &cdata->r, &cdata->g, &cdata->b); } SetPrivateColor(cdata->color, (int)cdata->r, (int)cdata->g, (int)cdata->b); } static void color_scroll(Widget w, float val, CReqData *cdata) { char cvalue[4]; sprintf(cvalue, "%d", (int)val); if(cdata->rgb) { if(w==cdata->red_scroll) { SetStringEntry(cdata->red_string, cvalue); cdata->r = val; } else if(w==cdata->green_scroll) { SetStringEntry(cdata->green_string, cvalue); cdata->g = val; } else if(w==cdata->blue_scroll) { SetStringEntry(cdata->blue_string, cvalue); cdata->b = val; } rgb2hsv(cdata->r, cdata->g, cdata->b, &cdata->h, &cdata->s, &cdata->v); } else { if(w==cdata->red_scroll) { SetStringEntry(cdata->red_string, cvalue); cdata->h = val; } else if(w==cdata->green_scroll) { SetStringEntry(cdata->green_string, cvalue); cdata->s = val; } else if(w==cdata->blue_scroll) { SetStringEntry(cdata->blue_string, cvalue); cdata->v = val; } hsv2rgb(cdata->h, cdata->s, cdata->v, &cdata->r, &cdata->g, &cdata->b); } SetPrivateColor(cdata->color, (int)cdata->r, (int)cdata->g, (int)cdata->b); } /* * color_redisplay() - Redisplay callback for the creq draw area */ static void color_redisplay(Widget w, int width, int height, CReqData *cdata) { DrawFilledBox(0, 0, width, height); } static void rgb2hsv(float r, float g, float b, float *h, float *s, float *v) { float max = MAX(r,MAX(g,b)); float min = MIN(r,MIN(g,b)); float delta; *v = max; if (max != 0.0) *s = (max - min) / max; else *s = 0.0; if (*s == 0) { *h = 0; } else { delta = max - min; if (r == max) *h = (g - b) / delta; else if (g == max) *h = 2 + (b - r) / delta; else if (b == max) *h = 4 + (r - g) / delta; *h *= 60; if (*h < 0.0) *h += 360; } *s *= 100.0; } static void hsv2rgb(float h, float _s, float v, float *r, float *g, float *b) { int i; float f,p,q,t; float s=_s; s /= 100.0; if (s == 0 && h == 0) { *r = *g = *b = v; } else { if (h >= 360.0) h = 0.0; h /= 60.0; i = h; f = h - i; p = v * (1 - s); q = v * (1 - (s * f)); t = v * (1 - (s * (1 - f))); switch (i) { case 0: *r = v; *g = t; *b = p; break; case 1: *r = q; *g = v; *b = p; break; case 2: *r = p; *g = v; *b = t; break; case 3: *r = p; *g = q; *b = v; break; case 4: *r = t; *g = p; *b = v; break; case 5: *r = v; *g = p; *b = q; break; } } } libsx-2.05/creq/main.c0000644000175000017500000000331511252443541015740 0ustar amckinstryamckinstry/* * -Allen Martin (amartin@wpi.wpi.edu) */ #include #include #include #include "libsx.h" /* gets us in the door with libsx */ #include "creq.h" /* Color Requestor header */ int init_display(int argc, char **argv, void *data); /* callback protos */ void cedit(Widget w, void *data); void quit(Widget w, void *data); void main(int argc, char **argv) { argc = init_display(argc, argv, NULL); /* setup the display */ if (argc == 0) exit(0); MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ int init_display(int argc, char **argv, void *data) { Widget w[2]; char *args[] = { "-bg" , "gray76", NULL }; PredefArgs = args; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; w[0] = MakeButton("Edit", cedit, data); w[1] = MakeButton("Quit!", quit, data); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); ShowDisplay(); GetStandardColors(); return argc; } /* * cedit() - This is the Callback function for the edit button. This * simply calls GetColor() to get an RGB value */ void cedit(Widget w, void *data) { unsigned char r=40,g=80,b=120; if(GetColor(&r,&g,&b)) printf("Cancelled\n"); else printf("Red=%d, Green=%d, Blue=%d\n", r, g, b); } /* * quit() - Callback function for the quit button */ void quit(Widget w, void *data) { exit(0); } libsx-2.05/creq/creq.h0000644000175000017500000000010411252443541015744 0ustar amckinstryamckinstryint GetColor(unsigned char *r, unsigned char *g, unsigned char *b); libsx-2.05/creq/makefile0000644000175000017500000000030211252443541016341 0ustar amckinstryamckinstry# # include ../libsx_defs OBJS = main.o creq.o all : creq creq : $(OBJS) $(CC) -o $@ $(OBJS) $(LIBS) main.o : main.c libsx.h creq.h creq.o : creq.c clean: rm -f *.o *~ core creq libsx-2.05/creq/libsx.h0000777000175000017500000000000011252443766020442 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/skel/0000755000175000017500000000000011252443541014652 5ustar amckinstryamckinstrylibsx-2.05/skel/callbacks.c0000644000175000017500000001072711252443541016744 0ustar amckinstryamckinstry/* This file contains routines that are called when a button is pressed * in your window or when things happen in a drawing area. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo */ #include #include "libsx.h" #include "main.h" #include "callbacks.h" /* -- CALLBACK ROUTINES -- * * These functions are called when various things happen in your windows. * They should handle what happened and give feedback to the user. Most * likely they will set options in your program (which is what the * MyProgram data structure is for), and cause different things to happen, * like loading and saving files, etc. * * Remember, the last argument to your callback is always a void pointer * to whatever data you specified when you created the widget. You * must cast the pointer to be whatever type it really is. */ void quit(Widget w, void *data) { /* Do any cleanup that is necessary for your program here */ exit(0); } void button1(Widget w, void *data) { printf("You clicked button #1\n"); } void button2(Widget w, void *data) { printf("You clicked button #2\n"); } /* * The following functions are callbacks for the drawing area widgets. * * The only required callback is redisplay(). The others are optional * but have been setup to be used by init_display() in main.c. */ /* Here is where all redrawing will take place for your program. * When the window needs to be redrawn, this function will be called. * When your program starts up for the first time, this function will * be called and you should draw anything you need to draw in here. */ void redisplay(Widget w, int new_width, int new_height, void *data) { MyProgram *me=data; ClearDrawArea(); /* start with a clean slate */ } void button_down(Widget w, int which_button, int x, int y, void *data) { printf("You clicked button %d at (%d,%d)\n", which_button, x,y); } void button_up(Widget w, int which_button, int x, int y, void *data) { printf("You released button %d at (%d,%d)\n", which_button, x,y); } /* * The following function is called when keypresses happen in the drawing * area widget. * * It is useful to know that the string returned to your program is * not necessarily a single ASCII character. You will get the usual * ASCII characters, including control characters (such as ^C or ^H). * But, the workstation's function keys will also be returned in a * string such as "F11" or "F23". You will also get other longer * strings such as "Control_L", "Alt_R", or "Shift_L". It is * important to understand that even if you just press the shift key to * get a capital letter, you will first receive the string "Shift_L" * or "Shift_R", then you will receive a capital letter (say, "H"). * You should probably ignore the "Shift_L" or "Shift_R" messages (but * who knows, you may find some use for them). * * The argument, up_or_down, tells you whether the given key was pressed * or released. If the key was pressed down, up_or_down has a zero (0), * if the key was released, up_or_down contains a 1. * * NOTE WELL: * The string that is returned to you can _NOT_ (I'll repeat that, * can _NOT_) be modified by your program. Got it? Do _NOT_ modify * the string. If you want to munge with it, make a copy using * strdup() or strcpy() into your own buffer space. */ void keypress(Widget w, char *input, int up_or_down, void *data) { char *str; if (input == NULL) return; if (up_or_down == 0) str = "pressed"; else str = "released"; printf("You %s : <<%s>>\n", str, input); } /* Called when a DrawingArea gets mouse motion events. The arguments * X and Y are the current position of the mouse in the window. * * NOTE: This routine should be _fast_ because *every* single time * the mouse moves in the drawing area, this function is called. * So even if you are just moving the mouse across the drawing area, * this routine is called. As it stands, it doesn't do anything. */ void motion(Widget w, int x, int y, void *data) { static int oldx = 0, oldy = 0; oldx = x; oldy = y; /* Be careful what you do with the mouse movement events, they * can make performance really bad if you don't process them fast */ } libsx-2.05/skel/main.c0000644000175000017500000000605011252443541015743 0ustar amckinstryamckinstry/* This is the main body of the program. It is just a simple skeleton * and should be fleshed out as desired. Mainly what you'll do to flesh * it out is to edit the data structure defined in main.h so that it contains * the information your program needs. Then modify init_display() to create * the interface you want, and then just write the associated callback * routines that are driven by the display. Easy, huh? * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* should come first, defines libsx stuff */ #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default draw area size, change as desired */ #define Y_SIZE 300 void main(int argc, char **argv) { MyProgram mydata; mydata.whatever = 0; /* do your initializations here */ init_display(argc, argv, &mydata); /* setup the display */ MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ void init_display(int argc, char **argv, MyProgram *me) { Widget w[5]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Button #1", button1, me); w[1] = MakeButton("Button #2", button2, me); w[2] = MakeButton("Quit!", quit, me); w[3] = MakeLabel("This is a label"); w[4] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); /* * These callbacks are unnecessary for most applications, but * they're here for completeness. Remove them if you don't * need them. */ SetButtonDownCB(w[4], button_down); SetButtonUpCB(w[4], button_up); SetKeypressCB(w[4], keypress); SetMouseMotionCB(w[4], motion); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); /* This call actually causes the whole thing to be displayed on the * screen. You have to call this function before doing any drawing * into the window. */ ShowDisplay(); /* Get standard (red, blue, green, yellow, black, white) colors for * drawing stuff. Check libsx.h for more info. */ GetStandardColors(); /* If you wanted to get all the colors in the colormap, you'd do the * following : * * GetAllColors(); * SetColorMap(GREY_SCALE_1); * * You can wait to do it till later if you want. There's no need * to do it here if you don't need to (because it wacks out the * colormap). */ } libsx-2.05/skel/makefile0000644000175000017500000000051611252443541016354 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o skel : $(OBJS) $(CC) -o skel $(OBJS) $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h callbacks.o : libsx.h callbacks.c clean : rm -f *.o *~ core skel libsx-2.05/skel/main.h0000644000175000017500000000072711252443541015755 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { int whatever; }MyProgram; /* protos */ void init_display(int argc, char **argv, MyProgram *me); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/skel/libsx.h0000777000175000017500000000000011252443766020446 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/skel/callbacks.h0000644000175000017500000000150011252443541016736 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error). * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void button1(Widget w, void *data); void button2(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); void button_down(Widget w, int which_button, int x,int y, void *data); void button_up(Widget w, int which_button, int x, int y, void *data); void keypress(Widget w, char *input, int up_or_down, void *data); void motion(Widget w, int x, int y, void *data); libsx-2.05/pcurve/0000755000175000017500000000000011252443541015220 5ustar amckinstryamckinstrylibsx-2.05/pcurve/makefile0000644000175000017500000000062111252443541016717 0ustar amckinstryamckinstry#!smake CFLAGS = -g -I../controlbox CLIBS = ../src/libsxGL.a -lGLU -lGL -lXaw -lXt -lXmu -lX11 -lm LDFLAGS = $(LIBPATH) $(LIBS) OBJS = fogl.o cfogl.o OTHEROBJS = ../controlbox/controlbox.o default: pcurve clean: rm -f $(OBJS) cool pcurve: pcurve.c cc $(CFLAGS) pcurve.c -o pcurve $(OTHEROBJS) $(LIBPATH) $(CLIBS) cool2: cool2.c cc $(CFLAGS) cool2.c $(OTHEROBJS) -o cool2 $(LIBPATH) $(CLIBS) libsx-2.05/pcurve/pcurve.c0000644000175000017500000000711511252443541016674 0ustar amckinstryamckinstry/* pcurve -- A program to draw parametric curves and let you play with the parameters. This program lets a user play with simple parametric curves of the form: (alpha * cos(u * t)) + (beta * sin(v * t)) The interesting parameters are u & v. Alpha and beta just affect the size of the overall curve (in x and y respectively). There are also controls for adjusting the number of divisions of the curve drawn and the number of periods of Pi to iterate over. All in all, pretty simple and basic but fun to play with. Dominic Giampaolo dbg@sgi.com */ #include #include "GL/gl.h" #include "GL/glx.h" #include "libsx.h" #include "controlbox.h" #include "math.h" int attributes[] = { GLX_RGBA, GLX_DOUBLEBUFFER, /* GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, */ None }; Widget gui[25]; #define QUIT 0 #define DRAW_AREA 1 #define PARAM_BOX 2 typedef struct CurveInfo { float alpha, beta; float u, v; float num_divisions; float periods; }CurveInfo; SliderVar params[] = { { "Alpha", NULL, 5.0, 0.05, NULL }, { "BETA", NULL, 5.0, 0.05, NULL }, { "U-val", NULL, 5.0, 0.05, NULL }, { "V-val", NULL, 5.0, 0.05, NULL }, { "# Divisions", NULL, 1000.0, 10.0, NULL }, { "# Periods", NULL, 20.0, 0.3, NULL }, { NULL, NULL, 0, 0, NULL } }; #define TIME_OUT 50 /* amount of time between redraw (in milli-secs) */ void glLine(float x1, float y1, float x2, float y2) { glBegin(GL_LINES); glVertex2f(x1, y1); glVertex2f(x2, y2); glEnd(); } void gl_setup(void) { /* * Clear the screen (both buffers). */ glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(); /* * Setup some standard gl stuff */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-5.0,5.0, -5.0,5.0, -5.0,5.0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); } void Quit(Widget w, void *data) { exit(0); } void redraw(Widget w, int width, int height, void *data) { SetDrawArea(w); glViewport(0,0,width,height); } void draw_stuff(void *data) { CurveInfo *ci = (CurveInfo *)data; float r,g,b,x,y; int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP); for(i=0; i < ci->num_divisions; i++) { float radian; radian = (float)i * ((M_PI * ci->periods)/ci->num_divisions); x = cos(radian * ci->u) * ci->alpha; y = sin(radian * ci->v) * ci->beta; glVertex2f(x, y); } glEnd(); SwapBuffers(); AddTimeOut(TIME_OUT, draw_stuff, ci); } int main(int argc, char **argv) { CurveInfo ci; argc = OpenGLDisplay(argc, argv, attributes); if (argc == 0) /* woops, couldn't get started */ exit(5); /* * Setup the initial curve info */ ci.alpha = 4.0; ci.beta = 4.0; ci.u = 1.0; ci.v = 1.0; ci.num_divisions = 100; ci.periods = 2.0; params[0].val = &ci.alpha; params[1].val = &ci.beta; params[2].val = &ci.u; params[3].val = &ci.v; params[4].val = &ci.num_divisions; params[5].val = &ci.periods; gui[QUIT] = MakeButton("Quit", Quit, &ci); gui[DRAW_AREA] = MakeDrawArea(500,500, redraw, &ci); gui[PARAM_BOX] = MakeControlBox("Curve Parameters", ¶ms[0]); SetWidgetPos(gui[PARAM_BOX], PLACE_UNDER, gui[QUIT], NO_CARE, NULL); SetWidgetPos(gui[DRAW_AREA], PLACE_UNDER, gui[PARAM_BOX], NO_CARE, NULL); srand48((long)101); ShowDisplay(); GetStandardColors(); gl_setup(); AddTimeOut(TIME_OUT, draw_stuff, &ci); MainLoop(); /* off we go! */ } libsx-2.05/pcurve/libsx.h0000777000175000017500000000000011252443766021014 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/controlbox/0000755000175000017500000000000011252443541016105 5ustar amckinstryamckinstrylibsx-2.05/controlbox/callbacks.c0000644000175000017500000001130711252443541020172 0ustar amckinstryamckinstry/* This file contains routines that are called when a button is pressed * in your window or when things happen in a drawing area. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo */ #include #include #include "libsx.h" #include "controlbox.h" #include "main.h" #include "callbacks.h" /* -- CALLBACK ROUTINES -- * * These functions are called when various things happen in your windows. * They should handle what happened and give feedback to the user. Most * likely they will set options in your program (which is what the * MyProgram data structure is for), and cause different things to happen, * like loading and saving files, etc. * * Remember, the last argument to your callback is always a void pointer * to whatever data you specified when you created the widget. You * must cast the pointer to be whatever type it really is. */ void quit(Widget w, void *data) { /* Do any cleanup that is necessary for your program here */ exit(0); } extern SliderVar sliders[]; void button1(Widget w, void *data) { printf("Changing slider #1\n"); SetScrollbar(sliders[0].slider, 50.0, 100.0, 100.0); } void button2(Widget w, void *data) { int i; printf("Dumping slider values:\n"); for(i=0; sliders[i].name != NULL; i++) printf("slider %d: value == %f\n", i, *sliders[i].val); } /* * The following functions are callbacks for the drawing area widgets. * * The only required callback is redisplay(). The others are optional * but have been setup to be used by init_display() in main.c. */ /* Here is where all redrawing will take place for your program. * When the window needs to be redrawn, this function will be called. * When your program starts up for the first time, this function will * be called and you should draw anything you need to draw in here. */ void redisplay(Widget w, int new_width, int new_height, void *data) { MyProgram *me=data; ClearDrawArea(); /* start with a clean slate */ } void button_down(Widget w, int which_button, int x, int y, void *data) { printf("You clicked button %d at (%d,%d)\n", which_button, x,y); } void button_up(Widget w, int which_button, int x, int y, void *data) { printf("You released button %d at (%d,%d)\n", which_button, x,y); } /* * The following function is called when keypresses happen in the drawing * area widget. * * It is useful to know that the string returned to your program is * not necessarily a single ASCII character. You will get the usual * ASCII characters, including control characters (such as ^C or ^H). * But, the workstation's function keys will also be returned in a * string such as "F11" or "F23". You will also get other longer * strings such as "Control_L", "Alt_R", or "Shift_L". It is * important to understand that even if you just press the shift key to * get a capital letter, you will first receive the string "Shift_L" * or "Shift_R", then you will receive a capital letter (say, "H"). * You should probably ignore the "Shift_L" or "Shift_R" messages (but * who knows, you may find some use for them). * * The argument, up_or_down, tells you whether the given key was pressed * or released. If the key was pressed down, up_or_down has a zero (0), * if the key was released, up_or_down contains a 1. * * NOTE WELL: * The string that is returned to you can _NOT_ (I'll repeat that, * can _NOT_) be modified by your program. Got it? Do _NOT_ modify * the string. If you want to munge with it, make a copy using * strdup() or strcpy() into your own buffer space. */ void keypress(Widget w, char *input, int up_or_down, void *data) { char *str; if (input == NULL) return; if (up_or_down == 0) str = "pressed"; else str = "released"; printf("You %s : <<%s>>\n", str, input); } /* Called when a DrawingArea gets mouse motion events. The arguments * X and Y are the current position of the mouse in the window. * * NOTE: This routine should be _fast_ because *every* single time * the mouse moves in the drawing area, this function is called. * So even if you are just moving the mouse across the drawing area, * this routine is called. As it stands, it doesn't do anything. */ void motion(Widget w, int x, int y, void *data) { static int oldx = 0, oldy = 0; oldx = x; oldy = y; /* Be careful what you do with the mouse movement events, they * can make performance really bad if you don't process them fast */ } libsx-2.05/controlbox/main.c0000644000175000017500000000617411252443541017205 0ustar amckinstryamckinstry/* This is the main body of the program. It is just a simple skeleton * and should be fleshed out as desired. Mainly what you'll do to flesh * it out is to edit the data structure defined in main.h so that it contains * the information your program needs. Then modify init_display() to create * the interface you want, and then just write the associated callback * routines that are driven by the display. Easy, huh? * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* should come first, defines libsx stuff */ #include "controlbox.h" #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default draw area size, change as desired */ #define Y_SIZE 300 void main(int argc, char **argv) { MyProgram mydata; mydata.whatever = 0; /* do your initializations here */ init_display(argc, argv, &mydata); /* setup the display */ MainLoop(); /* go right into the main loop */ } float f1=50.0, f2=0.75, f3=7.5; SliderVar sliders[] = { { "Var #1", &f1, 100.0, 1.0, NULL, NULL }, { "Float Var #2", &f2, 1.0, 0.1, NULL, NULL }, { "Thing 3", &f3, 25.0, 10.0, NULL, NULL }, { NULL, NULL, 0.0, 0.0, NULL, NULL } }; /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ void init_display(int argc, char **argv, MyProgram *me) { Widget w[6]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Change Slider #1", button1, me); w[1] = MakeButton("Dump Slider Vals", button2, me); w[2] = MakeButton("Quit!", quit, me); w[4] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); w[6] = MakeControlBox("Some Cool Sliders", &sliders[0]); SetWidgetPos(w[6], PLACE_UNDER, w[4], NO_CARE, NULL); /* * These callbacks are unnecessary for most applications, but * they're here for completeness. Remove them if you don't * need them. */ SetButtonDownCB(w[4], button_down); SetButtonUpCB(w[4], button_up); SetKeypressCB(w[4], keypress); SetMouseMotionCB(w[4], motion); /* This call actually causes the whole thing to be displayed on the * screen. You have to call this function before doing any drawing * into the window. */ ShowDisplay(); /* Get standard (red, blue, green, yellow, black, white) colors for * drawing stuff. Check libsx.h for more info. */ GetStandardColors(); SetBgColor(sliders[0].slider, RED); SetFgColor(sliders[0].slider, WHITE); } libsx-2.05/controlbox/controlbox.c0000644000175000017500000001303411252443541020443 0ustar amckinstryamckinstry/* * this file is an attempt at making a "control box" routine that will * take an array of variables and make a bunch of sliders to control * each of the variables. It will put them in their own form widget * and return the form widget which you can then place wherever you like. * * The idea here is that a lot of times you just have a bunch of * parameters you want to control with sliders. It should be easy * to do that, and this function is an attempt at making it easy. * All you should have to do with this is declare an array of SliderVal * structures describing the parameters you want to have under slider * control (i.e. min, max, size_shown and their name) and blammo! you've * got a nice box with a title that has a bunch of sliders that control * your variables. You also have access to the underlying slider widgets * in case you need to change the parameters. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include "libsx.h" #include "controlbox.h" static void change_val(Widget w, float new_val, void *arg) { SliderVar *var = (SliderVar *)arg; char buff[256]; sprintf(buff, "%f", new_val); SetStringEntry(var->text, buff); *var->val = new_val; } static void str_change_val(Widget w, char *txt, void *arg) { SliderVar *var = (SliderVar *)arg; float new_val; char buff[256]; if (txt == NULL) return; if (*txt != '.' && *txt != '-' && isdigit(*txt) == 0) return; new_val = atof(txt); if (new_val < 0) { new_val = 0.0; sprintf(buff, "%f", new_val); SetStringEntry(var->text, buff); } if (new_val > var->max) { new_val = var->max; sprintf(buff, "%f", new_val); SetStringEntry(var->text, buff); } SetScrollbar(var->slider, new_val, var->max, var->shown); *var->val = new_val; } Widget MakeControlBox(char *title_str, SliderVar *vars) { int i, longest_len, longest_index, num_sliders; Widget form, title, *label, *slider, *text, previous_form; XFont font; previous_form = GetForm(); form = MakeForm(TOP_LEVEL_FORM); /* the parent could be passed in */ if (form == NULL) return NULL; if (title_str) title = MakeLabel(title_str); longest_len = -1; font = GetWidgetFont(form); for(i=0; vars[i].name != NULL; i++) { int len; if (font != NULL) len = TextWidth(font, vars[i].name); else len = strlen(vars[i].name); if (len > longest_len) { longest_len = len; longest_index = i; } } /* * At this point "i" contains how many sliders we need to create. * We'll use this information to allocate some arrays to hold * the widget pointers we get back from the MakeXXX() functions. * We need to save the values so that we can set their position later. */ num_sliders = i; label = calloc(1, num_sliders*sizeof(Widget)); slider = calloc(1, num_sliders*sizeof(Widget)); text = calloc(1, num_sliders*sizeof(Widget)); if (label == NULL || slider == NULL || text == NULL) { if (label) free(label); if (slider) free(slider); if (text) free(text); return NULL; } /* * First we just create the widgets, then we'll lay them out. */ for(i=0; i < num_sliders; i++) { char buff[256]; sprintf(buff, "%f", *vars[i].val); label[i] = MakeLabel(vars[i].name); slider[i] = MakeHorizScrollbar(250, change_val, &vars[i]); text[i] = MakeStringEntry(buff, 100, str_change_val, &vars[i]); vars[i].slider = slider[i]; /* save it for the user */ vars[i].text = text[i]; if (label[i] == NULL || slider[i] == NULL || text == NULL) { /* XXX -- destroy the widgets? how? */ free(label); free(slider); free(text); return NULL; } SetScrollbar(slider[i], *vars[i].val, vars[i].max, vars[i].shown); } /* * Here we set the positions of all the widgets we just created. * We set the first row of things just under the title string * if there was one. All the sliders always get put to the right * of the widest name (based on the width of text). */ if (title) { AttachEdge(title, TOP_EDGE, ATTACH_TOP); AttachEdge(title, BOTTOM_EDGE, ATTACH_TOP); AttachEdge(title, LEFT_EDGE, ATTACH_LEFT); AttachEdge(title, RIGHT_EDGE, ATTACH_LEFT); } for(i=0; i < num_sliders; i++) { if (i == 0) { SetWidgetPos(label[i], PLACE_UNDER, title, NO_CARE, NULL); SetWidgetPos(slider[i], PLACE_RIGHT, label[longest_index], PLACE_UNDER, title); SetWidgetPos(text[i], PLACE_RIGHT, slider[i], PLACE_UNDER, title); } else { SetWidgetPos(label[i], PLACE_UNDER, label[i-1], NO_CARE, NULL); SetWidgetPos(slider[i], PLACE_RIGHT, label[longest_index], PLACE_UNDER, label[i-1]); SetWidgetPos(text[i], PLACE_RIGHT, slider[i],PLACE_UNDER,label[i-1]); } AttachEdge(label[i], TOP_EDGE, ATTACH_TOP); AttachEdge(label[i], BOTTOM_EDGE, ATTACH_TOP); AttachEdge(label[i], LEFT_EDGE, ATTACH_LEFT); AttachEdge(label[i], RIGHT_EDGE, ATTACH_LEFT); AttachEdge(slider[i], TOP_EDGE, ATTACH_TOP); AttachEdge(slider[i], BOTTOM_EDGE, ATTACH_TOP); AttachEdge(slider[i], LEFT_EDGE, ATTACH_LEFT); AttachEdge(slider[i], RIGHT_EDGE, ATTACH_RIGHT); AttachEdge(text[i], TOP_EDGE, ATTACH_TOP); AttachEdge(text[i], BOTTOM_EDGE, ATTACH_TOP); AttachEdge(text[i], LEFT_EDGE, ATTACH_RIGHT); AttachEdge(text[i], RIGHT_EDGE, ATTACH_RIGHT); } SetForm(previous_form); return form; } libsx-2.05/controlbox/makefile0000644000175000017500000000062511252443541017610 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o controlbox.o cbox : $(OBJS) $(CC) -o $@ $(OBJS) $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h controlbox.h callbacks.o : libsx.h callbacks.c controlbox.o : controlbox.c controlbox.c clean : rm -f *.o *~ core skel cbox libsx-2.05/controlbox/main.h0000644000175000017500000000072711252443541017210 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { int whatever; }MyProgram; /* protos */ void init_display(int argc, char **argv, MyProgram *me); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/controlbox/controlbox.h0000644000175000017500000000124611252443541020452 0ustar amckinstryamckinstry/* * This file contains the structures and #define's for use with * the control box routines. * * Dominic Giampaolo * dbg@sgi.com */ typedef struct SliderVar { char *name; float *val; float max, shown; Widget slider; /* gets filled in by MakeControlBox() */ Widget text; /* gets filled in by MakeControlBox() */ }SliderVar; /* * MakeControlBox() returns a form widget who's position you can * set with SetWidgetPos(). The form will contain an vertical array * of sliders and any time the user plays with one, your variables * will change. You don't have to do anything really. */ Widget MakeControlBox(char *title, SliderVar *variables); libsx-2.05/controlbox/libsx.h0000777000175000017500000000000011252443766021701 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/controlbox/callbacks.h0000644000175000017500000000150011252443541020171 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error). * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void button1(Widget w, void *data); void button2(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); void button_down(Widget w, int which_button, int x,int y, void *data); void button_up(Widget w, int which_button, int x, int y, void *data); void keypress(Widget w, char *input, int up_or_down, void *data); void motion(Widget w, int x, int y, void *data); libsx-2.05/multireq/0000755000175000017500000000000011252443541015556 5ustar amckinstryamckinstrylibsx-2.05/multireq/main.c0000644000175000017500000000442511252443541016653 0ustar amckinstryamckinstry/* * -Allen Martin (amartin@wpi.wpi.edu) */ #include #include #include #include "libsx.h" /* gets us in the door with libsx */ #include "multireq.h" int init_display(int argc, char **argv, void *data); /* callback protos */ void edit(Widget w, void *data); void quit(Widget w, void *data); void main(int argc, char **argv) { argc = init_display(argc, argv, NULL); /* setup the display */ if (argc == 0) exit(0); MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ int init_display(int argc, char **argv, void *data) { Widget w[2]; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; w[0] = MakeButton("Edit", edit, data); w[1] = MakeButton("Quit!", quit, data); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); ShowDisplay(); GetStandardColors(); return argc; } /* */ void edit(Widget w, void *data) { static char name[1024] = "Computer Geek"; static char address[1024] = "Fuller Labs, WPI"; static int number=123; static float height=456.789; TagList tags[] = { {TAG_WINDOW_LABEL, "Input Window", NULL, TAG_NOINIT}, {TAG_STRING, "Name:", name, TAG_INIT}, {TAG_LABEL, "Please Enter your Address below", NULL, TAG_NOINIT}, {TAG_STRING, "Address:", address, TAG_INIT}, {TAG_INT, "Number:", &number, TAG_INIT}, {TAG_FLOAT, "Height:", &height, TAG_INIT}, {TAG_DONE, NULL, NULL, TAG_NOINIT} }; if(GetValues(tags)) printf("Cancelled\n"); else { printf("Name: %s\n", name); printf("Address: %s\n", address); printf("Number: %d\n", number); printf("Height: %f\n", height); } } /* * quit() - Callback function for the quit button */ void quit(Widget w, void *data) { exit(0); } libsx-2.05/multireq/makefile0000644000175000017500000000035311252443541017257 0ustar amckinstryamckinstry# # include ../libsx_defs OBJS = main.o multireq.o all : multireq multireq : $(OBJS) $(CC) -g -o $@ $(OBJS) $(LIBS) main.o : main.c libsx.h multireq.h multireq.o : multireq.c multireq.h clean: rm -f *.o *~ core multireq libsx-2.05/multireq/multireq.h0000644000175000017500000000054411252443541017574 0ustar amckinstryamckinstrytypedef struct { int tag; char *label; void *data; int init; } TagList; #define TAG_NULL 0 #define TAG_STRING 1 #define TAG_INT 2 #define TAG_FLOAT 3 #define TAG_LABEL 4 #define TAG_WINDOW_LABEL 5 #define TAG_DONE 99 #define TAG_INIT 1 #define TAG_NOINIT 0 int GetValues(TagList *tags); libsx-2.05/multireq/libsx.h0000777000175000017500000000000011252443766021352 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/multireq/multireq.c0000644000175000017500000002302611252443541017567 0ustar amckinstryamckinstry/* * A simple form-fillout function that lets you pass an array of * Tag's that describe a form and it will pop up a window and let * a user fill out a form that describes the values you'd like. * * The main function is GetValues(). See the demo program in this * same directory (main.c, in the function edit()) for a more * detailed example. * * Written by Allen Martin, (amartin@cs.wpi.edu). * revised by Giampiero Raschetti (jimi@settimo.italtel.it) */ #include #include #include #include #include "libsx.h" #include "multireq.h" #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) typedef struct { Widget window; int cancelled; int numentry; Widget *w; TagList *tags; } MReqData; MReqData mdata; int BgColor,FgColor; /* protos */ static void mreq_ok(Widget w, MReqData *mdata); static void mreq_cancel(Widget w, MReqData *mdata); static void mreq_acceptfield(Widget w, char *str, MReqData *mdata); static void mreq_User(Widget w, MReqData *mdata); static void FillForm(); static void SwitchFocusF(); static void SwitchFocusB(); static void SetFocus(); static void tasto(); int GetValues(TagList *tags) { int num_tags=0, num_widg=0, num_labels=0; int i, w, l; Widget *label_w, ok_w, cancel_w; char string[256], window_name[256]="Requestor"; int maxwidth=0, widest_label=-1; /* first count the number of tag items and required widgets */ for(; tags[num_tags].tag != TAG_DONE; num_tags++) { if(tags[num_tags].tag == TAG_LABEL) { num_labels++; continue; } else if(tags[num_tags].tag == TAG_WINDOW_LABEL) { if(!tags[num_tags].label) { fprintf(stderr, "Invalid window name passed to GetValues()\n"); return(TRUE); } strcpy(window_name, tags[num_tags].label); continue; } /* determine the widest label */ if(strlen(tags[num_tags].label) > maxwidth) { maxwidth = strlen(tags[num_tags].label); widest_label = num_labels; } num_labels++; num_widg++; } /* allocate mem for the widgets */ if(!(mdata.w = (Widget *)malloc(num_widg * sizeof(Widget)))) return(TRUE); if(!(label_w = (Widget *)malloc(num_labels * sizeof(Widget)))) { free(mdata.w); return(TRUE); } mdata.window = MakeWindow(window_name, SAME_DISPLAY, EXCLUSIVE_WINDOW); mdata.tags = tags; mdata.numentry = num_widg; /* create the label widgets first */ for(i=0, l=0; icancelled = TRUE; SetCurrentWindow(mdata->window); CloseWindow(); } /************************************************************** * jimi **************************************************************/ static int CurrentFocus; static void mreq_acceptfield(Widget w, char *str, MReqData *mdata) { SwitchFocusF(); } static void FillForm(Widget w, XEvent *event, String *args, Cardinal n_args) { int widg_num; TagList *tagptr; char *cptr; /* extract the info from the widgets */ for(widg_num=0, tagptr=mdata.tags; tagptr->tag != TAG_DONE; tagptr++) { switch(tagptr->tag) { case TAG_STRING: cptr = GetStringEntry(mdata.w[widg_num++]); strcpy(tagptr->data, cptr); break; case TAG_INT: cptr = GetStringEntry(mdata.w[widg_num++]); *((int *)tagptr->data) = atoi(cptr); break; case TAG_FLOAT: cptr = GetStringEntry(mdata.w[widg_num++]); *((float *)tagptr->data) = atof(cptr); break; case TAG_WINDOW_LABEL: case TAG_LABEL: break; default: fprintf(stderr, "GetValues() : Invalid tag item %d\n", tagptr->tag); } } mdata.cancelled = FALSE; SetCurrentWindow(mdata.window); CloseWindow(); } /* FillForm */ static void SwitchFocusF(Widget w, XEvent *event, String *args, Cardinal n_args) { Arg wargs[3]; /* Used to set widget resources */ int n; n = 0; XtSetArg(wargs[n], XtNbackground, BgColor ); n++; XtSetArg(wargs[n], XtNforeground, FgColor ); n++; XtSetValues(mdata.w[CurrentFocus], wargs, n); if ( ++CurrentFocus >= mdata.numentry ) CurrentFocus=0; n = 0; XtSetArg(wargs[n], XtNbackground, FgColor ); n++; XtSetArg(wargs[n], XtNforeground, BgColor ); n++; XtSetValues(mdata.w[CurrentFocus], wargs, n); XtSetKeyboardFocus(mdata.window, mdata.w[CurrentFocus]); } /* SwitchFocusF */ static void SetFocus(Widget w, XEvent *event, String *args, Cardinal n_args) { int i,n; Arg wargs[3]; /* find clicked widget */ for(i=0; i < mdata.numentry; i++) { if(w == mdata.w[i]) break; } if (i >= mdata.numentry) return; n = 0; XtSetArg(wargs[n], XtNbackground, BgColor ); n++; XtSetArg(wargs[n], XtNforeground, FgColor ); n++; XtSetValues(mdata.w[CurrentFocus], wargs, n); n = 0; XtSetArg(wargs[n], XtNbackground, FgColor ); n++; XtSetArg(wargs[n], XtNforeground, BgColor ); n++; XtSetValues(mdata.w[i], wargs, n); CurrentFocus=i; XtSetKeyboardFocus(mdata.window, w); } /* SetFocus */ static void SwitchFocusB(Widget w, XEvent *event, String *args, Cardinal n_args) { Arg wargs[3]; /* Used to set widget resources */ int n; n = 0; XtSetArg(wargs[n], XtNbackground, BgColor ); n++; XtSetArg(wargs[n], XtNforeground, FgColor ); n++; XtSetValues(mdata.w[CurrentFocus], wargs, n); if ( CurrentFocus-- == 0 ) CurrentFocus = mdata.numentry - 1; n = 0; XtSetArg(wargs[n], XtNbackground, FgColor ); n++; XtSetArg(wargs[n], XtNforeground, BgColor ); n++; XtSetValues(mdata.w[CurrentFocus], wargs, n); XtSetKeyboardFocus(mdata.window, mdata.w[CurrentFocus]); } /* SwitchFocusB */ /*-----------------*/ extern XtAppContext lsx_app_con; /* variabile globale da non vedere ! */ static XtActionsRec actions_table[] = { { "SwitchF", (XtActionProc)SwitchFocusF }, { "SwitchB", (XtActionProc)SwitchFocusB }, { "SetFocus", (XtActionProc)SetFocus }, { "Close", (XtActionProc)FillForm }, }; InitFocus(MReqData *mdata) { Arg wargs[3]; /* Used to set widget resources */ int n; XtTranslations trans; /* Change background color in the first widget */ n = 0; XtSetArg(wargs[n], XtNbackground, FgColor ); n++; XtSetArg(wargs[n], XtNforeground, BgColor ); n++; XtSetValues(mdata->w[CurrentFocus], wargs, n); /* Set keyboard focus on the first widget */ XtSetKeyboardFocus(mdata->window, mdata->w[CurrentFocus]); /* Set Keyboard callback function to all StringEntry widgets */ XtAppAddActions(lsx_app_con, actions_table, XtNumber(actions_table)); trans = XtParseTranslationTable("#override \n\ ShiftTab: SwitchB()\n\ Tab: SwitchF()\n\ ShiftReturn: Close()\n\ : SetFocus()\n\ F10: SwitchB()\n"); for(n = 0; n < mdata->numentry; n++) XtOverrideTranslations(mdata->w[n], trans); } libsx-2.05/draw_demo/0000755000175000017500000000000011252443541015655 5ustar amckinstryamckinstrylibsx-2.05/draw_demo/draw_demo.c0000644000175000017500000000132711252443541017765 0ustar amckinstryamckinstry#include #include #include "libsx.h" void quit(Widget w, void *data) { exit(0); } void draw_stuff(Widget w, int width, int height, void *data) { ClearDrawArea(); DrawLine(50,50, width-50, height-50); /* just draw a diagonal line */ } int main(int argc, char **argv) { Widget w[2]; argc = OpenDisplay(argc, argv); if (argc == 0) /* woops, couldn't get started */ exit(5); /* could process our own command line options here. */ w[0] = MakeButton("Quit", quit, NULL); w[1] = MakeDrawArea(500,500, draw_stuff, NULL); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); ShowDisplay(); GetStandardColors(); MainLoop(); /* off we go! */ } libsx-2.05/draw_demo/makefile0000644000175000017500000000020011252443541017345 0ustar amckinstryamckinstry# # include ../libsx_defs draw_demo : draw_demo.o $(CC) -o draw_demo draw_demo.o $(LIBS) clean: rm -f *.o *~ core draw_demo libsx-2.05/draw_demo/libsx.h0000777000175000017500000000000011252443766021451 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/bezier/0000755000175000017500000000000011252443541015174 5ustar amckinstryamckinstrylibsx-2.05/bezier/bezier.c0000644000175000017500000000200411252443541016614 0ustar amckinstryamckinstry/* this file contains a routine to implement drawing a bezier * curve based on 4 control points * * dominic giampaolo * dbg@sgi.com */ #include "gfx.h" #include "libsx.h" #include "bezier.h" void bezier4(Point *p, int num_steps) { double t, t_sq, t_cb, incr; double r1, r2, r3, r4; ushort curve_x, curve_y; incr = 1.0 / (double)num_steps; MoveTo(p[0].x, p[0].y); for(t=incr; t <= 1.01; t += incr) { t_sq = t * t; t_cb = t * t_sq; r1 = (1 - 3*t + 3*t_sq - t_cb)*(double)p[0].x; r2 = ( 3*t - 6*t_sq + 3*t_cb)*(double)p[1].x; r3 = ( 3*t_sq - 3*t_cb)*(double)p[2].x; r4 = ( t_cb)*(double)p[3].x; curve_x = (ushort)(r1 + r2 + r3 + r4); r1 = (1 - 3*t + 3*t_sq - t_cb)*(double)p[0].y; r2 = ( 3*t - 6*t_sq + 3*t_cb)*(double)p[1].y; r3 = ( 3*t_sq - 3*t_cb)*(double)p[2].y; r4 = ( t_cb)*(double)p[3].y; curve_y = (ushort)(r1 + r2 + r3 + r4); LineTo(curve_x, curve_y); } } libsx-2.05/bezier/callbacks.c0000644000175000017500000002367511252443541017274 0ustar amckinstryamckinstry/* This file contains routines that manage the user interface. * * This code (for what it's worth) is under the GNU copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include "libsx.h" #include "gfx.h" #include "main.h" #include "callbacks.h" #include "bezier.h" #ifndef caddr_t #define caddr_t char* #endif /* * Would you believe that posix doesn't actually require that M_PI_2 and * M_PI_4 be defined? What a load of crap.... */ #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 #define M_PI_4 0.78539816339744830962 #endif /* internal prototypes */ void timeout(caddr_t data, XtIntervalId *id); int check_point(MyProgram *me, ushort x, ushort y); /* Each of the following functions is tied to a given interface button. * They are called whenever the user clicks on something on the display, * and happen independant of anything else that may be taking place on * the display. */ /* Just quit out of everything. */ void quit(Widget w, void *data) { exit(0); } /* Cause the curve to be redrawn. Not much to do here, this is basically * just a wrapper function for do_redisplay(). */ void redraw_curve(Widget w, void *data) { MyProgram *me = (MyProgram *)data; redisplay(NULL, me->width, me->height, me); } /* This resets the curve back to the original. */ void reset_curve(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->pts[0].x = 0; me->pts[0].y = 5000; me->pts[1].x = 2500; me->pts[1].y = 7500; me->pts[2].x = 5000; me->pts[2].y = 2500; me->pts[3].x = 7500; me->pts[3].y = 5000; redisplay(NULL, me->width, me->height, me); } /* This starts the animation going. It sets a flag and then calls the * timeout() routine. timeout() does its business and then adds itself * as a time-out that will happen every so many milliseconds. */ void bez_anim(Widget w, void *data) { MyProgram *me = (MyProgram *)data; if (me->remove_timeout == FALSE) /* already doing it */ return; me->remove_timeout = FALSE; ClearDrawArea(); timeout((caddr_t)me, NULL); /* start the ball rolling */ } /* This unsets a flag that was set in bez_anim(). This makes the * timeout() routine remove itself, and so the animation stops. */ void stop_anim(Widget w, void *data) { MyProgram *me = (MyProgram *)data; if (me->remove_timeout == TRUE) /* already stopped */ return; me->remove_timeout = TRUE; /* makes the timeout function remove itself */ } void time_out_adjust(Widget w, float new_val, void *data) { char buff[80]; MyProgram *me=data; me->timeout_val = new_val; sprintf(buff, "Timeout Val: %-6f ", me->timeout_val); SetLabel(me->label_widget, buff); } /* These callbacks down here are the standard ones for the drawing area, * and are where you'd implement your interface "policy". By that, I mean * these functions and what they do determines how your program behaves * and controls what the user will think of your program (i.e. this is * great or this is garbage). You really should think out what you do * in these functions. How do you want mouse clicks to work, what should * dragging operations behave like, etc. These are all important issues * that get implemented in the next few functions and determine the look * and feel (oh oh, watch out for Apple's lawyers :^) of your application. */ /* * Here is where we redraw things when necessary. It also re-maps the * view ports to reflect the new changes in the window size. */ void redisplay(Widget w, int new_width, int new_height, void *data) { MyProgram *me = data; ClearDrawArea(); /* start with a clean slate */ me->width = new_width; /* save new window size */ me->height = new_height; /* * Setup the proper mapping from world coordinates (10000 x 10000) to * window coordinates (width x height) */ SetView(0,0, 10000, 10000, &me->world_view); SetView(0,0, me->width, me->height, &me->view_port); MapView(&me->world_view, &me->view_port); SetColor(WHITE); /* draw the control points */ FilledBox(me->pts[0].x, me->pts[0].y, 100, 100); FilledBox(me->pts[1].x, me->pts[1].y, 100, 100); FilledBox(me->pts[2].x, me->pts[2].y, 100, 100); FilledBox(me->pts[3].x, me->pts[3].y, 100, 100); bezier4(me->pts, 20); /* draw the actual bezier curve */ } #define NO_MB 0 #define MB_1 1 #define MB_2 2 #define MB_3 4 #define MB_4 8 #define MB_5 16 int mouse_button = 0; void button_down(Widget w, int which_button, int x, int y, void *data) { MyProgram *me=data; Vp2World(&x, &y); /* convert from device to world coords */ switch (which_button) { case 1: mouse_button |= MB_1; if (check_point(me, x, y)) me->mode = MODE_MOVING; break; case 2: mouse_button |= MB_2; break; case 3: mouse_button |= MB_3; break; } } void button_up(Widget w, int which_button, int x, int y, void *data) { MyProgram *me=data; Vp2World(&x, &y); /* convert from device to world coords */ switch (which_button) { case 1: mouse_button &= ~MB_1; me->mode = MODE_NOTHING; redraw_curve(NULL, me); /* so any screen turds are cleaned up */ break; case 2: mouse_button &= ~MB_2; break; case 3: mouse_button &= ~MB_3; break; } } /* Called when DrawingArea canvas have pointer motion events */ void process_motion(Widget w, int x, int y, void *data) { static int oldx = 0, oldy = 0; Point old, cur; MyProgram *me=data; old.x = oldx; old.y = oldy; cur.x = x; cur.y = y; if ((me->mode & MODE_MOVING) == 0) return; if (me->cur_point == -1) return; Vp2World(&x, &y); /* convert from device to world coords */ SetColor(BLACK); /* erase the old stuff */ FilledBox(me->pts[me->cur_point].x, me->pts[me->cur_point].y, 100, 100); bezier4(me->pts, 20); if (x < 0) /* keep things in bounds */ x = 0; if (x > 10000) x = 10000; if (y < 0) y = 0; if (y > 10000) y = 10000; me->pts[me->cur_point].x = x; me->pts[me->cur_point].y = y; SetColor(WHITE); /* redraw the new stuff */ bezier4(me->pts, 20); FilledBox(me->pts[me->cur_point].x, me->pts[me->cur_point].y, 100,100); } /* Checks if a mouse click is near any control points. Notice the slop * factor. If we expected the user to click _exactly_ on the control * point, they'd get frustrated pretty quickly. You generally need * some kind of slop factor like this. It should also be parameterized * instead of hardcoded because on a different resolution screen, you'd * want smaller or larger "slop" values. */ int check_point(MyProgram *me, ushort x, ushort y) { int i; for(i=0; i < 4; i++) { /* * Here's a strange bug for ya: If you don't cast x & y to * be int, the test below will fail for the first control * point on some machines (because pts.x-150 becomes negative) * which is cast to be unsigned to match the type on the right. * Thanks go to Pierre Asselin (pa@appmag.com) for finding * this one. */ if ((int)x > me->pts[i].x-150 && (int)x < me->pts[i].x+150) if ((int)y > me->pts[i].y-150 && (int)y < me->pts[i].y+150) { me->cur_point = i; return TRUE; } } return FALSE; } /* Here is where the animation takes place. What happens is that we * first check to see if we should stop animating and remove ourselves. * If so, we just call redraw_curve() and return. Otherwise we check if * we should erase the last frame, and if so, just erase the stuff by * redrawing it in white and then adding ourselves to the time-out list * once again. Else, we are supposed to move things and redraw in black. * The updating of the control points should probably be in a separate * function, but I'm lazy for now. The ugliness that updates the control * points, moves them along a parametric curve that I stole from the Hill * graphics book. It's a pretty neat curve (i.e. really twisty and curvy). * Anyway, after all that rigamarole, we just add ourselves to the timeout * chain again, and then return. * * The thing that may not be immediately obvious is how this function * gets called. Well, lemme tellya. The function AddTimeOut() sets * up a function (this one) to be called when a given amount of time * expires. The code that actually calls this routine is part of the * X toolkit library, and isn't really visible. The only other thing to * notice is that each time when we are done, we have to add ourselves * again to the time-out list so that we will get called again in the * next few milliseconds (otherwise nothing would get called and the * animation would stop, which incidentally is how stop the animation). */ void timeout(caddr_t data, XtIntervalId *id) { static double rad = 0.0; MyProgram *me = (MyProgram *)data; if (me->remove_timeout == TRUE) { redraw_curve(NULL, me); return; } SetColor(BLACK); /* erase */ bezier4(me->pts, 20); { /* redraw */ int size = 5000; double x,y, n = 6.0; rad += 0.01; me->pts[0].x = (size * (cos(n * rad)) * cos(rad)) + 5000; me->pts[0].y = (size * (cos((n-1) * rad)) * sin(rad)) + 5000; me->pts[1].x = (size * (cos(n * (rad + M_PI_2))) * cos(rad)) + 5000; me->pts[1].y = (size * (cos((n-1) * (rad + M_PI_2))) * sin(rad)) + 5000; me->pts[2].x = (size * (cos(n * (rad + M_PI_4))) * cos(rad)) + 5000; me->pts[2].y = (size * (cos((n-1) * (rad + M_PI_4))) * sin(rad)) + 5000; size /= 2; me->pts[3].x = (size * (cos(rad) + sin(8*rad))) + 5000; me->pts[3].y = ((size/2) * (2*sin(rad) + sin(7*rad))) + 5000; SetColor(WHITE); bezier4(me->pts, 20); if (me->remove_timeout == FALSE) AddTimeOut((me->timeout_val*1000), (GeneralCB)timeout, data); } } libsx-2.05/bezier/main.c0000644000175000017500000000623411252443541016271 0ustar amckinstryamckinstry/* This program lets the user interactively play with bezier curves. It * will also animate them in a visually pleasing manner. It is a pretty * good example of user interface interaction and stuff like that (because * it handles letting the user click on points to move them interactively). * * This code (for what it's worth) is under the GNU copyleft. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* pick up the libsx stuff we need */ #include "gfx.h" /* some graphics stuff */ #include "main.h" #include "callbacks.h" #include "bezier.h" /* define's */ #define X_SIZE 750 #define Y_SIZE 750 /* internal protos */ int init_myprogram(MyProgram *me); main(int argc, char **argv) { MyProgram mydata; if (init_myprogram(&mydata) == FALSE) /* init our data */ exit(10); init_display(argc, argv, &mydata); /* set up the display */ MainLoop(); /* and interact with the user */ } /* This just initializes our program data structure to some sane * default values. Nothing more, nothing less. */ int init_myprogram(MyProgram *me) { memset(me, sizeof(MyProgram), '\0'); /* zero everything out */ me->pts = (Point *)malloc(sizeof(Point) * 4); if (me->pts == NULL) return FALSE; me->pts[0].x = 0; me->pts[0].y = 5000; me->pts[1].x = 2500; me->pts[1].y = 7500; me->pts[2].x = 5000; me->pts[2].y = 2500; me->pts[3].x = 7500; me->pts[3].y = 5000; me->cur_point = -1; me->remove_timeout = TRUE; me->timeout_val = 0.03; return TRUE; } void init_display(int argc, char **argv, MyProgram *me) { char buff[80]; Widget w[8]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Redraw Curve", redraw_curve, me); w[1] = MakeButton("Reset Curve", reset_curve, me); w[2] = MakeButton("Animate!", bez_anim, me); w[3] = MakeButton("Stop Anim", stop_anim, me); w[4] = MakeButton("Quit!", quit, me); w[5] = MakeHorizScrollbar(225, time_out_adjust, me); sprintf(buff, "Timeout Val: %-6f", me->timeout_val); w[6] = MakeLabel(buff); w[7] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_RIGHT, w[3], NO_CARE, NULL); SetWidgetPos(w[5], PLACE_RIGHT, w[4], NO_CARE, NULL); SetWidgetPos(w[6], PLACE_RIGHT, w[5], NO_CARE, NULL); SetWidgetPos(w[7], PLACE_UNDER, w[0], NO_CARE, NULL); me->label_widget = w[6]; me->draw_widg = w[7]; SetScrollbar(w[5], me->timeout_val, 0.12, 0.0005); SetButtonDownCB(me->draw_widg, button_down); SetButtonUpCB(me->draw_widg, button_up); SetMouseMotionCB(me->draw_widg, process_motion); SetView(0,0, 10000, 10000, &me->world_view); /* set world view */ SetView(0,0, X_SIZE, Y_SIZE, &me->view_port); /* set view port view */ MapView(&me->world_view, &me->view_port); ShowDisplay(); GetStandardColors(); SetBgColor(me->draw_widg, BLACK); } libsx-2.05/bezier/gfx.h0000644000175000017500000000161411252443541016133 0ustar amckinstryamckinstry/* This header file contains various little structure definitions for things * like points and rectangles. You would probably want to build up from * the things defined in here. * * * * -- This code under the GNU copyleft -- * * Dominic Giampaolo */ #ifndef GFX_H #define GFX_H /* Two dimensional things */ typedef struct Point { short x, y; } Point; typedef struct Point Point2d; typedef Point Vector2d; typedef struct FPoint { float x, y; }FPoint; typedef struct FPoint Fpoint; typedef struct FPoint FPoint2d; typedef struct Rectangle { unsigned short left_edge, top_edge; unsigned short width, height; } Rectangle; typedef struct Rectangle Box; typedef struct Rectangle Square; typedef struct FRectangle { float left_edge, top_edge; float width, height; } FRectangle; typedef struct FRectangle FBox; typedef struct FRectangle FSquare; #endif /* GFX_H */ libsx-2.05/bezier/gfx.c0000644000175000017500000000753611252443541016137 0ustar amckinstryamckinstry/* This file implements functions which operate on a world coordinate space. * The code is entirely integer based for speedier operation. * * The dimensions of the world are 16,384 x 16,384 (x 16,384). This is * changeable via #define's. I use 16,384 as a world size because it * works easily in decimal to simulate floating point numbers and it isn't * so large that you have to worry about overflow. * * These routines work use the lower level X routines in libsx. * */ #include #include "gfx.h" #include "libsx.h" #define ushort unsigned short /* serious hack... */ #define SCALE 16384 #define SCALE_SHIFT 14 static int sx = SCALE, /* scale */ sy = SCALE; static int tx = 0, /* translation */ ty = 0; static int cur_color = 1; /* Set a view, either world or viewport coords. * le == left edge of view * te == top edge of view * re == right edge of view * be == bottom edge of view */ void SetView(int le, int te, int re, int be, Rectangle *r) { if (r == NULL) return; r->left_edge = le; r->top_edge = te; r->width = re; /* really right edge */ r->height = be; /* really bottom edge */ } /* Maps ww onto vp for all subsequent drawing operations. * Since we use integers, we have to multiply by SCALE so as not to lose * precision (otherwise most everything here would be zero). */ void MapView(Rectangle *ww, Rectangle *vp) { sx = ((vp->width - vp->left_edge) << SCALE_SHIFT) / (ww->width - ww->left_edge); sy = ((vp->height - vp->top_edge) << SCALE_SHIFT) / (ww->height - ww->top_edge); if (sx == 0) sx = 1; /* just in case, to avoid division by zero */ if (sy == 0) sy = 1; /* just in case, to avoid division by zero */ tx = ((vp->left_edge * ww->width) - (ww->left_edge * vp->width)); tx = (tx) / (ww->width - ww->left_edge); ty = ((vp->top_edge * ww->height) - (ww->top_edge * vp->height)); ty = (ty) / (ww->height - ww->top_edge); } void Vp2World(int *x, int *y) /* convert from a mouse click to world coords */ { *x = ((*x - tx) << SCALE_SHIFT) / sx; *y = ((*y - ty) << SCALE_SHIFT) / sy; } static ushort cur_x, cur_y; /* these are in viewport coords */ void MoveTo(ushort x, ushort y) { cur_x = (((int)x * sx) >> SCALE_SHIFT) + tx; cur_y = (((int)y * sy) >> SCALE_SHIFT) + ty; } void LineTo(ushort x, ushort y) { int rx2, ry2; rx2 = (((int)x * sx) >> SCALE_SHIFT) + tx; ry2 = (((int)y * sy) >> SCALE_SHIFT) + ty; DrawLine(cur_x, cur_y, rx2, ry2); cur_x = rx2; cur_y = ry2; } void PutPoint(ushort x1, ushort y1) { int rx1, ry1; /* real x1,y1 */ rx1 = (((int)x1 * sx) >> SCALE_SHIFT) + tx; ry1 = (((int)y1 * sy) >> SCALE_SHIFT) + ty; DrawPixel(rx1, ry1); cur_x = rx1; cur_y = ry1; } void Line(ushort x1, ushort y1, ushort x2, ushort y2) { int rx1, ry1, rx2, ry2; /* real x1,y1, etc... */ rx1 = (((int)x1 * sx) >> SCALE_SHIFT) + tx; ry1 = (((int)y1 * sy) >> SCALE_SHIFT) + ty; rx2 = (((int)x2 * sx) >> SCALE_SHIFT) + tx; ry2 = (((int)y2 * sy) >> SCALE_SHIFT) + ty; DrawLine(rx1, ry1, rx2, ry2); cur_x = rx2; cur_y = ry2; } void PutBox(ushort x1, ushort y1, ushort x2, ushort y2) { int rx1, ry1, rx2, ry2; /* real x1,y1, etc... */ rx1 = (((int)x1 * sx) >> SCALE_SHIFT) + tx; ry1 = (((int)y1 * sy) >> SCALE_SHIFT) + ty; rx2 = (((int)x2 * sx) >> SCALE_SHIFT); ry2 = (((int)y2 * sy) >> SCALE_SHIFT); DrawBox(rx1, ry1, rx2, ry2); cur_x = rx1; cur_y = ry1; } void FilledBox(ushort x1, ushort y1, ushort x2, ushort y2) { int rx1, ry1, rx2, ry2; /* real x1,y1, etc... */ rx1 = (((int)x1 * sx) >> SCALE_SHIFT) + tx; ry1 = (((int)y1 * sy) >> SCALE_SHIFT) + ty; rx2 = (((int)x2 * sx) >> SCALE_SHIFT); ry2 = (((int)y2 * sy) >> SCALE_SHIFT); DrawFilledBox(rx1, ry1, rx2, ry2); cur_x = rx1; cur_y = ry1; } libsx-2.05/bezier/makefile0000644000175000017500000000062211252443541016674 0ustar amckinstryamckinstry# # include ../libsx_defs LOCAL_LIBS = -lm # the object files which the program depends on OBJS = main.o callbacks.o bezier.o gfx.o bez : $(OBJS) $(CC) -o bez $(OBJS) $(LIBS) $(LOCAL_LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h gfx.h callbacks.o : gfx.h callbacks.c main.h gfx.o : gfx.c gfx.h clean: rm -f *.o *~ core bez libsx-2.05/bezier/main.h0000644000175000017500000000134211252443541016271 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { Rectangle world_view, view_port; Point *pts; Widget label_widget, draw_widg; float timeout_val; int remove_timeout; int cur_point; int mode; int width, height; }MyProgram; #define MODE_NOTHING 0x00 #define MODE_MOVING 0x01 /* protos */ void init_display(int argc, char **argv, MyProgram *me); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/bezier/libsx.h0000777000175000017500000000000011252443766020770 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/bezier/callbacks.h0000644000175000017500000000102311252443541017260 0ustar amckinstryamckinstry/* callback protos */ void quit(Widget w, void *data); void redraw_curve(Widget w, void *data); void reset_curve(Widget w, void *data); void bez_anim(Widget w, void *data); void stop_anim(Widget w, void *data); void time_out_adjust(Widget w, float newval, void *data); void redisplay(Widget w, int width, int height, void *data); void button_down(Widget w, int which_button, int x, int y, void *data); void button_up(Widget w, int which_button, int x, int y, void *data); void process_motion(Widget w, int x, int y, void *data); libsx-2.05/bezier/bezier.h0000644000175000017500000000037511252443541016632 0ustar amckinstryamckinstryvoid bezier4(Point *control_pts, int num_steps); /* * Gag, this is ugly. Can't find a reliable way to pick up the * typedef for ushort, so we #define it instead. * * Will unix ever be clean? */ #ifndef ushort #define ushort unsigned short #endif libsx-2.05/CHANGES0000644000175000017500000000174611252443541014717 0ustar amckinstryamckinstryEarly versions of libsx have been released around 1993 by Dominic Giampaolo (dbg@sgi.com), using also code provided by Allen Martin (amartin@wpi.wpi.edu). The present release includes an html documentation produced by Stephen Chenney (stephen@cs.su.oz.au) and Winston Holmes (winston@nestor.engr.utk.edu), and some useful additional routines (pixmap buttons, file selector, color selector, internationalization). Libsx-2.05 should be mostly API compatible with earlier versions -- at least as much as libsx-1.1 was with libsx-1.0. These modifications have been made step by step over a period of 2 years 1998-2000. The first widely announced public release of version 2 was 2.03. Version 2.0x, especially, include an internationalization routine. To produce dialogs for a new language, it is only needed to translate the (20 lines) file src/dialogs/dialogs.XX where XX is the country code. Jean-Pierre Demailly Universit\'e de Grenoble I July 29, 2000 demailly@fourier.ujf-grenoble.fr libsx-2.05/HELP0000644000175000017500000001200311252443541014363 0ustar amckinstryamckinstryThis file contains answers to questions that come up when people try to build libsx. ---------------------------------------------------------------------------- Q: The library built fine, but when I run the demo program, I get the following error: Warning: Cannot convert string "" to type Cursor X Error of failed request: BadPixmap (invalid Pixmap parameter) Major opcode of failed request: 93 (X_CreateCursor) Resource id in failed request: 0x0 Serial number of failed request: 133 Current serial number in output stream: 135 A: This problem seems to occur on Sun workstations that have different versions of the shared X libraries and server. That is, if you have the R4 libraries and an R5 server or R5 libs and an R4 server, you'll have this problem. The solution is to get matching versions of the libraries and server. Everything should work fine then. Occasionally it seems this problem will happen when running OpenWindows. That's because OpenWindows usually sets the LD_LIBRARY_PATH variable to be /usr/openwin/lib instead of /usr/lib. That in itself isn't a big deal but if you have versions of the X libraries in /usr/lib, and compile against those but at run-time you end up using the libraries in /usr/openwin/lib, this "Cannont convert string" problem happens. The solution to this would be to make the X libraries (at minimum libXaw.so) symbolic links from /usr/openwin/lib to the corresponding version in /usr/lib. That should do the trick but I have not tried it myself. A competent sysadmin ought to be able to figure out a solution without terribly much difficulty (although a _really_ competent sysadmin wouldn't have the problem in the first place :-). ---------------------------------------------------------------------------- Q: The library builds ok, but when I try to compile one of the demo programs I get: /usr/bin/ld: Error: Undefined: XShapeQueryExtension XShapeCombineMask A: You need to put -lXext in the LIBS variable in libsx_defs. ---------------------------------------------------------------------------- Q: I get the following undefined symbols when I try to link the demo programs: _get_wmShellWidgetClass _get_applicationShellWidgetClass A: (this comes straight out of the comp.windows.x faq sheet) In SunOS 4.1.2 Sun fixed a shared-library bug in ld which conflicts with the way X builds the shared Xmu library, causing these symbols, notably, to be undefined when building some X11 clients on SunOS 4.1.[23]: _get_wmShellWidgetClass _get_applicationShellWidgetClass Compiling "-Bstatic -lXmu -Bdynamic" is overkill; be sure to set OSTeenyVersion correctly in the config/sun.cf file and rebuild X11R5. To solve the problem if you are using OpenWindows 3.0 (X11R4-based Xt), please contact your local Sun office and request the following patches: Patch i.d. Description 100512-02 4.1.x OpenWindows 3.0 libXt Jumbo patch 100573-03 4.1.x OpenWindows 3.0 undefined symbols when using shared libXmu [Greg Earle, earle@Sun.COM; 7/92] A source patch for use with the X11R4 libraries was developed by Conrad Kimball (cek@sdc.boeing.com); it retrofits into R4 some fixes made in R5 to get around this problem. The patch is on ftp.x.org in [1/93] contrib/X11R4_sunos4.1.2_patch_version3.Z ---------------------------------------------------------------------------- Q: The library builds ok, but when I try to compile one of the demo programs I get: /usr/bin/ld: Error: Undefined: sin cos A: You need to put -lm at the end of the LIBS variable in libsx_defs. ---------------------------------------------------------------------------- Q: The file requester, freq, doesn't work on Solaris. I get messages such as: kefile: No such file or directory eq.c: No such file or directory etc... A: What appears to be happening is that readdir() is returning bogus name fields. One way around this problem is to switch over to using readdir_r() which although it's not portable, will work on Solaris. If you switch to using readdir_r(), you will need to first declare an appropriate size dirent structure like this: res = (struct dirent *)malloc(sizeof(struct dirent)+_POSIX_PATH_MAX); Then use the pointer malloc() gives you in calls to readdir_r(). ---------------------------------------------------------------------------- Q: On an SGI, scrollbars don't seem to work properly. What's a matter? A: This is because in some earlier versions of Irix (pre 5.2), the header file has an incorrect prototype for the function XawScrollbarSetThumb(). The arguments wind up being defined as doubles instead of float. You can fix this by changing the scrollbar.c file so that just before Scrollbar.h gets #included, you put the following line: #undef NeedWidePrototypes And that should take care of any problems you have with scrollbars. libsx-2.05/demo0/0000755000175000017500000000000011252443541014720 5ustar amckinstryamckinstrylibsx-2.05/demo0/test.c0000644000175000017500000000113711252443541016045 0ustar amckinstryamckinstry#include #include "libsx.h" void quit(Widget w, void *data) { CloseWindow(); ExitMainLoop(); } void real_quit(Widget w, void *data) { exit(0); } main(int argc, char **argv) { MakeButton("Click to Quit", quit, NULL); MainLoop(); MakeWindow("Second Window", NULL, NONEXCLUSIVE_WINDOW); MakeButton("Click to Quit", quit, NULL); MainLoop(); MakeWindow("Third Window", NULL, NONEXCLUSIVE_WINDOW); MakeButton("Click to Quit", quit, NULL); MainLoop(); MakeWindow("Last Window", NULL, NONEXCLUSIVE_WINDOW); MakeButton("My last window.", real_quit, NULL); MainLoop(); } libsx-2.05/demo0/foo.h0000644000175000017500000000632111252443541015656 0ustar amckinstryamckinstry#define foo_width 64 #define foo_height 64 static unsigned char foo_bits[] = { 0x00, 0x40, 0x00, 0x04, 0x02, 0x60, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x04, 0x03, 0x30, 0x00, 0x00, 0x00, 0x80, 0x01, 0x04, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x81, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xd8, 0x80, 0x41, 0x00, 0x00, 0x00, 0x80, 0x03, 0x30, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x8c, 0x20, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x02, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x04, 0x00, 0x10, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x04, 0x00, 0x10, 0x00, 0xc0, 0x38, 0x00, 0x20, 0x08, 0x1c, 0x08, 0x00, 0x60, 0x30, 0x00, 0x10, 0x08, 0xe0, 0x0b, 0x00, 0x20, 0x10, 0x00, 0x08, 0x30, 0x00, 0x06, 0x00, 0x30, 0x08, 0x00, 0x04, 0xc0, 0x80, 0x01, 0x00, 0x0c, 0x0c, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x86, 0x07, 0x00, 0x01, 0x40, 0x00, 0x01, 0x78, 0xc3, 0x00, 0x80, 0x00, 0x40, 0x00, 0x01, 0xff, 0x61, 0x00, 0x40, 0x00, 0x40, 0x00, 0xe1, 0x7f, 0x30, 0x00, 0x60, 0x00, 0x20, 0x00, 0xfd, 0x3f, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0xff, 0x8f, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0xfe, 0x07, 0x07, 0x00, 0x00, 0x00, 0x60, 0x00, 0xfe, 0xa3, 0x07, 0x00, 0x00, 0x00, 0x70, 0x00, 0x8e, 0xe1, 0x03, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x4e, 0xf6, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x80, 0xff, 0x00, 0x1a, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x0e, 0x12, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x80, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfc, 0x0b, 0xf0, 0x86, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc9, 0x1f, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x77, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfd, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfc, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x90, 0x64, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x90, 0x24, 0x08, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x90, 0x11, 0x10, 0x00, 0x00, 0x00, 0x80, 0x07, 0x30, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x2c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x86, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x82, 0x00, 0x01, 0x00, 0x00, 0x00, 0x83, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x80, 0x40, 0x83, 0x01, 0x02, 0x04, 0x00, 0x00, 0x40, 0x40, 0x86, 0x00, 0x02, 0x04, 0x00, 0x00, 0x20, 0x60, 0x4c, 0x00, 0x04, 0x08, 0x00, 0x00, 0x10, 0x18, 0x78, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x04, 0x20, 0x00, 0x10, 0x20, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00}; libsx-2.05/demo0/hello_world.c0000644000175000017500000000017411252443541017400 0ustar amckinstryamckinstry#include "libsx.h" main(int argc, char **argv) { OpenDisplay(argc, argv); MakeLabel("Hello World"); MainLoop(); } libsx-2.05/demo0/callbacks.c0000644000175000017500000002226011252443541017005 0ustar amckinstryamckinstry/* This file contains routines that are called when a button is pressed * in your window or when things happen in a drawing area. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo */ #include #include #include #include "libsx.h" #include "main.h" #include "callbacks.h" static int width, height; /* -- CALLBACK ROUTINES -- * * These functions are called when various things happen in your windows. * They should handle what happened and give feedback to the user */ void quit(Widget w, void *data) { MyProgram *me = (MyProgram *)data; int index; char *str; str = GetStringEntry(me->str_entry); printf("Final value for string entry is: %s\n", str); index = GetCurrentListItem(me->list); printf("Current list index is: %d\n", index); CloseWindow(); /* This will free any resources and exit MainLoop() */ } void load(Widget w1, void *data) { char *fname; fname = GetString("Enter new window title", "X Blows"); if (fname) { printf("You entered: %s\n", fname); SetWindowTitle(fname); free(fname); } else printf("You clicked cancel.\n"); } void save(Widget w, void *data) { int ans; /* ans = GetYesNo("\nAre you a weenie?\n\n"); */ ans = GetTriState("\nAre you a weenie?\n\n"); if (ans == TRUE) printf("You're a weenie.\n"); else if (ans == FALSE) printf("You are not a weenie.\n"); else if (ans == -1) printf("You canceled.\n"); } void scroll_func(Widget w, float val, void *arg) { printf("new value is: %f\n", val); } void string_func(Widget w, char *txt, void *arg) { MyProgram *me = (MyProgram *)arg; FILE *fp; printf("Got text: %s\n", txt); if ((fp = fopen(txt, "r")) != NULL) /* test if it exists first */ { fclose(fp); SetTextWidgetText(me->text_widget, txt, EDIT_FILE); SetTextWidgetPosition(me->text_widget, 3000); } else { SetTextWidgetText(me->text_widget, txt, EDIT_STRING); } } void list_callback(Widget w, char *str, int index, void *arg) { printf("In list callback, got item: %s index==%d\n", str, index); } void do_stuff(Widget w, void *data) { int i; static int counter=2, asked=0; MyProgram *me=data; char *str="This takes over the colormap of the display.\n\n Are you Sure?"; if (asked == FALSE && GetYesNo(str) == FALSE) return; asked=1; GetAllColors(); SetColorMap(counter); counter = (counter + 1) % 4; SetFgColor(me->quit, 248); /* 255 should always be an ok color */ SetBorderColor(me->quit, 248); SetFgColor(me->color_widget, 248); SetBorderColor(me->color_widget, 248); me->in_color_mode = 1; for(i=0; i < 256; i++) { SetColor(i); DrawLine(i,0, i,255); } } void check_me(Widget w, void *data) { MyProgram *me=data; static int toggle=0; toggle ^= 1; SetMenuItemChecked(w, toggle); if (toggle) SetWidgetState(me->copy_menu, FALSE); else SetWidgetState(me->copy_menu, TRUE); } void write_ppm(char *name, char *data, int width, int height) { FILE *fp; int i,j; fp = fopen(name, "wb"); if (fp == NULL) return; fprintf(fp, "P5\n%d %d\n255\n", width, height); fwrite(data, width*height, 1, fp); fclose(fp); } void more_stuff(Widget w, void *data) { MyProgram *me=data; char *img; int width=100,height=100; printf("More stuff...\n"); img = (char *)malloc(width*height); if (img == NULL) return; GetImage(img, 25, 25, width, height); write_ppm("foo.ppm", img, width,height); ScrollDrawArea(0, FontHeight(me->draw_font), 0,0, 300,300); } void toggle1(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->toggle1 ^= 1; printf("toggle 1 changing state: %d\n", me->toggle1); } void toggle2(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->toggle2 ^= 1; printf("toggle 2 changing state: %d\n", me->toggle2); } void toggle3(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->toggle3 ^= 1; printf("toggle 3 changing state: %d\n", me->toggle3); } void toggle4(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->toggle4 ^= 1; printf("toggle 4 changing state: %d\n", me->toggle4); } void other_toggle(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->other_toggle ^= 1; printf("Other toggle changing state: %d\n", me->other_toggle); } void menu_item1(Widget w, void *data) { printf("menu item 1 chosen\n"); } void menu_item2(Widget w, void *data) { printf("menu item 2 chosen\n"); } void menu_item3(Widget w, void *data) { printf("menu item 3 chosen\n"); } void menu_item4(Widget w, void *data) { printf("menu item 4 chosen\n"); } /* * The following functions are callbacks for the drawing area widgets. * */ void redisplay(Widget w, int new_width, int new_height, void *data) { MyProgram *me = data; width = new_width; /* save new window size */ height = new_height; do_redisplay(me, width, height); } void button_down(Widget w, int which_button, int x, int y, void *data) { MyProgram *me=data; printf("You pressed mouse button %d at (%d,%d)\n", which_button, x,y); me->down = which_button; me->oldx = me->startx = x; me->oldy = me->starty = y; SetMouseMotionCB(w, motion); SetLineStyle(LineOnOffDash); SetDrawMode(SANE_XOR); SetColor(me->col1); SetBgColor(me->draw_widget, WHITE); SetLineStyle(LineSolid); } void button_up(Widget w, int which_button, int x, int y, void *data) { MyProgram *me=data; printf("You released mouse button %d at (%d,%d)\n", which_button, x,y); me->down = 0; SetDrawMode(GXcopy); /* sets things back to normal */ SetMouseMotionCB(w, NULL); } /* * The following function is called when keypresses happen in the drawing * area widget. * * It is useful to know that the string returned to your program is * not necessarily a single ASCII character. You will get the usual * ASCII characters, including control characters (such as ^C or ^H). * But, the workstation's function keys will also be returned in a * string such as "F11" or "F23". You will also get other longer * strings such as "Control_L", "Alt_R", or "Shift_L". It is * important to understand that even if you just press the shift key to * get a capital letter, you will first receive the string "Shift_L" * or "Shift_R", then you will receive a capital letter (say, "H"). * You should probably ignore the "Shift_L" or "Shift_R" messages (but * who knows, you may find some use for them). * * The argument, up_or_down, tells you whether the given key was pressed * or released. If the key was pressed down, up_or_down has a zero (0), * if the key was released, up_or_down contains a 1. * * * NOTE WELL: * The string that is returned to you can _NOT_ (I'll repeat that, * can _NOT_) be modified by your program. Got it? Do _NOT_ modify * the string. If you want to munge with it, make a copy using * strdup() or strcpy() into your own buffer space. */ void keypress(Widget w, char *input, int up_or_down, void *data) { char *str; if (input == NULL) return; if (up_or_down == 0) str = "Down"; else str = "up"; if (isprint(*input)) printf("Key: <<%s>> %s\n", input, str); else printf("Key: (decimal value %d (0x%x) %s\n", *input, *input, str); } /* Called when a DrawingArea gets mouse motion events. The arguments * X and Y are the current position of the mouse in the window. * * NOTE: This routine should be _fast_ because *every* single time * the mouse moves in the drawing area, this function is called. * So even if you are just moving the mouse across the drawing area, * this routine is called. As it stands, it doesn't do anything. */ void motion(Widget w, int x, int y, void *data) { MyProgram *me=data; int owidth, oheight; owidth = me->oldx - me->startx; oheight = me->oldy - me->starty; if (me->down == 1) /* draw box outlines */ { DrawBox(me->startx, me->starty, owidth, oheight); DrawBox(me->startx, me->starty, (x - me->startx), (y - me->starty)); } else if (me->down == 2) /* draw some circles */ { DrawArc(me->startx, me->starty, owidth, oheight, 0, 360); DrawArc(me->startx, me->starty, (x-me->startx),(y-me->starty), 360,360); } else if (me->down == 3) /* draw some filled boxes */ { DrawFilledBox(me->startx, me->starty, owidth, oheight); DrawFilledBox(me->startx, me->starty, (x - me->startx), (y - me->starty)); } me->oldx = x; me->oldy = y; } /* Called the pointer enters a Drawing Area. The arguments X and Y * are the coordinates of the entry point. */ void enter(Widget w, int x, int y, void *data) { /* printf("Entered drawing area at (%d, %d)\n", x, y); */ } /* Called the pointer leaves a Drawing Area. The arguments X and Y * are the coordinates of the exit point. */ void leave(Widget w, int x, int y, void *data) { /* printf("Exited drawing area at (%d, %d)\n", x, y); */ } libsx-2.05/demo0/main.c0000644000175000017500000001543011252443541016013 0ustar amckinstryamckinstry/* This is the main body of the program. It is just a simple skeleton * and should be fleshed out as desired. Mainly what you'll do to flesh * it out is to edit the data structure defined in main.h so that it contains * the information your program needs. Then modify init_display() to create * the interface you want, and then just write the associated callback * routines that are driven by the user's interaction with display. * * Easy, huh? (sorta) * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo */ #include #include #include #include #include "libsx.h" /* gets us in the door with libsx */ #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default window size, change as desired */ #define Y_SIZE 300 char *string_table[] = { "Kyuss", "KMFDM", "Monster Magnet", "Obituary", "L7", "NIN", "Prong", "Sepultura", "Metallica", "Black Sabbath", "Diamond Head", "Budgie", "Dio", "Ozzy Osbourne", "Flotsam and Jetsam", "George Micheal", "Slayer", "Candlemass", "Van Halen", "W.A.S.P.", "Anthrax", "Soundgarden", "Iron Maiden", "The Cult", "Danzig", "Queensryche", "Motorhead", "AC/DC", "Led Zepplin", "Misfits", "Jimi Hendrix", "Nudeswirl", "Nirvana", "Vivaldi", "Holst", "Ravel", "B-52's", "Ice Cube", "Yes", "The Police", "The Cure", "Minor Threat", "Cro-Mags", "Agnostic Front", "Ministry", "Ice-T", "N.W.A", "Run-DMC", "Deep Purple", "Agent Orange", NULL }; void main(int argc, char **argv) { MyProgram mydata; memset(&mydata, '\0', sizeof(MyProgram)); /* clear this out! */ argc = init_display(argc, argv, &mydata); /* setup the display */ if (argc == 0) exit(0); MainLoop(); /* go right into the main loop, exits after quit() */ } /* * This function sets up the display for us. */ int init_display(int argc, char **argv, MyProgram *me) { Widget w[25]; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; w[0] = MakeMenu("File"); w[1] = MakeMenuItem(w[0], "Load...", load, me); w[2] = MakeMenuItem(w[0], "Save...", save, me); w[3] = MakeMenuItem(w[0], "Quit", quit, me); w[4] = MakeMenu("Edit"); w[5] = MakeMenuItem(w[4], "Check me", check_me, me); w[6] = MakeMenuItem(w[4], "Copy", NULL, NULL); w[7] = MakeMenuItem(w[4], "Paste", NULL, NULL); w[8] = MakeButton("Color Stuff", do_stuff, me); w[9] = MakeButton("More Stuff", more_stuff, me); w[10] = MakeButton("Quit!", quit, me); w[11] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); w[12] = MakeScrollList(string_table, 125, 275, list_callback, NULL); w[13] = MakeHorizScrollbar(X_SIZE, scroll_func, me); w[14] = MakeHorizScrollbar(X_SIZE, scroll_func, me); w[15] = MakeVertScrollbar(Y_SIZE, scroll_func, me); w[16] = MakeToggle("Slow", TRUE, NULL, toggle1, me); w[17] = MakeToggle("Fast", FALSE, w[16], toggle2, me); w[18] = MakeToggle("Faster", FALSE, w[16], toggle3, me); w[19] = MakeToggle("Fastest", FALSE, w[16], toggle4, me); w[20] = MakeToggle("Toggle me", FALSE, NULL, other_toggle, me); w[21] = MakeStringEntry("button.c", 435, string_func, me); w[22] = MakeTextWidget("button.c", EDIT_FILE, CAN_MODIFY, 435, 200); w[23] = MakeLabel(" A Sample Libsx Demo Program (cool huh?)"); SetWidgetPos(w[4], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[8], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[9], PLACE_UNDER, w[0], PLACE_RIGHT, w[8]); SetWidgetPos(w[10], PLACE_UNDER, w[0], PLACE_RIGHT, w[9]); SetWidgetPos(w[11], PLACE_UNDER, w[8], NO_CARE, NULL); SetWidgetPos(w[13], PLACE_UNDER, w[11], NO_CARE, NULL); SetWidgetPos(w[14], PLACE_UNDER, w[13], NO_CARE, NULL); SetWidgetPos(w[15], PLACE_RIGHT, w[11], PLACE_UNDER, w[8]); SetWidgetPos(w[12], PLACE_RIGHT, w[15], PLACE_UNDER, w[8]); SetWidgetPos(w[16], PLACE_RIGHT, w[13], PLACE_UNDER, w[15]); SetWidgetPos(w[17], PLACE_RIGHT, w[16], PLACE_UNDER, w[15]); SetWidgetPos(w[18], PLACE_RIGHT, w[13], PLACE_UNDER, w[16]); SetWidgetPos(w[19], PLACE_RIGHT, w[18], PLACE_UNDER, w[16]); SetWidgetPos(w[20], PLACE_RIGHT, w[10], PLACE_UNDER, w[0]); SetWidgetPos(w[21], PLACE_UNDER, w[18], NO_CARE, NULL); SetWidgetPos(w[22], PLACE_UNDER, w[21], NO_CARE, NULL); SetWidgetPos(w[23], PLACE_RIGHT, w[4], NO_CARE, NULL); /* * initialize the state of the toggle variables. */ me->toggle1 = TRUE; me->toggle2 = me->toggle3 = me->toggle4 = me->other_toggle = FALSE; me->list = w[12]; /* save these widget values for later */ me->str_entry = w[21]; me->text_widget = w[22]; me->draw_widget = w[11]; me->quit = w[10]; me->color_widget = w[8]; me->copy_menu = w[6]; me->paste_menu = w[7]; me->draw_font = GetFont("10x20"); if (me->draw_font == NULL) me->draw_font = GetFont("fixed"); SetWidgetFont(me->draw_widget, me->draw_font); SetTextEditable(me->text_widget, FALSE); SetButtonDownCB(w[11], button_down); SetButtonUpCB(w[11], button_up); SetKeypressCB(w[11], keypress); SetEnterCB(w[11], enter); SetLeaveCB(w[11], leave); SetScrollbar(w[13], 3.0, 14.0, 14.0); SetScrollbar(w[14], 250.0, 255.0, 1.0); SetScrollbar(w[15], 30.0, 100.0, 25.0); /* * Now actually put the display on the screen. */ ShowDisplay(); TurnOnBackingStore(w[11]); /* * Get some colors for drawing with. */ GetStandardColors(); me->col1 = GetNamedColor("peachpuff2"); if (me->col1 == -1) fprintf(stderr, "Error getting color peachpuff\n"); me->col2 = GetRGBColor(255, 0, 255); if (me->col2 == -1) fprintf(stderr, "Error getting RGB color 0 255 255\n"); return argc; } void do_colorstuff(void); /* Here is where all redrawing will take place for your program. * When the window needs to be redrawn, this function will be called. * When your program starts up for the first time, this function will * be called and you should draw anything you need to draw in here. */ void do_redisplay(MyProgram *me, int width, int height) { int i; char *str = "My Cool Program"; if (me->in_color_mode) { do_colorstuff(); return; } SetBgColor(me->draw_widget, WHITE); ClearDrawArea(); /* start with a clean slate */ SetColor(BLACK); SetBgColor(me->draw_widget, GREEN); DrawText(str, (width-TextWidth(me->draw_font, str))/2, height/2); SetBgColor(me->draw_widget, WHITE); SetColor(me->col1); for(i=0; i < width; i+=5) DrawLine(0,i, i,height); SetColor(me->col2); for(i=0; i < width; i+=5) DrawLine(width,i, width-i,height); } void do_colorstuff(void) { int i; for(i=0; i < 256; i++) { SetColor(i); DrawLine(i,0, i,255); } } libsx-2.05/demo0/foo0.c0000644000175000017500000000046311252443541015732 0ustar amckinstryamckinstryvoid SetWidgetSize(Widget w, int width, int height) { int n = 0; Arg wargs[2]; if (width > 0) { XtSetArg(wargs[0], XtNwidth, width); n++; } if (height > 0) { XtSetArg(wargs[0], XtNheight, height); n++; } if (n > 0 && w != NULL) XtSetValues(w, wargs, n); } libsx-2.05/demo0/makefile0000644000175000017500000000117011252443541016417 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o all : test hello_world demo demo0 test: test.c $(CC) test.c -o test $(LIBS) hello_world: hello_world.c $(CC) hello_world.c -o hello_world $(LIBS) demo : $(OBJS) $(CC) -o demo $(OBJS) $(LIBS) demo0 : main0.o $(CC) -o demo0 main0.o $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h callbacks.o : libsx.h callbacks.c main.h # # A cleanup target. Type `make clean' to remove all the junk. # clean : rm -f *.o *~ core test hello_world demo demo0 libsx-2.05/demo0/main.h0000644000175000017500000000166511252443541016025 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { int down; /* for when the mouse button goes down */ int startx, starty, oldx, oldy; /* used for drawing out boxes */ int col1, col2; int toggle1, toggle2, toggle3, toggle4, other_toggle; int in_color_mode; Widget quit; Widget str_entry; Widget list; Widget other_window; Widget text_widget; Widget color_widget; Widget draw_widget; Widget copy_menu; Widget paste_menu; XFont draw_font; }MyProgram; /* protos */ int init_display(int argc, char **argv, MyProgram *me); void do_redisplay(MyProgram *me, int x, int y); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/demo0/main0.c0000644000175000017500000000767111252443541016103 0ustar amckinstryamckinstry/* * This is a simple demo program that shows how to use multiple form * widgets. All you really have to do is create the first form widget * before you create any of the child widgets. Then when you are done * creating all the widgets that will go in a particular form, lay them * out with calls to SetWidgetPos() if necessary. Then make your next * form, specifying where it should go relative to the previous form. Next * you create all of this new form's children, lay them out, etc. You can * create as many form widgets as you like in this manner. * * Just keep in mind that every time you create a form widget, all future * calls to the MakeXXX() functions will put that widget in the current * form widget (current is defined as the most recent form created). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* gets us in the door with libsx */ /* define's */ #define X_SIZE 300 /* default window size, change as desired */ #define Y_SIZE 300 void quit(Widget w, void *junk) { exit(0); } #include "foo.h" void redisplay(Widget w, int width, int height, void *arg) { int i,j,k; int colors[5]; SetBgColor(w, WHITE); ClearDrawArea(); colors[0] = BLACK; colors[1] = GREEN; colors[2] = RED; colors[3] = BLUE; colors[4] = YELLOW; for(i=0; i < width; i+=foo_width) for(j=0; j < height; j+=foo_height) { int fg, bg; /* pick some colors to draw with (that aren't the same) */ fg = colors[rand()%5]; while((bg = colors[rand()%5]) == fg) ; SetFgColor(w, fg); SetBgColor(w, bg); DrawBitmap(foo_bits, i,j, foo_width, foo_height); } } /* * This function sets up the display for us. */ int init_display(int argc, char **argv, void *junk) { Widget w[25], form1, form2, form3; XFont xf; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; form1 = MakeForm(TOP_LEVEL_FORM); SetWidgetPos(form1, NO_CARE, NULL, NO_CARE, NULL); w[0] = MakeButton("fufanu", NULL, NULL); w[1] = MakeButton("foo", NULL, NULL); w[2] = MakeButton("Long String", NULL, NULL); w[3] = MakeButton("Blah", NULL, NULL); w[4] = MakeButton("Bletchrl", NULL, NULL); w[5] = MakeButton("Quit", quit, NULL); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[3], NO_CARE, NULL); SetWidgetPos(w[5], PLACE_UNDER, w[4], NO_CARE, NULL); SetForm(TOP_LEVEL_FORM); w[6] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, NULL); SetWidgetPos(w[6], PLACE_RIGHT, form1, NO_CARE, NULL); form2 = MakeForm(TOP_LEVEL_FORM); SetWidgetPos(form2, PLACE_RIGHT, form1, PLACE_UNDER, w[6]); w[7] = MakeButton("Button1", NULL, NULL); w[8] = MakeButton("Button2", NULL, NULL); w[9] = MakeButton("Button3", NULL, NULL); SetWidgetPos(w[8], PLACE_RIGHT, w[7], NO_CARE, NULL); SetWidgetPos(w[9], PLACE_RIGHT, w[8], NO_CARE, NULL); form3 = MakeForm(form2); SetWidgetPos(form3, PLACE_UNDER, w[7], NO_CARE, NULL); w[10] = MakeButton("Sub Button1", NULL, NULL); w[11] = MakeButton("Sub Button2", NULL, NULL); w[12] = MakeButton("Sub Button3", NULL, NULL); SetWidgetPos(w[11], PLACE_UNDER, w[10], NO_CARE, NULL); SetWidgetPos(w[12], PLACE_UNDER, w[11], NO_CARE, NULL); /* * Now actually put the display on the screen. */ ShowDisplay(); /* * Get some colors for drawing with. */ GetStandardColors(); SetBgColor(form1, BLUE); SetBgColor(form2, YELLOW); SetBorderColor(w[6], GREEN); return argc; } void main(int argc, char **argv) { argc = init_display(argc, argv, NULL); /* setup the display */ if (argc == 0) exit(0); MainLoop(); /* go right into the main loop */ } libsx-2.05/demo0/libsx.h0000777000175000017500000000000011252443766020514 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/demo0/callbacks.h0000644000175000017500000000304511252443541017012 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error. * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void load(Widget w, void *data); void save(Widget w, void *data); void list_callback(Widget w, char *str, int index, void *arg); void string_func(Widget w, char *txt, void *arg); void scroll_func(Widget w, float val, void *arg); void color(Widget w, void *data); void do_stuff(Widget w, void *data); void more_stuff(Widget w, void *data); void check_me(Widget w, void *data); void toggle1(Widget w, void *data); void toggle2(Widget w, void *data); void toggle3(Widget w, void *data); void toggle4(Widget w, void *data); void other_toggle(Widget w, void *data); void menu_item1(Widget w, void *data); void menu_item2(Widget w, void *data); void menu_item3(Widget w, void *data); void menu_item4(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); void button_down(Widget w, int which_button, int x, int y, void *data); void button_up(Widget w, int which_button, int x, int y, void *data); void keypress(Widget w, char *input, int up_or_down, void *data); void motion(Widget w, int x, int y, void *data); void enter(Widget w, int x, int y, void *data); void leave(Widget w, int x, int y, void *data); libsx-2.05/Makefile0000644000175000017500000000241011252443541015351 0ustar amckinstryamckinstry# # Top level makefile for libsx and all the example code. # # Basically we just cd into each of the directories and build # the stuff that's there. # # I know I've committed a major sin by not using imake to generate # the makefiles, but I've never quite understood that beast and it seems # overly complicated to me (but then again I never put tons of effort # into understanding it). If someone would like to explain it to me, # I'd like that (or point to some simple to read documentation). # # Dominic Giamapolo # dbg@sgi.com # SHELL=/bin/sh DIRS = src demo0 demo1 demo2 demo3 demo4 bezier frac \ freq creq multireq skel xmore xrootbg draw_demo controlbox all : $(DIRS) src:: (cd src ; $(MAKE) ) demo0:: (cd demo0 ; $(MAKE) ) demo1:: (cd demo1 ; $(MAKE) ) demo2:: (cd demo2 ; $(MAKE) ) demo3:: (cd demo3 ; $(MAKE) ) demo4:: (cd demo4 ; $(MAKE) ) bezier:: (cd bezier ; $(MAKE) ) frac:: (cd frac ; $(MAKE) ) freq:: (cd freq ; $(MAKE) ) creq:: (cd creq ; $(MAKE) ) multireq:: (cd multireq ; $(MAKE) ) skel:: (cd skel ; $(MAKE) ) xmore:: (cd xmore ; $(MAKE) ) xrootbg:: (cd xrootbg ; $(MAKE) ) draw_demo:: (cd draw_demo ; $(MAKE) ) clean : rm -f core *~ for dir in $(DIRS); do \ cd $$dir ; make clean ; cd ..; \ done; libsx-2.05/xmore/0000755000175000017500000000000011252443541015046 5ustar amckinstryamckinstrylibsx-2.05/xmore/Makefile0000644000175000017500000000044211252443541016506 0ustar amckinstryamckinstry# # If you have trouble building, edit the file ../libsx_defs and # change stuff there. That file gets included everywhere else, so # you only need to change things there once. # include ../libsx_defs xmore : xmore.o $(CC) -O -o xmore xmore.o $(LIBS) clean: rm -f *.o *~ core xmore libsx-2.05/xmore/libsx.h0000777000175000017500000000000011252443766020642 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/xmore/xmore.c0000644000175000017500000001053511252443541016350 0ustar amckinstryamckinstry/* * A simple x window text viewer. Written in frustration with using * Xless (which seems to ignore Xlib command line options like -fn). * * Dominic Giampaolo */ #include #include #include #include "libsx.h" typedef struct wininfo { Widget window, text_widget, label_widget; int *num_windows; char *cur_path; }WinInfo; /* * Protos */ void make_text_viewer(char *fname, WinInfo *arg); void error(char *str, char *pname) { fprintf(stderr, "%s: %s", pname, str); exit(5); } void quit(Widget foo, void *arg) { WinInfo *wi=(WinInfo *)arg; *(wi->num_windows) = *(wi->num_windows) - 1; SetCurrentWindow(XtParent(XtParent(foo))); CloseWindow(); if (*(wi->num_windows) == 0) exit(0); } /* * Return the directory component of a string or NULL if it's in * the current directory. */ char *dirname(char *str) { char *ptr, *tmp; ptr = strrchr(str, '/'); if (ptr == NULL) return NULL; *ptr = '\0'; tmp = (char *)strdup(str); *ptr = '/'; return tmp; } /* * Open a new file in the same window. */ void new_file(Widget foo, void *arg) { WinInfo *wi=(WinInfo *)arg; char *fname; SetCurrentWindow(wi->window); fname = GetFile("Select new file", wi->cur_path, NULL, NULL); if (fname) { SetTextWidgetText(wi->text_widget, fname, EDIT_FILE); SetLabel(wi->label_widget, fname); if (wi->cur_path) free(wi->cur_path); wi->cur_path = dirname(fname); } } void new_window(Widget foo, void *arg) { WinInfo *wi=(WinInfo *)arg; WinInfo *new; char *fname; SetCurrentWindow(wi->window); fname = GetFile("New file in other window", wi->cur_path, NULL, NULL); if (fname == NULL) return; new = (WinInfo *)calloc(sizeof(WinInfo), 1); if (new == NULL) return; new->num_windows = wi->num_windows; new->cur_path = dirname(fname); *(new->num_windows) = *(new->num_windows) + 1; new->window = MakeWindow("xmore", NULL, NONEXCLUSIVE_WINDOW); make_text_viewer(fname, new); } #define MAXLABEL 80 void make_text_viewer(char *fname, WinInfo *arg) { Widget w[10]; static char dummy_label[MAXLABEL]; int i, width; XFont xf; for(i=0; i < MAXLABEL-1; i++) dummy_label[i] = ' '; dummy_label[i] = '\0'; w[0] = MakeLabel(dummy_label); xf = GetWidgetFont(w[0]); if (xf != NULL) width = TextWidth(xf, dummy_label); else width = 600; w[1] = MakeTextWidget(fname, EDIT_FILE, NO_MODIFY, width, 500); w[2] = MakeButton("Quit", quit, arg); w[3] = MakeButton("New File", new_file, arg); w[4] = MakeButton("New Window", new_window, arg); SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]); SetWidgetPos(w[4], PLACE_UNDER, w[1], PLACE_RIGHT, w[3]); AttachEdge(w[0], RIGHT_EDGE, ATTACH_LEFT); AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP); AttachEdge(w[1], LEFT_EDGE, ATTACH_LEFT); AttachEdge(w[1], RIGHT_EDGE, ATTACH_RIGHT); AttachEdge(w[1], TOP_EDGE, ATTACH_TOP); AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM); AttachEdge(w[2], LEFT_EDGE, ATTACH_LEFT); AttachEdge(w[2], RIGHT_EDGE, ATTACH_LEFT); AttachEdge(w[2], TOP_EDGE, ATTACH_BOTTOM); AttachEdge(w[2], BOTTOM_EDGE, ATTACH_BOTTOM); AttachEdge(w[3], LEFT_EDGE, ATTACH_LEFT); AttachEdge(w[3], RIGHT_EDGE, ATTACH_LEFT); AttachEdge(w[3], TOP_EDGE, ATTACH_BOTTOM); AttachEdge(w[3], BOTTOM_EDGE, ATTACH_BOTTOM); AttachEdge(w[4], LEFT_EDGE, ATTACH_LEFT); AttachEdge(w[4], RIGHT_EDGE, ATTACH_LEFT); AttachEdge(w[4], TOP_EDGE, ATTACH_BOTTOM); AttachEdge(w[4], BOTTOM_EDGE, ATTACH_BOTTOM); arg->text_widget = w[1]; arg->label_widget = w[0]; ShowDisplay(); SetLabel(w[0], fname); /* set the real filename */ } main(int argc, char **argv) { int i,num_windows=0; argc = OpenDisplay(argc, argv); if (argc == 0) error("Can't open display.", argv[0]); if (argc == 1) error("No files to view!\n", argv[0]); for(i=1; i < argc; i++) { WinInfo *wi; wi = (WinInfo *)calloc(sizeof(WinInfo), 1); if (wi == NULL) continue; wi->num_windows = &num_windows; wi->cur_path = dirname(argv[i]); num_windows++; if (i > 1) MakeWindow(argv[0], NULL, NONEXCLUSIVE_WINDOW); make_text_viewer(argv[i], wi); } MainLoop(); } libsx-2.05/LICENSE0000644000175000017500000006311011252443541014722 0ustar amckinstryamckinstryGNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: * a) The modified work must itself be a software library. * b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. * c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. * d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: * a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) * b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. * c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. * d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. * e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. * b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. one line to give the library's name and an idea of what it does. Copyright (C) year name of author This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. signature of Ty Coon, 1 April 1990 Ty Coon, President of Vice libsx-2.05/demo3/0000755000175000017500000000000011252443541014723 5ustar amckinstryamckinstrylibsx-2.05/demo3/callbacks.c0000644000175000017500000000351011252443541017005 0ustar amckinstryamckinstry/* This file contains callback routines that drive the display. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" #include "main.h" #include "callbacks.h" void quit(Widget w, void *data) { /* Do any cleanup that is necessary for your program here */ exit(0); } void next_cmap(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->cur_colormap++; if (me->cur_colormap > 3) me->cur_colormap = 0; SetColorMap(me->cur_colormap); } void prev_cmap(Widget w, void *data) { MyProgram *me = (MyProgram *)data; me->cur_colormap--; if (me->cur_colormap < 0) me->cur_colormap = 3; SetColorMap(me->cur_colormap); } /* Here is where all redrawing will take place for your program. * When the window needs to be redrawn, this function will be called. * When your program starts up for the first time, this function will * be called and you should draw anything you need to draw in here. */ void redisplay(Widget w, int width, int height, void *data) { MyProgram *me=data; int i; ClearDrawArea(); /* start with a clean slate */ for(i=0; i < width; i++) /* draw some pretty patterns */ { SetColor(i); /* this will step through the gradient of colors */ DrawLine(0,i, i,height); } for(i=0; i < width; i++) { SetColor(i); DrawLine(width,i, width-i,height); } SetColor(RED); DrawText("My Cool Program", (width/2)-50, height/2); } libsx-2.05/demo3/main.c0000644000175000017500000000512111252443541016012 0ustar amckinstryamckinstry/* This demo program shows you how to use the colormaps. It's fairly * simple. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* should come first, defines libsx stuff */ #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default draw area size, change as desired */ #define Y_SIZE 300 void main(int argc, char **argv) { MyProgram mydata; mydata.cur_colormap = RAINBOW_1; init_display(argc, argv, &mydata); /* setup the display */ MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ void init_display(int argc, char **argv, MyProgram *me) { int i; Widget w[5]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Next ColorMap", next_cmap, me); w[1] = MakeButton("Prev ColorMap", prev_cmap, me); w[2] = MakeButton("Quit!", quit, me); w[3] = MakeLabel("The ColorMap Demo"); w[4] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); /* This call actually causes the whole thing to be displayed on the * screen. You have to call this function before doing any drawing * into the window. */ ShowDisplay(); /* We are going to take over the colormap and install our own. * This will cause the colors in other windows to get wacked out, but * hey, that's the price you pay for nice smooth gradients. :-) * * Also note that after we've called GetAllColors(), we can call * SetColorMap() as often as we like. */ GetAllColors(); SetColorMap(me->cur_colormap); /* Now we make the widget outlines and text visible even though we've * taken over the colormap. Otherwise they kind of become invisible. * This isn't the most foolproof way in the world to do this, but * it works for most colormaps. */ for(i=0; i < 4; i++) { SetFgColor(w[i], 255); SetBorderColor(w[i], 255); } } libsx-2.05/demo3/makefile0000644000175000017500000000053111252443541016422 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o demo3 : $(OBJS) $(CC) -o demo3 $(OBJS) $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h callbacks.o : libsx.h callbacks.c main.h clean : rm -f *.o *~ core demo3 libsx-2.05/demo3/main.h0000644000175000017500000000101311252443541016013 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { int cur_colormap; }MyProgram; /* protos */ void init_display(int argc, char **argv, MyProgram *me); void do_redisplay(MyProgram *me, int x, int y); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/demo3/libsx.h0000777000175000017500000000000011252443766020517 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/demo3/callbacks.h0000644000175000017500000000110511252443541017010 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error. * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void next_cmap(Widget w, void *data); void prev_cmap(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); libsx-2.05/demo1/0000755000175000017500000000000011252443541014721 5ustar amckinstryamckinstrylibsx-2.05/demo1/callbacks.c0000644000175000017500000000652011252443541017007 0ustar amckinstryamckinstry/* This file contains callback routines that implement the logic of your * program. The function init_display() in main.c built the display * and setup the connection between these functions and the user interface * elements. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" #include "main.h" #include "callbacks.h" /* -- CALLBACK ROUTINES -- * * These functions are called when various things happen in your windows. * They should handle what happened and give feedback to the user. Most * likely they will set options in your program (which is what the * MyProgram data structure is for), and cause different things to happen, * like loading and saving files, etc. */ void quit(Widget w, void *data) { /* Do any cleanup that is necessary for your program here */ exit(0); } void load(Widget w, void *data) { char *string; string = GetString("\nEnter a filename to load\n", "untitled"); if (string) printf("You entered the name: %s\n", string); else printf("You clicked the cancel button.\n"); } void click_me(Widget w, void *data) { MyProgram *me = (MyProgram *)data; int ans; ans = GetYesNo("\nAre you a weenie?\n\n"); if (ans) { me->var1 = TRUE; printf("The user is a weenie.\n"); } else { me->var2 = FALSE; printf("You are not a weenie.\n"); } } /* * The following is the redisplay code for the drawing area widget. * * Each time it needs to be redisplayed (either because it the window * was resized or because it was obscured), this function gets called. */ void redisplay(Widget w, int width, int height, void *data) { MyProgram *me=data; ClearDrawArea(); /* start with a clean slate */ draw_stuff(width, height); } void draw_stuff(int width, int height) { draw_lines(width, height); draw_random_lines(); draw_points(); draw_text(width, height); } void draw_lines(int width, int height) { int i; SetColor(BLACK); /* draw some pretty patterns */ for(i=0; i < width; i+=5) DrawLine(0,i, i,height); SetColor(GREEN); for(i=0; i < width; i+=5) DrawLine(width,i, width-i,height); } void draw_random_lines(void) { int i; XPoint xpts[50]; srand(time(NULL) | 0x01); /* seed the random number generator */ for(i=0; i < 50; i++) { xpts[i].x = (rand() % 75) + 75; /* pick random vertices */ xpts[i].y = (rand() % 75) + 75; } SetColor(RED); DrawPolyline(xpts, 50); /* now draw all 50 of them in red */ } void draw_points(void) { int i, x,y; srand(time(NULL) | 0x01); /* seed the random number generator */ SetColor(BLUE); for(i=0; i < 100; i++) { x = (rand() % 75) + 150; /* pick a random point */ y = (rand() % 75) + 75; DrawPixel(x, y); /* now draw it on the screen */ } } void draw_text(int width, int height) { SetColor(BLACK); DrawText("My Cool Program", (width/2)-50, height/2); } libsx-2.05/demo1/main.c0000644000175000017500000000477311252443541016024 0ustar amckinstryamckinstry/* This demo program just opens up a simple window and draws some things * into it. It makes no pretensions about being sophisticated, but just * gets the job done. You can use this as a framework for your own programs, * just follow the comments, and you should be able to extend it as * needed. * * NOTE: * If you could care less about all the other stuff, and just want to write * graphics code, simply edit the function redisplay() in callbacks.c and * modify it to your desires. That is where all redrawing takes place. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" /* should come first, defines libsx stuff */ #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default draw area size, change as desired */ #define Y_SIZE 300 void main(int argc, char **argv) { MyProgram mydata; mydata.var1 = 1; /* do your initializations here */ mydata.var2 = 2; mydata.flags = 0; init_display(argc, argv, &mydata); /* setup the display */ MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display objects you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ void init_display(int argc, char **argv, MyProgram *me) { Widget w[5]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Load", load, me); w[1] = MakeButton("Click Me", click_me, me); w[2] = MakeButton("Quit!", quit, me); w[3] = MakeLabel("This is a label"); w[4] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); /* This call actually causes the whole thing to be displayed on the * screen. You have to call this function before doing any drawing * into the window. */ ShowDisplay(); /* Get standard (red, blue, green, yellow, black, white) colors for * drawing stuff. */ GetStandardColors(); } libsx-2.05/demo1/makefile0000644000175000017500000000063311252443541016423 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o demo1 : $(OBJS) $(CC) -o demo1 $(OBJS) $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h callbacks.o : libsx.h callbacks.c main.h # # A cleanup target. Type `make clean' to remove all the junk. # clean : rm -f *.o *~ core demo1 libsx-2.05/demo1/main.h0000644000175000017500000000076611252443541016027 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { int var1, var2; int curstate; int flags; }MyProgram; /* protos */ void init_display(int argc, char **argv, MyProgram *me); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/demo1/libsx.h0000777000175000017500000000000011252443766020515 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/demo1/callbacks.h0000644000175000017500000000143211252443541017011 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error. * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void load(Widget w, void *data); void click_me(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); /* drawing functions called from redisplay() */ void draw_stuff(int width, int height); void draw_lines(int width, int height); void draw_random_lines(void); void draw_points(void); void draw_text(int width, int height); libsx-2.05/README0000644000175000017500000004442211252443541014602 0ustar amckinstryamckinstry -- Libsx v2.05 -- The Simple X library by Dominic Giampaolo dbg@sgi.com Introduction: --- What is libsx? Libsx (the Simple X library) is a library of code that sits on top of and to the side of the Athena widget set. Its purpose is to make writing X applications *much* easier. To accomplish this, libsx encapsulates a large portion of the uglier details that arise while programming in X and it fills in some gaps that exist with the Athena Widget set (such as a widget for drawing graphics); libsx tries to simplify the common case down to a single function call with only a few arguments. With libsx, writing a simple program that opens a window, has a few buttons and draws some graphics (lines, circles, bitmaps, etc) is a matter of 5-10 lines of code, including the drawing code. Hello World is 2 lines. More complicated programs that respond to mouse clicks, have buttons, scrollbars, etc, can be written in 25-50 lines of code. Some libraries take the approach of completely hiding whatever they are layering on top of. In contrast, libsx doesn't drastically alter the base abstractions of X, it just packages them in the way they get used most of the time, so that with one function call and a few arguments you get the effect of 10-20 lines of pure X code. Access to the underlying X objects (Window id's, Display pointers, etc) is also possible if necessary, but not required. With libsx, the simple things are simple and the complex things are possible (where have I heard that before? :-). --- Building libsx 1. Edit the libsx_defs file in this directory and set the compiler you'd like to use and any necessary compiler flags. It is important that you take a look in this file and edit things as appropriate. By default it builds for an SGI system (gee, I wonder why that is? :-) If you are on a DECstation, their standard compiler will _not_ work as it is not ANSI compliant (gcc works great though). 2. Go to libsx/src and type make there. This should build both static and dynamic libraries: libsx.a, libsx.so On some Linux systems, you may have to uncomment the line extern char *caddr_t; in DrawingA.c 3. Type make install This installs the static and dynamic libraries in the target library directory specified by LIBDIR, and the libsx.h header file in the include library specified by by INCLUDEDIR 4. If you aren't short on disk space, go to the main libsx/ directory and type make. This builds all the demo programs in the other subdirectories. For anything else to work, the libsx/src directory must be compiled first. If you're short on disk space, you can go to any particular subdirectory and type make there to build only the corresponding demos. A word of caution. On some suns that have motif installed from a third party, you'll get lots of warnings about symbols being re-defined when compiling libsx. This is because of an incompatibility in the way the X header files get installed for the motif product (not sure who makes the one I encountered problems with). Anyway, the warnings are innocuous but definitely annoying. Unfortunately I can't seem to make them go away. The demo program that shows most of the features of the library is in the src directory (the executable is called `demo'). The other demo programs demonstrate various aspects of the library. Feel free to use them as skeletons for your own programs. The code has been compiled on wide variety of systems and compilers. It should be mostly clean POSIX code, but I would appreciate hearing about any difficulties you have while compiling. I have personally compiled it cleanly on Sun3's and 4's (SunOS 4.1.1 mind you), SGI (Indigo's, PowerSeries, Onyx, etc), and DECstations 3100/5100's. People on the net have told me that they've gotten it to work on HP-UX, Linux, SVR4.2, AIX 3.2, Sequent/ptx, and numerous other systems. A while ago I compiled it cleanly on a DG Aviion running a very strict version of SVR4. I've used gcc to compile it as well as the native compiler on most of the platforms. The code is ANSI C, so if you don't have an ANSI compiler, sorry.... Libsx also requires the Athena widget set, which isn't as omni-present as I once thought. I guess HP doesn't ship it on all of their systems. I can't help you much there. Bitch at your vendor and tell them to ship a version of the Athena widgets if you don't have it. BTW, there's no Imakefile because I don't understand imake (nor have I made much of an attempt to understand it). Imake seems like overkill for libsx. If someone would like to write an Imakefile, I'd gladly include it in future releases, but it's not likely I'll do it myself. --- More details about libsx The reason I wrote libsx was so that I could whip up simple X programs in not much time and not lots of X code. Originally it started because I wanted an easy way to write programs to draw graphics, but libsx also grew to encapsulate most of the other Athena widgets making all sorts of GUI programs possible The essential idea with libsx is that creating the user-interface should be simple and you should spend your time on the code that implements the logic of your program. In libsx, the core functions that control your application are connected to user-interface elements as callback functions. That is, when the user does something interesting with your interface, your callback function gets called. All of the low level management details are handled for you. Each user interface item (buttons, scrollbars, drawing area's, text entry, etc) only requires one function call to create it. One of the arguments to this creation routine is the name of a callback function that will be called each time an interesting event happens to that widget. For example, when a button or menu item is clicked on/chosen, your callback routine gets called. When a drawing area needs to be redrawn, your callback gets called. The intent of libsx was to ease the common case. For example, here is the code to create and manage a single line string entry with libsx: void str_callback(Widget w, char *string, void *data) { printf("You pressed: %s\n", string); } void main() { .... MakeStringEntry("preset text", 200, str_callback, NULL); } The first function is the callback function that gets called when the user presses return in the widget (and it just prints what the user entered). The call to MakeStringEntry() builds the widget and takes care of setting all the necessary resources and translations for everything to work. In comparison, the equivalent code in regular X calls is on the order of 20-25 lines of code (not counting the callback function which would be the same for both). Another example is drawing graphics. The plain Athena widget set does not provide a drawing area widget (like Motif does). Libsx includes David Nedde's Athena drawing area widget and encapsulates it so that a simple program to open a window and draw some graphics is now reduced to only a few lines of code. More complicated programs build upon the simple model and although creating the user interface may involve more lines of code, the basic model is the same. --- What exactly does libsx provide? Libsx encapsulates the following interface components (all based on Athena widgets, except for the DrawingArea widget which belongs to David Nedde): -- labels -- buttons -- radio button groups and toggle buttons -- single line text entry -- multi-line text entry (full text-edit box) -- scrollbars (horizontal or vertical) -- scrolling lists -- menu buttons (buttons with pop-up menus) -- drawing areas (you can draw in these and also receive mouse/keyboard events if you like) -- multiple form widgets (more advanced, not normally used) After creating the interface components you need, you lay-out your display in a logical fashion. The SetWidgetPos() function lets you specify what widgets are next-to or underneath (or both) other widgets. This avoids hard-coding pixel positions and makes setting up a display pretty simple and quick (though to be fair, some more complicated displays involving centering and such can be difficult if not impossible). You can easily change widget attributes and use different fonts. There are some simple dialog box routines (for getting yes/no answers and getting a single string). Libsx can also open multiple windows (even on different screens) and you can build your own dialog boxes (modal windows) if you like. Libsx also supports obtaining, managing and using colors (either individual colors or an entire 8-bit colormap). Getting specific named colors or colors based on RGB values is as simple as calling a single function (no need to worry about colormaps, color cells, or any of the other junk X makes you worry about). Grabbing the entire colormap is also very easy. Effectively, libsx maintains a lot of state for you; it manages all the grungy X details while providing a cleaner set of routines for your program to use. --- Has libsx traded complexity for functionality? I don't think so. While libsx makes it trivial to write simple programs (as mentioned before, hello world is 2 lines of code), it's also been used to write some fairly substantial programs. I've written 3-D object editors and all sorts of wire-frame/shaded graphics previewers. This afternoon I got fed up with XLess and wrote an equivalent replacement with a real file requestor in about an hour. Most of the time was spent working on the logic of how the program should behave, not the user interface. A friend used it to write a complete 3-D modeling/rendering system. I've written tons of small graphics programs with it (reaction-diffusion and iterated function system demos, etc). I've used it for a contract application that required a simulation of a train set on screen (modeled correctly to scale, etc), and I've been kicking around ideas for some sort of word processor/editor. Libsx is not some all-singing all-dancing type of library, but it does make writing common X applications substantially easier. If you do need the extra confusionality, I mean functionality that X offers, all the standard X functions are available and you have access to the Widget id's, Display pointers, etc. The point is that you don't have to worry about that if you don't want to. --- Where did libsx come from? I developed libsx over the course of about 2 years while in graduate school at Worcester Polytech (in good ole Worcester, Mass.) It all started when I took the grad course in Computer Graphics. I wanted a nice library of routines to deal with all the X crap so I could concentrate on my graphics code. Soon the library started evolving into a much more sophisticated thing and when I became the TA for the graphics course, I beefed it up a lot. When you have 65 undergrads beating on a library you've written, it's got to be solid. The next time that I was TA, I polished up some more rough edges in the library (the stuff the students complained about) and it went through the ringer a second time with about 45 more students. Finally, during the summer of 1993 I added a ton of more functionality to the library so a friend of mine could write his 3-D editor the way it should be written and so I could do some stuff I wanted to do. In September of 1993 I was hired at SGI and I've done a little bit more work on libsx since I've been here (mainly little cleanups and the rudimentary OpenGL support). That is effectively what you see today. I've spent a lot of time deciding how to structure libsx so it would be easy to use but still be open ended. Libsx doesn't try to hide all of X, it just tries to make it more digestable. The library has gotten pretty big at this point, but it should be sufficient to write most types of GUI programs without lots of fuss. I've also spent a lot of time deciding what should and shouldn't be in libsx. It's too easy to throw in everything just because it's easy to do so. Unfortunately that's almost never the right reason to include something. I've tried to pare the design down to the essentials needed to write a useful application. Comments and critiques of the design/approach are welcome (I'd like to hear what others have to say about it or how they would have done it). --- Does libsx hurt performance? I've never really noticed any problems and most of this code was developed originally on a Sun3 (so if it ran ok there it's almost guaranteed to run fine on anything else because a Sun3 is a pretty damn slow machine nowadays :-). Seriously though, once you've created the interface and put up the display, there isn't much libsx code that gets in the way of your application. Many calls go direct to your application and a few are routed through libsx code, but nothing fancy happens there. Using libsx I was able to write programs that interactively manipulated three dimensional objects of up to several hundred vertices with the mouse on a Sparc IPC, so I don't consider performance to be a problem. --- What are the drawbacks to using libsx? The single biggest drawback that I can think of is that some layouts of widgets are not possible because of limitations in the Athena Form widget. For example, it's impossible to create a widget that is centered in a window (to the best of my knowledge the Form widget doesn't support this, example code to the contrary would be greatly appreciated). This is a bit of an annoyance, but usually isn't too much of a problem. Libsx also doesn't let you name your widgets individually, so customization through your .Xdefaults file is possible, but not as flexible as it could be. For example, within a single program, all button widgets get called "button", and all label widgets are called "label" which makes it impossible to invdividually identify widgets in your .Xdefaults file. This means you can't use your .Xdefaults to specify that button X has green text with a purple background while button Y has orange text on a chartruse background with blue highlights. Either all your buttons are purple with green text or they are chartruse with orange text, but not both (hopefully none of them are either :-). This could be fixed by adding a name argument to the MakeXXX() functions, but I'd prefer not to add another argument to those routines. It's also possible to add a SetWidgetName() type of function which is a nice way to do it, but then it really starts to make generating an interface a very complicated thing. Maybe I'll add a SetWidgetName(), but for now I don't think so. The customization thing hasn't been too much of a big deal for me (you can still customize, it's just not as infinitely flexible as the underlying X mechanisms). Presently libsx doesn't offer much support for detecting double clicks. This is because of two reasons. First, X doesn't provide any way for a user to get/set their preferred double-click time (at least as far as I know, example code to the contrary is welcomed) Second, getting sub-second timer accuracy in a portable fashion turns out to be rather problematic. I've just learned that the times() function can be used in a roundabout way to get sub-second timing, but POSIX isn't as well and cleanly supported as one might hope. If you'd like to see code that checks for double-clicks, look in the freq directory at freq.c. It uses times() and seems to work well. --- Where do I go from here? If you haven't already done it, compile libsx. This builds the library itself and numerous demo programs. Then take a look at the demo programs and the code behind them. The main demo program is in the libsx/src directory (and is called `demo'). It demonstrates most of the features of libsx. The other directories contain demos of varying complexity and these are your best starting point for building your own applications. The most complicated application would be `bezier' which lets you interactively play with bezier curves. It's a good framework for handling user-interaction and what not, so have a look at the sources. Feel free to use the demo sources as the basis for your own programs (but of course I'd appreciate it if you give credit where credit is due). The directories freq, creq, and multireq contain code written by a friend of mine, Allen Martin (amartin@wpi.wpi.edu). Freq contains a file requestor function based on libsx. Freq provides a single function GetFile() that lets a user select a file while browsing through the directory hierarchy. Creq is a color chooser utility that lets a user select a color using RGB or HSV values (with sliders and all that jazz). Multi-req is a very nice way to do form-fillout dialogs. Take a look at the sample code in these directories and you should be able to figure out how to make use of the functions. The documentation is always a nice thing to read too (especially since I put so much time into it :-). The documentation isn't in man page style format (yet), sorry about that. It was easier to write this way. The documentation tries to cover all the bases, and with the example code, it shouldn't be hard to figure out (heck, if second year college students can do it with little or no help.... :-). If you have comments/criticism on the docs, let me know. If you'd like to convert the docs into a man page format, I'd also like to know :-) The documentation to start reading first is either libsx_intro or general.libsx.doc. Those introduce you to the basics and then you can go look at the more specific doc files for each of the various areas in libsx. Well, that about sums it up. I hope you find libsx handy and that you can make some use of it. Any comments, questions or other communication can be sent to: Dominic Giampaolo dbg@sgi.com Have Fun! p.s. Oh yeah, I need a disclaimer: This code was written by me, Dominic Giampaolo, and should not be taken to represent Silicon Graphics in any way, shape or form. I've written it on my own time, and for my own purposes. SGI has nothing to do with it, so don't bother them about it. (does that sound legal enough? :-) libsx-2.05/demo2/0000755000175000017500000000000011252443541014722 5ustar amckinstryamckinstrylibsx-2.05/demo2/callbacks.c0000644000175000017500000000524711252443541017015 0ustar amckinstryamckinstry/* This file contains routines that are called when a button is pressed * in your window or when things happen in a drawing area. * * If you add a function to this file, you should also add a function * prototype for it to the callbacks.h file (unless it is an internal * function, then you should just add it down below where it says * "internal prototypes"). * * -- This code is under the GNU copyleft -- * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include "libsx.h" #include "main.h" #include "callbacks.h" void quit(Widget w, void *data) { /* Do any cleanup that is necessary for your program here */ exit(0); } void pattern1(Widget w, void *data) /* fill in a different pattern */ { int i,j; char *ptr; MyProgram *me = (MyProgram *)data; ptr = me->bitmap; for(i=0; i < me->bitmap_height; i++) for(j=0; j < me->bitmap_width; j++, ptr++) { if ((j%3) == 0) *ptr = YELLOW; else if ((j%4) == 0) *ptr = BLUE; else if ((j%4) == 0) *ptr = GREEN; } /* since we changed things, we want them to be redisplayed, so.... */ redisplay(NULL, me->win_width, me->win_height, me); } void pattern2(Widget w, void *data) { int i,j; char *ptr; MyProgram *me = (MyProgram *)data; ptr = me->bitmap; for(i=0; i < me->bitmap_height; i++) for(j=0; j < me->bitmap_width; j++, ptr++) { if ((j%2) == 0) *ptr = RED; if ((j%3) == 0) *ptr = GREEN; if ((j%4) == 0) *ptr = BLUE; } /* since we changed things, we want them to be redisplayed, so.... */ redisplay(NULL, me->win_width, me->win_height, me); } /* * Here is where all redrawing will take place for your program. * When the window needs to be redrawn, this function will be called. * When your program starts up for the first time, this function will * be called and you should draw anything you need to draw in here. */ void redisplay(Widget w, int new_width, int new_height, void *data) { MyProgram *me = data; int x, y; me->win_width = new_width; me->win_height = new_height; ClearDrawArea(); /* start with a clean slate */ SetColor(RED); DrawText("My Cool Program", (me->win_width/2)-50, 30); /* x and y are the offsets into the drawing area of where we want the * bitmap to be drawn. If you had a bitmap the same size as the * drawing area, they'd be zero. We want it to be centered, so we * calculate them appropriately. */ x = (me->win_width - me->bitmap_width) / 2; y = (me->win_height - me->bitmap_height) / 2; DrawImage(me->bitmap, x,y, me->bitmap_width, me->bitmap_height); } libsx-2.05/demo2/main.c0000644000175000017500000000644611252443541016024 0ustar amckinstryamckinstry/* This demo program shows how to display a Raster Image (i.e. bitmap). * It allocates a small bitmap, fills it in with some data, and then draws * it centered in the drawing area. * * You should notice that I've modified the main.h file so that we can * store information about the bitmap there instead of having all kinds * of ugly global variables. * * Dominic Giampaolo * dbg@sgi.com */ #include #include #include #include #include #include "libsx.h" /* should come first, defines libsx stuff */ #include "main.h" /* where program specific stuff is defined */ #include "callbacks.h" /* prototypes for callback functions */ /* define's */ #define X_SIZE 300 /* default draw area size, change as desired */ #define Y_SIZE 300 /* internal prototype */ void fill_in_bitmap(MyProgram *me); void main(int argc, char **argv) { MyProgram mydata; mydata.bitmap = (char *)malloc(100*100); /* a 100x100 bitmap */ if (mydata.bitmap == NULL) { fprintf(stderr, "Fooey, no memory for bitmap.\n"); exit(10); } mydata.bitmap_width = 100; mydata.bitmap_height = 100; init_display(argc, argv, &mydata); /* setup the display */ fill_in_bitmap(&mydata); /* put some stuff in the bitmap */ MainLoop(); /* go right into the main loop */ } /* This function sets up the display. For any kind of a real program, * you'll probably want to save the values returned by the MakeXXX calls * so that you have a way to refer to the display widgets you have * created (like if you have more than one drawing area, and want to * draw into both of them). */ void init_display(int argc, char **argv, MyProgram *me) { Widget w[5]; if (OpenDisplay(argc, argv) == FALSE) return; w[0] = MakeButton("Pattern #1", pattern1, me); w[1] = MakeButton("Pattern #2", pattern2, me); w[2] = MakeButton("Quit!", quit, me); w[3] = MakeLabel("Bitmap demo program"); w[4] = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, me); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_UNDER, w[0], NO_CARE, NULL); /* This call actually causes the whole thing to be displayed on the * screen. You have to call this function before doing any drawing * into the window. */ ShowDisplay(); /* Get standard (red, blue, green, yellow, black, white) colors for * drawing stuff. Check libsx.h for more info. */ GetStandardColors(); /* If you wanted to get all the colors in the colormap, you'd do the * following : * * GetAllColors(); * SetColorMap(GREY_SCALE_1); * * You can wait to do it till later if you want. There's no need * to do it here if you don't need to (because it wacks out the * colormap). Check libsx.h for other colormap types you can * ask for (like RAINBOW_{1,2} or GREY_SCALE_{1,2}). */ } /* * Put some junk in the bitmap so it's a little interesting. */ void fill_in_bitmap(MyProgram *me) { int i,j; char *ptr = me->bitmap; for(i=0; i < me->bitmap_height; i++) for(j=0; j < me->bitmap_width; j++, ptr++) { *ptr = rand(); } } libsx-2.05/demo2/makefile0000644000175000017500000000053011252443541016420 0ustar amckinstryamckinstry# # include ../libsx_defs # the object files which the program depends on OBJS = main.o callbacks.o demo2 : $(OBJS) $(CC) -o demo2 $(OBJS) $(LIBS) # main.o depends on main.c (of course) and main.h and callbacks.h main.o : main.c main.h callbacks.h libsx.h callbacks.o : libsx.h callbacks.c main.h clean : rm -f *.o *~ core demo2 libsx-2.05/demo2/main.h0000644000175000017500000000103311252443541016014 0ustar amckinstryamckinstry/* This file contains the various things related to the main body of the * program. It is pretty sparse, and really shouldn't be too cluttered * up. * */ /* This structure contains information relevant to your program. * You should fill it in with information that you need. * */ typedef struct MyProgram { char *bitmap; int bitmap_width, bitmap_height; int win_width, win_height; }MyProgram; /* protos */ void init_display(int argc, char **argv, MyProgram *me); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif libsx-2.05/demo2/libsx.h0000777000175000017500000000000011252443766020516 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/demo2/callbacks.h0000644000175000017500000000110211252443541017004 0ustar amckinstryamckinstry/* This file contains prototypes for the functions in callbacks.c. It is * included by main.c so that when you create a new widget, you can tie * its callback function to something that has been defined (otherwise the * compiler will give you and error. * * If you add any functions to callbacks.c, you should put a corresponding * function prototype in here. */ /* callback protos */ void quit(Widget w, void *data); void pattern1(Widget w, void *data); void pattern2(Widget w, void *data); void redisplay(Widget w, int new_width, int new_height, void *data); libsx-2.05/demo4/0000755000175000017500000000000011252443541014724 5ustar amckinstryamckinstrylibsx-2.05/demo4/thing1.h0000644000175000017500000000156111252443541016272 0ustar amckinstryamckinstry#define thing1_width 32 #define thing1_height 32 static char thing1_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x0e, 0xe0, 0x00, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x10, 0x08, 0x1c, 0x00, 0x20, 0x08, 0x22, 0x00, 0x20, 0x08, 0x22, 0x00, 0x20, 0x04, 0x22, 0x00, 0x40, 0x04, 0x1c, 0x00, 0x40, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0x4c, 0x04, 0x00, 0x00, 0x44, 0x04, 0x00, 0x00, 0x44, 0x04, 0x00, 0x00, 0x46, 0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x80, 0x21, 0x08, 0x00, 0xc0, 0x20, 0x10, 0x00, 0x60, 0x10, 0x20, 0x00, 0x30, 0x08, 0x40, 0x00, 0x0e, 0x04, 0x80, 0xf0, 0x03, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0e, 0xe0, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}; libsx-2.05/demo4/thing2.h0000644000175000017500000000156111252443541016273 0ustar amckinstryamckinstry#define thing2_width 32 #define thing2_height 32 static char thing2_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xf3, 0x7f, 0x04, 0x00, 0xf2, 0x7f, 0x04, 0x00, 0xf2, 0x7f, 0x04, 0x00, 0xf2, 0x7f, 0x04, 0x00, 0xf2, 0x7f, 0x04, 0xff, 0xff, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0x04, 0x01, 0xf2, 0x7f, 0xf4, 0x7f, 0xf2, 0x7f, 0xf4, 0x7f, 0xf2, 0x7f, 0xf4, 0x7f, 0x02, 0x01, 0xfc, 0xff, 0x03, 0x01, 0xf0, 0x7f, 0x00, 0x01, 0xf0, 0x7f, 0x00, 0x21, 0xf0, 0x7f, 0x00, 0x21, 0xf0, 0x7f, 0x00, 0x21, 0xf0, 0x7f, 0x00, 0x21, 0xf0, 0x7f, 0x00, 0x21, 0xf0, 0xff, 0xff, 0x21, 0xf0, 0x7f, 0x00, 0x20, 0xf0, 0x7f, 0x00, 0x20, 0xf0, 0x7f, 0x00, 0x20, 0xf0, 0x7f, 0xfc, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; libsx-2.05/demo4/makefile0000644000175000017500000000015611252443541016426 0ustar amckinstryamckinstry# # include ../libsx_defs demo4 : demo4.o $(CC) -o demo4 demo4.o $(LIBS) clean: rm -f *.o *~ core demo4 libsx-2.05/demo4/thing3.h0000644000175000017500000000156111252443541016274 0ustar amckinstryamckinstry#define thing3_width 32 #define thing3_height 32 static char thing3_bits[] = { 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x80, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x09, 0x09, 0x7d, 0x88, 0x90, 0x10, 0x41, 0x48, 0x60, 0xa0, 0x20, 0x28, 0x60, 0x40, 0x10, 0x18, 0x90, 0x20, 0x08, 0x38, 0x08, 0x11, 0x7c, 0xc0, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18}; libsx-2.05/demo4/libsx.h0000777000175000017500000000000011252443766020520 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/demo4/demo4.c0000644000175000017500000000356511252443541016111 0ustar amckinstryamckinstry/* * This demo program shows how to use bitmaps in your button widgets. * All that's been done is that I created several bitmaps using that * horrible X bitmap editor program, bitmap. I saved those bitmaps * in files called thing1.h, thing2.h, etc. They get #include'ed * here, and then we use them as the imagery for the button. * * Notice how when the button gets created we use NULL instead of a * text string. * * The program doesn't really do much with the buttons once they're * up, it just lets you click on them. BTW, the bitmaps aren't * supposed to be anything in particular, it's just that I'm not much * of an artist. * * Dominic Giampaolo * dbg@sgi.com */ #include #include "libsx.h" #include "thing1.h" #include "thing2.h" #include "thing3.h" #include "thing4.h" void quit(Widget w, void *junk) { exit(0); } void thing1(Widget w, void *junk) { printf("Thing 1\n"); } void thing2(Widget w, void *junk) { printf("Thing 2\n"); } void thing3(Widget w, void *junk) { printf("Thing 3\n"); } void thing4(Widget w, void *junk) { printf("Thing 4\n"); } main(int argc, char **argv) { Widget w[6]; OpenDisplay(argc, argv); w[0] = MakeButton(NULL, thing1, NULL); w[1] = MakeButton(NULL, thing2, NULL); w[2] = MakeButton(NULL, thing3, NULL); w[3] = MakeButton(NULL, thing4, NULL); w[4] = MakeButton("Quit", quit, NULL); SetWidgetBitmap(w[0], thing1_bits, thing1_width, thing1_height); SetWidgetBitmap(w[1], thing2_bits, thing2_width, thing2_height); SetWidgetBitmap(w[2], thing3_bits, thing3_width, thing3_height); SetWidgetBitmap(w[3], thing4_bits, thing4_width, thing4_height); SetWidgetPos(w[1], PLACE_RIGHT, w[0], NO_CARE, NULL); SetWidgetPos(w[2], PLACE_RIGHT, w[1], NO_CARE, NULL); SetWidgetPos(w[3], PLACE_RIGHT, w[2], NO_CARE, NULL); SetWidgetPos(w[4], PLACE_RIGHT, w[3], NO_CARE, NULL); MainLoop(); } libsx-2.05/demo4/thing4.h0000644000175000017500000000156111252443541016275 0ustar amckinstryamckinstry#define thing4_width 32 #define thing4_height 32 static char thing4_bits[] = { 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x00, 0xf5, 0xff, 0xff, 0x3f, 0xf5, 0xff, 0xff, 0x3f, 0x35, 0x00, 0x00, 0x00, 0xb5, 0xff, 0xff, 0x1f, 0xb5, 0xff, 0xff, 0x1f, 0xb5, 0xff, 0xff, 0x1f, 0xb5, 0x03, 0x00, 0x00, 0xb5, 0xfb, 0xff, 0x0f, 0xb5, 0xfb, 0xff, 0x0f, 0xb5, 0xfb, 0xff, 0x0f, 0xb5, 0xfb, 0xff, 0x0f, 0xb5, 0x7b, 0x00, 0x00, 0xb5, 0x7b, 0xff, 0x07, 0xb5, 0x7b, 0xff, 0x07, 0xb5, 0x7b, 0xff, 0x07, 0xb5, 0x7b, 0xff, 0x07, 0xb5, 0x7b, 0xff, 0x07, 0xb5, 0x7b, 0x1f, 0x00, 0xb5, 0x7b, 0xdf, 0x03, 0xb5, 0x7b, 0xdf, 0x03, 0xb5, 0x7b, 0xdf, 0x03, 0xb5, 0x7b, 0xdf, 0x03, 0xb5, 0x7b, 0x1f, 0x00, 0xb5, 0x7b, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; libsx-2.05/libsx_defs0000644000175000017500000000632011252443541015762 0ustar amckinstryamckinstry# All configuration options are at the top. The things you'll want to # look at are the CC variable, CFLAGS variable and the RANLIB # variable. # # On Suns and DECstations we use gcc because the code is ANSI and # their base compilers don't deal with ANSI code. # # On an SGI you can use plain old cc (or gcc if you feel like it and # you have it). Using cc seems to also work on the RS/6000 (though # you may need the -xansi or -ansi flag). CC = gcc #CC = cc # Using gcc it's nice to be real strict and compile with -Wall, for # production versions of the library you probably just want -O or -O2 # # The -D_POSIX_SOURCE define is necessary on some systems (sun) # and less necessary on some systems like SGI. # # The -DOPENGL_SUPPORT is still preliminary and not suggested for # general use (though if you do use it, I'd like to hear about it). # # # On an SGI running Irix 5.x, I use: # CFLAGS = -O2 -D_POSIX_SOURCE # # On a sun w/sunos 4.1.1, I use: # CFLAGS = -O2 -D_POSIX_SOURCE # # On a Sun w/Solaris 2.3 and X11R6 # CFLAGS = -O2 -D_POSIX_SOURCE -I/usr/X11R6/include -DSVR4 # # On a DECstation, I used: # CFLAGS = -O2 -I/usr/include/mit # # On HP-UX, I've been told that the following works: # CFLAGS = +z -Aa -D_HPUX_SOURCE # # On an RS/6000 with AIX 3.2, twillis@drao.nrc.ca said that this works: # CFLAGS = -O -D_POSIX_SOURCE -DAIXV3 -I/usr/X11R5/include # # On an AIX running AIX 3.2.4 or higher w/AIXWindows 1.2.0 you might try: # CFLAGS = -O3 -D_POSIX_SOURCE # # On Linux, use CC=cc, RANLIB=ranlib, and: CFLAGS = -Wall -O2 -D_POSIX_SOURCE # # On a Motorola Delta/88K box, you can use (with gcc): # CFLAGS = -O2 -DSYSV -DUSG -DMOTOROLA -DMOTOR32V2 # [ You'll also have to shorten some of the filenames (sorry). ] # # If you're daring, and you have OpenGL, try: # CFLAGS = -g -D_POSIX_SOURCE -DOPENGL_SUPPORT # #CFLAGS = -g -D_POSIX_SOURCE -DOPENGL_SUPPORT #CFLAGS = -g -D_POSIX_SOURCE -fullwarn # # If you are on a System V (like the SGI) machine, just define RANLIB # to be something innocuous like `echo'. On a Sun or other BSD machine # (like a DECstation, AIX) we need to run the ranlib program. # RANLIB=ranlib #RANLIB=echo ifndef XAWLIB XAWLIB=Xaw endif # # libraries we need to link with... # # For most machines, the standard link line is fine. For some you'll # need to add -lXext, and if you compiled with -DOPENGL_SUPPORT, then # you'll need to add -lGL for _any_ program that links with libsx. # # For SGI and SunOS 4.x, the following is fine: # LIBS = $(LIBSX) -l$(XAWLIB) -lXmu -lXt -lX11 # # For Solaris 2.x, try: # LIBS = $(LIBSX) -l$(XAWLIB) -lXmu -lXt -lX11 -lsocket # # (NOTE: OpenWindows probably needs -lXext appended) # # For a DECstation, use: # LIBS = $(LIBSX) -l$(XAWLIB) -lXmu -lXt -lX11 -lXext # # RS/6000's may also need to append -L/usr/X11R5/lib # to the LIBSX macro. Some RS/6000's can get by with: # LIBS = $(LIBSX) -l$(XAWLIB) -lXmu -lXt -lX11 -lm -lXext # # # Some other machines may need to append a -lm to the line. # # Again, if you're daring and have OpenGL, use: # LIBS = $(LIBSX) -l$(XAWLIB) -lXmu -lXt -lX11 -lXext -lGL # #LIBSX = ../src/libsx.a LIBSX = -lsx -L/usr/X11R6/lib XPM_SUPPORT = yes LIBS = $(LIBSX) -lXpm -l$(XAWLIB) -lXmu -lXt -lX11 -L/usr/X11R6/lib libsx-2.05/xrootbg/0000755000175000017500000000000011252443541015400 5ustar amckinstryamckinstrylibsx-2.05/xrootbg/makefile0000644000175000017500000000041111252443541017074 0ustar amckinstryamckinstry# # XAWLIB=Xaw95 # XAWLIB=Xaw include ../libsx_defs CFLAGS = -Wall -O2 -D_POSIX_SOURCE -D$(XAWLIB) OBJS = xrootbg.o all : xrootbg xrootbg : $(OBJS) $(CC) -o $@ $(OBJS) $(LIBS) -lm strip xrootbg xrootbg.o : xrootbg.c clean: rm -f *.o *~ core xrootbg libsx-2.05/xrootbg/libsx.h0000777000175000017500000000000011252443766021174 2../src/libsx.hustar amckinstryamckinstrylibsx-2.05/xrootbg/xrootbg.c0000644000175000017500000000162411252443541017233 0ustar amckinstryamckinstry#include #include #include #include "libsx.h" static void color_exec(Widget w, CSelData *cdata) { char cmd[256]; sprintf(cmd, "xsetroot -solid \\#%02X%02X%02X ", (int)(cdata->r+0.5), (int)(cdata->g+0.5), (int)(cdata->b+0.5)); system(cmd); } int main(int argc, char **argv) { char *args[] = { "-bg" , "gray76", NULL }; char label[80]; char *ptr; PredefArgs = args; argc = OpenDisplay(argc, argv); if (argc == FALSE) return argc; GetStandardColors(); INPUTBG = WHITE; BUTTONBG = GetNamedColor("Gray84"); #ifndef Xaw SetScrollbarDirection(-1); #endif ptr = getenv("LANG"); if (!strncmp(ptr, "de", 2)) strcpy(label, "Grund Farbe"); else if (!strncmp(ptr, "fr", 2)) strcpy(label, "Couleur fond d'écran"); else strcpy(label, "Background color"); SelectColor("40,80,120", 0, label, color_exec, NULL); return(0); } libsx-2.05/HINTS0000644000175000017500000000141411252443541014524 0ustar amckinstryamckinstryThis file contains tidbits of related information that you might find useful. -- Check out the Xaw3d library available on ftp.x.org in the contrib/widgets/Xaw3d directory. Without any changes to your source code you can get a nice 3D motif-ish look to your application. All you have to do is link with -lXaw3d instead of -lXaw, and poof, all your widgets now have a nice 3D look to them. -- The Xaw95 library can also be used, if you insist to imitate that other commercial operating system. I hate to say it, but this is definitely what gives the best look to the libsx widgets ! -- If you want to get dialogs in some other languages than English, French or German, supply a suitable dialog.XX file in src/dialogs, eg. dialogs.fi for Finnish.