[Prev][Next][Index][Thread]
Huzzah for xqcam!
Huzzah for xqcam! I convinced it to work for me by not using shared
memory. Huzzah huzzah! The patch below, made to the xqcam.c in
qcam-0.3, adds a new compile-time option to disable shared memory
completely, or to make it a command-line option, -S, that defaults to
no use of shared memory. Oh, shoot -- I just noticed that I didn't
define away the -S option if NO_XSHM is defined, and I'm too lazy to
fix the diffs.
diff -u qcam-0.3.orig/xqcam.c qcam-0.3/xqcam.c
--- qcam-0.3/xqcam.c Sat Jan 6 14:12:48 1996
+++ qcam-0.3.orig/xqcam.c Wed Jan 10 16:36:00 1996
@@ -18,11 +18,13 @@
#include <X11/keysym.h>
#include <unistd.h>
+#ifndef NO_XSHM
/** MIT Shared Memory Extension for X ************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
XShmSegmentInfo SHMInfo;
+#endif
/** QuickCam include files */
@@ -41,8 +43,10 @@
GC gc;
int screen_num;
unsigned long white,black;
-int xstarted=0;
int quit=0;
+int shm_ckpnt = 0, use_shm = 0, xerror;
+
+static void unmap_shared_mem(void);
/* Set a flag to exit the loop at the end */
@@ -51,6 +55,27 @@
quit=1;
}
+static int error_handler(Display *disp, XErrorEvent *event)
+{
+ xerror = 1;
+
+ return 0;
+}
+
+static void trap_errors(void)
+{
+ xerror = 0;
+ XSetErrorHandler(error_handler);
+}
+
+static int untrap_errors(void)
+{
+ XSync(disp,0);
+ XSetErrorHandler(NULL);
+ return xerror;
+}
+
+
/** Initialize xwindows, and prepare a shared memory buffer for
the image. Returns pointer to shared memory buffer. */
@@ -64,6 +89,9 @@
char *window_name="QuickCam";
char *icon_name="QuickCam";
XTextProperty windowName, iconName;
+ int result;
+ int majver, minver;
+ Bool sharedpix;
width=q->width;
height=q->height;
@@ -106,43 +134,93 @@
XNextEvent(disp, &ev);
gc = XCreateGC(disp, win, 0, &values);
-
- ximage = XShmCreateImage(disp, DefaultVisual(disp, screen_num),
+
+ unmap_shared_mem();
+
+ if (!shm_ckpnt) atexit(unmap_shared_mem);
+ shm_ckpnt = 1;
+
+#ifndef NO_XSHM
+ if (use_shm && XShmQueryVersion(disp, &majver, &minver, &sharedpix)) {
+ printf("Using shared memory.\n");
+
+ trap_errors();
+ ximage = XShmCreateImage(disp, DefaultVisual(disp, screen_num),
8, ZPixmap, NULL, &SHMInfo, width, height);
- if(!ximage) {
- printf("CreateImage Failed\n");
- return(NULL);
- }
-
- SHMInfo.shmid=shmget(IPC_PRIVATE,
- ximage->bytes_per_line*ximage->height,
- IPC_CREAT|0777);
-
- if(SHMInfo.shmid < 0) {
- perror("shmget failed:");
- return (NULL);
- }
-
- sbuf = ximage->data = SHMInfo.shmaddr = shmat(SHMInfo.shmid, 0, 0);
- XShmAttach(disp, &SHMInfo);
+ if (untrap_errors()) {
+ unmap_shared_mem();
+ goto shmerror;
+ }
+ if (!ximage) {
+ printf("ShmCreateImage Failed\n");
+ return(NULL);
+ }
+ shm_ckpnt++;
+
+ SHMInfo.shmid=shmget(IPC_PRIVATE,
+ ximage->bytes_per_line*ximage->height,
+ IPC_CREAT|0777);
+
+ if(SHMInfo.shmid < 0) {
+ unmap_shared_mem();
+ goto shmerror;
+ }
+ shm_ckpnt++;
+
+ sbuf = ximage->data = SHMInfo.shmaddr = shmat(SHMInfo.shmid, 0, 0);
+ if (ximage->data == ((char *) -1)) {
+ unmap_shared_mem();
+ goto shmerror;
+ }
+ shm_ckpnt++;
+
+ SHMInfo.readOnly = False;
+
+ trap_errors();
+ result = XShmAttach(disp, &SHMInfo);
+ if (untrap_errors() || !result) {
+ unmap_shared_mem();
+ goto shmerror;
+ }
+ shm_ckpnt++;
+ } else
+#endif
+ {
+
+ shmerror:
+ use_shm = 0;
+
+ sbuf = malloc(width * height);
+ ximage = XCreateImage(disp,
+ DefaultVisual(disp,screen_num), 8,
+ ZPixmap, 0, sbuf, width, height,
+ 8, 0);
+ if (ximage == NULL) {
+ printf("CreateImage Failed\n");
+ return(NULL);
+ }
+ shm_ckpnt++;
+ }
+
signal(SIGHUP, quitprogram);
signal(SIGINT, quitprogram);
signal(SIGQUIT, quitprogram);
signal(SIGTERM, quitprogram);
- xstarted=1;
return(sbuf);
}
-void ExitXWindows(void)
+static void unmap_shared_mem(void)
{
- if(xstarted) {
- XShmDetach(disp, &SHMInfo);
- if(SHMInfo.shmaddr)
- shmdt(SHMInfo.shmaddr);
- if(SHMInfo.shmid > 0)
- shmctl(SHMInfo.shmid, IPC_RMID, 0);
+#ifndef NO_XSHM
+ if (shm_ckpnt > 4) XShmDetach(disp, &SHMInfo);
+ if (shm_ckpnt > 3) shmdt(SHMInfo.shmaddr);
+ if (shm_ckpnt > 2) shmctl(SHMInfo.shmid, IPC_RMID, 0);
+#endif
+ if (shm_ckpnt > 1) {
+ XDestroyImage(ximage);
}
+ if (shm_ckpnt > 0) shm_ckpnt = 1;
}
@@ -155,6 +233,7 @@
for(i=0; i<64; i++) {
col.red =col.green = col.blue = i * 1024;
+ col.flags = DoRed | DoGreen | DoBlue;
if (!XAllocColor(disp, cmap, &col)) {
fprintf(stderr,"XAllocColor failed on %d\n",i);
}
@@ -188,7 +267,15 @@
free(scan);
- XShmPutImage(disp, win, gc, ximage, 0,0,0,0,q->width, q->height, False);
+#ifndef NO_XSHM
+ if (use_shm)
+ XShmPutImage(disp, win, gc, ximage, 0, 0, 0, 0,
+ q->width, q->height, False);
+ else
+#endif
+ XPutImage(disp, win, gc, ximage, 0, 0, 0, 0,
+ q->width, q->height);
+
XFlush(disp);
}
@@ -207,6 +294,7 @@
fprintf(stderr," -b val Set brightness\n");
fprintf(stderr," -V Show version information\n");
fprintf(stderr," -v Verbose output\n");
+ fprintf(stderr," -S Use shared memory\n");
fprintf(stderr," -C Use private colormap\n");
@@ -245,7 +333,7 @@
/* Read command line */
- while((arg=getopt(argc,argv,"hCvx:y:p:b:B:c:w:V"))>0) {
+ while((arg=getopt(argc,argv,"hCvx:y:p:b:B:c:w:VS"))>0) {
switch (arg) {
case 'x':
q->width=atoi(optarg);
@@ -283,6 +371,9 @@
case 'v':
verbose=1;
break;
+ case 'S':
+ use_shm=1;
+ break;
default:
fprintf(stderr,"%s: Unknown option or error in option\n",argv[0]);
usage();
@@ -364,7 +455,7 @@
}
- ExitXWindows();
+ unmap_shared_mem();
/* Release IO privileges */
qc_close(q);
-russ <nelson@crynwr.com> http://www.crynwr.com/~nelson
Crynwr Software | Crynwr Software sells packet driver support | PGP ok
11 Grant St. | +1 315 268 1925 voice | Good government is a contradiction
Potsdam, NY 13676 | +1 315 268 9201 FAX | in terms. Ask me for details.