Common Desktop Environment: Programmer's Guide
Contents of Chapter:
- Summary
-
- Library and Header Files
-
- Demo Program
-
- Data Criteria and Data Attributes
-
- Data-Typing Functions
-
- Simple Data Typing
-
- Intermediate Data Typing
-
- Advanced Data Typing
-
- Data Types That Are Actions (DtDtsDataTypeIsAction)
-
- Registering Objects as Drop Zones
-
- Example of Using the Data-Typing Database
-
This chapter describes the data-typing functions and how to use the data- typing database.
Data typing provides an extension to the attributes of files and data beyond what is provided by the traditional UNIX file systems. These extensions consist of attributes, such as icon names, descriptions, and actions, that can be performed on files and data. This information is stored in name/value pairs in the DATA_ATTRIBUTES table (or database). The desktop uses a certain set of DATA_ATTRIBUTES, described in the following paragraphs. The DATA_ATTRIBUTES table is extendable for future and application-specific growth, although extending this table is not recommended because other applications may not check the additions.
Data is matched with a specific file or data entry in a DATA_CRITERIA table. The DATA_CRITERIA table entries are sorted in decreasing order from most specific to least specific. For example, /usr/lib/lib* is more specific than /usr/* and would, therefore, appear first. When a request to type a file or data is made, the table is checked in sequence to find the best match using the information provided either from the file or from the data. When an information and entry match is found, DATA_ATTRIBUTES_NAME is used to find the proper DATA_ATTRIBUTES entry.
If you want your application to present data objects (either files or data buffers) to the user in a manner consistent with the desktop, use the DtDts* API to determine how to display the data objects and how to operate on them. For example, your application can determine the icon that represents a data object by calling the DtDtsDataTypeToAttributeValue function for the ICON attribute.
To use data typing, you need to link to the libDtSvc library. Actions are usually loaded with the data-typing information. Actions require links to the libXm and libX11 libraries. The header files are Dt/Dts.h
and Dt/Dt.h
.
A demo program containing an example of how to use the data-typing database is in /usr/dt/examples/dtdts/datatypes/datatyping.c.
Data typing consists of two parts:
- A database that stores data criteria and data attributes
- A collection of routines that query the database
The attributes of data criteria, in alphabetical order, are:
- CONTENT
- DATA_ATTRIBUTES_NAME
- LINK_NAME
- LINK_PATH
- MODE
- NAME_PATTERN
- PATH_PATTERN
Table 9-1 describes the data criteria in the order in which you are most likely to use them.
Table 9-1 Data Criteria in Order of Most Likely Use
Some of the more common attributes of data types, in alphabetical order, are:
- ACTIONS
- COPY_TO_ACTION
- DESCRIPTION
- ICON
- INSTANCE_ICON
- IS_EXECUTABLE
- IS_TEXT
- LINK_TO_ACTION
- MEDIA
- MIME_TYPE
- MOVE_TO_ACTION
- NAME_TEMPLATE
- PROPERTIES
- X400_TYPE
Table 9-2 describes the data attributes in the order in which you are most likely to use them.
Table 9-2 Data Attributes in Order of Most Likely Use
Table 9-2 Data Attributes in Order of Most Likely Use (Continued)
The IS_TEXT field differs from the text attribute of the MIME_TYPE field, which is the MIME content type, as described in the referenced MIME_ RFC. The MIME content type determines whether the data consists of textual characters or byte values. If the data consists of textual characters, and the data is labeled as text/*, the IS_TEXT field determines whether it is appropriate for the data to be presented to users in textual form.
Table 9-3 shows some examples of IS_TEXT usage with different MIME_TYPE attributes.
Table 9-3 IS_TEXT Attribute Examples
See the dtdtsfile(4) man page for more information about data-type attributes.
To look up an attribute for a data object, you must first determine the type of the object and then ask for the appropriate attribute value for that type. The functions that you can use to query the database for data information are shown in Table 9-4. Each of these functions has a man page in section (3). Refer to the appropriate man page for more information.
Table 9-4 Data-Typing Database Query Functions
You can type data and retrieve attributes in one of three ways: simple, intermediate, or advanced.
Simple Data Typing
The simplest way to type data is to use the following functions:
- DtDtsFileToAttributeList
- DtDtsFileToAttributeValue
When you use these functions, a file is typed and a single attribute, or the entire list, is retrieved. System calls are made, data is typed, and the attribute is retrieved. These functions call the intermediate data-typing functions.
- DtDtsBufferToAttributeList
- DtDtsBufferToAttributeValue
Buffers are assumed to have a mode that matches regular files that have read/write permissions. See "Advanced Data Typing" to type read-only buffers.
Intermediate Data Typing
When you type data and retrieve attributes, the data-typing part of the process is the most expensive in terms of performance. You can type data in a second way that improves performance by separating the data-typing and attribute-retrieval functions. Use the following functions for intermediate data typing:
- DtDtsBufferToDataType
- DtDtsFileToDataType
- DtDtsDataTypeToAttributeList
- DtDtsDataTypeToAttributeValue
Use these functions if your application queries for more than a single attribute value. When you use these functions, an object is typed and then that type is used to retrieve one or more attributes from the attribute list.
Using the intermediate data-typing functions is the recommended way to type data and retrieve attributes. These functions call the advanced data-typing functions and make the same assumptions about buffers as the simpler data typing.
Advanced data typing separates system calls, data typing, and attribute retrieval even further. Advanced data typing is more complicated to code because it uses data from existing system calls, which are initialized in advance and are not included as part of the data-typing function. Use the following function for advanced data typing:
DtDtsDataToDataType
To type a read-only buffer, a stat structure should be passed that has the st_mode field set to S_IFREG | S_IROTH | S_IRGRP | S_IRUSR.
Data Types That Are Actions (DtDtsDataTypeIsAction)
For every action in a database a synthetic data type is generated when a database is loaded that allows actions to be typed. These data types may have two additional attributes:
- IS_ACTION is a string-Boolean value that tells users of this data type that it is an action. If IS_ACTION is set to the string true (independent of case), the data is an action.
- IS_SYNTHETIC is a string-Boolean value that tells users of this data type that it was generated from an entry in the ACTION table. If IS_SYNTHETIC is set to true, the data type was generated.
If your application defines data types, follow these steps to ensure that it provides all the drag and drop behavior that you intend:
- In your application, decide if you need to define any data types.
- For each data type you define, decide whether you want the associated object to be a drop zone.
- For each object that you want to register as a drop zone, decide which operations--move, copy, or link--you want to define.
- For the drop operations that are valid for each object, define the appropriate drop actions (set the MOVE_TO_ACTION, COPY_TO_ACTION, and LINK_TO_ACTION attributes).
If your application displays icons for data objects, you may choose to support those icons as drop zones. If so, you need to query the MOVE_TO_ACTION, COPY_TO_ACTION, or LINK_TO_ACTION attributes to determine the drop behavior for those data objects. Objects should support drop operations only if the corresponding attribute value is not NULL. If all three attributes have NULL values, the object should not be registered as a drop site. Whenever you set at least one of these attributes for an object with a defined data type, your application registers that object as a drop zone.
When a user drags an object to a drop zone, your application determines which gesture (that is, which drag operation) was used to make the drop. Based on the drag operation and the drop zone's data type, the application retrieves a drop attribute from the data-typing database. It then calls DtActionInvoke, using the following two rules to determine its parameters:
- If the user drops objects A and B onto object C, call DtActionInvoke with C, A and B as args. The action is the value of either MOVE_TO_ACTION, COPY_TO_ACTION, LINK_TO_ACTION of C. If object C is an action, the args list does not include C. Also, the action is C.
The File Manager, along with its directory and folder objects, exemplifies how the desktop uses the move, copy, and link drop attributes. A user can drag and drop objects (files) to directory folders. File Manager defines MOVE_TO_ACTION, COPY_TO_ACTION, and LINK_TO_ACTION actions for folder objects. These actions perform the appropriate file system move, copy, and link system functions.
See /usr/dt/appconfig/types/C/dtfile.dt for an example of how to define the MOVE_TO_ACTION, COPY_TO_ACTION, and LINK_TO_ACTION attributes. See Chapter 5, "Integrating with Drag and Drop," for information about how to use drag and drop.
This section contains example code of how to use data typing. You can find this example code in /usr/dt/examples/dtdts/datatyping.c. The example code displays the data type, icon name, and supported actions for each file passed to it. You can then use the dtaction client to run a supported action on the file. The usage for datatyping is:
datatyping file1 [file2 ...]
#include <Xm/Form.h>
#include <Xm/Text.h>
#include <Dt/Dts.h>
#define ApplicationClass "DtDatatyping"
static Widget text;
static void DisplayTypeInfo(int, char**);
int main(int argc, char **argv)
{
XtAppContext appContext;
Widget toplevel, form;
Arg args[20];
int n;
toplevel = XtAppInitialize(&appContext, ApplicationClass,
NULL, 0,
argc, argv, NULL, NULL, 0);
if (argc == 1) {
printf("%s: No files specified.\n", argv[0]);
exit(1);
}
form = XmCreateForm(toplevel, "form", NULL, 0);
XtManageChild(form);
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNeditable, False); n++;
XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg(args[n], XmNrows, 25); n++;
XtSetArg(args[n], XmNcolumns, 90); n++;
text = XmCreateScrolledText(form, "text", args, n);
XtManageChild(text);
XtRealizeWidget(toplevel);
if (DtAppInitialize(appContext, XtDisplay(toplevel), toplevel,
argv[0], ApplicationClass) == False) {
printf("%s: Couldn't initialize Dt\n", argv[0]);
exit(1);
}
DtDbLoad();
DisplayTypeInfo(argc, argv);
XtAppMainLoop(appContext);
}
static void DisplayTypeInfo(int argc, char **argv)
{
char *file;
char *datatype;
char *icon;
char *actions;
char str[100];
int i;
sprintf(str, "%-30s\t%-10s\t%-8s\t%-20s\n",
"File",
"DataType",
"Icon",
"Actions");
XmTextInsert(text, XmTextGetLastPosition(text), str);
sprintf(str, "%-30s\t%-10s\t%-8s\t%-20s\n",
"-------------------",
"--------",
"----",
"-------");
XmTextInsert(text, XmTextGetLastPosition(text), str);
for(i=1; i < argc; i++) {
char *file = argv[i];
/* find out the Dts data type */
datatype = DtDtsFileToDataType(file);
if(datatype) {
/* find the icon attribute for the data type */
icon = DtDtsDataTypeToAttributeValue(datatype,
DtDTS_DA_ICON, file);
}
/* Directly find the action attribute for a file */
actions = DtDtsFileToAttributeValue(file,
DtDTS_DA_ACTION_LIST);
sprintf(str, "%-30s\t%-10s\t%-8s\t%s\n",
file,
datatype?datatype:"unknown",
icon?icon:"unknown",
actions?actions:"unknown");
XmTextInsert(text, XmTextGetLastPosition(text), str);
/* Free the space allocated by Dts */
DtDtsFreeAttributeValue(icon);
DtDtsFreeAttributeValue(actions);
DtDtsFreeDataType(datatype);
}
}
Generated with CERN WebMaker