Solaris Common Desktop Environment: Programmer's Guide

Part II Recommended Integration

Chapters 2 through 5 describe how to perform the following recommended integration tasks:

Chapter 2 Integrating Fonts

Your application may be used by someone sitting at an X terminal, or by someone at a remote workstation across a network. In these situations, the fonts available to the user's X display from the X window server might be different from your application's defaults, and some fonts may not be available.

The standard interface font names defined by CDE are guaranteed to be available on all CDE-compliant systems. These names do not specify actual fonts. Instead, they are aliases that each system vendor maps to its best available fonts. If you use only these font names in your application, you can be sure of getting the closest matching font on any CDE-compliant system.

These standard interface font names are guaranteed to be available for all locales, whereas the standard application font names are only guaranteed for ISO Latin locales. See the man pages, DtStdInterfaceFontNames and DtStdAppFontNames for more information.

Standard Interface Fonts

Default Font Names

The set of standard interface font names is defined by the XLFD field name values described in Table 2-2.

Table 2-1 Field Name Values for Standard Interface Font Names

Field 

Value 

Description 

FOUNDRY

dt

CDE name 

FAMILY_NAME

interface system or interface user

CDE standard interface font name 

WEIGHT_NAME

medium or bold

Weight of the font 

SLANT

r

Roman 

SET_WIDTH

normal

Normal set width 

SPACING

p or m 

 

ADD_STYLE

size hint 

sans or serif

Proportional or Monospace values from xxs to xxl 

Sans for sans serif font or serif for serif 

PIXEL_SIZE

Platform dependent 

 

POINT_SIZE

Platform dependent 

 

RESOLUTION_X

Platform dependent 

 

RESOLUTION_Y

Platform dependent 

 

AVERAGE_WIDTH

m

Monospace for user font 

Proportional for system font 

NUMERIC FIELD

Platform dependent 

 

CHAR_SET_REGISTRY

Locale Dependent 

 

ENCODING

Locale Dependent 

 

Point Sizes for Standard Interface Fonts

The seven named point sizes for each of the three styles are prepend in the ADD_STYLE_NAME field. The font XLFD patterns matching these names can match a named size, not a numeric size. These named sizes are used because the exact size of an interface font is less important than its nominal size, and implementation differences for the hand-tuned interface fonts do not allow common numeric point sizes to be assured across systems.

The seven nominal sizes are as follows:

xxs  

extra extra small 

xs  

extra small 

s  

small 

m  

medium 

l  

large 

xl  

extra large 

xxl  

extra extra large 

The goal of these named sizes is to provide enough fonts to display a variety monitor sizes and resolutions that CDE will run on, and the range of user preferences for comfortably reading button labels, window titles and so forth, can be accommodated in the GUI. Both the smallest size, xxs, and the largest size, xxl, are meant to be reasonable sizes for displaying and viewing the CDE desktop on common displays and X terminals; they are not meant to imply either hard-to-read fine print or headline-sized display type.

Patterns for the Standard Interface Font Names

Using these values, the XLFD pattern

-dt-interface*-*

logically matches the full set of XCDE Standard Interface Font Names. (Note that no specific X server behavior is implied).

For example, in Western locales, the full set of 21 CDE Standard Interface Font Names can be represented:

-dt-interface system-medium-r-normal-*-*-*-*-*-*-*-iso8859-1
-dt-interface user-medium-r-normal-*-*-*-*-*-m-*-iso8859-1
-dt-interface user-bold-r-normal-*-*-*-*-*-m-*-iso8859-1

The full set of patterns in the app-defaults files for all seven system font sizes is:

-dt-interface system-medium-r-normal-xxs*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-xs*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-s*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-m*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-l*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-xl*-*-*-*-*-*-*-iso8859-1
-dt-interface system-medium-r-normal-xxl*-*-*-*-*-*-*-iso8859-1

These patterns could be used in a resource file and will match the full CDE Standard Interface Names for the iso Latin-1 locales on all CDE-compliant systems. For more information, see the DtStdInterfaceFontNames(5) man page.

Using Fonts in CDE Configuration Files

CDE specifies a set of generic standard application font names, in several sizes, that can be used by applications running under CDE on all platforms. Each CDE vendor maps the standard set of font names to its available fonts. The mapping of font names to existing fonts may vary from vendor to vendor.

When you use the standard application font names in your app-defaults files, you can use a single app-defaults file across all CDE platforms. If you do not use the standard font names, you must supply a different app-defaults files for each application on each CDE platform.

All CDE systems provide a set of 13 standard application font names, in at least 6 sizes, that represent 12 generic design and style variations (serif and sans serif), as well as a symbol font. These standard names are provided in addition to the names of the fonts that the standard names are mapped to for a particular CDE platform. An additional four standard font names--to allow both serif and sans serif designs in a monospaced font--may also be provided by CDE platform vendors.

These 13 font names are provided in CDE platforms for the locales using the ISO 8859-1 character set. See the Common Desktop Environment: Internationalization Programmer's Guide for information on using standard font names in other locales.

Standard Application Fonts

Default Font Names

The set of standard application default font names is defined by the XLFD field name values described in Table 2-2 .

Table 2-2 Field Name Values for Standard Application Font Names

Field 

Value 

Description 

FOUNDRY

dt

CDE name 

FAMILY_NAME

application

CDE standard application font name 

WEIGHT_NAME

medium or bold

Weight of the font 

SLANT

r

i

Roman 

Italic 

SET_WIDTH

normal

Normal set width 

ADD_STYLE

sans

serif

Sans serif font 

Serif font 

PIXEL_SIZE

*

Platform dependent 

POINT_SIZE

pointsize

Point size of the desired font 

RESOLUTION_X

*

Platform dependent 

RESOLUTION_Y

*

Platform dependent 

AVERAGE_WIDTH

p

m

Proportional 

Monospace 

NUMERIC FIELD

*

Platform dependent 

CHAR_SET_REGISTRY

iso8859-1

Defining standards authority 

ENCODING

1

Character set number 

The standard names are available using the regular X Windows XLFD font- naming scheme. When properly specified with appropriate wildcards for the platform-dependent fields, a CDE font name is guaranteed to open a valid, corresponding platform-dependent font. The XLFD name returned from a call to the Xlib XListFont function, however, is not guaranteed to be the same on all CDE platforms.

Using these values, the XLFD pattern

-dt-application-*

matches the full set of CDE standard application font names on a given platform. The pattern

-dt-application-bold-*-*-*-*-*-*-*-p-*-*-*-

matches the bold, proportionally spaced CDE fonts, both serif and sans serif. And the pattern

-dt-application-*-*-*-*-*-*-*-*-m-*-*-*-

matches the monospaced fonts (whether serif or sans serif, or both).

The full set of CDE Standard Application Font Names can be represented as follows:

-dt-application-bold-i-normal-serif-*-*-*-*-p-*-iso8859-1
-dt-application-bold-r-normal-serif-*-*-*-*-p-*-iso8859-1
-dt-application-medium-i-normal-serif-*-*-*-*-p-*-iso8859-1
-dt-application-medium-r-normal-serif-*-*-*-*-p-*-iso8859-1
-dt-application-bold-i-normal-sans-*-*-*-*-p-*-iso8859-1
-dt-application-bold-r-normal-sans-*-*-*-*-p-*-iso8859-1
-dt-application-medium-i-normal-sans-*-*-*-*-p-*-iso8859-1
-dt-application-medium-r-normal-sans-*-*-*-*-p-*-iso8859-1
-dt-application-bold-i-normal-*-*-*-*-*-m-*-iso8859-1
-dt-application-bold-r-normal-*-*-*-*-*-m-*-iso8859-1
-dt-application-medium-i-normal-*-*-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-*-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-*-*-*-*-p-*-dtsymbol-1

Point Sizes for Standard Application Fonts

The complete set of point sizes available for each of the standard application font names is determined by the set of fonts shipped with a vendor's CDE platform, whether bitmapped only or both bitmapped and scalable outline. The minimum set of sizes required and available on all CDE platforms corresponds to the standard sizes of bitmapped fonts that make up the default mapping for X11R5: 8, 10, 12, 14, 18, and 24.

For example, the entire set of six sizes of the plain monospaced font can be represented by the patterns:

-dt-application-medium-r-normal-*-80-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-100-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-120-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-140-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-180-*-*-*-m-*-iso8859-1
-dt-application-medium-r-normal-*-240-*-*-*-m-*-iso8859-1

These patterns match the corresponding standard font name on any CDE platform, even though the numeric fields other than POINTSIZE may be different on various platforms, and the matched fonts may be either serif or sans serif, depending on how the vendor implemented the set of standard names.

Standard Application Font Names in app-defaults Files

You can code a single app-defaults file to specify font resources for your application and use it across all CDE platforms. Because the parts of the standard names that are defined are the same across different vendors' platforms, you can specify these values in the resource specification in the app-defaults file. However, you must use wildcards for the other fields (PIXEL_SIZE, RESOLUTION_X, RESOLUTION_Y, and AVERAGE_WIDTH) because they may vary across platforms. For example, to specify some of the default resource needs for an application named appOne, you might use:

appOne*headFont:
-dt-application-bold-r-normal-sans-*-140-*-*-p-*-iso8859-1 

appOne*linkFont:
-dt-application-bold-i-normal-sans-*-100-*-*-p-*-iso8859-1

As another example, suppose that appTwo running on a vendor's platform defines two font resources for headings and hypertext links. appTwo uses a 14 point bold, serif font (Lucidabright bold) and a 12-point bold, italic sans serif font (Lucida bold-italic). You would then change the font definition from:

apptwo *headingFont:
-b&h-lucidabright-bold-r-normal--20-140-100-100-p-127-iso8859-1 

apptwo *linkFont:   
-b&h-lucida-bold-i-normal-sans-17-120-100-100-p-96-iso8859-1

to:

apptwo *headingFont: 
-dt-application-bold-r-normal-serif-*-140-*-*-p-*-iso8859-1

apptwo *linkFont:   
-dt-application-bold-i-normal-sans-*-120-*-*-p-*-iso8859-1

in your app-defaults file. Even though you may not know the names of the fonts on other CDE platforms, these platform-independent patterns specified with the CDE standard application font names match appropriate fonts on each platform.

You encode them exactly as shown, complete with the * wildcards, in your resource definitions. By applying the wildcards to the numeric fields other than point size, you ensure that the resources match CDE fonts on all platforms, even if the exact pixel size or average width of the fonts is slightly different.

See the DtStdAppFontNames(5) man page for more information.

Chapter 3 Displaying Errors from Your Application

Users running your application expect messages to be displayed in message footers, error dialogs, or warning dialogs, with further explanations available in online help when appropriate. Applications in the Common Desktop Environment follow a common model for presenting error messages and warnings.

How to Present Error Messages

Because of the way message text is handled, users may not see messages from your application unless you display them in a dialog, footer, or elsewhere in the user interface.

In CDE, such messages are directed to log files that a casual user may not routinely examine. Use the following rules when deciding where to tell users about warnings, messages, and error conditions:

Information to Present in Error Dialogs

A good error dialog or warning dialog gives the user the following information:

If the information cannot be presented in four or five lines of the error dialog, consider adding a help button to the dialog and link it to a topic in the help volume for your application.

For more information on writing messages, see the Common Desktop Environment: Internationalization Programmer's Guide.

Linking Message Dialogs to Online Help

In cases where additional background information is required, or where it takes more than four or five lines of a dialog to explain an error fully, you should add a button that links the user to online help.

Adding online help for a dialog is a straightforward task. Once you have decided that a particular dialog is a candidate for online help, do the following:

  1. Choose a unique ID for the error help.

    This ID provides the link to the online help text. IDs should be 64 characters or less; for example, DiskSpaceError.

  2. Create the dialog and add a help callback.

    Use the XmCreateErrorDialog() convenience function for error messages and XmCreateWarningDialog() for warnings, adding the help callback as follows:

    XtAddCallback(dialog, XmNhelpCallback,
    	helpfn, "ID");

    In this example, helpfn is a help function you have created to manage the help dialog, and the string "ID" is the ID you chose for the error message (for example, DiskSpaceError). In your help function, set the XmNlocationId resource to the value of ID. The /usr/dt/examples/dthelp directory contains examples of how to set up such a help function.

    For detailed information about creating and managing help dialog widgets, see the Common Desktop Environment: Help System Author's and Programmer's Guide.

  3. Write a corresponding help section for the error message.

    Document the message in the "messages" chapter of your help volume. In the help source document, you should have a separate section for each message, and the ID= attribute at the beginning of the section should match the ID you chose in your code for the error.

    For example, in the s1 section heading, the ID is DiskSpaceError.

    When the user's system has insufficient disk space, the error message the user sees from the following heading is "Could Not Save File."

     <s1 ID=DiskSpaceError>Could Not Save File <\s1>

    Note that by convention, the text of the section heading should correspond closely to the text in the error dialog.

  4. Rebuild the help file.

    The new help section for the error message becomes active as soon as you rebuild the help file (using the dthelptag program) and recompile your application.

For information about writing and building online help, see the Common Desktop Environment: Help System Author's and Programmer's Guide.

Recovery Routines

If a recovery routine exists for an error condition, consider adding a Retry button to the dialog. For example, if a file could not be copied because the system had insufficient disk space, you might offer a Recopy option in the dialog that users could choose once they have corrected a disk space or permissions problem.

Chapter 4 Integrating with Session Manager

Session Manager saves information about the Desktop environment and the applications running when the user logs out (of the current session) or when the user saves the environment (in a home session). For an application to be saved as part of the current session or the home session and then restarted as part of the next session, it must participate in the X Inter-Client Communication Conventions Manual (ICCCM) 1.1 Session Management Protocol. This chapter outlines how Session Manager saves and restores sessions and details the steps necessary for an application to participate in session management.

How Session Manager Saves Sessions and Applications

When you exit a session or when you save a Home session, Session Manager:

  1. Saves the selected resource settings and X server settings

  2. Allows each application to save its state and waits for the save to be completed

  3. Obtains the command line required to restart the application

How to Program the Application for Session Management

Setting the Program Environment

This section describes the programming steps necessary for an application to be saved as part of the integration process.

Follow these steps to set the program environment:

  1. Include the following header files:

    • Xm/Xm.h

    • Xm/Protocols.h

    • Dt/Session.h

  2. Link with libXm and libDtSvc.

  3. Initialize the toolkit and create a top-level widget.

Setting the WM_SAVE_YOURSELF Atom

Use the Motif XmAddWMProtocol() function to set the WM_SAVE_YOURSELF atom on the WM_PROTOCOLS property for the top-level window of your application, as shown in the following example.

Atom XaWmSaveYourself; 
Display *dsp;
   dsp = XtDisplay(toplevel);
  XaWmSaveYourself = XmInternAtom(dsp,
 "WM_SAVE_YOURSELF", False); 

XmAddWMProtocols(toplevel, &XaWmSaveYourself, 1);

Note -

Do not set the WM_SAVE_YOURSELF atom for more than one window.


Prepare to Receive the WM_SAVE_YOURSELF Message

Use the Motif XmAddWMProtocolCallback() function to establish a callback procedure to be called when the application receives a WM_SAVE_YOURSELF client message:

XmAddWMProtocolCallback(toplevel,
 XaWmSaveYourself, SaveYourselfProc,
 toplevel);

Processing the WM_SAVE_YOURSELF Message

When Session Manager sends a WM_SAVE_YOURSELF client message to this sample application's top-level window, the SaveYourselfProc() callback procedure is called. Use thecallback to save the application's state. The application can save its state by any means you want, but cannot interact with the user during the save.

Session Manager provides the DtSessionSavePath() function as a way to return a full path name and a base file name to use for saving the application's state.

Setting the WM_COMMAND Property

After the application has finished processing the WM_SAVE_YOURSELF message, either by saving its state or ignoring the message, the application must set the WM_COMMAND property on its top-level window to tell Session Manager that the save operation is complete.

Use the Xlib XsetCommand() function to set the WM_COMMAND property on the application's top-level window. Setting this property lets Session Manager know that the application has finished processing the WM_SAVE_YOURSELF message and gives Session Manager the command line it needs to restart the application.

XsetCommand() accepts an array of command-line arguments. If the application uses the DtSessionSavePath() function as part of the save process, XsetCommand() needs an additional command-line argument: -session basename, where basename is the base file name returned by DtSessionSavePath().

How Session Manager Restores a Session

Session Manager restores a session by:

  1. Restoring the resource database and server settings

  2. Restarting applications using the saved command lines

If the application used DtSessionSavePath() to find a path for its saved state, the application can pass the base file name from the -session argument to the DtSessionRestorePath() function to find the full path name of its saved-state file.

Chapter 5 Integrating with Drag and Drop

This chapter describes the drag-and-drop user model and the Common Desktop Environment drag-and-drop convenience application program interface (API), and describes how to use drag and drop.

Summary

The Common Desktop Environment contains an application program interface (API) for drag and drop that is layered on top of Motif to provide convenient, consistent, and interoperable drag and drop across the desktop. The Common Desktop Environment drag-and-drop API makes it easier for developers to implement drag and drop. With drag and drop, users can manipulate objects on the screen directly by grabbing them, dragging them around the display, and dropping them on other objects to perform a transfer of data.

Text, files, and buffers are the three categories of data that are used with the Common Desktop Environment drag-and-drop API. Text is defined, in this context, as any user-visible text such as text in type-in fields. A file is a container of data that resides in the file system. Each file also has a format that describes its contents. Buffers are data contained in memory. Typically, each buffer also has a format that describes its contents.

Library and Header Files

To use drag and drop, you need to link to the DtSvc library. The header file is Dt/Dnd.h.

Demo Program

A demo program containing an example of drag and drop is in /usr/dt/examples/dtdnd.

Using Drag and Drop

To Integrate with Drag and Drop

To integrate your application with drag and drop, follow these steps:

  1. Include Dt/Dnd.h.

  2. Link to libDtsvc.

  3. As recipient:

    1. Register as a drop zone using DtDndDropRegister.

    2. Optionally, write a drop animate callback.

    3. Write a transfer callback.

  4. As source:

    1. Recognize user action (possibly requiring a modification of translation tables) and call DtDndDragStart.

    2. Write a convert callback.

    3. Write a drag finish callback.

Drag-and-Drop User Model

This section describes the user model behind drag and drop to help you design an application that is consistent with the rest of the desktop and users' expectations.

See the Common Desktop Environment: Style Guide and Certification Checklist for more information about the drag-and-drop user model and for guidelines for the visual appearance of drag-and-drop elements.

When drag and drop is available for all applications on the desktop, the system is more predictable to the user and is, therefore, easier to use and to learn. Users leverage their learning across more applications by using skills that they already know. In addition, many users prefer drag and drop to using menus.

In this chapter, the term drop zone is used to describe places where users can drop something. Drop zones are usually represented by a control or icon graphic; for example, a trash icon or a type-in field graphic. The term drop target is used to describe the rectangular area that represents the drop zone.

Drag and Drop Capability

With the Drag and Drop capability, users can select and manipulate objects represented as icons.


Note -

Drag and drop is an accelerator to functionality that is accessible through other user interface controls supported within your application. However, not all users are able to take advantage of drag and drop. Do not support any basic operations solely through drag and drop. Any basic function that your application supports through drag and drop should also be supported by menus, buttons, or dialog boxes.


Drag Icons

When users select and manipulate icons using drag and drop, they expect the graphic icon that represents the item being dragged to remain consistent from the selection through the drag and drop. If the user selects a message icon in the File Manager and starts to drag it, the source portion of the drag icon is represented by that message icon. Providing this kind of consistency makes drag and drop more predictable to the user. Where the destination application uses icons, the icon shown should, in most cases, be the same one that was selected and then dragged and dropped. This behavior is not, however, always appropriate for all applications. Dragging text is an exception. A text drag icon is used instead of dragging the selected text.

Both the source and destination applications specify the visual appearance of drag icons. You are responsible for ensuring that an application has a consistent and appropriate icon to drag. Although the drag-and-drop library provides default icons, it is a good idea for you to specify your own for each application. Most often, you should use the data-typing database to obtain the icon associated with the type data represented by the icon. See Chapter 9, Accessing the Data-Typing Database.

When users start a drag without selecting an icon, it is appropriate for you to provide a relevant drag icon. For example, in an appointment editor, the user can select an appointment out of a scrolling list--which may or may not show icons. You should use an appointment icon as the source indicator. The destination application (for example, a File Manager) should display the same appointment icon.

Parts of the Drag Icon

The drag icon changes appearance to provide drag-over feedback when the user moves it over potential drop zones.

The drag icon has three parts that combine to provide the drag-over feedback:

The state indicator is a pointer used for positioning combined with a valid or invalid drop zone indicator. The valid state indicator is an arrow pointer. The pointer has a hot spot so users can position it in a predictable manner. The invalid state indicator--a circle with a diagonal line--is displayed when users have positioned the cursor over an invalid drop zone.

The operation indicator gives users feedback on what operation is occurring during the drag; either move, copy, or link. Because most drags are moves, users are given additional feedback when they perform the less-frequent copy or link operations.


Note -

The operation feedback is drawn on top of the state and source feedback. This behavior is consistent with Motif drag-and-drop behavior.


The user can choose the drag operation move, copy, or link by pressing and holding certain keys during a drag, as shown in Table 5-1.

Table 5-1 Keys Used to Modify a Drag Operation

Modifier Key 

Operation 

Shift 

Move 

Control 

Copy 

Control and Shift 

Link 

The source application can force a copy, as in the case of the read-only File Manager window. When the user chooses an operation, the drop zone must match that operation for the drop to succeed; otherwise, the drop zone is invalid. In other words, if the user chooses a copy by holding down the Control key, and then drags the drag icon over the trash icon, the drag icon should show the trash icon as an invalid drop zone and any drop should fail, because copying to the trash is not allowed.

The source indicator represents the selection (or the item being dragged). The source indicator varies depending on whether the selection represents single or multiple items and what kind of item the selection represents.

Drags from Inside Windows

Sometimes an application needs to enable a drag from within a dialog box or window. The Appointment Editor in Calendar has a scrolling list of appointments and an entry area for editing an appointment. Users can drag from the scrolling list to get an appointment, but users also need to be able to drag from the appointment entry area. Enabling users to drag from the entry area covers those times when the appointment is not yet inserted in the calendar (for example, when a proposed meeting time is entered but not inserted into the calendar).

The item that can be dragged needs to have an icon graphic associated with it. Place the icon graphic in the dialog box in an appropriate area adjacent to the information to be dragged. The upper-right corner of the dialog box or window is the recommended default position. The icon lets the user know that something can be dragged and the graphic used is the same graphic used in the drag icon to provide consistency. The icon should be 32x32 pixels and have a label so that it resembles a File Manager icon. See the Common Desktop Environment: Style Guide and Certification Checklist chapter on drag and drop for more information.


Note -

Drags are only enabled from human interface elements that have components or items that can be selected. Drags cannot be enabled from static labels such as those on buttons or menus.


Visual Feedback

The following sections describe the drop zone feedback and transition effects of drag and drop.

Drop Zone Feedback

The default drop zone feedback, called drag under, can be a solid line drawn around the site, a raised or lowered surface with a beveled edge around the drop zone, or a pixmap drawing over the drop zone.

Transition Effects

Transition effects show the user that the drop has either succeeded or failed. The two transition effects are melt and snap back.

Melting occurs when the user drops a drag icon on a valid drop zone. When the user drops a drag icon on a valid drop zone, the drag icon melts into the drop zone. The drag icon is replaced by the icon appropriate to the destination application. A printer on the Front Panel may show nothing other than the melting effect. An open File Manager window may display an appropriate icon.

When an icon is dropped, sometimes the melting effect does not take place immediately. The icon is displayed where it is placed until the transfer is done. It is a good idea for the destination to set its cursor to a busy state while the transfer is occurring. The user cannot move or select the icon until the transfer is complete; the busy cursor lets the user know the transfer is in process.

Snap back occurs when a drop fails. Drops can fail in two ways. If the user drops a drag icon over an invalid drop zone, then the drag icon snaps back to the source application. Once a drop occurs, the source and destination applications have to transfer the data. If the data transfer fails, the drag icon snaps back and the destination application is responsible for indicating failure to the user and providing information on why the drop failed.

Drag-and-Drop Sources

To help you understand the behavior of drag-and-drop sources, Table 5-2 describes the key desktop components that can be a source of drags of text selections, files, and buffers.

Table 5-2 Desktop Components That Can Be Drag Sources

Drag Source 

Text Selections 

Files 

Buffers 

Text fields (Motif)* 

Selected text 

N/A 

N/A 

Text Editor: Main Window 

Selected Text 

N/A 

N/A 

Terminal: Main Window 

Selected Text 

N/A 

N/A 

File Manager: Folder Window 

N/A 

Files 

N/A 

File Manager: Trash Window 

N/A 

Files 

N/A 

Mail: Message List 

N/A 

N/A 

Message in mail-message format 

Mail: Attachment List 

N/A 

N/A 

Attachment in format of the attachment 

Calendar: Appointment Editor 

N/A 

N/A 

Appointment in appointment format 

*Any application that has Motif text field sources selected drags text.

Drag-and-Drop Destinations

The following components on the desktop provide drop destinations:

Each component accepts drops of text selections, files, and buffers. Most of the text drop destinations are provided automatically by the Motif library. File or buffer data drop destinations require additional code.

When a user drops data from a file, and that file is modified in some way, the modifications can be written back to the original holder of the file. This behavior is described as saveback. However, when data is dropped from a buffer, the data does not have information about an originating file. As a result, changes to data from buffers cannot be written back, because there is no original holder of the data. This behavior is described as no saveback.

For example, the Mailer can export mail attachments to editors using drag and drop. If the attachment is exported as a buffer (that has no saveback), the editor has no way to change the original attachment in the mailer. So, the editor can only save its modified version of the attachment to a new file.

Because mail attachments are not already separate files (they are embedded into a mail folder file), they are only exported as buffers and cannot be saved back by other editors.

If the attachment is exported as a file (that has saveback) the editor saves its modified version to that same file. Table 5-3 describes the drops of text selections, files, and buffers on editor-type components such as Text Editor, Icon Editor, Calendar and Mailer.

Table 5-3 Editor Drop Destinations

Drop Destination 

Text Selections 

Files 

Buffers 

Text Editor: Main Window 

Insert 

Insert 

Insert 

Terminal: Main Window 

Insert 

N/A 

N/A 

Icon Editor: Main Window 

N/A 

Load (if file in icon format) saveback 

Load into read-only (if data in icon format) no saveback 

Mailer: Message List 

N/A 

Append (if file in mail format) 

Append (if data in mail format) 

Mailer: Compose 

Insert 

Insert 

Insert 

Mailer: Attachment List 

Attach 

Attach 

Attach 

Calendar: Main Window 

N/A 

Schedule Appointment (if file in appointment format) 

Schedule appointment (if data in appointment format) 

Calendar: Appointment Editor 

Insert into text field 

Fill in appointment fields (if file in appointment format) 

Fill in appointment fields (if data in appointment format) 

AppBuilder 

N/A 

Load (if file in BIX or BIL format) saveback 

Load into read-only (if data in BIP format) no saveback 

Table 5-4 describes the drops of text selections, files, and buffers on file and folder icons in the File Manager.

Table 5-4 File Manager Drop Destinations

Drop Destination 

Text Selections 

Files 

Buffers 

File Icon 

Invoke drop action on target file and dropped text (if file accepts text drops and dropped text in appropriate format) no saveback/copy 

Invoke drop action on target file and dropped file (if file accepts file drop and dropped file in appropriate format) saveback 

Invoke drop action on target file and dropped data (if file accepts data drop and dropped data in appropriate format) no saveback/copy 

Folder Icon 

Insert text into new file using "Untitled" name in folder 

Copy/move file to folder 

Insert data into new file using supplied name (if available) in folder else using "Untitled" 

Action Icon 

Invoke action on text (if appropriate format and accepts text drop) no saveback 

Invoke action on files (if appropriate format and accepts file drop) saveback 

Invoke action on data (if appropriate format and accepts data drop) no saveback 

Mail Container Icon 

Append to mailbox (if text in mail format) 

Append to mailbox (if file in mail format) 

Append to mailbox (if data in mail format) 

Table 5-5 describes the drops of text selections, files, and buffers on action icons in the Front Panel.

Table 5-5 Front Panel Drop Destinations

Drop Destination 

Text Selections 

Files 

Buffers 

Text Editor 

Load into read-only no saveback 

Load saveback 

Load into read-only no saveback 

Calendar 

Schedule appointment (if text in appointment format) 

Schedule appointment (if file in appointment format) 

Schedule appointment (if data in appointment format) 

Mail 

Compose message attach text 

Compose message attach file 

Compose message attach data 

Printer 

Print text (if print method available for text) 

Print file contents (if print method available for file format) 

Print data (if print method available for data format) 

Trash Can 

N/A 

Move file to Trash Can 

N/A 

Subpanel: Install Icon 

N/A 

Install icon 

N/A 

Subpanel: Action 

Same as File Manager 

Same as File Manager 

Same as File Manager 

Subpanel: Executable 

Same as File Manager 

Same as File Manager 

Same as File Manager 

See the Common Desktop Environment: Style Guide and Certification Checklist for more information and guidelines on how the drag and drop should appear to the user.

Drag-and-Drop Convenience API

The Common Desktop Environment provides a drag-and-drop convenience API to promote consistency and interoperability across the desktop, and to make it easier for developers to implement drag and drop.

The existing Motif API for drag and drop provides reasonable functionality to achieve a rendezvous between the source and destination applications in the transaction. It provides a framework for data transfer but leaves the actual data transfer details up to the application. For true consistency and interoperability between applications across the desktop, all applications must use the same data transfer protocols. The Common Desktop Environment drag-and-drop convenience API provides common data transfer routines.

Simplify Use for Developers

The existing Motif API for drag and drop is very flexible and, therefore, is somewhat difficult for nonexpert developers to use. The Common Desktop Environment drag-and-drop convenience API provides some convenience functions, described in the following paragraphs, that result in an API that is simpler and easier to use by providing the following services:

Establish Policy

The drag-and-drop API establishes policy in three areas:

Provide Common Functionality

The drag-and-drop API provides common functionality in these areas:

Leverage Existing Motif API

The API for drag and drop does not invent a new drag-and-drop subsystem; rather, it uses the existing Motif API. In addition, since common data transfer protocols were chosen, where available, applications can interoperate at the selection protocol level without requiring global use of the new API.

The transfer of text and files use existing protocols. Buffer transfer uses new protocols.

Drag-and-Drop Transaction

Figure 5-1 illustrates how the basic drag-and-drop transaction is performed.

Figure 5-1 The basic drag-and-drop transaction

Graphic

Figure 5-2 illustrates the optional transitions and operations for the drag-and-drop transaction. The dotted-line boxes show the basic transaction. The solid boxes show the optional transitions and operations.

Figure 5-2 Optional transitions and operations for drag and drop

Graphic

Integration Action Plan

This section suggests a plan of action for integrating your application with drag and drop in Common Desktop Environment 1.3.

Review Drag-and-Drop API and Sample Code

Use the information provided in this chapter to familiarize yourself with the drag-and-drop API. Once you have a basic understanding of the API, review the source code for the drag-and-drop demo program, /usr/dt/examples/dtdnd. This code provides examples of how to use the API in various ways. The examples should give you an understanding of the character and amount of code you need to write to support drag and drop in your application. Understanding the actions and the data-typing API is useful as well.

Review Your Application for Possible Drop Zones

Identify the types of data your application might accept through a drag-and-drop transaction. If, for example, you are writing a bitmap editor, you want to support the drop of files. Once you have identified the data types you will allow to be dropped on your application, determine the widget or widgets that should be drop zones. For the bitmap editor example, you may decide the only place a file should be dropped on the application is the bitmap editing area. In this case, register the widget representing this area using DtDndDropRegister() and provide the appropriate callbacks.

Because it is easiest to handle the drop of file names, start by implementing them. Once you have mastered this technique, you will find it easier to move on to implementing the drop of text and buffers.

Review Your Application for Possible Drag Sources

Identify the types of data your application might permit as sources for a drag-and-drop transaction. In the example of the bitmap editor, you may want bitmap data containing the current bitmap selection to be a drag source as an accelerator for cut and paste. Once you have identified the data types you will allow to be dragged from your application, determine the widget or widgets that should be drag sources. In the bitmap editor example, you may decide the bitmap editing area containing the highlighted bitmap selection should serve as the drag source. In this case, enable the widget representing this area for sourcing drags.

Start by implementing the drag of buffers that are most appropriate or specific to your application. You will also want to add the ability to drop buffers on your application to enable easy data transfer between multiple invocations of your application.

API Overview

This section provides an overview of the drag-and-drop application program interface (API).

DtSvc Library and Header File

The drag-and-drop functionality is implemented in the Desktop Services library, DtSvc. To access the drag-and-drop API, include the header file <Dt/Dnd.h> and link with -lDtSvc.

Functions

The API includes four function calls, which are declared in the header file Dnd.h and outlined in the following paragraphs. These functions are described in greater detail in later sections.

The DtDndContext Structure

You handle transfers of data using the DtDndContext data structure. This structure contains fields for the transfer protocol, the number of items being transferred, and an array of the data items being transferred. See the DtDndDragStart(3X) and DtDndDropRegister(3X) man pages for details about the syntax of this structure.

Protocols

Protocols are used to tell the API the type of data being transferred. The predefined protocols are shown in Table 5-6.

Table 5-6 Predefined Protocols

Protocol 

Description 

DtDND_TEXT_TRANSFER

Text transfer. Compound text. (Motif uses a compound text target for text transfers.) 

DtDND_FILENAME_TRANSFER

File name transfer. 

DtDND_BUFFER_TRANSFER

Memory buffer. 

Operations

The drag source and the drop zone can transfer the data in one of three ways, as described in Table 5-7.

Table 5-7 Data Transfer Operations

Operation 

Description 

XmDROP_MOVE

Moves the data (Copy followed by Delete). 

XmDROP_COPY

Copies the data. 

XmDROP_LINK

Contains a link to the data. 

How Drag Sources Are Used

This section describes how drag sources are used.

Starting a Drag

A drag is started in one of two ways. First, the user may start a drag by pressing down Btransfer, the middle mouse button. As soon as the button is pressed down, the drag begins. Second, the user may start a drag by pressing and holding down Bselect, the left mouse button, and moving the cursor across the screen. The drag begins when the user moves the mouse a certain distance. This distance is called the drag threshold and it is measured in pixels. The default drag threshold is 10 pixels for Bselect. For Btransfer, the drag threshold is 0; because there is no drag threshold, the drag begins as soon as the pointer is moved. Motif scrolled text lists and text widgets are automatically registered as drag sources for text drags using Btransfer and Bselect.

Dragging from Lists or Icons

There are two common interface objects that can be used to source a drag: lists and icons. The Motif List widget automatically sources text drags. If other types of drags are desired, this is accomplished by overriding the default widget translations with new Bntl and Btn2 translations. There is no icon widget in Motif but often a drawing area is used as container of icons. In this case, an event handler for Btn1Motion would be used to start the drag. Refer to the sample code in /usr/dt/examples/dtdnd for more detailed code examples.

Drag Threshold

When starting a drag using Bselect the widget event handler or translation procedures must apply the drag threshold of 10 pixels before starting the drag. For Btransfer, there is no threshold and the drag starts immediately.

Btransfer or Badjust

Style Manager has a setting in the Mouse category that controls whether Btn2, the middle mouse button, acts as Btransfer or Badjust. This setting is stored as a resource name: enableBtn1Transfer. A setting of 1 indicates that Btn2 is Badjust and should adjust the selection while a setting of any other value means that Btn2 is Btransfer and should start a drag. Btn1, the left mouse button, always starts a drag.

The following example shows how to determine whether Btn2 should be Btransfer or Badjust.

Display* display;

int
adjust;
  XtVaGetValues ((Widget)XmGetXmDisplay(display,
	"enableBtn1Transfer", &adjust, 	NULL);

  if (adjust == 1)

 	  /* Btn2 is adjust */

 else

       /* Btn2 is transfer */

Initiating a Drag

Common Desktop Environment 1.0 applications start a drag by calling DtDndDragStart(). This function performs some desktop-specific setup and calls XmDragStart() to initiate a drag. The DtDndDragStart() function synopsis and parameter usage are described as follows:

Widget DtDndDragStart(
 	Widget				dragSource,
 	XEvent 				*event,
  	DtDndProtocol				protocol,
 	Cardinal				numItems,
 	unsigned char				operations,
 	XtCallbackList 	convertCallback,
 	XtCallbackList dragFinishCallback 	ArgList				argList,
		Cardinal				argCount)

Widget dragSource

The widget that received the event that triggered the drag.


XEvent *event

The button press or button motion event that triggered the drag.


DtDndProtocol protocol

The protocol used for the data transfer. The protocol may be one of the following:

DtDND_TEXT_TRANSFER

DtDND_FILENAME_TRANSFER

DtDND_BUFFER_TRANSFER


Cardinal numItems

Specifies the number of items being dragged.


unsigned char operations

Specifies options supported by dragSource. The options are XmDROP_MOVE, XmDROP_COPY, and XmDROP_LINK. A drag source may support any combination of these operations. You specify a combination of operations by using or. For example, to support the move and copy operations, specify XmDROP_MOVE | XmDROP_COPY.


XtCallbackList convertCallback

This callback is invoked when a drop has started and the drop zone has requested data from the drag source. The convertCallback is explained in more detail in the next section.


XtCallbackList dragFinishCallback

This callback is invoked when the drag-and-drop transaction is complete. The dragFinishCallback should reset the dragMotionHandler() and free any memory allocated by the drag source during the drag-and-drop transaction.

Using Convert Callbacks

The convert callback provides data to the drop zone when a drop occurs. The first action in the convert callback is a verification of the reason field in the callData. If the reason is not DtCR_CONVERT_DATA or DtCR_CONVERT_DELETE, you should return immediately; otherwise, proceed to convert the data. For example, if you are handling the conversion of a file name, retrieve the appropriate file name from your internal data structures and copy it into the file data object. If your drag source supports the move operation, you need to support conversion of the DELETE target. That is, when convertCallback is called with a reason of DtCR_CONVERT_DELETE, perform the appropriate deletion action for the data that was moved. In the case of the file transfer, delete the file. Here is a simple convertCallback that handles the conversion and deletion of file names.

void
convertFileCallback(
 	Widget dragContext,
 	XtPointer clientData,
 	XtPointer callData) 
{
 	DtDndConvertCallbackStruct *convertInfo =	(DtDndConvertCallbackStruct*)
  allData;
 	char	 *fileName = (char *) clientData;
  	if (convertInfo->reason == DtCR_DND_CONVERT_DATA) 
   {
		convertInfo->dragData->data.files[0]=
 				XtNewString(fileName); 	
   }

else if (convertInfo->reason == DtCR_DND_CONVERT_DELETE)
   {
		deleteFile(fileName);
 	} else {
 	convertInfo->status = DtDND_FAILURE;
 	}

}

How Drop Zones Are Used

This section describes how drop zones are used.

Registering a Drop Zone

You generally register drop zones just after the widget that is going to be the drop zone is created. If you want a modal drop zone, you may register the widget as a drop zone when you want users to be able to drop on it and unregister it when you do not want users to drop on it.

Motif text widgets are automatically registered as drop zones for text when they are created. Dual registration is allowed. If you want a text widget to accept drops of other data, such as file names, in addition to text, you may register the text widget as a drop zone for file names as well. The text drop functionality provided by Motif is preserved. The functionality for file-name (or other data-type) drops is layered on top.

Use the function DtDndDropRegister() to register a widget as a drop zone. This function handles dual registration, if necessary, performs desktop-specific setup, and calls XmDropSiteRegister(). The DtDndDropRegister() function synopsis and parameter use are as follows.

void
DtDndDropRegister(
   Widget  dropSite,
 	DtDndProtocol	protocols;
 	unsigned char	operations;
	   XtCallbackList	transferCallback;
 	ArgList	argList;
   Cardinal	argCount)

Widget dropSite

The widget that is being registered as a drop zone.


DtDndProtocol protocols

Specifies the list of data transfer protocols that the drop zone can use. To specify the use of more than one protocol, use OR with the protocol values.


unsigned char operations

The operations supported by the drop zone. The drop zone may support any combination of XmDROP_MOVE, XmDROP_COPY, and XmDROP_LINK by using OR for the desired combination of operations.


XtCallbackList transferCallback

This function accepts the data that is dropped on the drop zone. The transfer callback is explained in greater detail in the next section.


ArgList argList

Specifies an optional argument list.


Cardinal argCount

Specifies the number of arguments in argList.

Using the Transfer Callback

The transfer callback accepts data from the drag source when a drop occurs. The first action in the transfer callback is a verification of the reason field in the callData. If the reason is not DtCR_DND_TRANSFER_DATA, you should return immediately; otherwise, proceed with data transfer based on its type and the operation specified in the reason. For example, if you are handling the copy of a file, retrieve the file name from the data structure, open the file, and copy its contents. If your drop zone supports more than one data type, you need to support the transfer of each data type appropriately.

Here is a simple transfer callback for a drawing area drop zone that supports the copying of text and file-name data types.

void
	TransferCallback(
 	Widget widget,
 	XtPointer clientData,
 	XtPointer callData)
{
   DtDndTransferCallbackStruct *transferInfo =
				(DtDndTransferCallbackStruct*) callData;
   int ii;

   DtDndcontext * dropData = transferInfo->dropData;
 			return;
   switch dropData->protocol {
 	case DtDND_FILENAME_TRANSFER:
 		for (ii=0; ii < dropData->numItems; ii++) {
 			drawTheString(dropData->data, strings[ii]);
 		}
 		break;
 	case DtDND_TEXT_TRANSFER:
 		for (ii=0; ii<dropData->numItems; ii++){
      drawTheFile(dropData->data.files[ii]);
 		}
      break;
 	default:
			transferInfo->status = DtDND_FAILURE;
     }
}

Using Data Typing

In an application that accepts drops of buffers, you may want to handle the dropped data in a different way depending on its type. To accomplish data typing, use the data-typing API. Data-typing function calls of interest are DtDtsBufferToDataType() and DtDtsBufferToAttributeValue(). The former returns the data attribute name for the data, the latter returns the value of a specified attribute of the data. Attributes you may find useful for drag and drop are shown in Table 5-8.

Table 5-8 Data-Typing Attributes

Attributes 

Description 

ICON

Path of icon to use for this data.  

MEDIA

The Message Alliance media name for this data. 

See Chapter 9, Accessing the Data-Typing Database for more information.