2 * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3 * Copyright (c) 1999, 2000 Alex Holden <alex@linuxhacker.org>
4 * Copyright (c) 1991 David I. Bell
5 * Copyright (c) 2000 Vidar Hokstad
6 * Copyright (c) 2000 Morten Rolland <mortenro@screenmedia.no>
8 * Permission is granted to use, distribute, or modify this source,
9 * provided that this copyright notice remains intact.
11 * Client routines to do graphics with windows and graphics contexts.
13 * Rewritten heavily for speed by Greg Haerr
15 * Whenever you add a new API entry point, please comment it in the same way
16 * as the rest of the functions in this file. Also add your functions to the
17 * appropriate section(s) in doc/nano-X/nano-X-sections.txt and regenerate the
18 * documentation by running make in the doc/nano-X/ directory. If you do not
19 * have the necessary tools (gtk-doc and the docbook-tools) to rebuild the
20 * documentation, just skip that step and we will do it for you.
31 #if HAVE_SHAREDMEM_SUPPORT
32 #include <sys/types.h>
37 #include <sys/socket.h>
39 #include <linuxmt/na.h>
40 #include <linuxmt/time.h>
42 #include <netinet/in.h>
43 #include <sys/select.h>
44 #include <cyg/kernel/kapi.h>
45 #define _NO_SVR_MAPPING
46 #define getpid() ((int)cyg_thread_self())
53 #include <sys/select.h>
61 #define GR_CLOSE_FIX 1 /* dirty hack attempts to fix GrClose hang bug*/
63 #define SHM_BLOCK_SIZE 4096
66 /* exported global data */
67 int nxSocket = -1; /* The network socket descriptor */
68 #if HAVE_SHAREDMEM_SUPPORT
69 char * nxSharedMem = 0; /* Address of shared memory segment*/
70 static int nxSharedMemSize; /* Size in bytes of shared mem segment*/
73 static int regfdmax = -1; /* GrRegisterInput globals*/
74 static fd_set regfdset;
76 /* readable error strings*/
77 char *nxErrorStrings[] = {
81 static EVENT_LIST * evlist;
84 * The following is the user defined function for handling errors.
85 * If this is not set, then the default action is to close the connection
86 * to the server, describe the error, and then exit. This error function
87 * will only be called when the client asks for events.
89 static GR_FNCALLBACKEVENT ErrorFunc = GrDefaultErrorHandler;
93 * eCos uses a thread data pointer to store all statics in...
95 int ecos_nanox_client_data_index = CYGNUM_KERNEL_THREADS_DATA_MAX;
97 /* readable error strings*/
98 char *nxErrorStrings[] = {
104 * Queue an event in FIFO for later retrieval.
107 QueueEvent(GR_EVENT *ep)
110 EVENT_LIST * prevelp;
111 ACCESS_PER_THREAD_DATA()
113 elp = malloc(sizeof(EVENT_LIST));
118 /* add as last entry on list*/
124 while (prevelp->next)
125 prevelp = prevelp->next;
131 * Retrieve first event in FIFO event queue.
134 GetNextQueuedEvent(GR_EVENT *ep)
136 ACCESS_PER_THREAD_DATA()
138 evlist = evlist->next;
142 * Read n bytes of data from the server into block *b. Make sure the data
143 * you are about to read are actually of the correct type - e.g. make a
144 * check for the first block of data you read as a response to a command
145 * with the Typed version of this function. Returns 0 on success or -1 on
148 static int GrReadBlock(void *b, int n)
152 ACCESS_PER_THREAD_DATA()
157 while(v < ((char *) b + n)) {
158 i = read(nxSocket, v, ((char *) b + n - v));
161 /* We should maybe produce an event here,
164 EPRINTF("nxclient: lost connection to Nano-X "
168 if ( errno == EINTR || errno == EAGAIN )
171 EPRINTF("nxclient: bad readblock %d\n", i);
181 * Read a byte of data from the server.
183 static int GrReadByte()
187 if(GrReadBlock(&c, 1) == -1)
193 * Check if this is a CLIENT_DATA event, in which case we need to read the
194 * data for the event into a buffer and set the event data pointer to the
195 * address of it (or NULL if the malloc() fails). We also don't try to read
196 * any data if datalen is 0.
198 static void GrCheckForClientData(GR_EVENT *evp)
200 GR_EVENT_CLIENT_DATA *event;
202 if(evp->type == GR_EVENT_TYPE_CLIENT_DATA) {
203 event = (GR_EVENT_CLIENT_DATA *)evp;
204 if(!event->datalen) {
208 if(!(event->data = malloc(event->datalen))) return;
209 GrReadBlock(event->data, event->datalen);
214 * Check if the data we are about to read is of the correct type. This
215 * must be done in order to avoid reading an event as part of the response
216 * from the server to a command that requires a reply.
218 static int GrCheckBlockType(short packettype)
223 while (GrReadBlock(&b,sizeof(b)) != -1) {
227 if (b == GrNumGetNextEvent) {
228 /*EPRINTF("nxclient %d: Storing event (expected %d)\n",
229 getpid(), packettype);*/
232 /* We only need to handle one event, since the next
233 * event won't arrive until the next GrPrepareSelect()
234 * has been called, and by then we have already
235 * handled this event in GrServiceSelect(). If
236 * GrPrepareSelect() is never called, then we should
237 * never get here either, so that is cool too.
239 GrReadBlock(&storedevent_data,
240 sizeof(storedevent_data));
241 GrCheckForClientData(&storedevent_data);
244 /* read event and queue it for later processing*/
245 GrReadBlock(&event, sizeof(event));
248 EPRINTF("nxclient %d: Wrong packet type %d "
249 "(expected %d)\n", getpid(),b, packettype);
252 EPRINTF("nxclient %d: Corrupted packet\n", getpid());
257 * Actually read a response from the server, much like the GrReadBlock but
258 * make sure the response is of the right kind, e.g. store the event that
259 * may have sneaked into the stream.
261 static int GrTypedReadBlock(void *b, int n, int type)
265 r = GrCheckBlockType(type);
268 return GrReadBlock(b,n);
272 * Check if the passed event is an error event, and call the error handler if
273 * there is one. After calling the handler (if it returns), the event type is
274 * set to a non-event so that we don't return an error event through the
275 * GetEvent() mechanism. This solution is simpler than creating a client-side
279 CheckErrorEvent(GR_EVENT *ep)
281 ACCESS_PER_THREAD_DATA()
283 if (ep->type == GR_EVENT_TYPE_ERROR) {
285 /* call error handler*/
288 /* then convert to null event*/
289 ep->type = GR_EVENT_TYPE_NONE;
297 * Flush the message buffer of any messages it may contain.
307 * @Returns: the fd of the connection to the server or -1 on failure
309 * Open a connection to the graphics server.
319 struct sockaddr_na name;
320 #define ADDR_FAM AF_NANO
321 #elif defined(__ECOS)
322 struct sockaddr_in name;
323 #define ADDR_FAM AF_INET
325 struct sockaddr_un name;
326 #define ADDR_FAM AF_UNIX
328 ACCESS_PER_THREAD_DATA()
330 if (nxSocket == -1) {
331 if((nxSocket = socket(ADDR_FAM, SOCK_STREAM, 0)) == -1) {
340 name.sun_family = AF_NANO;
341 name.sun_no = GR_NUMB_SOCKET;
342 size = sizeof(struct sockaddr_na);
343 #elif defined(__ECOS)
344 name.sin_family = AF_INET;
345 name.sin_port = htons(6600); /* Nano-X server port*/
346 name.sin_len = sizeof(name);
347 name.sin_addr.s_addr = inet_addr("127.0.0.1"); /* Loopback address*/
348 size = sizeof(struct sockaddr_in);
350 name.sun_family = AF_UNIX;
351 strcpy(name.sun_path, GR_NAMED_SOCKET);
352 size = (offsetof(struct sockaddr_un, sun_path) +
353 strlen(name.sun_path) + 1);
357 * Try to open the connection for up to a second,
358 * waiting 1/10 second between attempts.
360 for (tries=1; tries<=10; ++tries) {
363 ret = connect(nxSocket, (struct sockaddr *) &name, size);
367 req.tv_nsec = 100000000L;
368 nanosleep(&req, NULL);
369 EPRINTF("nxclient: retry connect attempt %d\n", tries);
378 * By Performing the 'GrOpen' without allocating a buffer, just
379 * shuffeling the struct over the wire, we can postpone the
380 * allocation of the client size command buffer, which will never be
381 * allocated if the first command after GrOpen() is
382 * GrReqShmCmds() which allocates a replacement shared memory
384 * So: Calling GrReqShmCmds() right after GrOpen will prevent the
385 * traditional command queue buffer from being allocated from
386 * the process heap - and only the shared memory segment is
389 req.reqType = GrNumOpen;
391 req.length = sizeof(req);
392 /* associate the process ID with the client*/
395 nxWriteSocket((char *)&req,sizeof(req));
401 mySignalhandler(int sig)
403 if (sig == SIGALRM) {
404 printf("Oops! nxFlushReq() timed out, cowardly chickening "
414 * Close the graphics device, flushing any waiting messages.
416 /* Vladimir Cotfas: hang in GrFlush() --> nxFlushReq(0L,1); */
420 ACCESS_PER_THREAD_DATA()
422 /* allow 1 second to flush*/
423 void * oldSignalHandler = signal(SIGALRM, mySignalhandler);
430 signal(SIGALRM, oldSignalHandler);
437 * GrDefaultErrorHandler:
438 * @ep: the error event structure
440 * The default error handler which is called when the server reports an error
441 * event and the client hasn't set up a handler of it's own.
443 * Generates a human readable error message on stderr describing what error
444 * occurred and what function it occured in, then exits.
447 GrDefaultErrorHandler(GR_EVENT *ep)
449 if (ep->type == GR_EVENT_TYPE_ERROR) {
450 EPRINTF("nxclient %d: Error (%s) ", getpid(), ep->error.name);
451 EPRINTF(nxErrorStrings[ep->error.code], ep->error.id);
459 * @fncb: the function to call to handle error events
460 * @Returns: the address of the previous error handler
462 * Sets an error handling routine that will be called on any errors from
463 * the server (assuming the client has asked to receive them). If zero is
464 * used as the argument, errors will be returned as regular events instead.
467 GrSetErrorHandler(GR_FNCALLBACKEVENT fncb)
469 ACCESS_PER_THREAD_DATA()
470 GR_FNCALLBACKEVENT orig = ErrorFunc;
478 * @msecs: number of milliseconds to delay
480 * This function suspends execution of the program for the specified
481 * number of milliseconds.
484 GrDelay(GR_TIMEOUT msecs)
486 struct timeval timeval;
488 timeval.tv_sec = msecs / 1000;
489 timeval.tv_usec = msecs % 1000;
490 select(0, NULL, NULL, NULL, &timeval);
495 * @sip: pointer to a GR_SCREEN_INFO structure
497 * Fills in the specified GR_SCREEN_INFO structure.
500 GrGetScreenInfo(GR_SCREEN_INFO *sip)
502 AllocReq(GetScreenInfo);
503 GrTypedReadBlock(sip, sizeof(GR_SCREEN_INFO),GrNumGetScreenInfo);
508 * @index: an index into the server's colour look up table
509 * @Returns: the colour found at the specified index
511 * Returns the colour at the specified index into the server's colour look
512 * up table. The colours in the table are those with names like
513 * "GR_COLOR_DESKTOP", "GR_COLOR_ACTIVECAPTION", "GR_COLOR_APPWINDOW", etc.
514 * as listed in nano-X.h
517 GrGetSysColor(int index)
519 nxGetSysColorReq *req;
522 req = AllocReq(GetSysColor);
524 if(GrTypedReadBlock(&color, sizeof(color),GrNumGetSysColor) == -1)
531 * @fontno: the font ID number
532 * @fip: pointer to a GR_FONT_INFO structure
534 * Fills in the specified GR_FONT_INFO structure with information regarding
535 * the specified font.
538 GrGetFontInfo(GR_FONT_ID fontno, GR_FONT_INFO *fip)
540 nxGetFontInfoReq *req;
542 req = AllocReq(GetFontInfo);
543 req->fontid = fontno;
544 GrTypedReadBlock(fip, sizeof(GR_FONT_INFO),GrNumGetFontInfo);
549 * @gc: a graphics context
550 * @gcip: pointer to a GR_GC_INFO structure
552 * Fills in the specified GR_GC_INFO structure with information regarding the
553 * specified graphics context.
555 void GrGetGCInfo(GR_GC_ID gc, GR_GC_INFO *gcip)
559 req = AllocReq(GetGCInfo);
561 GrTypedReadBlock(gcip, sizeof(GR_GC_INFO),GrNumGetGCInfo);
566 * @gc: the graphics context
567 * @str: pointer to a text string
568 * @count: the length of the string
569 * @flags: text rendering flags (GR_TF*)
570 * @retwidth: pointer to the variable the width will be returned in
571 * @retheight: pointer to the variable the height will be returned in
572 * @retbase: pointer to the variable the baseline height will be returned in
574 * Calculates the dimensions of the specified text string using the current font
575 * and flags in the specified graphics context. The count argument can be -1
576 * if the string is null terminated.
578 void GrGetGCTextSize(GR_GC_ID gc, void *str, int count, int flags,
579 GR_SIZE *retwidth, GR_SIZE *retheight, GR_SIZE *retbase)
581 nxGetGCTextSizeReq *req;
584 if(count == -1 && (flags&MWTF_PACKMASK) == MWTF_ASCII)
585 count = strlen((char *)str);
587 size = nxCalcStringBytes(str, count, flags);
589 req = AllocReqExtra(GetGCTextSize, size);
592 memcpy(GetReqData(req), str, size);
593 GrTypedReadBlock(retwidth, sizeof(*retwidth),GrNumGetGCTextSize);
594 GrReadBlock(retheight, sizeof(*retheight));
595 GrReadBlock(retbase, sizeof(*retbase));
600 * @fd: the file descriptor to monitor
602 * Register an extra file descriptor to monitor in the main select() call.
603 * An event will be returned when the fd has data waiting to be read if that
604 * event has been selected for.
607 GrRegisterInput(int fd)
609 ACCESS_PER_THREAD_DATA()
613 FD_SET(fd, ®fdset);
614 if (fd > regfdmax) regfdmax = fd + 1;
619 * @fd: the file descriptor to stop monitoring
621 * Stop monitoring a file descriptor (previously registered with
622 * GrRegisterInput()) in the main select() call.
625 GrUnregisterInput(int fd)
628 ACCESS_PER_THREAD_DATA()
630 /* unregister all inputs if fd is -1 */
637 FD_CLR(fd, ®fdset);
638 /* recalculate the max file descriptor */
639 for (i = 0, max = regfdmax, regfdmax = -1; i < max; i++)
640 if (FD_ISSET(i, ®fdset))
646 * @maxfd: pointer to a variable which the highest in use fd will be written to
647 * @rfdset: pointer to the file descriptor set structure to use
649 * Prepare for a GrServiceSelect function by asking the server to send the next
650 * event but not waiting around for it to arrive and initialising the
651 * specified fd_set structure with the client/server socket descriptor and any
652 * previously registered external file descriptors. Also compares the current
653 * contents of maxfd, the client/server socket descriptor, and the previously
654 * registered external file descriptors, and returns the highest of them in
658 GrPrepareSelect(int *maxfd,void *rfdset)
660 fd_set *rfds = rfdset;
663 ACCESS_PER_THREAD_DATA()
665 AllocReq(GetNextEvent);
668 FD_SET(nxSocket, rfds);
669 if(nxSocket > *maxfd)
672 /* handle registered input file descriptors*/
673 for (fd = 0; fd < regfdmax; fd++) {
674 if (FD_ISSET(fd, ®fdset)) {
676 if (fd > *maxfd) *maxfd = fd;
683 * @rfdset: pointer to the file descriptor set to monitor
684 * @fncb: pointer to the function to call when an event needs handling
686 * Used by GrMainLoop() to call the specified callback function when an
687 * event arrives or there is data waiting on an external fd specified by
691 GrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb)
693 fd_set * rfds = rfdset;
697 ACCESS_PER_THREAD_DATA()
699 /* Clean out any event that might have arrived while waiting
700 * for other data, for instance by doing Nano-X requests
701 * between GrPrepareSelect() and GrServiceSelect(), or when
702 * an event is generated in Nano-X at the same time as the
703 * client wakes up for some reason and calls Nano-X functions.
706 /*DPRINTF("nxclient: Handling queued event\n");*/
707 GetNextQueuedEvent(&ev);
708 CheckErrorEvent(&ev);
712 if(FD_ISSET(nxSocket, rfds)) {
713 GrTypedReadBlock(&ev, sizeof(ev),GrNumGetNextEvent);
714 GrCheckForClientData(&ev);
715 CheckErrorEvent(&ev);
720 /* check for input on registered file descriptors */
721 for (fd = 0; fd < regfdmax; fd++) {
722 if (FD_ISSET(fd, ®fdset) && FD_ISSET(fd, rfds)) {
723 ev.type = GR_EVENT_TYPE_FDINPUT;
734 * A convenience function which calls the specified callback function whenever
735 * an event arrives or there is data to be read on a file descriptor previously
736 * specified by GrRegisterInput(). Currently never returns.
739 GrMainLoop(GR_FNCALLBACKEVENT fncb)
746 GrPrepareSelect(&setsize, &rfds);
747 if(select(setsize+1, &rfds, NULL, NULL, NULL) > 0)
748 GrServiceSelect(&rfds, fncb);
754 * @ep: pointer to the GR_EVENT structure to return the event in
756 * Gets the next event from the event queue and places it in the specified
757 * GR_EVENT structure. If the queue is currently empty, we sleep until the
758 * next event arrives from the server or input is read on a file descriptor
759 * previously specified by GrRegisterInput().
762 GrGetNextEvent(GR_EVENT *ep)
764 GrGetNextEventTimeout(ep, 0L);
768 * GrGetNextEventTimeout:
769 * @ep: pointer to the GR_EVENT structure to return the event in
770 * @timeout: the number of milliseconds to wait before timing out
772 * Gets the next event from the event queue and places it in the specified
773 * GR_EVENT structure. If the queue is currently empty, we sleep until the
774 * next event arrives from the server, input is read on a file descriptor
775 * previously specified by GrRegisterInput(), or a timeout occurs. Note
776 * that a value of 0 for the timeout parameter doesn't mean "timeout after 0
777 * milliseconds" but is in fact a magic number meaning "never time out".
780 GrGetNextEventTimeout(GR_EVENT *ep, GR_TIMEOUT timeout)
786 ACCESS_PER_THREAD_DATA()
789 /*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/
790 GetNextQueuedEvent(ep);
797 * This will cause a GrGetNextEvent to be sent down the wire.
798 * If we timeout before the server responds, and then
799 * call this procedure again, and the server has more than
800 * one event waiting for this process, then more than one
801 * event will be written on the socket by the server. At
802 * that point, a single stored event won't work, and the
803 * client needs an event queue.
805 GrPrepareSelect(&setsize, &rfds);
807 to.tv_sec = timeout / 1000;
808 to.tv_usec = (timeout % 1000) * 1000;
811 if((e = select(setsize+1, &rfds, NULL, NULL, timeout ? &to : NULL))>0) {
814 if(FD_ISSET(nxSocket, &rfds)) {
816 * This will never be GR_EVENT_NONE with the current
819 GrTypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent);
820 GrCheckForClientData(ep);
825 /* check for input on registered file descriptors */
826 for (fd = 0; fd < regfdmax; fd++) {
827 if (FD_ISSET(fd, ®fdset) && FD_ISSET(fd, &rfds)) {
828 ep->type = GR_EVENT_TYPE_FDINPUT;
836 * Timeout has occured. We currently return a timeout event
837 * regardless of whether the client has selected for it.
839 ep->type = GR_EVENT_TYPE_TIMEOUT;
842 ep->type = GR_EVENT_TYPE_NONE;
844 EPRINTF("nxclient: select failed\n");
853 * @ep: pointer to the GR_EVENT structure to return the event in
855 * Gets the next event from the event queue if there is one, or returns
856 * immediately with an event type of GR_EVENT_TYPE_NONE if it is empty.
859 GrCheckNextEvent(GR_EVENT *ep)
861 ACCESS_PER_THREAD_DATA()
863 /*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/
864 GetNextQueuedEvent(ep);
869 AllocReq(CheckNextEvent);
870 GrTypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent);
871 GrCheckForClientData(ep);
877 * @ep: pointer to the GR_EVENT structure to return the event in
878 * @Returns: 1 if an event was returned, or 0 if the queue was empty
880 * Fills in the specified event structure with a copy of the next event on the
881 * queue, without actually removing it from the queue. An event type of
882 * GR_EVENT_TYPE_NONE is given if the queue is empty.
885 GrPeekEvent(GR_EVENT *ep)
888 ACCESS_PER_THREAD_DATA()
897 GrTypedReadBlock(ep, sizeof(*ep),GrNumPeekEvent);
898 GrCheckForClientData(ep);
906 * @ep: pointer to the GR_EVENT structure to return the event in
908 * Wait until an event is available for a client, and then peek at it.
911 GrPeekWaitEvent(GR_EVENT *ep)
914 ACCESS_PER_THREAD_DATA()
922 /* no events, wait for next event*/
925 /* add event back on head of list*/
926 elp = malloc(sizeof(EVENT_LIST));
938 * @wid: the ID of the window to set the event mask of
939 * @eventmask: a bit field specifying the desired event mask
941 * Select the event types which should be returned for the specified window.
944 GrSelectEvents(GR_WINDOW_ID wid, GR_EVENT_MASK eventmask)
947 nxSelectEventsReq *req;
949 req = AllocReq(SelectEvents);
951 req->eventmask = eventmask;
956 * @parent: the ID of the parent window
957 * @x: the X coordinate of the new window relative to the parent window
958 * @y: the Y coordinate of the new window relative to the parent window
959 * @width: the width of the new window
960 * @height: the height of the new window
961 * @bordersize: the width of the window border
962 * @background: the colour of the window background
963 * @bordercolor: the colour of the window border
964 * @Returns: the ID of the newly created window
966 * Create a new window with the specified parent and window attributes.
969 GrNewWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width,
970 GR_SIZE height, GR_SIZE bordersize, GR_COLOR background,
971 GR_COLOR bordercolor)
976 req = AllocReq(NewWindow);
977 req->parentid = parent;
981 req->height = height;
982 req->backgroundcolor = background;
983 req->bordercolor = bordercolor;
984 req->bordersize = bordersize;
985 if(GrTypedReadBlock(&wid, sizeof(wid),GrNumNewWindow) == -1)
993 * @width: the width of the pixmap
994 * @height: the height of the pixmap
995 * @addr: currently unused in client/server mode
996 * @Returns: the ID of the newly created pixmap
998 * Create a new server side pixmap (an offscreen drawing area which can be
999 * copied into a window using a GrCopyArea call) of the specified width and
1002 /* FIXME: Add support for shared memory... */
1004 GrNewPixmap(GR_SIZE width, GR_SIZE height, void *addr)
1006 nxNewPixmapReq *req;
1009 req = AllocReq(NewPixmap);
1011 req->height = height;
1012 if(GrTypedReadBlock(&wid, sizeof(wid), GrNumNewPixmap) == -1)
1019 * @parent: the ID of the window to use as the parent of the new window
1020 * @x: the X coordinate of the new window relative to the parent window
1021 * @y: the Y coordinate of the new window relative to the parent window
1022 * @width: the width of the new window
1023 * @height: the height of the new window
1024 * @Returns: the ID of the newly created window
1026 * Create a new input-only window with the specified dimensions which is a
1027 * child of the specified parent window.
1030 GrNewInputWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width,
1033 nxNewInputWindowReq *req;
1036 req = AllocReq(NewInputWindow);
1037 req->parentid = parent;
1041 req->height = height;
1042 if(GrTypedReadBlock(&wid, sizeof(wid), GrNumNewInputWindow) == -1)
1049 * @wid: the ID of the window to destroy
1051 * Recursively unmaps and frees the data structures associated with the
1052 * specified window and all of its children.
1055 GrDestroyWindow(GR_WINDOW_ID wid)
1057 nxDestroyWindowReq *req;
1059 req = AllocReq(DestroyWindow);
1060 req->windowid = wid;
1065 * @wid: the ID of the window to retrieve information about
1066 * @infoptr: pointer to a GR_WINDOW_INFO structure to return the information in
1068 * Fills in a GR_WINDOW_INFO structure with information regarding the window
1069 * with the specified window ID.
1072 GrGetWindowInfo(GR_WINDOW_ID wid, GR_WINDOW_INFO *infoptr)
1074 nxGetWindowInfoReq *req;
1076 req = AllocReq(GetWindowInfo);
1077 req->windowid = wid;
1078 GrTypedReadBlock(infoptr, sizeof(GR_WINDOW_INFO), GrNumGetWindowInfo);
1083 * @Returns: the ID of the newly created graphics context or 0 on error
1085 * Creates a new graphics context structure and returns the ID used to refer
1086 * to it. The structure is initialised with a set of default parameters.
1094 if(GrTypedReadBlock(&gc, sizeof(gc),GrNumNewGC) == -1)
1101 * @gc: the already existing graphics context to copy the parameters from
1102 * @Returns: the ID of the newly created graphics context or 0 on error
1104 * Creates a new graphics context structure and fills it in with the values
1105 * from the specified already existing graphics context.
1108 GrCopyGC(GR_GC_ID gc)
1113 req = AllocReq(CopyGC);
1115 if(GrTypedReadBlock(&newgc, sizeof(newgc),GrNumCopyGC) == -1)
1122 * @gc: the ID of the graphics context structure to destroy
1124 * Destroys the graphics context structure with the specified ID.
1127 GrDestroyGC(GR_GC_ID gc)
1129 nxDestroyGCReq *req;
1131 req = AllocReq(DestroyGC);
1137 * @Returns: the ID of the newly created region
1139 * Creates a new region structure and returns the ID used to refer to it.
1140 * The structure is initialised with a set of default parameters.
1145 GR_REGION_ID region;
1147 AllocReq(NewRegion);
1148 if(GrTypedReadBlock(®ion, sizeof(region),GrNumNewRegion) == -1)
1155 * @region: the ID of the region structure to destroy
1157 * Destroys the region structure with the specified ID.
1160 GrDestroyRegion(GR_REGION_ID region)
1162 nxDestroyRegionReq *req;
1164 req = AllocReq(DestroyRegion);
1165 req->regionid = region;
1169 * GrUnionRectWithRegion:
1170 * @region: the ID of the region to modify
1171 * @rect: a pointer to the rectangle to add to the region
1173 * Makes a union of the specified region and the specified rectangle and
1174 * places the result back in the source region.
1177 GrUnionRectWithRegion(GR_REGION_ID region, GR_RECT *rect)
1179 nxUnionRectWithRegionReq *req;
1181 req = AllocReq(UnionRectWithRegion);
1183 memcpy(&req->rect, rect, sizeof(*rect));
1184 req->regionid = region;
1189 * @dst_rgn: the ID of the destination region
1190 * @src_rgn1: the ID of the first source region
1191 * @src_rgn2: the ID of the second source region
1193 * Makes a union of the specified source regions and places the result in the
1194 * specified destination region.
1197 GrUnionRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
1198 GR_REGION_ID src_rgn2)
1200 nxUnionRegionReq *req;
1202 req = AllocReq(UnionRegion);
1203 req->regionid = dst_rgn;
1204 req->srcregionid1 = src_rgn1;
1205 req->srcregionid2 = src_rgn2;
1210 * @dst_rgn: the ID of the destination region
1211 * @src_rgn1: the ID of the first source region
1212 * @src_rgn2: the ID of the second source region
1214 * Subtracts the second source region from the first source region and places
1215 * the result in the specified destination region.
1218 GrSubtractRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
1219 GR_REGION_ID src_rgn2)
1221 nxSubtractRegionReq *req;
1223 req = AllocReq(SubtractRegion);
1224 req->regionid = dst_rgn;
1225 req->srcregionid1 = src_rgn1;
1226 req->srcregionid2 = src_rgn2;
1231 * @dst_rgn: the ID of the destination region
1232 * @src_rgn1: the ID of the first source region
1233 * @src_rgn2: the ID of the second source region
1235 * Performs a logical exclusive OR operation on the specified source regions
1236 * and places the result in the destination region. The destination region
1237 * will contain only the parts of the source regions which do not overlap.
1240 GrXorRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
1241 GR_REGION_ID src_rgn2)
1243 nxXorRegionReq *req;
1245 req = AllocReq(XorRegion);
1246 req->regionid = dst_rgn;
1247 req->srcregionid1 = src_rgn1;
1248 req->srcregionid2 = src_rgn2;
1252 * GrIntersectRegion:
1253 * @dst_rgn: the ID of the destination region
1254 * @src_rgn1: the ID of the first source region
1255 * @src_rgn2: the ID of the second source region
1257 * Calculates the intersection of the two specified source regions and places
1258 * the result in the specified destination region. The destination region
1259 * will contain only the parts of the source regions which overlap each other.
1262 GrIntersectRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
1263 GR_REGION_ID src_rgn2)
1265 nxIntersectRegionReq *req;
1267 req = AllocReq(IntersectRegion);
1268 req->regionid = dst_rgn;
1269 req->srcregionid1 = src_rgn1;
1270 req->srcregionid2 = src_rgn2;
1275 * @gc: the ID of the graphics context to set the clip mask of
1276 * @region: the ID of the region to use as the clip mask
1278 * Sets the clip mask of the specified graphics context to the specified
1279 * region. Subsequent drawing operations using this graphics context will not
1280 * draw outside the specified region. The region ID can be set to 0 to remove
1281 * the clipping region from the specified graphics context.
1284 GrSetGCRegion(GR_GC_ID gc, GR_REGION_ID region)
1286 nxSetGCRegionReq *req;
1288 req = AllocReq(SetGCRegion);
1290 req->regionid = region;
1294 * GrSetGCClipOrigin:
1295 * @gc: the ID of the graphics context with user clip region
1296 * @xoff: new X offset of user clip region
1297 * @xoff: new Y offset of user clip region
1299 * Sets the X,Y origin of the user clip region in the specified
1303 GrSetGCClipOrigin(GR_GC_ID gc, int x, int y)
1305 nxSetGCClipOriginReq *req;
1307 req = AllocReq(SetGCClipOrigin);
1315 * @region: the ID of the region to examine
1316 * @x: the X coordinate of the point to test for
1317 * @y: the Y coordinate of the point to test for
1318 * @Returns: True if the point is within the region, or False otherwise
1320 * Tests whether the specified point is within the specified region, and
1321 * then returns either True or False depending on the result.
1324 GrPointInRegion(GR_REGION_ID region, GR_COORD x, GR_COORD y)
1326 nxPointInRegionReq *req;
1329 req = AllocReq(PointInRegion);
1330 req->regionid = region;
1333 if(GrTypedReadBlock(&ret_value, sizeof(ret_value),
1334 GrNumPointInRegion) == -1)
1341 * @region: the ID of the region to examine
1342 * @x: the X coordinates of the rectangle to test
1343 * @y: the Y coordinates of the rectangle to test
1344 * @w: the width of the rectangle to test
1345 * @h: the height of the rectangle to test
1346 * @Returns: GR_RECT_PARTIN, GR_RECT_ALLIN, or GR_RECT_OUT
1348 * Tests whether the specified rectangle is contained within the specified
1349 * region. Returns GR_RECT_OUT if it is not inside it at all, GR_RECT_ALLIN
1350 * if it is completely contained within the region, or GR_RECT_PARTIN if
1351 * it is partially contained within the region.
1354 GrRectInRegion(GR_REGION_ID region, GR_COORD x, GR_COORD y, GR_COORD w,
1357 nxRectInRegionReq *req;
1358 unsigned short ret_value;
1360 req = AllocReq(RectInRegion);
1361 req->regionid = region;
1366 if(GrTypedReadBlock(&ret_value, sizeof(ret_value),
1367 GrNumRectInRegion) == -1)
1369 return (int)ret_value;
1374 * @region: the ID of the region to examine
1375 * @Returns: GR_TRUE if the region is empty, or GR_FALSE if it is not
1377 * Determines whether the specified region is empty, and returns GR_TRUE
1378 * if it is, or GR_FALSE otherwise.
1381 GrEmptyRegion(GR_REGION_ID region)
1383 nxEmptyRegionReq *req;
1386 req = AllocReq(EmptyRegion);
1387 req->regionid = region;
1388 if(GrTypedReadBlock(&ret_value, sizeof(ret_value),
1389 GrNumEmptyRegion) == -1)
1396 * @rgn1: the ID of the first region to examine
1397 * @rgn2: the ID of the second region to examine
1398 * @Returns: GR_TRUE if the regions are equal, or GR_FALSE otherwise
1400 * Determines whether the specified regions are identical, and returns GR_TRUE
1401 * if it is, or GR_FALSE otherwise.
1404 GrEqualRegion(GR_REGION_ID rgn1, GR_REGION_ID rgn2)
1406 nxEqualRegionReq *req;
1409 req = AllocReq(EqualRegion);
1410 req->region1 = rgn1;
1411 req->region2 = rgn2;
1412 if(GrTypedReadBlock(&ret_value, sizeof(ret_value),
1413 GrNumEqualRegion) == -1)
1420 * @region: the ID of the region to offset
1421 * @dx: the distance to offset the region by in the X axis
1422 * @dy: the distance to offset the region by in the Y axis
1424 * Offsets the specified region by the specified distance.
1427 GrOffsetRegion(GR_REGION_ID region, GR_SIZE dx, GR_SIZE dy)
1429 nxOffsetRegionReq *req;
1431 req = AllocReq(OffsetRegion);
1432 req->region = region;
1439 * @region: the ID of the region to get the bounding box of
1440 * @rect: pointer to a rectangle structure
1441 * @Returns: the region type
1443 * Fills in the specified rectangle structure with a bounding box that would
1444 * completely enclose the specified region, and also returns the type of the
1448 GrGetRegionBox(GR_REGION_ID region, GR_RECT *rect)
1450 nxGetRegionBoxReq *req;
1451 unsigned short ret_value;
1455 req = AllocReq(GetRegionBox);
1456 req->regionid = region;
1457 if(GrTypedReadBlock(rect, sizeof(*rect), GrNumGetRegionBox) == -1)
1459 if(GrTypedReadBlock(&ret_value, sizeof(ret_value),
1460 GrNumGetRegionBox) == -1)
1466 * GrNewPolygonRegion:
1467 * @mode: the polygon mode to use (GR_POLY_EVENODD or GR_POLY_WINDING)
1468 * @count: the number of points in the polygon
1469 * @points: pointer to an array of point structures describing the polygon
1470 * @Returns: the ID of the newly allocated region structure, or 0 on error
1472 * Creates a new region structure, fills it with the region described by the
1473 * specified polygon, and returns the ID used to refer to it.
1476 GrNewPolygonRegion(int mode, GR_COUNT count, GR_POINT *points)
1478 nxNewPolygonRegionReq *req;
1480 GR_REGION_ID region;
1483 return GrNewRegion();
1488 size = (long)count * sizeof(GR_POINT);
1489 req = AllocReqExtra(NewPolygonRegion, size);
1491 /* FIXME: unportable method, depends on sizeof(int) in GR_POINT*/
1492 memcpy(GetReqData(req), points, size);
1494 if(GrTypedReadBlock(®ion, sizeof(region),
1495 GrNumNewPolygonRegion) == -1)
1502 * @wid: the ID of the window to map
1504 * Recursively maps (makes visible) the specified window and all of the
1505 * child windows which have a sufficient map count. The border and background
1506 * of the window are painted, and an exposure event is generated for the
1507 * window and every child which becomes visible.
1510 GrMapWindow(GR_WINDOW_ID wid)
1512 nxMapWindowReq *req;
1514 req = AllocReq(MapWindow);
1515 req->windowid = wid;
1520 * @wid: the ID of the window to unmap
1522 * Recursively unmaps (makes invisible) the specified window and all of the
1526 GrUnmapWindow(GR_WINDOW_ID wid)
1528 nxUnmapWindowReq *req;
1530 req = AllocReq(UnmapWindow);
1531 req->windowid = wid;
1536 * @wid: the ID of the window to raise
1538 * Places the specified window at the top of its parents drawing stack, above
1539 * all of its sibling windows.
1542 GrRaiseWindow(GR_WINDOW_ID wid)
1544 nxRaiseWindowReq *req;
1546 req = AllocReq(RaiseWindow);
1547 req->windowid = wid;
1552 * @wid: the ID of the window to lower
1554 * Places the specified window at the bottom of its parents drawing stack,
1555 * below all of its sibling windows.
1558 GrLowerWindow(GR_WINDOW_ID wid)
1560 nxLowerWindowReq *req;
1562 req = AllocReq(LowerWindow);
1563 req->windowid = wid;
1568 * @wid: the ID of the window to move
1569 * @x: the X coordinate to move the window to relative to its parent.
1570 * @y: the Y coordinate to move the window to relative to its parent.
1572 * Moves the specified window to the specified position relative to its
1576 GrMoveWindow(GR_WINDOW_ID wid, GR_COORD x, GR_COORD y)
1578 nxMoveWindowReq *req;
1580 req = AllocReq(MoveWindow);
1581 req->windowid = wid;
1588 * @wid: the ID of the window to resize
1589 * @width: the width to resize the window to
1590 * @height: the height to resize the window to
1592 * Resizes the specified window to be the specified width and height.
1595 GrResizeWindow(GR_WINDOW_ID wid, GR_SIZE width, GR_SIZE height)
1597 nxResizeWindowReq *req;
1599 req = AllocReq(ResizeWindow);
1600 req->windowid = wid;
1602 req->height = height;
1607 * @wid: the ID of the window to reparent
1608 * @pwid: the ID of the new parent window
1609 * @x: the X coordinate to place the window at relative to the new parent
1610 * @y: the Y coordinate to place the window at relative to the new parent
1612 * Changes the parent window of the specified window to the specified parent
1613 * window and places it at the specified coordinates relative to the new
1617 GrReparentWindow(GR_WINDOW_ID wid, GR_WINDOW_ID pwid, GR_COORD x, GR_COORD y)
1619 nxReparentWindowReq *req;
1621 req = AllocReq(ReparentWindow);
1622 req->windowid = wid;
1623 req->parentid = pwid;
1631 * @exposeflag: a flag indicating whether to also generate an exposure event
1633 * Clears the specified window by to its background color or pixmap.
1634 * If exposeflag is non zero, an exposure event is generated for
1635 * the window after it has been cleared.
1638 GrClearArea(GR_WINDOW_ID wid, GR_COORD x, GR_COORD y, GR_SIZE width,
1639 GR_SIZE height, GR_BOOL exposeflag)
1641 nxClearAreaReq *req;
1643 req = AllocReq(ClearArea);
1644 req->windowid = wid;
1648 req->height = height;
1649 req->exposeflag = exposeflag;
1654 * @Returns: the ID of the window which currently has the keyboard focus
1656 * Returns the ID of the window which currently has the keyboard focus.
1664 if(GrTypedReadBlock(&wid, sizeof(wid), GrNumGetFocus) == -1)
1671 * @wid: the ID of the window to set the focus to
1673 * Sets the keyboard focus to the specified window.
1676 GrSetFocus(GR_WINDOW_ID wid)
1680 req = AllocReq(SetFocus);
1681 req->windowid = wid;
1685 * GrSetWindowCursor:
1686 * @wid: the ID of the window to set the cursor for
1687 * @cid: the cursor ID
1689 * Specify a cursor for a window.
1690 * This cursor will only be used within that window, and by default
1691 * for its new children. If the cursor is currently within this
1692 * window, it will be changed to the new one immediately.
1693 * If the new cursor ID is 0, revert to the root window cursor.
1696 GrSetWindowCursor(GR_WINDOW_ID wid, GR_CURSOR_ID cid)
1698 nxSetWindowCursorReq *req;
1700 req = AllocReq(SetWindowCursor);
1701 req->windowid = wid;
1702 req->cursorid = cid;
1707 * @width: the width of the pointer bitmap
1708 * @height: the height of the pointer bitmap
1709 * @hotx: the X coordinate within the bitmap used as the target of the pointer
1710 * @hoty: the Y coordinate within the bitmap used as the target of the pointer
1711 * @foreground: the colour to use for the foreground of the pointer
1712 * @background: the colour to use for the background of the pointer
1713 * @fgbitmap: pointer to bitmap data specifying the foreground of the pointer
1714 * @bgbitmap: pointer to bitmap data specifying the background of the pointer
1716 * Creates a server-based cursor (mouse graphic) resource.
1719 GrNewCursor(GR_SIZE width, GR_SIZE height, GR_COORD hotx, GR_COORD hoty,
1720 GR_COLOR foreground, GR_COLOR background,
1721 GR_BITMAP *fgbitmap, GR_BITMAP *bgbitmap)
1723 nxNewCursorReq *req;
1726 GR_CURSOR_ID cursorid;
1728 bitmapsize = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);
1729 req = AllocReqExtra(NewCursor, bitmapsize*2);
1731 req->height = height;
1734 req->fgcolor = foreground;
1735 req->bgcolor = background;
1736 data = GetReqData(req);
1737 memcpy(data, fgbitmap, bitmapsize);
1738 memcpy(data+bitmapsize, bgbitmap, bitmapsize);
1740 if(GrTypedReadBlock(&cursorid, sizeof(cursorid), GrNumNewCursor) == -1)
1747 * @x: the X coordinate to move the pointer to
1748 * @y: the Y coordinate to move the pointer to
1750 * Moves the cursor (mouse pointer) to the specified coordinates.
1751 * The coordinates are relative to the root window, where (0,0) is the upper
1752 * left hand corner of the screen. The reference point used for the pointer
1753 * is that of the "hot spot". After moving the pointer, the graphic used for
1754 * the pointer will change to the graphic defined for use in the window which
1758 GrMoveCursor(GR_COORD x, GR_COORD y)
1760 nxMoveCursorReq *req;
1762 req = AllocReq(MoveCursor);
1768 * GrSetGCForeground:
1769 * @gc: the ID of the graphics context to set the foreground colour of
1770 * @foreground: the colour to use as the new foreground colour
1772 * Changes the foreground colour of the specified graphics context to the
1776 GrSetGCForeground(GR_GC_ID gc, GR_COLOR foreground)
1778 nxSetGCForegroundReq *req;
1780 req = AllocReq(SetGCForeground);
1782 req->color = foreground;
1786 * GrSetGCBackground:
1787 * @gc: the ID of the graphics context to set the background colour of
1788 * @background: the colour to use as the new background colour
1790 * Changes the background colour of the specified graphics context to the
1794 GrSetGCBackground(GR_GC_ID gc, GR_COLOR background)
1796 nxSetGCBackgroundReq *req;
1798 req = AllocReq(SetGCBackground);
1800 req->color = background;
1805 * @gc: the ID of the graphics context to set the drawing mode of
1806 * @mode: the new drawing mode
1808 * Changes the drawing mode (SET, XOR, OR, AND, etc.) of the specified
1809 * graphics context to the specified mode.
1812 GrSetGCMode(GR_GC_ID gc, int mode)
1814 nxSetGCModeReq *req;
1816 req = AllocReq(SetGCMode);
1822 * GrSetGCUseBackground:
1823 * @gc: the ID of the graphics context to change the "use background" flag of
1824 * @flag: flag specifying whether to use the background colour or not
1826 * Sets the flag which chooses whether or not the background colour is used
1827 * when drawing bitmaps and text using the specified graphics context to the
1831 GrSetGCUseBackground(GR_GC_ID gc, GR_BOOL flag)
1833 nxSetGCUseBackgroundReq *req;
1835 req = AllocReq(SetGCUseBackground);
1842 * @name: string containing the name of a built in font to look for
1843 * @height: the desired height of the font
1844 * @plogfont: pointer to a LOGFONT structure
1845 * @Returns: a font ID number which can be used to refer to the font
1847 * Attempts to locate a font with the desired attributes and returns a font
1848 * ID number which can be used to refer to it. If the plogfont argument is
1849 * not NULL, the values in that structure will be used to choose a font.
1850 * Otherwise, if the height is non zero, the built in font with the closest
1851 * height to that specified will be used. If the height is zero, the built
1852 * in font with the specified name will be used. If the desired font is not
1853 * found, the first built in font will be returned as a last resort.
1856 GrCreateFont(GR_CHAR *name, GR_COORD height, GR_LOGFONT *plogfont)
1858 nxCreateFontReq *req;
1861 req = AllocReq(CreateFont);
1863 memcpy(&req->lf, plogfont, sizeof(*plogfont));
1868 strcpy(req->lf.lfFaceName, name);
1869 else req->lf.lfFaceName[0] = '\0';
1870 req->height = height;
1874 if(GrTypedReadBlock(&fontid, sizeof(fontid),GrNumCreateFont) == -1)
1881 * @fonts: pointer used to return an array of font names.
1882 * @numfonts: pointer used to return the number of names found.
1884 * Returns an array of strings containing the names of available fonts and an
1885 * integer that specifies the number of strings returned.
1888 GrGetFontList(GR_FONTLIST ***fonts, int *numfonts)
1890 nxGetFontListReq *req;
1892 GR_FONTLIST **flist;
1895 req = AllocReq(GetFontList);
1897 GrTypedReadBlock(&num, sizeof(int), GrNumGetFontList);
1904 flist = (GR_FONTLIST**)malloc(num * sizeof(GR_FONTLIST*));
1906 for(i = 0; i < num; i++)
1907 flist[i] = (GR_FONTLIST*)malloc(sizeof(GR_FONTLIST*));
1909 for(i = 0; i < num; i++) {
1910 GrReadBlock(&len, sizeof(int));
1911 tmpstr = (char*)malloc(len * sizeof(char));
1912 GrReadBlock(tmpstr, len * sizeof(char));
1913 flist[i]->ttname = tmpstr;
1915 GrReadBlock(&len, sizeof(int));
1916 tmpstr = (char*)malloc(len * sizeof(char));
1917 GrReadBlock(tmpstr, len * sizeof(char));
1918 flist[i]->mwname = tmpstr;
1927 * @fonts: pointer to array returned by GrGetFontList
1928 * @numfonts: the number of font names in the array
1930 * free's the specified array.
1933 GrFreeFontList(GR_FONTLIST ***fonts, int n)
1936 MWFONTLIST *g, **list = *fonts;
1938 for (i = 0; i < n; i++) {
1954 * @fontid: the ID number of the font to change the size of
1955 * @fontsize: the size to change the font to
1957 * Changes the size of the specified font to the specified size.
1960 GrSetFontSize(GR_FONT_ID fontid, GR_COORD fontsize)
1962 nxSetFontSizeReq *req;
1964 req = AllocReq(SetFontSize);
1965 req->fontid = fontid;
1966 req->fontsize = fontsize;
1970 * GrSetFontRotation:
1971 * @fontid: the ID number of the font to rotate
1972 * @tenthdegrees: the angle to set the rotation to in tenths of a degree
1974 * Changes the rotation of the specified font to the specified angle.
1977 GrSetFontRotation(GR_FONT_ID fontid, int tenthdegrees)
1979 nxSetFontRotationReq *req;
1981 req = AllocReq(SetFontRotation);
1982 req->fontid = fontid;
1983 req->tenthdegrees = tenthdegrees;
1988 * @fontid: the ID of the font to set the attributes of
1989 * @setflags: mask specifying attribute flags to set
1990 * @clrflags: mask specifying attribute flags to clear
1992 * Changes the attributes (GR_TFKERNING, GR_TFANTIALIAS, GR_TFUNDERLINE, etc.)
1993 * of the specified font according to the set and clear mask arguments.
1996 GrSetFontAttr(GR_FONT_ID fontid, int setflags, int clrflags)
1998 nxSetFontAttrReq *req;
2000 req = AllocReq(SetFontAttr);
2001 req->fontid = fontid;
2002 req->setflags = setflags;
2003 req->clrflags = clrflags;
2008 * @fontid: the ID of the font to destroy
2010 * Frees all resources associated with the specified font ID, and if the font
2011 * is a non built in type and this is the last ID referring to it, unloads the
2015 GrDestroyFont(GR_FONT_ID fontid)
2017 nxDestroyFontReq *req;
2019 req = AllocReq(DestroyFont);
2020 req->fontid = fontid;
2025 * @gc: the ID of the graphics context to set the font of
2026 * @font: the ID of the font
2028 * Sets the font to be used for text drawing in the specified graphics
2029 * context to the specified font ID.
2032 GrSetGCFont(GR_GC_ID gc, GR_FONT_ID font)
2034 nxSetGCFontReq *req;
2036 req = AllocReq(SetGCFont);
2043 * @id: the ID of the drawable to draw the line on
2044 * @gc: the ID of the graphics context to use when drawing the line
2045 * @x1: the X coordinate of the start of the line relative to the drawable
2046 * @y1: the Y coordinate of the start of the line relative to the drawable
2047 * @x2: the X coordinate of the end of the line relative to the drawable
2048 * @y2: the Y coordinate of the end of the line relative to the drawable
2050 * Draws a line using the specified graphics context on the specified drawable
2051 * from (x1, y1) to (x2, y2), with coordinates given relative to the drawable.
2054 GrLine(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x1, GR_COORD y1, GR_COORD x2,
2059 req = AllocReq(Line);
2070 * @id: the ID of the drawable to draw the rectangle on
2071 * @gc: the ID of the graphics context to use when drawing the rectangle
2072 * @x: the X coordinate of the rectangle relative to the drawable
2073 * @y: the Y coordinate of the rectangle relative to the drawable
2074 * @width: the width of the rectangle
2075 * @height: the height of the rectangle
2077 * Draw the boundary of a rectangle of the specified dimensions and position
2078 * on the specified drawable using the specified graphics context.
2081 GrRect(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
2086 req = AllocReq(Rect);
2092 req->height = height;
2097 * @id: the ID of the drawable to draw the rectangle on
2098 * @gc: the ID of the graphics context to use when drawing the rectangle
2099 * @x: the X coordinate of the rectangle relative to the drawable
2100 * @y: the Y coordinate of the rectangle relative to the drawable
2101 * @width: the width of the rectangle
2102 * @height: the height of the rectangle
2104 * Draw a filled rectangle of the specified dimensions and position on the
2105 * specified drawable using the specified graphics context.
2108 GrFillRect(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2109 GR_SIZE width, GR_SIZE height)
2113 req = AllocReq(FillRect);
2119 req->height = height;
2124 * @id: the ID of the drawable to draw the ellipse on
2125 * @gc: the ID of the graphics context to use when drawing the ellipse
2126 * @x: the X coordinate to draw the ellipse at relative to the drawable
2127 * @y: the Y coordinate to draw the ellipse at relative to the drawable
2128 * @rx: the radius of the ellipse on the X axis
2129 * @ry: the radius of the ellipse on the Y axis
2131 * Draws the boundary of ellipse at the specified position using the specified
2132 * dimensions and graphics context on the specified drawable.
2135 GrEllipse(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE rx,
2140 req = AllocReq(Ellipse);
2151 * @id: the ID of the drawable to draw the filled ellipse on
2152 * @gc: the ID of the graphics context to use when drawing the ellipse
2153 * @x: the X coordinate to draw the ellipse at relative to the drawable
2154 * @y: the Y coordinate to draw the ellipse at relative to the drawable
2155 * @rx: the radius of the ellipse on the X axis
2156 * @ry: the radius of the ellipse on the Y axis
2158 * Draws a filled ellipse at the specified position using the specified
2159 * dimensions and graphics context on the specified drawable.
2162 GrFillEllipse(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2163 GR_SIZE rx, GR_SIZE ry)
2165 nxFillEllipseReq *req;
2167 req = AllocReq(FillEllipse);
2178 * @id: the ID of the drawable to draw the arc on
2179 * @gc: the graphics context to use when drawing the arc
2180 * @x: the X coordinate to draw the arc at relative to the drawable
2181 * @y: the Y coordinate to draw the arc at relative to the drawable
2182 * @rx: the radius of the arc on the X axis
2183 * @ry: the radius of the arc on the Y axis
2184 * @ax: the X coordinate of the start of the arc relative to the drawable
2185 * @ay: the Y coordinate of the start of the arc relative to the drawable
2186 * @bx: the X coordinate of the end of the arc relative to the drawable
2187 * @by: the Y coordinate of the end of the arc relative to the drawable
2188 * @type: the fill style to use when drawing the arc
2190 * Draws an arc with the specified dimensions at the specified position
2191 * on the specified drawable using the specified graphics context.
2192 * The type specifies the fill type. Possible values include GR_ARC and
2196 GrArc(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2197 GR_SIZE rx, GR_SIZE ry, GR_COORD ax, GR_COORD ay,
2198 GR_COORD bx, GR_COORD by, int type)
2202 req = AllocReq(Arc);
2218 * @id: the ID of the drawable to draw the arc on
2219 * @gc: the graphics context to use when drawing the arc
2220 * @x: the X coordinate to draw the arc at relative to the drawable
2221 * @y: the Y coordinate to draw the arc at relative to the drawable
2222 * @rx: the radius of the arc on the X axis
2223 * @ry: the radius of the arc on the Y axis
2224 * @angle1: the angle of the start of the arc
2225 * @angle2: the angle of the end of the arc
2226 * @type: the fill style to use when drawing the arc
2228 * Draws an arc with the specified dimensions at the specified position
2229 * on the specified drawable using the specified graphics context.
2230 * The type specifies the fill type. Possible values include GR_ARC and
2231 * GR_PIE. This function requires floating point support, and is slightly
2232 * slower than the GrArc() function which does not require floating point.
2235 GrArcAngle(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2236 GR_SIZE rx, GR_SIZE ry, GR_COORD angle1, GR_COORD angle2, int type)
2240 req = AllocReq(ArcAngle);
2247 req->angle1 = angle1;
2248 req->angle2 = angle2;
2254 * @id: the ID of the drawable to draw the bitmap onto
2255 * @gc: the ID of the graphics context to use when drawing the bitmap
2256 * @x: the X coordinate to draw the bitmap at relative to the drawable
2257 * @y: the Y coordinate to draw the bitmap at relative to the drawable
2258 * @width: the width of the bitmap
2259 * @height: the height of the bitmap
2260 * @bitmaptable: pointer to the bitmap data
2262 * Draws the monochrome bitmap data provided in the bitmaptable argument
2263 * at the specified position on the specified drawable using the specified
2264 * graphics context. Note that the bitmap data should be an array of aligned
2265 * 16 bit words. The usebackground flag in the graphics context specifies
2266 * whether to draw the background colour wherever a bit value is zero.
2269 GrBitmap(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
2270 GR_SIZE height, GR_BITMAP *bitmaptable)
2275 bitmapsize = (long)GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);
2276 req = AllocReqExtra(Bitmap, bitmapsize);
2282 req->height = height;
2283 memcpy(GetReqData(req), bitmaptable, bitmapsize);
2288 * @id: the ID of the drawable to draw the image onto
2289 * @gc: the ID of the graphics context to use when drawing the image
2290 * @x: the X coordinate to draw the image at relative to the drawable
2291 * @y: the Y coordinate to draw the image at relative to the drawable
2292 * @pimage: pointer to the image structure
2294 * Draws the image contained in the specified image structure onto the
2295 * specified drawable at the specified coordinates using the specified
2299 GrDrawImageBits(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2300 GR_IMAGE_HDR *pimage)
2302 nxDrawImageBitsReq *req;
2307 imagesize = pimage->pitch * pimage->height;
2308 palsize = pimage->palsize * sizeof(MWPALENTRY);
2309 req = AllocReqExtra(DrawImageBits, imagesize + palsize);
2314 /* fill MWIMAGEHDR items passed externally*/
2315 req->width = pimage->width;
2316 req->height = pimage->height;
2317 req->planes = pimage->planes;
2318 req->bpp = pimage->bpp;
2319 req->pitch = pimage->pitch;
2320 req->bytesperpixel = pimage->bytesperpixel;
2321 req->compression = pimage->compression;
2322 req->palsize = pimage->palsize;
2323 req->transcolor = pimage->transcolor;
2324 addr = GetReqData(req);
2325 memcpy(addr, pimage->imagebits, imagesize);
2326 memcpy(addr+imagesize, pimage->palette, palsize);
2330 * GrDrawImageFromFile:
2331 * @id: the ID of the drawable to draw the image onto
2332 * @gc: the ID of the graphics context to use when drawing the image
2333 * @x: the X coordinate to draw the image at relative to the drawable
2334 * @y: the Y coordinate to draw the image at relative to the drawable
2335 * @width: the maximum image width
2336 * @height: the maximum image height
2337 * @path: string containing the filename of the image to load
2338 * @flags: flags specific to the particular image loader
2340 * Loads the specified image file and draws it at the specified position
2341 * on the specified drawable using the specified graphics context. The
2342 * width and height values specify the size of the image to draw- if the
2343 * actual image is a different size, it will be scaled to fit. The image type
2344 * is automatically detected using the magic numbers in the image header (ie.
2345 * the filename extension is irrelevant). The currently supported image types
2346 * include GIF, JPEG, Windows BMP, PNG, XPM, and both ascii and binary
2347 * variants of PBM, PGM, and PPM. However the image types supported by a
2348 * particular server depend on which image types were enabled in the server
2349 * configuration at build time.
2352 GrDrawImageFromFile(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2353 GR_SIZE width, GR_SIZE height, char* path, int flags)
2355 nxDrawImageFromFileReq *req;
2357 req = AllocReqExtra(DrawImageFromFile, strlen(path)+1);
2363 req->height = height;
2365 memcpy(GetReqData(req), path, strlen(path)+1);
2369 * GrLoadImageFromFile:
2370 * @path: string containing the filename of the image to load
2371 * @flags: flags specific to the particular image loader
2372 * @Returns: ID of the image buffer the image was loaded into
2374 * Loads the specified image file into a newly created server image buffer
2375 * and returns the ID of the buffer. The image type is automatically detected
2376 * using the magic numbers in the image header (ie. the filename extension is
2377 * irrelevant). The currently supported image types include GIF, JPEG, Windows
2378 * BMP, PNG, XPM, and both ascii and binary variants of PBM, PGM, and PPM.
2379 * However the image types supported by a particular server depend on which
2380 * image types were enabled in the server configuration at build time.
2383 GrLoadImageFromFile(char *path, int flags)
2385 nxLoadImageFromFileReq *req;
2386 GR_IMAGE_ID imageid;
2388 req = AllocReqExtra(LoadImageFromFile, strlen(path)+1);
2390 memcpy(GetReqData(req), path, strlen(path)+1);
2392 if(GrTypedReadBlock(&imageid, sizeof(imageid),
2393 GrNumLoadImageFromFile) == -1)
2400 * @id: the ID of the drawable to draw the image onto
2401 * @gc: the ID of the graphics context to use when drawing the image
2402 * @x: the X coordinate to draw the image at relative to the drawable
2403 * @y: the Y coordinate to draw the image at relative to the drawable
2404 * @width: the maximum image width
2405 * @height: the maximum image height
2406 * @imageid: the ID of the image buffer containing the image to display
2408 * Draws the image from the specified image buffer at the specified position
2409 * on the specified drawable using the specified graphics context. The
2410 * width and height values specify the size of the image to draw- if the
2411 * actual image is a different size, it will be scaled to fit.
2414 GrDrawImageToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2415 GR_SIZE width, GR_SIZE height, GR_IMAGE_ID imageid)
2417 nxDrawImageToFitReq *req;
2419 req = AllocReq(DrawImageToFit);
2425 req->height = height;
2426 req->imageid = imageid;
2431 * @id: ID of the image buffer to free
2433 * Destroys the specified image buffer and reclaims the memory used by it.
2436 GrFreeImage(GR_IMAGE_ID id)
2438 nxFreeImageReq *req;
2440 req = AllocReq(FreeImage);
2446 * @id: ID of an image buffer
2447 * @iip: pointer to a GR_IMAGE_INFO structure
2449 * Fills in the specified image information structure with the details of the
2450 * specified image buffer.
2453 GrGetImageInfo(GR_IMAGE_ID id, GR_IMAGE_INFO *iip)
2455 nxGetImageInfoReq *req;
2457 req = AllocReq(GetImageInfo);
2459 GrTypedReadBlock(iip, sizeof(GR_IMAGE_INFO), GrNumGetImageInfo);
2462 static int sendImageBuffer(void *buffer, int size) {
2466 void *bufptr = buffer;
2468 nxImageBufferAllocReq *alloc;
2469 nxImageBufferSendReq *send;
2471 /* Step 1 - Allocate a buffer on the other side */
2473 alloc = AllocReq(ImageBufferAlloc);
2476 GrTypedReadBlock(&bufid, sizeof(bufid), GrNumImageBufferAlloc);
2478 if (bufid < 0) return(0);
2480 /* step 2 - Send the buffer across */
2482 while(bufsize > 0) {
2483 int chunk = (MAXREQUESTSZ - sizeof(nxImageBufferSendReq));
2484 if (chunk > bufsize) chunk=bufsize;
2486 send = AllocReqExtra(ImageBufferSend, chunk);
2487 send->buffer_id = bufid;
2490 memcpy(GetReqData(send), bufptr, chunk);
2498 GR_IMAGE_ID GrLoadImageFromBuffer(void *buffer, int size, int flags) {
2501 nxLoadImageFromBufferReq *req;
2502 GR_IMAGE_ID imageid;
2504 /* Step 1 - Send the buffer to the other side */
2505 bufid = sendImageBuffer(buffer, size);
2507 if (!bufid) return(0);
2509 /* Step 2 - Send the command to load the image */
2510 /* Note - This will free the buffer automagically */
2512 req = AllocReq(LoadImageFromBuffer);
2514 req->buffer = bufid;
2516 if(GrTypedReadBlock(&imageid, sizeof(imageid),
2517 GrNumLoadImageFromBuffer) == -1)
2523 void GrDrawImageFromBuffer(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2524 GR_SIZE width, GR_SIZE height,
2525 void *buffer, int size, int flags) {
2528 nxDrawImageFromBufferReq *req;
2530 /* Step 1 - Send the buffer to the other side */
2531 bufid = sendImageBuffer(buffer, size);
2535 /* Step 2 - Send the command to load/draw the image */
2536 /* Note - This will free the buffer automagically */
2538 req = AllocReq(DrawImageFromBuffer);
2545 req->height = height;
2547 req->buffer = bufid;
2552 * Draw a rectangular area in the specified drawable using the specified
2553 * graphics context. This differs from rectangle drawing in that the
2554 * color values for each pixel in the rectangle are specified.
2555 * The color table is indexed
2556 * row by row. Values whose color matches the background color are only
2557 * written if the usebackground flag is set in the GC.
2559 * The pixels are packed according to pixtype:
2562 * MWPF_RGB MWCOLORVAL (unsigned long)
2563 * MWPF_PIXELVAL MWPIXELVAL (compile-time dependent)
2564 * MWPF_PALETTE unsigned char
2565 * MWPF_TRUECOLOR0888 unsigned long
2566 * MWPF_TRUECOLOR888 packed struct {char r,char g,char b} (24 bits)
2567 * MWPF_TRUECOLOR565 unsigned short
2568 * MWPF_TRUECOLOR555 unsigned short
2569 * MWPF_TRUECOLOR332 unsigned char
2570 * MWPF_TRUECOLOR223 unsigned char
2574 * @id: the ID of the drawable to draw the area onto
2575 * @gc: the ID of the graphics context to use when drawing the area
2576 * @x: the X coordinate to draw the area at relative to the drawable
2577 * @y: the Y coordinate to draw the area at relative to the drawable
2578 * @width: the width of the area
2579 * @height: the height of the area
2580 * @pixels: pointer to an array containing the pixel data
2581 * @pixtype: the format of the pixel data
2583 * Draws the specified pixel array of the specified size and format onto the
2584 * specified drawable using the specified graphics context at the specified
2585 * position. Note that colour conversion is currently only performed when using
2586 * the GR_PF_RGB format, which is an unsigned long containing RGBX data.
2589 GrArea(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
2590 GR_SIZE height, void *pixels, int pixtype)
2597 /* Calculate size of packed pixels*/
2600 pixsize = sizeof(MWCOLORVAL);
2603 pixsize = sizeof(MWPIXELVAL);
2606 case MWPF_TRUECOLOR332:
2607 case MWPF_TRUECOLOR233:
2608 pixsize = sizeof(unsigned char);
2610 case MWPF_TRUECOLOR0888:
2611 pixsize = sizeof(unsigned long);
2613 case MWPF_TRUECOLOR888:
2616 case MWPF_TRUECOLOR565:
2617 case MWPF_TRUECOLOR555:
2618 pixsize = sizeof(unsigned short);
2624 /* Break request into MAXREQUESTSZ size packets*/
2626 chunk_y = (MAXREQUESTSZ - sizeof(nxAreaReq)) /
2627 ((long)width * pixsize);
2628 if(chunk_y > height)
2630 size = chunk_y * ((long)width * pixsize);
2631 req = AllocReqExtra(Area, size);
2637 req->height = chunk_y;
2638 req->pixtype = pixtype;
2639 memcpy(GetReqData(req), pixels, size);
2640 pixels = (void *)(((char *)pixels) + size);
2648 * @id: the ID of the drawable to copy the area to
2649 * @gc: the ID of the graphics context to use when copying the area
2650 * @x: the X coordinate to copy the area to within the destination drawable
2651 * @y: the Y coordinate to copy the area to within the destination drawable
2652 * @width: the width of the area to copy
2653 * @height: the height of the area to copy
2654 * @srcid: the ID of the drawable to copy the area from
2655 * @srcx: the X coordinate to copy the area from within the source drawable
2656 * @srcy: the Y coordinate to copy the area from within the source drawable
2657 * @op: the ROP codes to pass to the blitter when performing the copy
2659 * Copies the specified area of the specified size between the specified
2660 * drawables at the specified positions using the specified graphics context
2661 * and ROP codes. 0 is a sensible default ROP code in most cases.
2664 GrCopyArea(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
2665 GR_SIZE width, GR_SIZE height, GR_DRAW_ID srcid,
2666 GR_COORD srcx, GR_COORD srcy, int op)
2670 req = AllocReq(CopyArea);
2676 req->height = height;
2686 * @id: the ID of the drawable to read an area from
2687 * @x: the X coordinate to read the area from relative to the drawable
2688 * @y: the Y coordinate to read the area from relative to the drawable
2689 * @width: the width of the area to read
2690 * @height: the height of the area to read
2691 * @pixels: pointer to an area of memory to place the pixel data in
2693 * Reads the pixel data of the specified size from the specified position on
2694 * the specified drawable into the specified pixel array. If the drawable is
2695 * a window, the data returned will be the pixel values from the relevant
2696 * position on the screen regardless of whether the window is obscured by other
2697 * windows. If the window is unmapped, or partially or fully outside a window
2698 * boundary, black pixel values will be returned.
2701 GrReadArea(GR_DRAW_ID id,GR_COORD x,GR_COORD y,GR_SIZE width,
2702 GR_SIZE height, GR_PIXELVAL *pixels)
2707 req = AllocReq(ReadArea);
2712 req->height = height;
2713 size = (long)width * height * sizeof(MWPIXELVAL);
2714 GrTypedReadBlock(pixels, size, GrNumReadArea);
2719 * @id: the ID of the drawable to draw a point on
2720 * @gc: the ID of the graphics context to use when drawing the point
2721 * @x: the X coordinate to draw the point at relative to the drawable
2722 * @y: the Y coordinate to draw the point at relative to the drawable
2724 * Draws a point using the specified graphics context at the specified position
2725 * on the specified drawable.
2728 GrPoint(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y)
2732 req = AllocReq(Point);
2742 * @id: the ID of the drawable to draw a point on
2743 * @gc: the ID of the graphics context to use when drawing the point
2744 * @count: the number of points in the point table
2745 * @pointtable: pointer to a GR_POINT array which lists the points to draw
2747 * Draws a set of points using the specified graphics context at the positions
2748 * specified by the point table on the specified drawable.
2751 GrPoints(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count, GR_POINT *pointtable)
2756 size = (long)count * sizeof(GR_POINT);
2757 req = AllocReqExtra(Points, size);
2760 memcpy(GetReqData(req), pointtable, size);
2765 * @id: the ID of the drawable to draw the polygon onto
2766 * @gc: the ID of the graphics context to use when drawing the polygon
2767 * @count: the number of points in the point array
2768 * @pointtable: pointer to an array of points describing the polygon
2770 * Draws an unfilled polygon on the specified drawable using the specified
2771 * graphics context. The polygon is specified by an array of point structures.
2772 * The polygon is not automatically closed- if a closed polygon is desired,
2773 * the last point must be the same as the first.
2776 GrPoly(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count, GR_POINT *pointtable)
2781 size = (long)count * sizeof(GR_POINT);
2782 req = AllocReqExtra(Poly, size);
2785 memcpy(GetReqData(req), pointtable, size);
2790 * @id: the ID of the drawable to draw the polygon onto
2791 * @gc: the ID of the graphics context to use when drawing the polygon
2792 * @count: the number of points in the point array
2793 * @pointtable: pointer to an array of points describing the polygon
2795 * Draws a filled polygon on the specified drawable using the specified
2796 * graphics context. The polygon is specified by an array of point structures.
2797 * The polygon is automatically closed- the last point need not be the same as
2798 * the first in order for the polygon to be closed.
2801 GrFillPoly(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count,GR_POINT *pointtable)
2806 size = (long)count * sizeof(GR_POINT);
2807 req = AllocReqExtra(FillPoly, size);
2810 memcpy(GetReqData(req), pointtable, size);
2815 * @id: the ID of the drawable to draw the text string onto
2816 * @gc: the ID of the graphics context to use when drawing the text string
2817 * @x: the X coordinate to draw the string at relative to the drawable
2818 * @y: the Y coordinate to draw the string at relative to the drawable
2819 * @str: the text string to draw
2820 * @count: the number of characters (not bytes) in the string
2821 * @flags: flags specifying text encoding, alignment, etc.
2823 * Draws the specified text string at the specified position on the specified
2824 * drawable using the specified graphics context and flags. The default flags
2825 * specify ASCII encoding and baseline alignment.
2828 GrText(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, void *str,
2829 GR_COUNT count, int flags)
2834 if(count == -1 && (flags&MWTF_PACKMASK) == MWTF_ASCII)
2835 count = strlen((char *)str);
2837 size = nxCalcStringBytes(str, count, flags);
2839 req = AllocReqExtra(Text, size);
2846 memcpy(GetReqData(req), str, size);
2851 * GrGetSystemPalette:
2852 * @pal: pointer to a palette structure to fill in with the system palette
2854 * Retrieves the system palette and places it in the specified palette
2858 GrGetSystemPalette(GR_PALETTE *pal)
2860 AllocReq(GetSystemPalette);
2861 GrTypedReadBlock(pal, sizeof(*pal), GrNumGetSystemPalette);
2865 * GrSetSystemPalette:
2866 * @first: the first palette value to set
2867 * @pal: pointer to a palette structure containing the new values
2869 * Sets the system palette to the values stored in the specified palette
2870 * structure. The values before the specified first value are not set.
2873 GrSetSystemPalette(GR_COUNT first, GR_PALETTE *pal)
2875 nxSetSystemPaletteReq *req;
2877 req = AllocReq(SetSystemPalette);
2879 req->count = pal->count;
2880 memcpy(req->palette, pal->palette, sizeof(GR_PALENTRY) * pal->count);
2885 * @c: the colour value to find
2886 * @retpixel: pointer to the returned pixel value
2888 * Calculates the pixel value to use to display the specified colour value.
2889 * The colour value is specified as a GR_COLOR, which is a 32 bit truecolour
2890 * value stored as RGBX. The pixel value size depends on the architecture.
2893 GrFindColor(GR_COLOR c, GR_PIXELVAL *retpixel)
2895 nxFindColorReq *req;
2897 req = AllocReq(FindColor);
2899 GrTypedReadBlock(retpixel, sizeof(*retpixel), GrNumFindColor);
2904 * @shmsize: the size of the shared memory area to allocate
2906 * Requests a shared memory area of the specified size to use for transferring
2907 * command arguments. This is faster but less portable than the standard BSD
2908 * sockets method of communication (and of course will only work if the client
2909 * and server are on the same machine). Apart from the initial allocation of
2910 * the area using this call, the use of shared memory is completely
2911 * transparent. Additionally, if the allocation fails we silently and
2912 * automatically fall back on socket communication. It is safe to call this
2913 * function even if shared memory support is not compiled in; it will simply
2916 * FIXME: how does the user decide what size of shared memory area to allocate?
2919 GrReqShmCmds(long shmsize)
2921 #if HAVE_SHAREDMEM_SUPPORT
2922 nxReqShmCmdsReq req;
2925 if ( nxSharedMem != 0 )
2930 shmsize = (shmsize+SHM_BLOCK_SIZE-1) & ~(SHM_BLOCK_SIZE-1);
2932 req.reqType = GrNumReqShmCmds;
2934 req.length = sizeof(req);
2937 nxWriteSocket((char *)&req,sizeof(req));
2938 GrReadBlock(&key,sizeof(key));
2941 EPRINTF("nxclient: no shared memory support on server\n");
2945 shmid = shmget(key,shmsize,0);
2946 if ( shmid == -1 ) {
2947 EPRINTF("nxclient: Can't shmget key %d: %m\n", key);
2951 nxSharedMem = shmat(shmid,0,0);
2952 shmctl(shmid,IPC_RMID,0); /* Prevent other from attaching */
2953 if ( nxSharedMem == (char *)-1 )
2956 nxSharedMemSize = shmsize;
2957 nxAssignReqbuffer(nxSharedMem, shmsize);
2958 #endif /* HAVE_SHAREDMEM_SUPPORT*/
2962 * GrInjectPointerEvent:
2963 * @x: the X coordinate of the pointer event relevant to the root window
2964 * @y: the Y coordinate of the pointer event relevant to the root window
2965 * @button: the pointer button status
2966 * @visible: whether to display the pointer after the event
2968 * Sets the pointer invisible if the visible parameter is GR_FALSE, or visible
2969 * if it is GR_TRUE, then moves the pointer to the specified position and
2970 * generates a mouse event with the specified button status. Also performs
2971 * a GrFlush() so that the event takes effect immediately.
2974 GrInjectPointerEvent(GR_COORD x, GR_COORD y, int button, int visible)
2976 nxInjectEventReq *req;
2978 req = AllocReq(InjectEvent);
2979 req->event_type = GR_INJECT_EVENT_POINTER;
2980 req->event.pointer.visible = visible;
2981 req->event.pointer.x = x;
2982 req->event.pointer.y = y;
2983 req->event.pointer.button = button;
2989 * GrInjectKeyboardEvent:
2990 * @wid: ID of the window to send the event to, or 0
2991 * @uch: 32 bit Unicode keystroke value to inject
2992 * @ch: 8 bit ascii keystroke value to inject
2993 * @modifier: modifiers (shift, ctrl, alt, etc.) to inject
2994 * @special: special keys to inject
2995 * @content: mask specifying which arguments are valid
2997 * Sends a keyboard event to the specified window, or to the window with the
2998 * current keyboard focus if 0 is used as the ID. The other arguments
2999 * correspond directly to the fields of the same names in the keyboard event
3003 GrInjectKeyboardEvent(GR_WINDOW_ID wid, GR_KEY keyvalue,
3004 GR_KEYMOD modifier, GR_SCANCODE scancode, GR_BOOL pressed)
3006 nxInjectEventReq *req;
3008 req = AllocReq(InjectEvent);
3009 req->event_type = GR_INJECT_EVENT_KEYBOARD;
3010 req->event.keyboard.wid = wid;
3011 req->event.keyboard.keyvalue = keyvalue;
3012 req->event.keyboard.modifier = modifier;
3013 req->event.keyboard.scancode = scancode;
3014 req->event.keyboard.pressed = pressed;
3020 * GrSetWMProperties:
3021 * @wid: the ID of the window to set the WM properties of
3022 * @props: pointer to a GR_WM_PROPERTIES structure
3024 * Copies the provided GR_WM_PROPERTIES structure into the the GR_WM_PROPERTIES
3025 * structure of the specified window id.
3028 GrSetWMProperties(GR_WINDOW_ID wid, GR_WM_PROPERTIES *props)
3030 nxSetWMPropertiesReq *req;
3034 if ((props->flags & GR_WM_FLAGS_TITLE) && props->title)
3035 s = strlen(props->title) + 1;
3038 req = AllocReqExtra(SetWMProperties, s + sizeof(GR_WM_PROPERTIES));
3039 req->windowid = wid;
3040 addr = GetReqData(req);
3041 memcpy(addr, props, sizeof(GR_WM_PROPERTIES));
3043 memcpy(addr + sizeof(GR_WM_PROPERTIES), props->title, s);
3047 * GrGetWMProperties:
3048 * @wid: the ID of the window to retreive the WM properties of
3049 * @props: pointer to a GR_WM_PROPERTIES structure to fill in
3051 * Reads the GR_WM_PROPERTIES structure for the window with the specified
3052 * id and fills in the provided structure with the information.
3053 * It is the callers responsibility to free the title member as it is allocated
3054 * dynamically. The title field will be set to NULL if the window has no title.
3057 GrGetWMProperties(GR_WINDOW_ID wid, GR_WM_PROPERTIES *props)
3059 nxGetWMPropertiesReq *req;
3063 req = AllocReq(GetWMProperties);
3064 req->windowid = wid;
3066 GrTypedReadBlock(props, sizeof(GR_WM_PROPERTIES), GrNumGetWMProperties);
3067 GrReadBlock(&textlen, sizeof(textlen));
3069 props->title = NULL;
3072 if(!(props->title = malloc(textlen))) {
3073 /* Oh dear, we're out of memory but still have to purge the
3074 requested data (and throw it away) */
3075 while(textlen--) GrReadBlock(&c, 1);
3077 GrReadBlock(props->title, textlen);
3083 * @wid: the ID of the window to send the CLOSE_REQ event to
3085 * Sends a CLOSE_REQ event to the specified window if the client has selected
3086 * to receive CLOSE_REQ events on this window. Used to request an application
3087 * to shut down but not force it to do so immediately, so the application can
3088 * ask whether to save changed files before shutting down cleanly.
3091 GrCloseWindow(GR_WINDOW_ID wid)
3093 nxCloseWindowReq *req;
3095 req = AllocReq(CloseWindow);
3096 req->windowid = wid;
3101 * @wid: the ID of the window to kill
3103 * Forcibly disconnects the client which owns this window with the specified
3104 * ID number. Used to kill an application which has locked up and is not
3105 * responding to CLOSE_REQ events.
3108 GrKillWindow(GR_WINDOW_ID wid)
3110 nxKillWindowReq *req;
3112 req = AllocReq(KillWindow);
3113 req->windowid = wid;
3117 * GrSetScreenSaverTimeout:
3118 * @timeout: the number of seconds of inactivity before screen saver activates
3120 * Sets the number of seconds of inactivity before a screen saver activate
3121 * event is sent to the root window ID. A value of 0 activates the
3122 * screen saver immediately, and a value of -1 disables the screen saver
3126 GrSetScreenSaverTimeout(GR_TIMEOUT timeout)
3128 nxSetScreenSaverTimeoutReq *req;
3130 req = AllocReq(SetScreenSaverTimeout);
3131 req->timeout = timeout;
3135 * GrSetSelectionOwner:
3136 * @wid: the ID of the window to set the selection owner to
3137 * @typelist: list of mime types selection data can be supplied as
3139 * Sets the current selection (otherwise known as the clipboard) ownership
3140 * to the specified window. Specifying an owner of 0 disowns the selection.
3141 * The typelist argument is a list of mime types (seperated by space
3142 * characters) which the window is able to supply the data as. At least one
3143 * type must be specified unless you are disowning the selection (typically
3144 * text/plain for plain ASCII text or text/uri-list for a filename).
3146 * The window which owns the current selection must be prepared to handle
3147 * SELECTION_LOST events (received when another window takes ownership of the
3148 * selection) and CLIENT_DATA_REQ events (received when a client wishes to
3149 * retreive the selection data).
3152 GrSetSelectionOwner(GR_WINDOW_ID wid, GR_CHAR *typelist)
3154 nxSetSelectionOwnerReq *req;
3159 len = strlen(typelist) + 1;
3160 req = AllocReqExtra(SetSelectionOwner, len);
3161 p = GetReqData(req);
3162 memcpy(p, typelist, len);
3164 req = AllocReq(SetSelectionOwner);
3171 * GrGetSelectionOwner:
3172 * @typelist: pointer used to return the list of available mime types
3173 * @Returns: the ID of the window which currently owns the selection, or 0
3175 * Finds the window which currently owns the selection and returns its ID,
3176 * or 0 if no window currently owns the selection. A pointer to the list of
3177 * mime types the selection owner is capable of supplying is placed in the
3178 * pointer specified by the typelist argument. The typelist is null terminated,
3179 * and the fields are seperated by space characters. It is the callers
3180 * responsibility to free the typelist string, as it is allocated dynamically.
3181 * If the allocation fails, it will be set to a NULL pointer, so remember to
3182 * check the value of it before using it.
3185 GrGetSelectionOwner(GR_CHAR **typelist)
3187 nxGetSelectionOwnerReq *req;
3192 req = AllocReq(GetSelectionOwner);
3193 GrTypedReadBlock(&wid, sizeof(wid), GrNumGetSelectionOwner);
3195 GrReadBlock(&textlen, sizeof(textlen));
3196 if(!(*typelist = malloc(textlen))) {
3197 /* Oh dear, we're out of memory but still have to
3198 purge the requested data (and throw it away) */
3199 while(textlen--) GrReadBlock(&c, 1);
3201 GrReadBlock(*typelist, textlen);
3209 * GrRequestClientData:
3210 * @wid: the ID of the window requesting the data
3211 * @rid: the ID of the window to request the data from
3212 * @serial: the serial number of the request
3213 * @mimetype: the number of the desired mime type to request
3215 * Sends a CLIENT_DATA_REQ event to the specified window. Used for requesting
3216 * both selection and "drag and drop" data. The mimetype argument specifies
3217 * the format of the data you would like to receive, as an index into the list
3218 * returned by GrGetSelectionOwner (the first type in the list is index 0).
3219 * The server makes no guarantees as to when, or even if, the client will
3220 * reply to the request. If the client does reply, the reply will take the
3221 * form of one or more CLIENT_DATA events. The request serial number is
3222 * typically a unique ID which the client can assign to a request in order for
3223 * it to be able to keep track of transfers (CLIENT_DATA events contain the
3224 * same number in the sid field). Remember to free the data field of the
3225 * CLIENT_DATA events as they are dynamically allocated. Also note that if
3226 * the allocation fails the data field will be set to NULL, so you should
3227 * check the value before using it.
3230 GrRequestClientData(GR_WINDOW_ID wid, GR_WINDOW_ID rid, GR_SERIALNO serial,
3231 GR_MIMETYPE mimetype)
3233 nxRequestClientDataReq *req;
3235 req = AllocReq(RequestClientData);
3238 req->serial = serial;
3239 req->mimetype = mimetype;
3244 * @wid: the ID of the window sending the data
3245 * @did: the ID of the destination window
3246 * @sid: the serial number of the request
3247 * @len: the number of bytes of data to transfer
3248 * @thislen: the number of bytes in this packet
3249 * @data: pointer to the data to transfer
3251 * Used as the response to a CLIENT_DATA_REQ event. Sends the specified data
3252 * of the specified length to the specified window using the specified source
3253 * window ID and transfer serial number. Any fragmentation of the data into
3254 * multiple CLIENT_DATA events which is required is handled automatically.
3255 * The serial number should always be set to the value supplied by the
3256 * CLIENT_DATA_REQ event. The thislen parameter is used internally to split
3257 * the data up into packets. It should be set to the same value as the len
3262 GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial,
3263 GR_LENGTH len, GR_LENGTH thislen, void *data)
3265 nxSendClientDataReq *req;
3267 GR_LENGTH l, pos = 0;
3270 l = MAXREQUESTSZ - sizeof(nxSendClientDataReq);
3271 if(l > (len - pos)) l = len - pos;
3272 req = AllocReqExtra(SendClientData, l);
3275 req->serial = serial;
3277 p = GetReqData(req);
3278 memcpy(p, data + pos, l);
3286 * Asks the server to ring the console bell on behalf of the client (intended
3287 * for terminal apps to be able to ring the bell on the server even if they
3288 * are running remotely).
3297 * GrSetBackgroundPixmap:
3298 * @wid: ID of the window to set the background of
3299 * @pixmap: ID of the pixmap to use as the background
3300 * @flags: flags specifying how to draw the pixmap onto the window
3302 * Sets the background of the specified window to the specified pixmap.
3303 * The flags which specify how to draw the pixmap (in the top left of the
3304 * window, in the centre of the window, tiled, etc.) are those which start with
3305 * GR_BACKGROUND_ in nano-X.h. If the pixmap value is 0, the server will
3306 * disable the background pixmap and return to using a solid colour fill.
3309 GrSetBackgroundPixmap(GR_WINDOW_ID wid, GR_WINDOW_ID pixmap, int flags)
3311 nxSetBackgroundPixmapReq *req;
3313 req = AllocReq(SetBackgroundPixmap);
3315 req->pixmap = pixmap;
3321 * @id: ID of the cursor to destory
3323 * Destroys the specified server-based cursor and
3324 * reclaims the memory used by it.
3327 GrDestroyCursor(GR_CURSOR_ID cid)
3329 nxDestroyCursorReq *req;
3331 req = AllocReq(DestroyCursor);
3332 req->cursorid = cid;
3337 * @wid: window ID for query
3338 * @parentid: returned parent ID
3339 * @children: returned children ID list
3340 * @nchildren: returned children count
3342 * Return window parent and list of children.
3343 * Caller must free() children list after use.
3346 GrQueryTree(GR_WINDOW_ID wid, GR_WINDOW_ID *parentid, GR_WINDOW_ID **children,
3347 GR_COUNT *nchildren)
3349 nxQueryTreeReq *req;
3353 req = AllocReq(QueryTree);
3354 req->windowid = wid;
3356 GrTypedReadBlock(parentid, sizeof(*parentid), GrNumQueryTree);
3357 GrReadBlock(nchildren, sizeof(*nchildren));
3363 if(!(*children = malloc(count * sizeof(GR_WINDOW_ID)))) {
3364 /* We're out of memory but still have to purge the
3365 requested data (and throw it away) */
3367 GrReadBlock(&dummy, sizeof(GR_WINDOW_ID));
3369 GrReadBlock(*children, count * sizeof(GR_WINDOW_ID));
3373 #if YOU_WANT_TO_IMPLEMENT_DRAG_AND_DROP
3375 * GrRegisterDragAndDropWindow:
3376 * @wid: the ID of the window to use as the drag and drop source window
3377 * @iid: the ID of the pixmap to use as the drag and drop icon
3378 * @typelist: list of mime types the drag and drop data can be supplied as
3380 * Enables the specified window to be used as a drag and drop source. The
3381 * specified pixmap will be used as the icon shown whilst dragging, and the
3382 * null terminated, newline seperated list of mime types which the data can
3383 * be supplied as is specified by the typelist argument. At least one type
3384 * (typically text/plain for plain ASCII or text/uri-list for a filename or
3385 * list of filenames) must be specified. When the icon is dropped,
3386 * the window which it is dropped on will receive a DROP event (providing it
3387 * has selected for DROP events), and if the client wishes to accept the data
3388 * and is able to handle one of the mime types in the type list, it should use
3389 * GrRequestClientData() to retrieve the data from the drag and drop source
3390 * window. Remember to free the typelist field of the DROP event as it is
3391 * dynamically allocated. It is possible for a client to select for DROP events
3392 * on the Root window if it is desired to allow dropping icons on the desktop.
3395 GrRegisterDragAndDropWindow(GR_WINDOW_ID wid, GR_WINDOW_ID iid,
3403 GrCreateTimer (GR_WINDOW_ID wid, GR_TIMEOUT period)
3405 nxCreateTimerReq *req;
3406 GR_TIMER_ID timerid;
3408 req = AllocReq(CreateTimer);
3411 req->period = period;
3413 if (GrTypedReadBlock(&timerid, sizeof (timerid), GrNumCreateTimer) == -1)
3419 GrDestroyTimer (GR_TIMER_ID tid)
3421 nxDestroyTimerReq *req;
3423 req = AllocReq(DestroyTimer);
3428 GrSetPortraitMode(int portraitmode)
3430 nxSetPortraitModeReq *req;
3432 req = AllocReq(SetPortraitMode);
3433 req->portraitmode = portraitmode;