XInteractive.c revision 1029
341N/A/*
943N/A * Copyright (c) 1993, 2006, Oracle and/or its affiliates. All rights reserved.
341N/A *
341N/A * Permission is hereby granted, free of charge, to any person obtaining a
919N/A * copy of this software and associated documentation files (the "Software"),
919N/A * to deal in the Software without restriction, including without limitation
919N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
919N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
919N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
341N/A */
341N/A
341N/A
341N/A/*
341N/A
341N/A Client side XIA extension code.
341N/A
341N/A One can XSolarisIASetProceesInfo or XIASolarisGetProceesInfo.
341N/A Currently only passing process ids is supported.
341N/A
341N/A Of course QueryVersion and QueryExtension are supported.
341N/A
341N/A No support for error messages is involved. Yet. If this
341N/A interface becomes public this will need to be rewhacked
341N/A */
341N/A
341N/A/* THIS IS NOT AN X CONSORTIUM STANDARD */
341N/A
341N/A#define NEED_EVENTS
341N/A#define NEED_REPLIES
1029N/A
1029N/A#if !defined(lint)
1029N/A#ifdef HAVE_CONFIG_H
1029N/A#include <config.h>
1029N/A#endif
1029N/A#endif
1029N/A
341N/A#include <unistd.h>
341N/A#include <stdio.h>
341N/A#include <X11/Xlibint.h>
341N/A#include <X11/extensions/interactive.h>
341N/A#include <X11/extensions/Xext.h>
1029N/A#include <X11/extensions/XInteractive.h>
341N/A
341N/A#ifdef IA_USE_EXTUTIL
341N/A#include <X11/extensions/extutil.h>
341N/A
341N/Astatic XExtensionInfo _ia_info_data;
341N/Astatic XExtensionInfo *ia_info = &_ia_info_data;
341N/A
341N/Astatic /* const */ char *ia_extension_name = IANAME;
341N/A
341N/A#define IACheckExtension(dpy,i,val) \
341N/A XextCheckExtension (dpy, i, ia_extension_name, val)
341N/A#else
341N/Atypedef struct _IAExtDisplayInfo {
341N/A Display *display;
341N/A XExtCodes *codes;
341N/A struct _IAExtDisplayInfo *next;
341N/A} IAExtDisplayInfo;
341N/A
341N/Astatic IAExtDisplayInfo *iaExtDisplayList = NULL;
341N/Astatic const char *ia_extension_name = IANAME;
341N/A
341N/A#define XExtDisplayInfo IAExtDisplayInfo
341N/A
341N/A#define XextHasExtension(i) (((i) != NULL) && ((i)->codes != NULL))
341N/A
341N/A#define IACheckExtension(dpy,i,val) \
341N/A if (!XextHasExtension(i)) { \
341N/A /* XMissingExtension (dpy, ia_extension_name); */ \
341N/A return val; \
341N/A }
341N/A
341N/A#endif /* IA_USE_EXTUTIL */
341N/A
341N/A/*****************************************************************************
341N/A * *
341N/A * private utility routines *
341N/A * *
341N/A *****************************************************************************/
341N/A
341N/A#ifdef IA_USE_EXTUTIL
341N/Astatic int close_display();
341N/Astatic char *error_string();
341N/Astatic /* const */ XExtensionHooks ia_extension_hooks = {
341N/A NULL, /* create_gc */
341N/A NULL, /* copy_gc */
341N/A NULL, /* flush_gc */
341N/A NULL, /* free_gc */
341N/A NULL, /* create_font */
341N/A NULL, /* free_font */
341N/A close_display, /* close_display */
341N/A NULL, /* wire_to_event */
341N/A NULL, /* event_to_wire */
341N/A NULL, /* error */
341N/A error_string, /* error_string */
341N/A};
341N/A#endif
341N/A
341N/Astatic const char *ia_error_list[] = {
341N/A "BadPid", /* Bad process id */
341N/A};
341N/A
341N/A#ifdef IA_USE_EXTUTIL
341N/Astatic XEXT_GENERATE_FIND_DISPLAY (find_display, ia_info, ia_extension_name,
341N/A &ia_extension_hooks, IANumberEvents, NULL)
341N/A
341N/Astatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, ia_info)
341N/A
341N/Astatic XEXT_GENERATE_ERROR_STRING (error_string, ia_extension_name,
341N/A IANumberErrors, ia_error_list)
341N/A#else
341N/Astatic int ia_close_display(Display *dpy, XExtCodes *codes)
341N/A{
341N/A IAExtDisplayInfo *di, *prev, *next;
341N/A
341N/A for (di = iaExtDisplayList, prev = NULL; di != NULL; di = next) {
341N/A next = di->next;
341N/A if (di->display == dpy) {
341N/A if (prev != NULL) {
341N/A prev->next = di->next;
341N/A } else {
341N/A iaExtDisplayList = di->next;
341N/A }
341N/A Xfree(di);
341N/A } else {
341N/A prev = di;
341N/A }
341N/A }
341N/A return Success;
341N/A}
341N/A
341N/Astatic char *ia_error_string (Display *dpy, int err, XExtCodes *codes,
341N/A char *buf, int nbytes)
341N/A{
341N/A err -= codes->first_error;
341N/A if (err >= 0 && err < IANumberErrors) {
341N/A char tmp[256];
341N/A snprintf (tmp, sizeof(tmp), "%s.%d", ia_extension_name, err);
341N/A XGetErrorDatabaseText (dpy, "XProtoError", tmp, ia_error_list[err],
341N/A buf, nbytes);
341N/A return buf;
341N/A }
341N/A return NULL;
341N/A}
341N/A
341N/Astatic IAExtDisplayInfo *ia_find_display(Display *dpy)
341N/A{
341N/A IAExtDisplayInfo *di;
341N/A
341N/A for (di = iaExtDisplayList ; di != NULL; di = di->next) {
341N/A if (di->display == dpy) {
341N/A return di;
341N/A }
341N/A }
341N/A /* Did not find on list, add new entry */
341N/A di = (IAExtDisplayInfo *) Xmalloc(sizeof(IAExtDisplayInfo));
341N/A if (di == NULL) { return NULL; }
341N/A di->display = dpy;
341N/A di->codes = XInitExtension(dpy, ia_extension_name);
341N/A di->next = iaExtDisplayList;
341N/A iaExtDisplayList = di;
341N/A XESetCloseDisplay(dpy, di->codes->extension, ia_close_display);
341N/A XESetErrorString(dpy, di->codes->extension, ia_error_string);
341N/A return di;
341N/A}
341N/A
341N/A#define find_display ia_find_display
341N/A#endif /* IA_USE_EXTUTIL */
341N/A
341N/A/*****************************************************************************
341N/A * *
341N/A * public Interactive Extension routines *
341N/A * *
341N/A *****************************************************************************/
341N/A
341N/ABool
341N/AXSolarisIAQueryExtension(
341N/A Display *dpy
341N/A)
341N/A{
341N/A XExtDisplayInfo *info = find_display(dpy);
341N/A
341N/A if (XextHasExtension(info)) {
341N/A return True;
341N/A } else {
341N/A return False;
341N/A }
341N/A}
341N/A
341N/A
341N/ABool
341N/AXSolarisIAQueryVersion(
341N/A Display *dpy,
341N/A int *majorVersion,
341N/A int *minorVersion
341N/A)
341N/A{
341N/A XExtDisplayInfo *info = find_display(dpy);
341N/A xIAQueryVersionReply rep;
341N/A xIAQueryVersionReq *req;
341N/A
341N/A IACheckExtension(dpy, info, False);
341N/A
341N/A LockDisplay(dpy);
341N/A GetReq(IAQueryVersion, req);
341N/A req->reqType = info->codes->major_opcode;
341N/A req->IAReqType = X_IAQueryVersion;
341N/A if (!_XReply(dpy, (xReply *)(&rep), 0, xFalse)) {
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return False;
341N/A }
341N/A *majorVersion = rep.majorVersion;
341N/A *minorVersion = rep.minorVersion;
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return True;
341N/A}
341N/A
341N/A
341N/ABool
341N/AXSolarisIAGetProcessInfo(
341N/A Display *dpy,
341N/A unsigned char **Pinfo,
341N/A CARD32 flags,
341N/A int *count
341N/A)
341N/A{
341N/A XExtDisplayInfo *info = find_display(dpy);
341N/A xIAGetProcessInfoReq *req;
341N/A xIAGetProcessInfoReply rep;
341N/A long length = 0;
341N/A
341N/A IACheckExtension(dpy, info, False);
341N/A
341N/A *Pinfo = NULL;
341N/A
341N/A LockDisplay(dpy);
341N/A GetReq(IAGetProcessInfo, req);
341N/A req->reqType = info->codes->major_opcode;
341N/A req->connectionAttrType = X_IAGetProcessInfo;
341N/A req->flags = flags;
341N/A if (!_XReply(dpy, (xReply *)(&rep), 0, xFalse)) {
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return False;
341N/A }
341N/A *count = rep.count;
341N/A *Pinfo = (unsigned char *)Xmalloc((rep.count) * sizeof(ConnectionPidRec));
341N/A if (*Pinfo == NULL) {
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return False; /* not Success */
341N/A }
341N/A length = rep.count << 2;
341N/A _XRead32(dpy, (long *)(*Pinfo), length);
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return True;
341N/A}
341N/A
341N/A
341N/ABool
341N/AXSolarisIASetProcessInfo(
341N/A Display *dpy,
341N/A unsigned char *Pinfo,
341N/A CARD32 flags,
341N/A CARD32 count
341N/A)
341N/A{
341N/A XExtDisplayInfo *info = find_display(dpy);
341N/A xIASetProcessInfoReq *req;
341N/A unsigned long length;
341N/A
341N/A IACheckExtension(dpy, info, False);
341N/A
341N/A LockDisplay(dpy);
341N/A GetReq(IASetProcessInfo, req);
341N/A req->reqType = info->codes->major_opcode;
341N/A req->connectionAttrType = X_IASetProcessInfo;
341N/A req->flags = flags;
341N/A req->length += count;
341N/A req->uid = (CARD32)getuid();
341N/A if (flags & INTERACTIVE_INFO) {
341N/A length=count << 2;
341N/A Data32(dpy, (long *)Pinfo, length);
341N/A }
341N/A if (flags & INTERACTIVE_SETTING) {
341N/A length = count << 2;
341N/A Data32(dpy, (long *)Pinfo, length);
341N/A }
341N/A UnlockDisplay(dpy);
341N/A SyncHandle();
341N/A return True;
341N/A}
341N/A
1029N/A#if USE_XCB
1029N/A
1029N/ABool
1029N/AXCBSolarisIAQueryExtension(xcb_connection_t* conn)
1029N/A{
1029N/A xcb_xia_query_extension_reply_t* re;
1029N/A xcb_xia_query_extension_cookie_t ce;
1029N/A xcb_generic_error_t* error;
1029N/A
1029N/A (void) memset(&ce, '\0', sizeof(ce));
1029N/A
1029N/A ce = xcb_xia_query_extension(conn);
1029N/A re = xcb_xia_query_extension_reply(conn, ce, &error);
1029N/A
1029N/A if (re && !error)
1029N/A return True;
1029N/A
1029N/A return False;
1029N/A}
1029N/A
1029N/A
1029N/ABool
1029N/AXCBSolarisIAQueryVersion(xcb_connection_t* conn,
1029N/A int* majorVersion,
1029N/A int* minorVersion)
1029N/A{
1029N/A xcb_xia_query_version_reply_t* rv;
1029N/A xcb_xia_query_version_cookie_t cv;
1029N/A xcb_generic_error_t* error;
1029N/A
1029N/A (void) memset(&cv, '\0', sizeof(cv));
1029N/A
1029N/A cv = xcb_xia_query_version(conn);
1029N/A rv = xcb_xia_query_version_reply(conn, cv, &error);
1029N/A
1029N/A if (rv && !error) {
1029N/A *majorVersion = rv->major;
1029N/A *minorVersion = rv->minor;
1029N/A return True;
1029N/A }
1029N/A
1029N/A *majorVersion = 0;
1029N/A *minorVersion = 0;
1029N/A return False;
1029N/A}
1029N/A
1029N/A
1029N/ABool
1029N/AXCBSolarisIAGetProcessInfo(xcb_connection_t* conn,
1029N/A unsigned char** Pinfo,
1029N/A CARD32 flags,
1029N/A int* count)
1029N/A{
1029N/A xcb_xia_get_process_info_cookie_t pc;
1029N/A xcb_generic_iterator_t itr;
1029N/A xcb_xia_get_process_info_reply_t* pr;
1029N/A xcb_generic_error_t* error;
1029N/A uint32_t* pinfo;
1029N/A
1029N/A if ((conn == NULL) || (count == NULL) || (Pinfo == NULL))
1029N/A return False;
1029N/A
1029N/A *Pinfo = NULL;
1029N/A *count = 0;
1029N/A (void) memset(&pc, '\0', sizeof(pc));
1029N/A
1029N/A pc = xcb_xia_get_process_info(conn, flags);
1029N/A pr = xcb_xia_get_process_info_reply(conn, pc, &error);
1029N/A
1029N/A if (pr && !error && (pr->count > 0)) {
1029N/A uint32_t* pid = xcb_xia_get_process_info_pinfo(pr);
1029N/A if (pid == NULL)
1029N/A return False;
1029N/A
1029N/A pinfo = (uint32_t*) Xmalloc((size_t) (pr->count * sizeof(uint32_t)));
1029N/A if (pinfo == NULL)
1029N/A return False;
1029N/A
1029N/A *count = pr->count;
1029N/A (void) memcpy(pinfo, pid, (size_t) (*count * sizeof(uint32_t)));
1029N/A *Pinfo = (unsigned char *) pinfo;
1029N/A return True;
1029N/A }
1029N/A
1029N/A return False;
1029N/A}
1029N/A
1029N/A
1029N/ABool
1029N/AXCBSolarisIASetProcessInfo(xcb_connection_t* conn,
1029N/A unsigned char* Pinfo,
1029N/A CARD32 flags,
1029N/A CARD32 count)
1029N/A{
1029N/A xcb_void_cookie_t pc;
1029N/A
1029N/A if (count == 0)
1029N/A return True;
1029N/A
1029N/A if ((conn == NULL) || (Pinfo == NULL))
1029N/A return False;
1029N/A
1029N/A pc = xcb_xia_set_process_info(conn, flags,
1029N/A (uint32_t) getuid(), count, (uint32_t *) Pinfo);
1029N/A
1029N/A return True;
1029N/A}
1029N/A
1029N/A#endif /* USE_XCB */
1029N/A