static void DndReadSourceProperty(Display * dpy, Window window, Atom dnd_selection, Atom ** targets, unsigned short * num_targets) { unsigned char *retval = 0; Atom type ; int format ; unsigned long bytesafter, lengthRtn; if ((XGetWindowProperty (dpy, window, dnd_selection, 0L, 100000L, False, ATOM(_MOTIF_DRAG_INITIATOR_INFO), &type, &format, &lengthRtn, &bytesafter, &retval) != Success) || (type == XNone)) { *num_targets = 0; return ; } DndSrcProp * src_prop = (DndSrcProp *)retval; if (src_prop->byte_order != DndByteOrder()) { SWAP2BYTES(src_prop->target_index); SWAP4BYTES(src_prop->selection); } *num_targets = _DndIndexToTargets(dpy, src_prop->target_index, targets); XFree((char*)src_prop); }
/* * extracts n values (formatted as CARD32) from the drag buffer and * converts them to Atoms */ static void read_atoms_from_drag_buffer(XmDndBufMgr bmgr, int n, Boolean swap, Atom* atoms) { DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atoms_from_drag_buffer(%d) - count %d swap %s\n", __FILE__, __LINE__, n, swap ? "True" : "False")); if (sizeof(Atom) == sizeof(CARD32)) { _XmReadDragBuffer(bmgr, False, (char*) atoms, sizeof(Atom) * n); if (swap) { int i; for (i = 0; i < n; i++) { SWAP4BYTES(atoms[i]); } } } else { CARD32 in; int i; if (swap) { for (i = 0; i < n; i++) { _XmReadDragBuffer(bmgr, False, (char*) &in, sizeof(CARD32)); SWAP4BYTES(in); atoms[i] = in; } } else { for (i = 0; i < n; i++) { _XmReadDragBuffer(bmgr, False, (char*) &in, sizeof(CARD32)); atoms[i] = in; } } } }
static DndTargetsTable TargetsTable(Display *display) { Atom type; int format; unsigned long size; unsigned long bytes_after; Window motif_window = MotifWindow(display) ; unsigned char *retval; DndTargetsTable targets_table ; int i,j ; char * target_data ; /* this version does no caching, so it's slow: round trip each time */ /* ideally, register for property notify on this target_list atom and update when necessary only */ if ((XGetWindowProperty (display, motif_window, ATOM(_MOTIF_DRAG_TARGETS), 0L, 100000L, False, ATOM(_MOTIF_DRAG_TARGETS), &type, &format, &size, &bytes_after, &retval) != Success) || type == XNone) { qWarning("QMotifDND: Cannot get property on Motif window"); return 0; } DndTargets * target_prop = (DndTargets *)retval; if (target_prop->protocol_version != DND_PROTOCOL_VERSION) { qWarning("QMotifDND: Protocol mismatch"); } if (target_prop->byte_order != DndByteOrder()) { /* need to swap num_target_lists and size */ SWAP2BYTES(target_prop->num_target_lists); SWAP4BYTES(target_prop->data_size); } /* now parse DndTarget prop data in a TargetsTable */ targets_table = (DndTargetsTable)malloc(sizeof(DndTargetsTableRec)); targets_table->num_entries = target_prop->num_target_lists ; targets_table->entries = (DndTargetsTableEntry) malloc(sizeof(DndTargetsTableEntryRec) * target_prop->num_target_lists); target_data = (char*)target_prop + sizeof(*target_prop) ; for (i = 0 ; i < targets_table->num_entries; i++) { CARD16 num_targets ; CARD32 atom ; memcpy(&num_targets, target_data, 2); target_data += 2; /* potential swap needed here */ if (target_prop->byte_order != DndByteOrder()) SWAP2BYTES(num_targets); targets_table->entries[i].num_targets = num_targets ; targets_table->entries[i].targets = (Atom *) malloc(sizeof(Atom) * targets_table->entries[i].num_targets); for (j = 0; j < num_targets; j++) { memcpy(&atom, target_data, 4); target_data += 4; /* another potential swap needed here */ if (target_prop->byte_order != DndByteOrder()) SWAP4BYTES(atom); targets_table->entries[i].targets[j] = (Atom) atom ; } } if (target_prop) { XFree((char *)target_prop); } return targets_table ; }
static Bool DndParseClientMessage(XClientMessageEvent *cm, DndData * dnd_data, char * receiver) { DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ; if (cm->message_type != ATOM(_MOTIF_DRAG_AND_DROP_MESSAGE)) { return False ; } if (dnd_message->byte_order != DndByteOrder()) { SWAP2BYTES(dnd_message->flags); SWAP4BYTES(dnd_message->time); } /* do the rest in the switch */ dnd_data->reason = dnd_message->reason ; if (DND_GET_EVENT_TYPE(dnd_data->reason)) *receiver = 1 ; else *receiver = 0 ; dnd_data->reason &= DND_CLEAR_EVENT_TYPE ; dnd_data->time = dnd_message->time ; /* we're reading in more stuff that necessary. but who cares */ dnd_data->status = DND_GET_STATUS(dnd_message->flags) ; dnd_data->operation = DND_GET_OPERATION(dnd_message->flags) ; dnd_data->operations = DND_GET_OPERATIONS(dnd_message->flags) ; dnd_data->completion = DND_GET_COMPLETION(dnd_message->flags) ; switch(dnd_data->reason) { case DND_TOP_LEVEL_ENTER: case DND_TOP_LEVEL_LEAVE: if (dnd_message->byte_order != DndByteOrder()) { SWAP4BYTES(dnd_message->data.top.src_window); SWAP4BYTES(dnd_message->data.top.property); } dnd_data->src_window = dnd_message->data.top.src_window ; dnd_data->property = dnd_message->data.top.property ; break ; /* cannot fall through, see above comment in write msg */ case DND_DRAG_MOTION: case DND_OPERATION_CHANGED: case DND_DROP_SITE_ENTER: case DND_DROP_START: if (dnd_message->byte_order != DndByteOrder()) { SWAP2BYTES(dnd_message->data.pot.x); SWAP2BYTES(dnd_message->data.pot.y); SWAP4BYTES(dnd_message->data.pot.property); SWAP4BYTES(dnd_message->data.pot.src_window); } dnd_data->x = dnd_message->data.pot.x ; dnd_data->y = dnd_message->data.pot.y ; dnd_data->property = dnd_message->data.pot.property ; dnd_data->src_window = dnd_message->data.pot.src_window ; break ; case DND_DROP_SITE_LEAVE: break; default: break ; } return True ; }
static Boolean read_atoms_table(Display *display, XmDndAtomsTable tbl) { Atom da, atype; Window win; int aformat, i; unsigned long nitems, bafter; XmDndAtoms *atoms = NULL; Boolean got_it = False; XmDndAtomsTableEntryRec atom_ent; XmDndBufMgrRec bmgr; DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atoms_table(%d)\n", __FILE__, __LINE__)); da = XmInternAtom(display, _XA_MOTIF_DRAG_ATOMS, False); win = get_drag_window(display); begin_protection(display, win); if (XGetWindowProperty(display, win, da, 0L, PROP_LENGTH, False, da, &atype, &aformat, &nitems, &bafter, (unsigned char **)&atoms) == Success && nitems >= 8) { DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - got property, bafter=%i\n", __FILE__, __LINE__, bafter)); got_it = True; } end_protection(display); if (bad_window) { _XmWarning((Widget)XmGetXmDisplay(display), "Invalid DRAG WINDOW fetching DRAG_ATOMS."); } if (!got_it) { if (atoms) { XFree((XPointer)atoms); } return False; } if (atoms->protocol_version != DND_PROTOCOL_VERSION) { _XmWarning((Widget)XmGetXmDisplay(display), "DND Protocol version mismatch."); } if (atoms->byte_order != _XmByteOrder()) { SWAP2BYTES(atoms->num_atoms); SWAP4BYTES(atoms->data_size); } if (!tbl) { tbl = (XmDndAtomsTable) XtMalloc(sizeof(XmDndAtomsTableRec)); tbl->num_entries = 0; tbl->entries = NULL; set_atoms_table(display, tbl); } if (tbl->num_entries < atoms->num_atoms) { tbl->entries = (XmDndAtomsTableEntry) XtRealloc((char *)tbl->entries, atoms->num_atoms * sizeof(XmDndAtomsTableEntryRec)); } if (atoms->num_atoms > 0) { bmgr.atoms = (char *)atoms; bmgr.atom_start = (char *)(atoms + 1); bmgr.atom_size = atoms->data_size; for (i = 0; i < atoms->num_atoms; i++) { _XmReadDragBuffer(&bmgr, False, (char *)&atom_ent, sizeof(XmDndAtomsTableEntryRec)); if (atoms->byte_order != _XmByteOrder()) { SWAP4BYTES(atom_ent.atom); SWAP4BYTES(atom_ent.time); } tbl->entries[i].atom = atom_ent.atom; tbl->entries[i].time = atom_ent.time; } } return True; }
/* * get the ATOM_PAIRS. They may or may not already exist */ static Boolean read_atom_pairs(Display *display) { Atom pa, atype; Window win; Boolean gotit = False; XmDndAtomPairs *pairs; XmDndBufMgrRec bmgr; int i; XmDndAtomPair pair; char buf[32]; int aformat; unsigned long nitems, bafter; unsigned char *prop = NULL; DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d)\n", __FILE__, __LINE__)); pa = XmInternAtom(display, _XA_MOTIF_DRAG_ATOM_PAIRS, False); win = get_drag_window(display); begin_protection(display, win); if (XGetWindowProperty(display, win, pa, 0L, PROP_LENGTH, False, pa, &atype, &aformat, &nitems, &bafter, (unsigned char **)&pairs) == Success && nitems >= 8 && pairs != NULL) { DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - got property, bafter=%i\n", __FILE__, __LINE__, bafter)); gotit = True; prop = (unsigned char *)pairs; } end_protection(display); if (bad_window) { _XmWarning((Widget)XmGetXmDisplay(display), "Bad window ATOM_PAIRS property on DRAG_WINDOW."); } if (!gotit) { #if 0 _XmWarning((Widget)XmGetXmDisplay(display), "No ATOM_PAIRS property on DRAG_WINDOW."); #endif if (prop) { XFree((char *)prop); } DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - did not get property\n", __FILE__, __LINE__)); return False; } if (pairs->protocol_version != DND_PROTOCOL_VERSION) { _XmWarning((Widget)XmGetXmDisplay(display), "DND Protocol version mismatch."); } if (pairs->byte_order != _XmByteOrder()) { SWAP2BYTES(pairs->num_pairs); SWAP4BYTES(pairs->data_size); } DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - %i pairs\n", __FILE__, __LINE__, pairs->num_pairs)); if (pairs->num_pairs > 0) { bmgr.atoms = (char *)pairs; bmgr.atom_start = (char *)(pairs + 1); bmgr.atom_size = pairs->data_size; bmgr.names = (char *)pairs + pairs->data_size; bmgr.name_start = (char *)pairs + pairs->data_size; bmgr.name_size = nitems - pairs->data_size; for (i = 0; i < pairs->num_pairs; i++) { _XmReadDragBuffer(&bmgr, False, (char *)&pair, sizeof(XmDndAtomPair)); if (pairs->byte_order != _XmByteOrder()) { SWAP4BYTES(pair.atom); SWAP2BYTES(pair.namelen); } _XmReadDragBuffer(&bmgr, True, buf, pair.namelen); DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - intern %s\n", __FILE__, __LINE__, buf)); _XmInternAtomAndName(display, pair.atom, buf); } } if (prop) { XFree((char *)prop); } return gotit; }
/* * get the drag receiver info property from the target * * check out the _XA_MOTIF_DRAG_RECEIVER_INFO property on a Motif * application's window. There's a lot more there than what Daniel * talks about. Must be due to PREREGISTER, yes? */ extern Boolean _XmGetDragReceiverInfo(Display *display, Window win, XmDragReceiverInfo ri) { Atom dri; XmDndReceiverProp *receiver; Atom type; int format; unsigned int border; unsigned long bafter, length; Window root; DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:_XmGetDragReceiverInfo(%d)\n", __FILE__, __LINE__)); DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - %p\n", __FILE__, __LINE__, win)); dri = XmInternAtom(display, _XA_MOTIF_DRAG_RECEIVER_INFO, False); if (XGetWindowProperty(display, win, dri, 0L, PROP_LENGTH, False, dri, &type, &format, &length, &bafter, (unsigned char **)&receiver) != Success) { DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - getting prop failed\n", __FILE__, __LINE__)); return False; } if (length < sizeof(XmDndReceiverProp)) { ri->dragProtocolStyle = XmDRAG_NONE; XFree((char *)receiver); DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - None available\n", __FILE__, __LINE__)); return False; } if (receiver->protocol_version != DND_PROTOCOL_VERSION) { _XmWarning(NULL, "Drag protocol version mismatch: %d vs %d\n", DND_PROTOCOL_VERSION, receiver->protocol_version); } if (receiver->byte_order != _XmByteOrder()) { SWAP4BYTES(receiver->proxy_window); SWAP2BYTES(receiver->num_drop_sites); SWAP4BYTES(receiver->total_size); } Display_ProxyWindow(XmGetXmDisplay(display)) = receiver->proxy_window; ri->dragProtocolStyle = receiver->protocol_style; ri->iccInfo = (XtPointer)XtMalloc(sizeof(XmShellDropSiteInfoRec)); DSI_ByteOrder(ri->iccInfo) = receiver->byte_order; DSI_NumDropSites(ri->iccInfo) = receiver->num_drop_sites; DSI_Info(ri->iccInfo).atoms = (char *)receiver; DSI_Info(ri->iccInfo).atom_size = receiver->total_size; DSI_Info(ri->iccInfo).atom_start = (char *)(receiver + 1); DSI_Info(ri->iccInfo).names = (char *)receiver + receiver->total_size; DSI_Info(ri->iccInfo).name_size = length - receiver->total_size; XGetGeometry(display, win, &root, &ri->xOrigin, &ri->yOrigin, &ri->width, &ri->height, &border, &ri->depth); XTranslateCoordinates(display, win, root, -border, -border, &ri->xOrigin, &ri->yOrigin, &root); return True; }
static Boolean read_targets_table(Display *display, XmDndTargetsTable tbl) { Atom ta, atype; Window win; int aformat, i; unsigned long nitems, bafter; XmDndTargets *targets = NULL; Boolean got_it = False; XmDndBufMgrRec bmgr; CARD16 nents; DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d)\n", __FILE__, __LINE__)); ta = XmInternAtom(display, _XA_MOTIF_DRAG_TARGETS, False); win = get_drag_window(display); begin_protection(display, win); if (XGetWindowProperty(display, win, ta, 0L, PROP_LENGTH, False, ta, &atype, &aformat, &nitems, &bafter, (unsigned char **)&targets) == Success && nitems >= 8) { DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) bafter=%i\n", __FILE__, __LINE__, bafter)); got_it = True; } end_protection(display); if (bad_window) { _XmWarning((Widget)XmGetXmDisplay(display), "Invalid DRAG WINDOW fetching DRAG_ATOMS."); } if (!got_it) { if (targets) { XFree((XPointer)targets); } DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) - False\n", __FILE__, __LINE__)); return False; } if (targets->protocol_version != DND_PROTOCOL_VERSION) { _XmWarning((Widget)XmGetXmDisplay(display), "DND Protocol version mismatch."); } if (targets->byte_order != _XmByteOrder()) { SWAP2BYTES(targets->num_target_lists); SWAP4BYTES(targets->data_size); } if (!tbl) { tbl = (XmDndTargetsTable)XtMalloc(sizeof(XmDndTargetsTableRec)); tbl->num_entries = 0; tbl->entries = NULL; set_targets_table(display, tbl); } if (tbl->num_entries < targets->num_target_lists) { tbl->num_entries = targets->num_target_lists; tbl->entries = (XmDndTargetsTableEntry)XtRealloc((char *)tbl->entries, targets->num_target_lists * sizeof(XmDndTargetsTableEntryRec)); } if (targets->num_target_lists > 0) { bmgr.atoms = (char *)targets; bmgr.atom_start = (char *)(targets + 1); bmgr.atom_size = targets->data_size; for (i = 0; i < targets->num_target_lists; i++) { _XmReadDragBuffer(&bmgr, False, (char *)&nents, sizeof(CARD16)); if (targets->byte_order != _XmByteOrder()) { SWAP2BYTES(nents); } tbl->entries[i].num_targets = nents; tbl->entries[i].targets = (Atom *)XtMalloc(nents * sizeof(Atom)); read_atoms_from_drag_buffer(&bmgr, tbl->entries[i].num_targets, targets->byte_order != _XmByteOrder(), tbl->entries[i].targets); } } DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) - True %p\n", __FILE__, __LINE__, tbl)); if (targets) { XFree((XPointer)targets); } return True; }
static PyObject * py_decodelzw(PyObject *obj, PyObject *args) { PyThreadState *_save = NULL; PyObject *byteobj = NULL; PyObject *result = NULL; int i, j; unsigned int encoded_len = 0; unsigned int decoded_len = 0; unsigned int result_len = 0; unsigned int table_len = 0; unsigned int len; unsigned int code, c, oldcode, mask, bitw, shr, bitcount; char *encoded = NULL; char *result_ptr = NULL; char *table2 = NULL; char *cptr; struct BYTE_STRING *decoded = NULL; struct BYTE_STRING *table[4096]; struct BYTE_STRING *decoded_ptr, *newentry, *newresult, *t; int little_endian = 0; if (!PyArg_ParseTuple(args, "O", &byteobj)) return NULL; if (!PyBytes_Check(byteobj)) { PyErr_Format(PyExc_TypeError, "expected byte string as input"); goto _fail; } Py_INCREF(byteobj); encoded = PyBytes_AS_STRING(byteobj); encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj); /* release GIL: byte/string objects are immutable */ _save = PyEval_SaveThread(); if ((*encoded != -128) || ((*(encoded+1) & 128))) { PyEval_RestoreThread(_save); PyErr_Format(PyExc_ValueError, "strip must begin with CLEAR code"); goto _fail; } little_endian = (*(unsigned short *)encoded) & 128; /* allocate buffer for codes and pointers */ decoded_len = 0; len = (encoded_len + encoded_len/9) * sizeof(decoded); decoded = PyMem_Malloc(len * sizeof(void *)); if (decoded == NULL) { PyEval_RestoreThread(_save); PyErr_Format(PyExc_MemoryError, "failed to allocate decoded"); goto _fail; } memset((void *)decoded, 0, len * sizeof(void *)); decoded_ptr = decoded; /* cache strings of length 2 */ cptr = table2 = PyMem_Malloc(256*256*2 * sizeof(char)); if (table2 == NULL) { PyEval_RestoreThread(_save); PyErr_Format(PyExc_MemoryError, "failed to allocate table2"); goto _fail; } for (i = 0; i < 256; i++) { for (j = 0; j < 256; j++) { *cptr++ = (char)i; *cptr++ = (char)j; } } memset(table, 0, sizeof(table)); table_len = 258; bitw = 9; shr = 23; mask = 4286578688; bitcount = 0; result_len = 0; code = 0; oldcode = 0; while ((unsigned int)((bitcount + bitw) >> 3) <= encoded_len) { /* read next code */ code = *((unsigned int *)((void *)(encoded + (bitcount / 8)))); if (little_endian) code = SWAP4BYTES(code); code <<= bitcount % 8; code &= mask; code >>= shr; bitcount += bitw; if (code == 257) /* end of information */ break; if (code == 256) { /* clearcode */ /* initialize table and switch to 9 bit */ while (table_len > 258) { t = table[--table_len]; t->ref--; if (t->ref == 0) { if (t->len > 2) PyMem_Free(t->str); PyMem_Free(t); } } bitw = 9; shr = 23; mask = 4286578688; /* read next code */ code = *((unsigned int *)((void *)(encoded + (bitcount / 8)))); if (little_endian) code = SWAP4BYTES(code); code <<= bitcount % 8; code &= mask; code >>= shr; bitcount += bitw; if (code == 257) /* end of information */ break; /* decoded.append(table[code]) */ if (code < 256) { result_len++; *((int *)decoded_ptr++) = code; } else { newresult = table[code]; newresult->ref++; result_len += newresult->len; *(struct BYTE_STRING **)decoded_ptr++ = newresult; } } else { if (code < table_len) { /* code is in table */ /* newresult = table[code]; */ /* newentry = table[oldcode] + table[code][0] */ /* decoded.append(newresult); table.append(newentry) */ if (code < 256) { c = code; *((unsigned int *)decoded_ptr++) = code; result_len++; } else { newresult = table[code]; newresult->ref++; c = (unsigned int) *newresult->str; *(struct BYTE_STRING **)decoded_ptr++ = newresult; result_len += newresult->len; } newentry = PyMem_Malloc(sizeof(struct BYTE_STRING)); newentry->ref = 1; if (oldcode < 256) { newentry->len = 2; newentry->str = table2 + (oldcode << 9) + ((unsigned char)c << 1); } else { len = table[oldcode]->len; newentry->len = len + 1; newentry->str = PyMem_Malloc(newentry->len); if (newentry->str == NULL) break; memmove(newentry->str, table[oldcode]->str, len); newentry->str[len] = c; } table[table_len++] = newentry; } else { /* code is not in table */ /* newentry = newresult = table[oldcode] + table[oldcode][0] */ /* decoded.append(newresult); table.append(newentry) */ newresult = PyMem_Malloc(sizeof(struct BYTE_STRING)); newentry = newresult; newentry->ref = 2; if (oldcode < 256) { newentry->len = 2; newentry->str = table2 + 514*oldcode; } else { len = table[oldcode]->len; newentry->len = len + 1; newentry->str = PyMem_Malloc(newentry->len); if (newentry->str == NULL) break; memmove(newentry->str, table[oldcode]->str, len); newentry->str[len] = *table[oldcode]->str; } table[table_len++] = newentry; *(struct BYTE_STRING **)decoded_ptr++ = newresult; result_len += newresult->len; } } oldcode = code; /* increase bit-width if necessary */ switch (table_len) { case 511: bitw = 10; shr = 22; mask = 4290772992; break; case 1023: bitw = 11; shr = 21; mask = 4292870144; break; case 2047: bitw = 12; shr = 20; mask = 4293918720; } }