/* capsind This program is Spokane's implimentation of the caps-lock indicator program supplied without source by WS-COE. It is intended to be run as a front-panel client control. It works by calling XQueryPointer every 300 milliseconds and examining the modifier flags returned. The window displayed is a simple label that says "nocap" when caps lock is off and "CAPS" when it is on. The background of the label is turned red when caps lock is on. */ char ident[]="@(#)capsind Spokane $Revision: 1.6 $ $Date: 2000-08-16 11:36:14-07 $"; char progname[]="capsind"; #include #include #include #include #include #include #include #include #include #include /* X Windows objects and pointers */ XtAppContext app_context; Display *app_display; Widget top_level; Window mywin; Widget FPlabel; Pixel DefaultBackground; /* For saving the default color */ Pixel RedPixel; XtIntervalId TimerID; unsigned int last_lockmask=0; void CheckMasks(); XtArgVal GetPixel(); void WM_SaveSelfCB(); void WM_ShutDownCB(); /****************************** BEGIN MAIN ************************/ main(argc,argv) int argc; char *argv[]; { Arg args[10]; int n; char *null_display=NULL; Atom atom; XmString label_string; Widget myframe; XmFontListEntry flentry1; XmFontList fontlist; /* Attempt to open the display so we don't blow up if we can't for some reason. */ if ((app_display=XOpenDisplay(null_display))==NULL) { fprintf(stderr,"%s: ERR: Unable to connect to X server.\n",progname); exit(1); } /* Initialize the toolkit, create an application context, and open the display "officially". Also, Xlib parses options it understands from the command line. */ top_level=XtAppInitialize(&app_context,"Capsind", (XrmOptionDescRec *)NULL,(Cardinal)0,&argc,argv, NULL,args,0); app_display=XtDisplay(top_level); /* Register callbacks for the window manager to cover the Delete_Window and Save_Yourself events. */ atom=XmInternAtom(app_display,"WM_SAVE_YOURSELF",True); XmAddWMProtocols(top_level,&atom,1); XmAddWMProtocolCallback(top_level,atom,WM_SaveSelfCB,NULL); atom=XmInternAtom(app_display,"WM_DELETE_WINDOW",True); XmAddWMProtocols(top_level,&atom,1); XmAddWMProtocolCallback(top_level,atom,WM_ShutDownCB,NULL); /* Select a font that will fit in the space on the front panel. Use one of the standard CDE user fonts to be compatible between platforms. */ /* "-dt-interface user-medium-r-normal-s*-*-*-*-*-*-*-*-*:", */ flentry1=XmFontListEntryLoad(app_display, "-misc-fixed-bold-r-normal-*-*-*-*-*-*-*-*-*", XmFONT_IS_FONT,"fonttag1"); fontlist=XmFontListAppendEntry(NULL,flentry1); /* Create a frame to contain the label widget */ n=0; XtSetArg(args[n],XmNshadowType,XmSHADOW_OUT); n++; XtSetArg(args[n],XmNshadowThickness,2); n++; myframe=XmCreateFrame(top_level,"FPframe",args,n); XtManageChild(myframe); /* Create the main label widget. */ label_string=XmStringCreateLocalized("nocap"); n=0; XtSetArg(args[n],XmNlabelString,label_string); n++; XtSetArg(args[n],XmNfontList,fontlist); n++; FPlabel=XmCreateLabel(myframe,"FPlabel",args,n); XmStringFree(label_string); XtManageChild(FPlabel); /* Save the default background color being used in the label. This will differ, depending on the user's platform and desktop style setting. */ n=0; XtSetArg(args[n],XmNbackground,&DefaultBackground); n++; XtGetValues(FPlabel,args,n); /* Get a red pixel value for use when capslock is on. */ RedPixel=(Pixel)GetPixel(top_level,"red"); XtRealizeWidget(top_level); mywin=XtWindow(top_level); /* Set the initial timed callback. */ TimerID=XtAppAddTimeOut(app_context,300,(XtTimerCallbackProc)CheckMasks, (XtPointer)NULL); XtAppMainLoop(app_context); exit(0); } /****************************** END MAIN ************************/ /********************************/ void CheckMasks(client_data,ID) XtPointer client_data; XtIntervalId *ID; { Arg args[10]; int n; Window root_return, child_return; int root_x_return, root_y_return, win_x_return, win_y_return; unsigned int mask_return=0, current_lockmask; XmString label_string; XQueryPointer(app_display,mywin,&root_return,&child_return, &root_x_return,&root_y_return,&win_x_return,&win_y_return, &mask_return); current_lockmask=mask_return&LockMask; if (current_lockmask!=last_lockmask) { n=0; if (current_lockmask) { label_string=XmStringCreateLocalized("CAPS"); XtSetArg(args[n],XmNbackground,RedPixel); n++; } else { label_string=XmStringCreateLocalized("nocap"); XtSetArg(args[n],XmNbackground,DefaultBackground); n++; } XtSetArg(args[n],XmNlabelString,label_string); n++; XtSetValues(FPlabel,args,n); XmStringFree(label_string); last_lockmask=current_lockmask; } TimerID=XtAppAddTimeOut(app_context,300,(XtTimerCallbackProc)CheckMasks, (XtPointer)NULL); } /********************************/ /********************************/ XtArgVal GetPixel(widget,colorstr) Widget widget; char *colorstr; /* This function takes an ascii text color name such as "red" and converts it to a pixel value suitable for use in an XtSetArg() call. */ { XrmValue from, to; from.size=strlen(colorstr)+1; if (from.size