/* wmressel.c X11 resolution selector (for Window Maker) by Sébastien "Slix" Liénard , GCU Squad (http://gcu-squad.org) based on gvidm and wmtimer and licensed through the GNU General Public License. Read the COPYING file for the complete GNU license. */ #include #include #include #include #include #include #include #include #include #include #include #include #define V_PHSYNC 0x001 #define V_NHSYNC 0x002 #define V_PVSYNC 0x004 #define V_NVSYNC 0x008 #define V_INTERLACE 0x010 #define V_DBLSCAN 0x020 #define V_CSYNC 0x040 #define V_PCSYNC 0x080 #define V_NCSYNC 0x100 #ifdef HAVE_LIBXINERAMA #include #endif #include #include "wmgeneral/wmgeneral.h" #include "wmgeneral/misc.h" #include "wmressel-master.xpm" #include "wmressel-mask.xbm" #define MY_EMAIL "slix@gcu-squad.org" #define GCU_HOME "http://gcu-squad.org/" #define WMRESSEL_VERSION "0.8" typedef struct { int screen; int mode; } MENU_CHOICE; void usage(void); void printVersion(void); void BlitString(char *name, int x, int y); void BlitNum(int num, int x, int y); void wmressel_routine(int, char **, int); void MenuEvent (GtkWidget *, gpointer); void on_deactivate(void); void create_popup(int); GtkWidget *create_screen_submenu (int); char *create_submenu_label(XF86VidModeModeInfo *, XF86VidModeModeLine, int); void update_res_display(int); void show_screen_number(int); int get_screen_count(void); char *ProgName; int show_refresh_rate=0; int show_doublescan=0; int show_only_selected=0; int main(int argc, char *argv[]) { int i, selected_screen=0; char *endp=NULL; /* Parse Command Line */ ProgName = argv[0]; if (strlen(ProgName) >= 5) ProgName += (strlen(ProgName) - 5); for (i=1; i screen_count-1) { printf("\nScreen number %i is not valid !!!\n", selected_screen); usage(); exit(1); } if (screen_count > 1) { show_screen_number(selected_screen); show_number=1; } else { update_res_display(selected_screen); } AddMouseRegion( 0, 5, 5, 55, 55); gtk_init (&argc, &argv); while (1) { /* X Events */ while (XPending(display)) { XNextEvent(display, &Event); switch (Event.type) { case Expose: RedrawWindow(); break; case DestroyNotify: XCloseDisplay(display); exit(0); break; case ButtonPress: i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y); but_stat = i; break; case ButtonRelease: i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y); if (but_stat == i && but_stat >= 0) { screen_count=get_screen_count(); if(Event.xbutton.button==1) { /* Left button pressed, popup menu */ create_popup(selected_screen); gtk_main(); update_res_display(selected_screen); } else if (Event.xbutton.button==3 && screen_count>1) { /* Right button pressed, view screen number */ show_screen_number(selected_screen); show_number=1; } else if (Event.xbutton.button==4 && screen_count>1) { /* Mouse wheel up, select next screen */ if(selected_screen==get_screen_count()-1) { selected_screen=0; } else { selected_screen++; } show_screen_number(selected_screen); show_number=1; } else if (Event.xbutton.button==5 && screen_count>1) { /* Mouse wheel down, select previous screen */ if(selected_screen==0) { selected_screen=get_screen_count()-1; } else { selected_screen--; } show_screen_number(selected_screen); show_number=1; } } but_stat = -1; break; } } if(show_number) { j++; if (j==10) { update_res_display(selected_screen); show_number=0; j=0; } } usleep(100000L); } } /******************** * Create popup menu * ********************/ void create_popup(int selected_screen) { GtkWidget *menu_ptr; int i; char label_str[14]; GtkWidget *submenu_ptr, *menuitem_ptr; int screen_count = get_screen_count(); if (screen_count > 1 && !show_only_selected) { menu_ptr = gtk_menu_new(); for (i=0; iscreen, &vm_count, &vm_modelines); XF86VidModeSwitchToMode(display, ((MENU_CHOICE *)menu_choice)->screen, vm_modelines[((MENU_CHOICE *)menu_choice)->mode]); XFlush(display); free(vm_modelines); } /*************************** * Return number of screens * ***************************/ int get_screen_count() { int screen_count; #ifdef HAVE_LIBXINERAMA int i; int screen_exists[1024]; XineramaScreenInfo *screen; if (XineramaIsActive(display)) { screen = XineramaQueryScreens(display, screen_exists); for (i=0; i==screen[i].screen_number; i++){} screen_count=i; XFree(screen); } else { #endif screen_count = XScreenCount(display); #ifdef HAVE_LIBXINERAMA } #endif return(screen_count); } void on_deactivate(void) { gtk_main_quit(); } /********************************* * Create a label for a menu item * **********************************/ char *create_submenu_label(XF86VidModeModeInfo *modeline, XF86VidModeModeLine current, int dotclock) { char *label_str; char def[3], res[12]; char rr[8]=""; char ds[3]=""; label_str = malloc(sizeof(def)+sizeof(res)+sizeof(rr)+sizeof(ds)-3); if ((current.hdisplay==modeline->hdisplay) && (current.vdisplay==modeline->vdisplay) && (dotclock==modeline->dotclock)) { sprintf(def, "* "); } else { sprintf(def, " "); } sprintf(res, "%ix%i", modeline->hdisplay, modeline->vdisplay); if (show_refresh_rate) { if ((modeline->flags) & V_DBLSCAN) { sprintf(rr, "@%iHz", modeline->dotclock*500/(modeline->htotal*modeline->vtotal)); } else { sprintf(rr, "@%iHz", modeline->dotclock*1000/(modeline->htotal*modeline->vtotal)); } } if (show_doublescan && ((modeline->flags) & V_DBLSCAN)) sprintf (ds, " D"); sprintf(label_str, "%s%s%s%s", def, res, rr, ds); return (label_str); } /******************************************************* * Create menu composed of available modes for a screen * *******************************************************/ GtkWidget *create_screen_submenu (int screen) { int i, dotclock, vm_count=0; MENU_CHOICE *menu_choice; char *label_str; GtkWidget *menuitem_ptr, *menu_ptr; XF86VidModeModeInfo **vm_modelines; XF86VidModeModeLine modeline; XF86VidModeGetAllModeLines(display, screen, &vm_count, &vm_modelines); XF86VidModeGetModeLine(display, screen, &dotclock, &modeline); menu_ptr = gtk_menu_new(); for (i=0; iscreen=screen; menu_choice->mode=i; menuitem_ptr = gtk_menu_item_new_with_label(label_str); gtk_signal_connect(GTK_OBJECT (menuitem_ptr), "activate", GTK_SIGNAL_FUNC (MenuEvent), (gpointer)menu_choice); gtk_menu_append(GTK_MENU (menu_ptr), menuitem_ptr); gtk_widget_show(menuitem_ptr); free(label_str); } free(vm_modelines); return(menu_ptr); } /****************************************** * Update displayed resolution information * ******************************************/ void update_res_display(int screen) { int dotclock; XF86VidModeModeLine modeline; XF86VidModeGetModeLine(display, screen, &dotclock, &modeline); /* Clear screen zone */ copyXPMArea(76, 12, 35, 29, 14, 13); /* Show resolution */ BlitNum(modeline.hdisplay, 41, 14); BlitString("X", 15, 23); BlitNum(modeline.vdisplay, 41, 23); /* Show frequency */ if ((modeline.flags) & V_DBLSCAN) { BlitNum(dotclock*500/(modeline.htotal*modeline.vtotal), 29, 32); } else { BlitNum(dotclock*1000/(modeline.htotal*modeline.vtotal), 29, 32); } BlitString("Hz", 35, 32); RedrawWindow(); } /***************************** * Show screen number (SCR X) * *****************************/ void show_screen_number(int screen) { /* Clear screen zone */ copyXPMArea(76, 12, 35, 29, 14, 13); BlitString("Scr", 15, 23); BlitNum(screen, 41, 23); RedrawWindow(); } /* Blits a string at given co-ordinates */ void BlitString(char *name, int x, int y) { int i; int c; int k; k = x; for (i=0; name[i]; i++) { c = toupper(name[i]); if (c >= 'A' && c <= 'Z') { /* its a letter */ c -= 'A'; copyXPMArea(c * 6, 74, 6, 8, k, y); k += 6; } else { /* its a number or symbol */ c -= '0'; copyXPMArea(c * 6, 64, 6, 8, k, y); k += 6; } } } /* Blits number to give coordinates.. nine 0's, right justified */ void BlitNum(int num, int x, int y) { char buf[1024]; int newx=x; if ( num > 9 ) newx -= 6; if ( num > 99 ) newx -= 6; if ( num > 999 ) newx -= 6; if ( num > 9999 ) newx -= 6; sprintf(buf, "%i", num); BlitString(buf, newx, y); } /*******************************************************************************\ |* usage *| \*******************************************************************************/ void usage(void) { printf ("\n wmressel version %s -- X11 resolution selector for Window Maker\n", WMRESSEL_VERSION ); printf (" Copyright (C) 2002 Sébastien Liénard <%s>\n", MY_EMAIL); printf (" from GCU (%s)\n",GCU_HOME); printf (" This software comes with NO WARRANTY.\n\n"); printf ("usage:\n"); printf ("\t-r\t\t\tShow refresh rates in menu\n"); printf ("\t-d\t\t\tShow in menu if a mode is a Doublescan mode (D)\n"); printf ("\t-s \t\tShow information about this screen\n"); printf ("\t-o\t\t\tOnly show menu for selected screen\n"); printf ("\t--display \tSet display\n"); printf ("\t-h\t\t\tthis help screen\n"); printf ("\t-v\t\t\tprint the version number\n"); printf ("\n"); } /*******************************************************************************\ |* printVersion *| \*******************************************************************************/ void printVersion(void) { fprintf(stderr, "wmressel v%s\n", WMRESSEL_VERSION); }