/* Process Motif ClientMessage */ void HandleMotifMessage(Display *dpy, XClientMessageEvent *event) { motif_drop_start_t info; drop_info_t *drop_info; Window dest_win; dest_win = event->window; info.message_type = event->data.b[0]; info.byte_order = event->data.b[1]; if (info.message_type & MOTIF_RECEIVER_BIT) { /* receiver message If initiator is Motif then forward it this message. */ if (event->window != proxy_win) XSendEvent(dpy, event->window, False, NoEventMask, (XEvent *) event); } else { /* initiator message */ if ((info.message_type & MOTIF_MESSAGE_TYPE_MASK)== MOTIF_DROP_START) { unsigned long site_id; Window event_win; XClientMessageEvent out_event; CARD32 olit_action; /* receiver will never be MOTIF because MOTIF receivers don't set the proxy field of RECEIVER_INFO atom */ info.flags = Swap2Bytes(info.byte_order, event->data.s[1]); /* since dropSiteStatus can't be determined in a short amount of time, always return a valid drop site */ info.flags &= MOTIF_DROP_SITE_STATUS_MASK; info.flags |= MOTIF_DROP_SITE_STATUS_VALID; info.time = Swap4Bytes(info.byte_order, event->data.l[1]); info.x = Swap2Bytes(info.byte_order, event->data.s[4]); info.y = Swap2Bytes(info.byte_order, event->data.s[5]); info.icc_handle = Swap4Bytes(info.byte_order, event->data.l[3]); info.src_window = Swap4Bytes(info.byte_order, event->data.l[4]); /* send a drop start ack here to give ourselves more time to process the drop because GetOlitDropSite or selection processing might take a long time */ info.message_type = event->data.b[0] |= MOTIF_RECEIVER_BIT; event->data.s[1] = Swap2Bytes(info.byte_order, info.flags); event->window = info.src_window; XSendEvent(dpy, event->window, False, NoEventMask, (XEvent *) event); /* get olit drop site */ GetOlitDropSite(dpy, dest_win, info.x, info.y, &site_id, &event_win); drop_info = NewDropInfo(); olit_action = ConvertMotifAction(info.flags); if (event_win && olit_action) { drop_info->source_handle = info.icc_handle; drop_info->time_stamp = info.time; out_event.type = ClientMessage; out_event.send_event = True; out_event.display = dpy; out_event.window = event_win; out_event.message_type = ATOM_SUN_DND_TRIGGER; out_event.format = 32; out_event.data.l[OLIT_DROP_SELECTION]= drop_info->proxy_handle; out_event.data.l[OLIT_DROP_TIME] = info.time; out_event.data.l[OLIT_DROP_COORDINATE] = (info.x << 16) | info.y; out_event.data.l[OLIT_DROP_SITE_ID] = site_id; out_event.data.l[OLIT_DROP_OPERATION] = olit_action; XSendEvent(dpy, out_event.window, False, NoEventMask, (XEvent *) &out_event); } else { /* tell motif initiator that the drop failed */ XConvertSelection(dpy, info.icc_handle, ATOM_MOTIF_FAILURE, None, proxy_win, info.time); } } } }
/* * A function to load a tga file and return the OpenGL texture object */ int LoadTgaImage(const char filename[],unsigned char** ppData,unsigned int* w,unsigned int* h,unsigned int* bpp) { /* * Create an instance of the struct to hold the tga file header */ tga_header header; /* * Create a file pointer called fp and attempt to open the file */ FILE *fp = fopen(filename,"rb"); /* * if the file pointer is equal to NULL, the file failed to open */ if(fp) { /* * A pointer to hold the memory location of allocated memory that * we will require in order to store the pixel data */ unsigned int i,j,k; /* * Read the file header */ fread(&header,1,sizeof(tga_header),fp); /* * Check the byte ordering of the computer to see if we have to swap any bytes . * It's that pesky MSB/LSB thing again.... */ if(CheckByteOrder()) { /* * Swap the 2byte variables from the tga file header so that they make * sense on a unix box... */ Swap2Bytes( (void*)&header.m_ColourMapOrigin ); Swap2Bytes( (void*)&header.m_ColourMapSize ); Swap2Bytes( (void*)&header.m_Xorigin ); Swap2Bytes( (void*)&header.m_Yorigin ); Swap2Bytes( (void*)&header.m_Width ); Swap2Bytes( (void*)&header.m_Height ); } *w = header.m_Width; *h = header.m_Height; /* skip the image identification field if present */ for( i=0; i!=header.m_ImageIdent; ++i ) { fgetc(fp); } /* store bytes per pixel */ *bpp = header.m_PixelIndexSize/8; /* * Determine the size (in bytes) of the pixel data size contained * in the file. width * height * 3 bytes per colour (RGB). * * Use malloc to allocate the required memory size */ *ppData = (unsigned char*)malloc( (*bpp) * header.m_Width * header.m_Height ); /* * Use assert to ensure that the allocation succeeded */ assert( *ppData != NULL); /* an 8bit colour mapped image */ if( header.m_ImageType == 1 ) { /* This pointer holds reference to the actual 8bit data */ unsigned char* tempptr = *ppData,*pd=0,*pData=0; /* number of bytes per row */ unsigned int rowsize = (header.m_ColourMapESize/8) * header.m_Width; /* allocate and then read in the colour map.... */ unsigned char* colourMap = (unsigned char*) malloc ( header.m_ColourMapSize * (header.m_ColourMapESize/8) ); /* check allocation */ assert( colourMap ); /* store the new bytes per pixel (as given by the colour map entry size) */ *bpp = ( header.m_ColourMapESize / 8 ); /* read colour map data */ fread( colourMap, header.m_ColourMapSize *(*bpp), 1, fp ); /* flip colour map from BGR to RGB */ BGR_TO_RGB( colourMap, header.m_ColourMapSize, *bpp ); /* read the data in one go, we'll flip it upside down when expanding the colour map data.... */ fread( tempptr, 1, header.m_Width * header.m_Height, fp ); /* allocate memory for the new expanded image data... */ *ppData = (unsigned char*) malloc( header.m_Height * rowsize ); assert( *ppData ); /* this pointer is used as an iterator */ pData = (*ppData); /* now going to run backwards through 8bit image and write it upside down when expanding the colour map */ for( i=0; i != header.m_Height; ++i ) { /* get a pointer to the data row */ pd = tempptr + ( (header.m_Height-i-1) * header.m_Width ); /* loop till the end of the row */ for( j=0; j != rowsize; ++pd ) { /* get pointer to actual colour in colour map */ unsigned char *col = &colourMap[ 3*(*pd) ]; /* get end of colour */ unsigned char *colend = col + *bpp; /* copy the colour over (3 or 4bytes probably...) */ for( ; col != colend; ++col, ++j, ++pData ) { /* copy colour from colour map into correct place in expanded image */ *pData = *col; } } } /* free up any data... */ free( tempptr ); free( colourMap ); } else /* uncompressed grey/RGB/RGBA data */ if( header.m_ImageType == 2 ) { /* number of bytes per row */ unsigned int rowsize = (*bpp) * header.m_Width; /* pointer to last row in image data */ unsigned char* pd = *ppData + (*bpp) * (header.m_Height-1) * header.m_Width; /* * read the pixel data from the file in rows cos tga files are upside down... */ for( i = 0; i < header.m_Height; ++i, pd -= rowsize ) { fread( pd, 1, rowsize, fp ); } /* don't bother flipping bytes if greyscale image */ if( *bpp != 1 ) { /* * the tga file stores pixel data as bgr values. OpenGL however requires * the data in RGB. Therefore we have to traverse the array and swap the * pixel data around abit. */ BGR_TO_RGB( (*ppData), header.m_Height * header.m_Width, *bpp ); } } else /* RLE colour mapped images */ if( header.m_ImageType == 9 ) { /* This pointer holds reference to the actual 8bit data */ /* unsigned char* tempptr = *ppData;*/ /* number of bytes per row */ unsigned int rowsize = (header.m_ColourMapESize/8) * header.m_Width; /* allocate and then read in the colour map.... */ unsigned char* colourMap = (unsigned char*) malloc ( header.m_ColourMapSize * (header.m_ColourMapESize/8) ); /* temporary iterator pointers */ unsigned char *pde,*pData; /* check allocation */ assert( colourMap ); /* store the new bytes per pixel (as given by the colour map entry size) */ *bpp = ( header.m_ColourMapESize / 8 ); /* read colour map data */ fread( colourMap, header.m_ColourMapSize * (*bpp), 1, fp ); /* flip colour map from BGR to RGB */ BGR_TO_RGB( colourMap, header.m_ColourMapSize, *bpp ); /* allocate memory for the uncompressed image... */ *ppData = (unsigned char*) malloc ( header.m_Height * header.m_Width * (*bpp) ); /* get ptr to first element */ pData = *ppData; /* get end pointer marker */ pde = pData + header.m_Height * header.m_Width * (*bpp); /* now the reading process begins!! */ while( pde != pData ) { unsigned char byte; fread( &byte, 1, 1, fp ); /* * if the flag is zero, then the count indicates a run of raw data */ if( (byte & 0x80) == 0 ) { byte++; for(j=0;j<byte; ++j) { unsigned char c = fgetc(fp); for( k = 0; k != *bpp; ++k, ++pData ) { *pData = colourMap[ (*bpp)*c + k ]; } } } /* * If the flag is one, then the count represents the amount of times that the next byte * is repeated. This is the RLE bit.... */ else { unsigned char c = fgetc(fp); byte -= 0x7F; for(j=0;j<byte; ++j) { for( k = 0; k != *bpp; ++k, ++pData ) { *pData = colourMap[ (*bpp)*c + k ]; } } } } /* turn the image upside down .... */ FlipDaImage( *ppData, rowsize, header.m_Height ); } else /* RLE compressed grey/RGB/RGBA images */ if( header.m_ImageType == 10 ) { /* This pointer holds reference to the actual 8bit data */ /* unsigned char* tempptr = *ppData;*/ /* number of bytes per row */ unsigned int rowsize = (*bpp) * header.m_Width; /* temporary iterator pointers */ unsigned char* pde,*pData; /* get ptr to first element */ pData = *ppData; /* get end pointer marker */ pde = pData + header.m_Height * header.m_Width * (*bpp); /* now the reading process begins!! */ while( pData < pde ) { unsigned char colour[10] = {0,0,0,0}; unsigned char byte; fread( &byte, 1, 1, fp ); /* * if the flag is zero, then the count indicates a run of raw data */ if( (byte & 0x80) == 0 ) { byte++; for(j=0;j<byte; ++j) { fread( colour, 1, *bpp, fp ); for( k = 0; k != *bpp; ++k, ++pData ) { *pData = colour[ k ]; } } } /* * If the flag is one, then the count represents the amount of times that the next byte * is repeated. This is the RLE bit.... */ else { byte -= 0x7F; fread( colour, 1, *bpp, fp ); for(j=0;j<byte; ++j) { for( k = 0; k != *bpp; ++k, ++pData ) { *pData = colour[ k ]; } } } } /* flip colour map from BGR to RGB */ BGR_TO_RGB( *ppData, header.m_Width*header.m_Height, *bpp ); /* turn the image upside down .... */ FlipDaImage( *ppData, rowsize, header.m_Height ); } /* unsupported image type... */ else { switch( header.m_ImageType ) { case 0: printf("[ERROR] The file %s contains no image data\n",filename); break; case 3: printf("[ERROR] The file %s contains black & white data which is unsupported\n",filename); break; case 11: printf("[ERROR] The file %s contains compressed black & white data which is unsupported\n",filename); break; case 32: printf("[ERROR] The file %s contains compressed color map data which is un-supported\n",filename); break; case 33: printf("[ERROR] The file %s contains compressed color map data which is un-supported (4pass quad tree process)\n",filename); break; default: printf("[ERROR] The file %s does not appear to be valid\n",filename); break; } } /* * close the file */ fclose(fp); return 1; } return 0; }