void display_image() { Display *d; int s; Window w; XEvent e; /* open connection with the server */ d=XOpenDisplay(NULL); if(d==NULL) { printf("Cannot open display\n"); exit(1); } s=DefaultScreen(d); Visual * vis; vis = DefaultVisual(d,s); char * dImage = (char *)malloc(sizeof(png_byte) * height); XImage * image = XCreateImage(d,vis, bit_depth, ZPixmap, 0, dImage, width, height, 16, 0); // XCreatePixmap(d, DefaultRootWindow(display),width, height, depth); //gc = XCreateGC(display, pixmap, 0, &gcv); //XPutImage(display, pixmap, gc, image, 0,0,0,0,width, height); /* create window */ w=XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1, BlackPixel(d, s), WhitePixel(d, s)); // Process Window Close Event through event handler so XNextEvent does Not fail Atom delWindow = XInternAtom( d, "WM_DELETE_WINDOW", 0 ); XSetWMProtocols(d , w, &delWindow, 1); /* select kind of events we are interested in */ XSelectInput(d, w, ExposureMask | KeyPressMask); /* map (show) the window */ XMapWindow(d, w); /* event loop */ while(1) { XNextEvent(d, &e); /* draw or redraw the window */ if(e.type==Expose) { XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); } /* exit on key press */ if(e.type==KeyPress) break; // Handle Windows Close Event if(e.type==ClientMessage) break; } /* destroy our window */ XDestroyWindow(d, w); /* close connection to server */ XCloseDisplay(d); }
void win::set_wm_close() { Atom wm_delete_window; wm_delete_window = XInternAtom(disp, "WM_DELETE_WINDOW", False); XSetWMProtocols(disp, w, &wm_delete_window, 1); }
int main(int argc, char *argv[]) { Boolean exists; char *filename; FileAccess file_access; Widget source; XtAppContext appcon; Boolean show_dir; xedit_flist_item *first_item; unsigned int i, lineno; lineno = 0; show_dir = FALSE; first_item = NULL; topwindow = XtAppInitialize(&appcon, "Xedit", NULL, 0, &argc, argv, NULL, NULL, 0); XtAppAddActions(appcon, actions, XtNumber(actions)); XtOverrideTranslations(topwindow, XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()")); XtGetApplicationResources(topwindow, (XtPointer) &app_resources, resources, XtNumber(resources), NULL, 0); CurDpy = XtDisplay(topwindow); XawSimpleMenuAddGlobalActions(appcon); XtRegisterGrabAction(PopupMenu, True, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync); makeButtonsAndBoxes(topwindow); StartHints(); StartFormatPosition(); (void)StartHooks(appcon); if (position_format_mask == 0) { for (i = 0; i < 3; i++) XtRemoveCallback(texts[i], XtNpositionCallback, PositionChanged, NULL); } XtRealizeWidget(topwindow); #ifndef __UNIXOS2__ XeditLispInitialize(); #endif options_popup = XtCreatePopupShell("optionsMenu", simpleMenuWidgetClass, topwindow, NULL, 0); XtRealizeWidget(options_popup); XtAddCallback(XtCreateManagedWidget("ispell", smeBSBObjectClass, options_popup, NULL, 0), XtNcallback, IspellCallback, NULL); CreateEditPopup(); wm_delete_window = XInternAtom(XtDisplay(topwindow), "WM_DELETE_WINDOW", False); (void)XSetWMProtocols(XtDisplay(topwindow), XtWindow(topwindow), &wm_delete_window, 1); /* This first call is just to save the default font and colors */ UpdateTextProperties(0); if (argc > 1) { xedit_flist_item *item; Arg args[2]; unsigned int num_args; for (i = 1; i < argc; i++) { struct stat st; if (argv[i][0] == '+') { char *endptr; lineno = strtol(argv[i], &endptr, 10); /* Don't warn about incorrect input? */ if (*endptr) lineno = 0; continue; } filename = ResolveName(argv[i]); if (filename == NULL || FindTextSource(NULL, filename) != NULL) continue; num_args = 0; if (stat(filename, &st) == 0 && !S_ISREG(st.st_mode)) { if (S_ISDIR(st.st_mode)) { if (!first_item) { char path[BUFSIZ + 1]; strncpy(path, filename, sizeof(path) - 2); path[sizeof(path) - 2] = '\0'; if (*path) { if (path[strlen(path) - 1] != '/') strcat(path, "/"); } else strcpy(path, "./"); XtSetArg(args[0], XtNlabel, ""); XtSetValues(dirlabel, args, 1); SwitchDirWindow(True); DirWindowCB(dirwindow, path, NULL); show_dir = True; } continue; } } switch (file_access = CheckFilePermissions(filename, &exists)) { case NO_READ: if (exists) XeditPrintf("File %s exists, and could not be opened for " "reading.\n", argv[i]); else XeditPrintf("File %s does not exist, and the directory " "could not be opened for writing.\n", argv[i]); break; case READ_OK: XtSetArg(args[num_args], XtNeditType, XawtextRead); num_args++; XeditPrintf("File %s opened READ ONLY.\n", argv[i]); break; case WRITE_OK: XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++; XeditPrintf("File %s opened read - write.\n", argv[i]); break; } if (file_access != NO_READ) { int flags; if (exists) { flags = EXISTS_BIT; XtSetArg(args[num_args], XtNstring, filename);num_args++; } else { flags = 0; XtSetArg(args[num_args], XtNstring, NULL); num_args++; } source = XtVaCreateWidget("textSource", international ? multiSrcObjectClass : asciiSrcObjectClass, topwindow, XtNtype, XawAsciiFile, XtNeditType, XawtextEdit, NULL, NULL); XtSetValues(source, args, num_args); item = AddTextSource(source, argv[i], filename, flags, file_access); XtAddCallback(item->source, XtNcallback, SourceChanged, (XtPointer)item); if (exists && file_access == WRITE_OK) { item->mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); item->mtime = st.st_mtime; } if (!first_item && !show_dir) first_item = item; ResetSourceChanged(item); } } } if (!flist.pixmap && strlen(app_resources.changed_pixmap_name)) { XrmValue from, to; from.size = strlen(app_resources.changed_pixmap_name); from.addr = app_resources.changed_pixmap_name; to.size = sizeof(Pixmap); to.addr = (XtPointer)&(flist.pixmap); XtConvertAndStore(flist.popup, XtRString, &from, XtRBitmap, &to); } if (first_item == NULL) { XtSetKeyboardFocus(topwindow, filenamewindow); XtVaSetValues(textwindow, XtNwrap, XawtextWrapLine, NULL); } else { SwitchTextSource(first_item); XtSetKeyboardFocus(topwindow, textwindow); if (lineno) { XawTextPosition position; source = XawTextGetSource(textwindow); position = RSCAN(XawTextGetInsertionPoint(textwindow), lineno, False); position = LSCAN(position, 1, False); XawTextSetInsertionPoint(textwindow, position); } } XtAppMainLoop(appcon); return EXIT_SUCCESS; }
// Create the X11 window (and its colormap) // static GLboolean createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { unsigned long wamask; XSetWindowAttributes wa; XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; // Every window needs a colormap // Create one based on the visual used by the current context // TODO: Decouple this from context creation window->x11.colormap = XCreateColormap(_glfw.x11.display, _glfw.x11.root, visual->visual, AllocNone); // Create the actual window { wamask = CWBorderPixel | CWColormap | CWEventMask; wa.colormap = window->x11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask; if (wndconfig->monitor == NULL) { // HACK: This is a workaround for windows without a background pixel // not getting any decorations on certain older versions of Compiz // running on Intel hardware wa.background_pixel = BlackPixel(_glfw.x11.display, _glfw.x11.screen); wamask |= CWBackPixel; } window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, 0, 0, wndconfig->width, wndconfig->height, 0, // Border width visual->depth, // Color depth InputOutput, visual->visual, wamask, &wa); if (!window->x11.handle) { // TODO: Handle all the various error codes here and translate them // to GLFW errors _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); return GL_FALSE; } if (!wndconfig->decorated) { MotifWmHints hints; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.MOTIF_WM_HINTS, _glfw.x11.MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char*) &hints, sizeof(MotifWmHints) / sizeof(long)); } XSaveContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context, (XPointer) window); } if (window->monitor && !_glfw.x11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window // manager ignore the window completely (ICCCM, section 4) // The good thing is that this makes undecorated fullscreen windows // easy to do; the bad thing is that we have to do everything manually // and some things (like iconify/restore) won't work at all, as those // are tasks usually performed by the window manager XSetWindowAttributes attributes; attributes.override_redirect = True; XChangeWindowAttributes(_glfw.x11.display, window->x11.handle, CWOverrideRedirect, &attributes); window->x11.overrideRedirect = GL_TRUE; } // Declare the WM protocols supported by GLFW { int count = 0; Atom protocols[2]; // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol if (_glfw.x11.WM_DELETE_WINDOW != None) protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; // The _NET_WM_PING EWMH protocol // Tells the WM to ping the GLFW window and flag the application as // unresponsive if the WM doesn't get a reply within a few seconds if (_glfw.x11.NET_WM_PING != None) protocols[count++] = _glfw.x11.NET_WM_PING; if (count > 0) { XSetWMProtocols(_glfw.x11.display, window->x11.handle, protocols, count); } } if (_glfw.x11.NET_WM_PID != None) { const pid_t pid = getpid(); XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &pid, 1); } // Set ICCCM WM_HINTS property { XWMHints* hints = XAllocWMHints(); if (!hints) { _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints"); return GL_FALSE; } hints->flags = StateHint; hints->initial_state = NormalState; XSetWMHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) { XSizeHints* hints = XAllocSizeHints(); hints->flags = 0; if (wndconfig->monitor) { hints->flags |= PPosition; _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); } if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); hints->min_width = hints->max_width = wndconfig->width; hints->min_height = hints->max_height = wndconfig->height; } XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } if (_glfw.x11.xi.available) { // Select for XInput2 events /* XIEventMask eventmask; unsigned char mask[] = { 0 }; eventmask.deviceid = 2; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_Motion); XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); */ } _glfwPlatformSetWindowTitle(window, wndconfig->title); // XRRSelectInput(_glfw.x11.display, window->x11.handle, // RRScreenChangeNotifyMask); _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); return GL_TRUE; }
bool X11Window::_impl_open(WindowDesc desc) { union { X11::XVisualInfo_a* _vi; XVisualInfo* vi; }; if( !sX11Display ) { sX11Display = XOpenDisplay(0); } if( sX11Context == 0 ){ sX11Context = XUniqueContext(); } m_Display = sX11Display; if(!m_Display){ LOG_ERROR(General, "Cannt connect to X server"); return false; } int32 visual_attribs[] = { GLX_X_RENDERABLE , 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , desc.red_bits, GLX_GREEN_SIZE , desc.green_bits, GLX_BLUE_SIZE , desc.blue_bits, GLX_ALPHA_SIZE , desc.alpha_bits, GLX_DEPTH_SIZE , desc.depth_bits, GLX_STENCIL_SIZE , desc.stencil_bits, GLX_DOUBLEBUFFER , True, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; int32 fbcount; GLXFBConfig* fbc = glXChooseFBConfig(m_Display, DefaultScreen(m_Display), visual_attribs, &fbcount); if(!fbc) { LOG_ERROR(General,"Failed to rectrieve a framebuffer config"); return false; } int32 best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; for (int32 i=0; i<fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig( m_Display, fbc[i] ); if ( vi ) { int32 samp_buf, samples; glXGetFBConfigAttrib( m_Display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( m_Display, fbc[i], GLX_SAMPLES , &samples ); if ( best_fbc < 0 || samp_buf && samples > best_num_samp ) best_fbc = i, best_num_samp = samples; if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) worst_fbc = i, worst_num_samp = samples; } } GLXFBConfig bestFbc = fbc[ best_fbc ]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree( fbc ); m_FBConfig = bestFbc; // Get a visual vi = glXGetVisualFromFBConfig( m_Display, bestFbc ); m_VisualInfo = _vi; XSetWindowAttributes swa; Colormap cmap; swa.colormap = cmap = XCreateColormap( m_Display, RootWindow( m_Display, vi->screen ), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; //int32 ret = XChangeWindowAttributes(display, window, CWBorderPixel|CWColormap|CWEventMask, &swa); m_Window = XCreateWindow( m_Display, RootWindow( m_Display, vi->screen ), desc.posX, desc.posY, desc.width, desc.height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); XStoreName( m_Display, m_Window, desc.title); uint32 ctx = sX11Context; XSaveContext(m_Display, m_Window, sX11Context, (XPointer) this); /* XWMHints *hints; hints.x = desc.posX; hints.y = desc.posY; hints.width = desc.width; hints.height = desc.height; hints.flags = USPosition|USSize; XWMHints *startup_state; startup_state = XAllocWMHints(); startup_state->initial_state = NormalState; startup_state->flags = StateHint; XSetWMProperties(display, window, &textprop, &textprop, NULL, 0, &hints, startup_state, NULL); XFree(startup_state); */ //if ( !window ) //{ // return; //} // // => https://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_%28GLX%29 // // Done with the visual info data //XFree( vi ); //m_Window = (void*)XCreateSimpleWindow((x11Display*)m_Display, DefaultRootWindow((x11Display*)m_Display), desc.posX, desc.posY, desc.width, desc.height, 0,0, 0); XMapWindow(m_Display, m_Window); Atom WM_DELETE_WINDOW = XInternAtom(m_Display, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_Display, m_Window, &WM_DELETE_WINDOW, 1); XSelectInput(m_Display, m_Window, StructureNotifyMask); XEvent event; do{XNextEvent(m_Display, &event); }while(event.type != MapNotify); return true; }
/* PROGRAM EXECUTION BEGINS HERE */ int main(int argc, char** argv) { /** Declare variables **/ /* People */ int total_number_of_people = 50; int total_num_initially_infected = 1; int total_num_infected = 1; int our_number_of_people = 50; int our_person1 = 0; int our_current_infected_person = 0; int our_num_initially_infected = 1; int our_num_infected = 0; int our_current_location_x = 0; int our_current_location_y = 0; int our_num_susceptible = 0; int our_num_immune = 0; int our_num_dead = 0; int my_current_person_id = 0; int my_num_infected_nearby = 0; int my_person2 = 0; /* Environment */ int environment_width = 30; int environment_height = 30; /* Disease */ int infection_radius = 3; int duration_of_disease = 50; int contagiousness_factor = 30; int deadliness_factor = 30; #ifdef SHOW_RESULTS double our_num_infections = 0.0; double our_num_infection_attempts = 0.0; double our_num_deaths = 0.0; double our_num_recovery_attempts = 0.0; #endif /* Time */ int total_number_of_days = 250; int our_current_day = 0; int microseconds_per_day = 100000; /* Movement */ int my_x_move_direction = 0; int my_y_move_direction = 0; /* Distributed Memory Information */ int total_number_of_processes = 1; int our_rank = 0; int current_rank = 0; int current_displ = 0; /* getopt */ int c = 0; /* Integer arrays, a.k.a. integer pointers */ int *x_locations; int *y_locations; int *our_x_locations; int *our_y_locations; int *our_infected_x_locations; int *our_infected_y_locations; int *their_infected_x_locations; int *their_infected_y_locations; int *our_num_days_infected; int *recvcounts; int *displs; /* Character arrays, a.k.a. character pointers */ char *states; char *our_states; #ifdef TEXT_DISPLAY /* Array of character arrays, a.k.a. array of character pointers, for text * display */ char **environment; #endif #ifdef X_DISPLAY /* Declare X-related variables */ Display *display; Window window; int screen; Atom delete_window; GC gc; XColor infected_color; XColor immune_color; XColor susceptible_color; XColor dead_color; Colormap colormap; char red[] = "#FF0000"; char green[] = "#00FF00"; char black[] = "#000000"; char white[] = "#FFFFFF"; #endif /* To test the timing of each section */ double beginTime, initTime, compTime1, compTime2, rsTime, commTime, totalCommTime = 0.0, finTime, minTime = DBL_MAX, compTime; double init[16], comp[16], begin[16], buf[3]; int i, j; beginTime = omp_get_wtime(); /* Each process initializes the distributed memory environment */ MPI_Init(&argc, &argv); initTime = omp_get_wtime(); /* ALG I: Each process determines its rank and the total number of processes */ MPI_Comm_rank(MPI_COMM_WORLD, &our_rank); MPI_Comm_size(MPI_COMM_WORLD, &total_number_of_processes); rsTime = omp_get_wtime() - initTime; /* ALG II: Each process is given the parameters of the simulation */ /* Get command line options -- this follows the idiom presented in the * getopt man page (enter 'man 3 getopt' on the shell for more) */ while((c = getopt(argc, argv, "n:i:w:h:t:T:c:d:D:m:")) != -1) { switch(c) { case 'n': total_number_of_people = atoi(optarg); break; case 'i': total_num_initially_infected = atoi(optarg); break; case 'w': environment_width = atoi(optarg); break; case 'h': environment_height = atoi(optarg); break; case 't': total_number_of_days = atoi(optarg); break; case 'T': duration_of_disease = atoi(optarg); break; case 'c': contagiousness_factor = atoi(optarg); break; case 'd': infection_radius = atoi(optarg); break; case 'D': deadliness_factor = atoi(optarg); break; case 'm': microseconds_per_day = atoi(optarg); break; /* If the user entered "-?" or an unrecognized option, we need * to print a usage message before exiting. */ case '?': default: fprintf(stderr, "Usage: "); fprintf(stderr, "mpirun -np total_number_of_processes "); fprintf(stderr, "%s [-n total_number_of_people][-i total_num_initially_infected][-w environment_width][-h environment_height][-t total_number_of_days][-T duration_of_disease][-c contagiousness_factor][-d infection_radius][-D deadliness_factor][-m microseconds_per_day]\n", argv[0]); exit(-1); } } argc -= optind; argv += optind; /* ALG III: Each process makes sure that the total number of initially * infected people is less than the total number of people */ if(total_num_initially_infected > total_number_of_people) { fprintf(stderr, "ERROR: initial number of infected (%d) must be less than total number of people (%d)\n", total_num_initially_infected, total_number_of_people); exit(-1); } /* ALG IV: Each process determines the number of people for which it is * responsible */ our_number_of_people = total_number_of_people / total_number_of_processes; /* ALG V: The last process is responsible for the remainder */ if(our_rank == total_number_of_processes - 1) { our_number_of_people += total_number_of_people % total_number_of_processes; } /* ALG VI: Each process determines the number of initially infected people * for which it is responsible */ our_num_initially_infected = total_num_initially_infected / total_number_of_processes; /* ALG VII: The last process is responsible for the remainder */ if(our_rank == total_number_of_processes - 1) { our_num_initially_infected += total_num_initially_infected % total_number_of_processes; } /* Allocate the arrays */ x_locations = (int*)malloc(total_number_of_people * sizeof(int)); y_locations = (int*)malloc(total_number_of_people * sizeof(int)); our_x_locations = (int*)malloc(our_number_of_people * sizeof(int)); our_y_locations = (int*)malloc(our_number_of_people * sizeof(int)); our_infected_x_locations = (int*)malloc(our_number_of_people * sizeof(int)); our_infected_y_locations = (int*)malloc(our_number_of_people * sizeof(int)); their_infected_x_locations = (int*)malloc(total_number_of_people * sizeof(int)); their_infected_y_locations = (int*)malloc(total_number_of_people * sizeof(int)); our_num_days_infected = (int*)malloc(our_number_of_people * sizeof(int)); recvcounts = (int*)malloc(total_number_of_processes * sizeof(int)); displs = (int*)malloc(total_number_of_processes * sizeof(int)); states = (char*)malloc(total_number_of_people * sizeof(char)); our_states = (char*)malloc(our_number_of_people * sizeof(char)); #ifdef TEXT_DISPLAY environment = (char**)malloc(environment_width * environment_height * sizeof(char*)); for(our_current_location_x = 0; our_current_location_x <= environment_width - 1; our_current_location_x++) { environment[our_current_location_x] = (char*)malloc(environment_height * sizeof(char)); } #endif /* ALG VIII: Each process seeds the random number generator based on the * current time */ srandom(time(NULL) + our_rank * 12345); /* ALG IX: Each process spawns threads to set the states of the initially * infected people and set the count of its infected people */ for(my_current_person_id = 0; my_current_person_id <= our_num_initially_infected - 1; my_current_person_id++) { our_states[my_current_person_id] = INFECTED; our_num_infected++; } /* ALG X: Each process spawns threads to set the states of the rest of its * people and set the count of its susceptible people */ for(my_current_person_id = our_num_initially_infected; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { our_states[my_current_person_id] = SUSCEPTIBLE; our_num_susceptible++; } /* ALG XI: Each process spawns threads to set random x and y locations for * each of its people */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { our_x_locations[my_current_person_id] = random() % environment_width; our_y_locations[my_current_person_id] = random() % environment_height; } /* ALG XII: Each process spawns threads to initialize the number of days * infected of each of its people to 0 */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { our_num_days_infected[my_current_person_id] = 0; } /* ALG XIII: Rank 0 initializes the graphics display */ #ifdef X_DISPLAY if(our_rank == 0) { /* Initialize the X Windows Environment * This all comes from * http://en.wikibooks.org/wiki/X_Window_Programming/XLib * http://tronche.com/gui/x/xlib-tutorial * http://user.xmission.com/~georgeps/documentation/tutorials/ * Xlib_Beginner.html */ /* Open a connection to the X server */ display = XOpenDisplay(NULL); if(display == NULL) { fprintf(stderr, "Error: could not open X display\n"); } screen = DefaultScreen(display); window = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, environment_width * PIXEL_WIDTH_PER_PERSON, environment_height * PIXEL_HEIGHT_PER_PERSON, 1, BlackPixel(display, screen), WhitePixel(display, screen)); delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0); XSetWMProtocols(display, window, &delete_window, 1); XSelectInput(display, window, ExposureMask | KeyPressMask); XMapWindow(display, window); colormap = DefaultColormap(display, 0); gc = XCreateGC(display, window, 0, 0); XParseColor(display, colormap, red, &infected_color); XParseColor(display, colormap, green, &immune_color); XParseColor(display, colormap, white, &dead_color); XParseColor(display, colormap, black, &susceptible_color); XAllocColor(display, colormap, &infected_color); XAllocColor(display, colormap, &immune_color); XAllocColor(display, colormap, &susceptible_color); XAllocColor(display, colormap, &dead_color); } #endif compTime1 = omp_get_wtime(); /* ALG XIV: Each process starts a loop to run the simulation for the * specified number of days */ for(our_current_day = 0; our_current_day <= total_number_of_days - 1; our_current_day++) { /* ALG XIV.A: Each process determines its infected x locations and * infected y locations */ our_current_infected_person = 0; for(our_person1 = 0; our_person1 <= our_number_of_people - 1; our_person1++) { if(our_states[our_person1] == INFECTED) { our_infected_x_locations[our_current_infected_person] = our_x_locations[our_person1]; our_infected_y_locations[our_current_infected_person] = our_y_locations[our_person1]; our_current_infected_person++; } } /* ALG XIV.B: Each process sends its count of infected people to all the * other processes and receives their counts */ commTime = omp_get_wtime(); MPI_Allgather(&our_num_infected, 1, MPI_INT, recvcounts, 1, MPI_INT, MPI_COMM_WORLD); totalCommTime += omp_get_wtime() - commTime; total_num_infected = 0; for(current_rank = 0; current_rank <= total_number_of_processes - 1; current_rank++) { total_num_infected += recvcounts[current_rank]; } /* Set up the displacements in the receive buffer (see the man page for * MPI_Allgatherv) */ current_displ = 0; for(current_rank = 0; current_rank <= total_number_of_processes - 1; current_rank++) { displs[current_rank] = current_displ; current_displ += recvcounts[current_rank]; } /* ALG XIV.C: Each process sends the x locations of its infected people * to all the other processes and receives the x locations of their * infected people */ commTime = omp_get_wtime(); MPI_Allgatherv(our_infected_x_locations, our_num_infected, MPI_INT, their_infected_x_locations, recvcounts, displs, MPI_INT, MPI_COMM_WORLD); /* ALG XIV.D: Each process sends the y locations of its infected people * to all the other processes and receives the y locations of their * infected people */ MPI_Allgatherv(our_infected_y_locations, our_num_infected, MPI_INT, their_infected_y_locations, recvcounts, displs, MPI_INT, MPI_COMM_WORLD); totalCommTime += omp_get_wtime() - commTime; #if defined(X_DISPLAY) || defined(TEXT_DISPLAY) /* ALG XIV.E: If display is enabled, Rank 0 gathers the states, x * locations, and y locations of the people for which each process is * responsible */ /* Set up the receive counts and displacements in the receive buffer * (see the man page for MPI_Gatherv) */ current_displ = 0; for(current_rank = 0; current_rank <= total_number_of_processes - 1; current_rank++) { displs[current_rank] = current_displ; recvcounts[current_rank] = total_number_of_people / total_number_of_processes; if(current_rank == total_number_of_processes - 1) { recvcounts[current_rank] += total_number_of_people % total_number_of_processes; } current_displ += recvcounts[current_rank]; } commTime = omp_get_wtime(); MPI_Gatherv(our_states, our_number_of_people, MPI_CHAR, states, recvcounts, displs, MPI_CHAR, 0, MPI_COMM_WORLD); MPI_Gatherv(our_x_locations, our_number_of_people, MPI_INT, x_locations, recvcounts, displs, MPI_INT, 0, MPI_COMM_WORLD); MPI_Gatherv(our_y_locations, our_number_of_people, MPI_INT, y_locations, recvcounts, displs, MPI_INT, 0, MPI_COMM_WORLD); totalCommTime += omp_get_wtime() - commTime; #endif /* ALG XIV.F: If display is enabled, Rank 0 displays a graphic of the * current day */ #ifdef X_DISPLAY if(our_rank == 0) { XClearWindow(display, window); for(my_current_person_id = 0; my_current_person_id <= total_number_of_people - 1; my_current_person_id++) { if(states[my_current_person_id] == INFECTED) { XSetForeground(display, gc, infected_color.pixel); } else if(states[my_current_person_id] == IMMUNE) { XSetForeground(display, gc, immune_color.pixel); } else if(states[my_current_person_id] == SUSCEPTIBLE) { XSetForeground(display, gc, susceptible_color.pixel); } else if(states[my_current_person_id] == DEAD) { XSetForeground(display, gc, dead_color.pixel); } else { fprintf(stderr, "ERROR: person %d has state '%c'\n", my_current_person_id, states[my_current_person_id]); exit(-1); } XFillRectangle(display, window, gc, x_locations[my_current_person_id] * PIXEL_WIDTH_PER_PERSON, y_locations[my_current_person_id] * PIXEL_HEIGHT_PER_PERSON, PIXEL_WIDTH_PER_PERSON, PIXEL_HEIGHT_PER_PERSON); } XFlush(display); } #endif #ifdef TEXT_DISPLAY if(our_rank == 0) { for(our_current_location_y = 0; our_current_location_y <= environment_height - 1; our_current_location_y++) { for(our_current_location_x = 0; our_current_location_x <= environment_width - 1; our_current_location_x++) { environment[our_current_location_x][our_current_location_y] = ' '; } } for(my_current_person_id = 0; my_current_person_id <= total_number_of_people - 1; my_current_person_id++) { environment[x_locations[my_current_person_id]] [y_locations[my_current_person_id]] = states[my_current_person_id]; } printf("----------------------\n"); for(our_current_location_y = 0; our_current_location_y <= environment_height - 1; our_current_location_y++) { for(our_current_location_x = 0; our_current_location_x <= environment_width - 1; our_current_location_x++) { printf("%c", environment[our_current_location_x] [our_current_location_y]); } printf("\n"); } } #endif #if defined(X_DISPLAY) || defined(TEXT_DISPLAY) /* Wait between frames of animation */ usleep(microseconds_per_day); #endif /* ALG XIV.G: For each of the process’s people, each process spawns * threads to do the following */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { /* ALG XIV.G.1: If the person is not dead, then */ if(our_states[my_current_person_id] != DEAD) { /* ALG XIV.G.1.a: The thread randomly picks whether the person * moves left or right or does not move in the x dimension */ my_x_move_direction = (random() % 3) - 1; /* ALG XIV.G.1.b: The thread randomly picks whether the person * moves up or down or does not move in the y dimension */ my_y_move_direction = (random() % 3) - 1; /* ALG XIV.G.1.c: If the person will remain in the bounds of the * environment after moving, then */ if((our_x_locations[my_current_person_id] + my_x_move_direction >= 0) && (our_x_locations[my_current_person_id] + my_x_move_direction < environment_width) && (our_y_locations[my_current_person_id] + my_y_move_direction >= 0) && (our_y_locations[my_current_person_id] + my_y_move_direction < environment_height)) { /* ALG XIV.G.i: The thread moves the person */ our_x_locations[my_current_person_id] += my_x_move_direction; our_y_locations[my_current_person_id] += my_y_move_direction; } } } /* ALG XIV.H: For each of the process’s people, each process spawns * threads to do the following */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { /* ALG XIV.H.1: If the person is susceptible, then */ if(our_states[my_current_person_id] == SUSCEPTIBLE) { /* ALG XIV.H.1.a: For each of the infected people (received * earlier from all processes) or until the number of infected * people nearby is 1, the thread does the following */ my_num_infected_nearby = 0; for(my_person2 = 0; my_person2 <= total_num_infected - 1 && my_num_infected_nearby < 1; my_person2++) { /* ALG XIV.H.1.a.i: If person 1 is within the infection * radius, then */ if((our_x_locations[my_current_person_id] > their_infected_x_locations[my_person2] - infection_radius) && (our_x_locations[my_current_person_id] < their_infected_x_locations[my_person2] + infection_radius) && (our_y_locations[my_current_person_id] > their_infected_y_locations[my_person2] - infection_radius) && (our_y_locations[my_current_person_id] < their_infected_y_locations[my_person2] + infection_radius)) { /* ALG XIV.H.1.a.i.1: The thread increments the number * of infected people nearby */ my_num_infected_nearby++; } } #ifdef SHOW_RESULTS if(my_num_infected_nearby >= 1) our_num_infection_attempts++; #endif /* ALG XIV.H.1.b: If there is at least one infected person * nearby, and a random number less than 100 is less than or * equal to the contagiousness factor, then */ if(my_num_infected_nearby >= 1 && (random() % 100) <= contagiousness_factor) { /* ALG XIV.H.1.b.i: The thread changes person1’s state to * infected */ our_states[my_current_person_id] = INFECTED; /* ALG XIV.H.1.b.ii: The thread updates the counters */ our_num_infected++; our_num_susceptible--; #ifdef SHOW_RESULTS our_num_infections++; #endif } } } /* ALG XIV.I: For each of the process’s people, each process spawns * threads to do the following */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { /* ALG XIV.I.1: If the person is infected and has been for the full * duration of the disease, then */ if(our_states[my_current_person_id] == INFECTED && our_num_days_infected[my_current_person_id] == duration_of_disease) { #ifdef SHOW_RESULTS our_num_recovery_attempts++; #endif /* ALG XIV.I.a: If a random number less than 100 is less than * the deadliness factor, then */ if((random() % 100) < deadliness_factor) { /* ALG XIV.I.a.i: The thread changes the person’s state to * dead */ our_states[my_current_person_id] = DEAD; /* ALG XIV.I.a.ii: The thread updates the counters */ our_num_dead++; our_num_infected--; #ifdef SHOW_RESULTS our_num_deaths++; #endif } /* ALG XIV.I.b: Otherwise, */ else { /* ALG XIV.I.b.i: The thread changes the person’s state to * immune */ our_states[my_current_person_id] = IMMUNE; /* ALG XIV.I.b.ii: The thread updates the counters */ our_num_immune++; our_num_infected--; } } } /* ALG XIV.J: For each of the process’s people, each process spawns * threads to do the following */ for(my_current_person_id = 0; my_current_person_id <= our_number_of_people - 1; my_current_person_id++) { /* ALG XIV.J.1: If the person is infected, then */ if(our_states[my_current_person_id] == INFECTED) { /* ALG XIV.J.1.a: Increment the number of days the person has * been infected */ our_num_days_infected[my_current_person_id]++; } } } compTime2 = omp_get_wtime(); compTime = compTime2 - compTime1 - totalCommTime; /* ALG XV: If X display is enabled, then Rank 0 destroys the X Window and * closes the display */ #ifdef X_DISPLAY if(our_rank == 0) { XDestroyWindow(display, window); XCloseDisplay(display); } #endif #ifdef SHOW_RESULTS printf("Rank %d final counts: %d susceptible, %d infected, %d immune, \ %d dead\nRank %d actual contagiousness: %f\nRank %d actual deadliness: \ %f\n", our_rank, our_num_susceptible, our_num_infected, our_num_immune, our_num_dead, our_rank, 100.0 * (our_num_infections / (our_num_infection_attempts == 0 ? 1 : our_num_infection_attempts)), our_rank, 100.0 * (our_num_deaths / (our_num_recovery_attempts == 0 ? 1 : our_num_recovery_attempts))); #endif /* Deallocate the arrays -- we have finished using the memory, so now we * "free" it back to the heap */ #ifdef TEXT_DISPLAY for(our_current_location_x = environment_width - 1; our_current_location_x >= 0; our_current_location_x--) { free(environment[our_current_location_x]); } free(environment); #endif free(our_states); free(states); free(displs); free(recvcounts); free(our_num_days_infected); free(their_infected_y_locations); free(their_infected_x_locations); free(our_infected_y_locations); free(our_infected_x_locations); free(our_y_locations); free(our_x_locations); free(y_locations); free(x_locations); /* Printout of all the recorded times */ if (our_rank == 0) printf("%3s: %18s, %18s, %18s, %18s\n", "", "init", "computation", "communication", "rankSize"); MPI_Barrier(MPI_COMM_WORLD); printf("%3d: %18.15f, %18.15f, %18.15f, %18.15f\n", our_rank, initTime - beginTime, compTime, totalCommTime, rsTime); if (our_rank % 32 == 16) { buf[0] = beginTime; buf[1] = initTime; buf[2] = compTime2; MPI_Send(buf, 3, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD); } MPI_Barrier(MPI_COMM_WORLD); if (our_rank == 0) { for (i = 16, j = 0; i < total_number_of_processes; i += 32, j++) { MPI_Recv(buf, 3, MPI_DOUBLE, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); begin[j] = buf[0]; init[j] = buf[1]; comp[j] = buf[2]; if (begin[j] < minTime) { minTime = begin[j]; } } printf("----------------------------------------------------\n"); printf("%3s: %18s, %18s, %18s\n", "", "init-ref", "comp-ref", "comp-init"); for (i = 0; i < total_number_of_processes / 32; i++) { printf("%3d: %18.15f, %18.15f, %18.15f\n", i * 32 + 16, init[i] - minTime, comp[i] - minTime, comp[i] - init[i]); } } /* MPI execution is finished; no MPI calls are allowed after this */ finTime = omp_get_wtime(); MPI_Finalize(); finTime = omp_get_wtime() - finTime; /* The program has finished executing successfully */ return 0; }
static bool gfx_ctx_glx_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { XEvent event; bool true_full = false, windowed_full; int val, x_off = 0, y_off = 0; XVisualInfo *vi = NULL; XSetWindowAttributes swa = {0}; int (*old_handler)(Display*, XErrorEvent*) = NULL; driver_t *driver = driver_get_ptr(); gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data; struct sigaction sa = {{0}}; settings_t *settings = config_get_ptr(); sa.sa_handler = glx_sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); if (!glx) return false; windowed_full = settings->video.windowed_fullscreen; true_full = false; vi = glXGetVisualFromFBConfig(glx->g_dpy, glx->g_fbc); if (!vi) goto error; swa.colormap = glx->g_cmap = XCreateColormap(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask | ButtonPressMask; swa.override_redirect = fullscreen ? True : False; if (fullscreen && !windowed_full) { if (x11_enter_fullscreen(glx->g_dpy, width, height, &glx->g_desktop_mode)) { glx->g_should_reset_mode = true; true_full = true; } else RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } if (settings->video.monitor_index) glx->g_screen = settings->video.monitor_index - 1; #ifdef HAVE_XINERAMA if (fullscreen || glx->g_screen != 0) { unsigned new_width = width; unsigned new_height = height; if (x11_get_xinerama_coord(glx->g_dpy, glx->g_screen, &x_off, &y_off, &new_width, &new_height)) RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", glx->g_screen); else RARCH_LOG("[GLX]: Xinerama is not active on screen.\n"); if (fullscreen) { width = new_width; height = new_height; } } #endif RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n", x_off, y_off, width, height); glx->g_win = XCreateWindow(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(glx->g_dpy, glx->g_win, 0); glx->g_glx_win = glXCreateWindow(glx->g_dpy, glx->g_fbc, glx->g_win, 0); x11_set_window_attr(glx->g_dpy, glx->g_win); if (fullscreen) x11_show_mouse(glx->g_dpy, glx->g_win, false); if (true_full) { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(glx->g_dpy, glx->g_win); } else if (fullscreen) /* We attempted true fullscreen, but failed. Attempt using windowed fullscreen. */ { XMapRaised(glx->g_dpy, glx->g_win); RARCH_LOG("[GLX]: Using windowed fullscreen.\n"); /* We have to move the window to the screen we want to go fullscreen on first. * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); x11_windowed_fullscreen(glx->g_dpy, glx->g_win); } else { XMapWindow(glx->g_dpy, glx->g_win); /* If we want to map the window on a different screen, we'll have to do it by force. * Otherwise, we should try to let the window manager sort it out. * x_off and y_off usually get ignored in XCreateWindow(). */ if (glx->g_screen) x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); } XIfEvent(glx->g_dpy, &event, glx_wait_notify, NULL); if (!glx->g_ctx) { if (glx->g_core_es || glx->g_debug) { int attribs[16]; int *aptr = attribs; if (glx->g_core_es) { *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB; *aptr++ = g_major; *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB; *aptr++ = g_minor; if (glx->g_core_es_core) { /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending on GL_ARB_compatibility. */ *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB; #ifdef HAVE_OPENGLES2 *aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT; #else *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; #endif } } if (glx->g_debug) { *aptr++ = GLX_CONTEXT_FLAGS_ARB; *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB; } *aptr = None; glx->g_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, NULL, True, attribs); if (glx->g_use_hw_ctx) { RARCH_LOG("[GLX]: Creating shared HW context.\n"); glx->g_hw_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, glx->g_ctx, True, attribs); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } else { glx->g_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, 0, True); if (glx->g_use_hw_ctx) { glx->g_hw_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, glx->g_ctx, True); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } if (!glx->g_ctx) { RARCH_ERR("[GLX]: Failed to create new context.\n"); goto error; } } else { driver->video_cache_context_ack = true; RARCH_LOG("[GLX]: Using cached GL context.\n"); } glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, glx->g_ctx); XSync(glx->g_dpy, False); g_quit_atom = XInternAtom(glx->g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) XSetWMProtocols(glx->g_dpy, glx->g_win, &g_quit_atom, 1); glXGetConfig(glx->g_dpy, vi, GLX_DOUBLEBUFFER, &val); glx->g_is_double = val; if (glx->g_is_double) { const char *swap_func = NULL; g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); g_pglSwapIntervalSGI = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); if (g_pglSwapIntervalEXT) swap_func = "glXSwapIntervalEXT"; else if (g_pglSwapInterval) swap_func = "glXSwapIntervalMESA"; else if (g_pglSwapIntervalSGI) swap_func = "glXSwapIntervalSGI"; if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI) RARCH_WARN("[GLX]: Cannot find swap interval call.\n"); else RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func); } else RARCH_WARN("[GLX]: Context is not double buffered!.\n"); gfx_ctx_glx_swap_interval(data, glx->g_interval); /* This can blow up on some drivers. It's not fatal, so override errors for this call. */ old_handler = XSetErrorHandler(glx_nul_handler); XSetInputFocus(glx->g_dpy, glx->g_win, RevertToNone, CurrentTime); XSync(glx->g_dpy, False); XSetErrorHandler(old_handler); XFree(vi); glx->g_has_focus = true; if (!x11_create_input_context(glx->g_dpy, glx->g_win, &glx->g_xim, &glx->g_xic)) goto error; driver->display_type = RARCH_DISPLAY_X11; driver->video_display = (uintptr_t)glx->g_dpy; driver->video_window = (uintptr_t)glx->g_win; glx->g_true_full = true_full; return true; error: if (vi) XFree(vi); ctx_glx_destroy_resources(glx); if (glx) free(glx); return false; }
// Create the X11 window (and its colormap) // static GLboolean createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { unsigned long wamask; XSetWindowAttributes wa; XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; // Every window needs a colormap // Create one based on the visual used by the current context // TODO: Decouple this from context creation window->x11.colormap = XCreateColormap(_glfw.x11.display, _glfw.x11.root, visual->visual, AllocNone); // Create the actual window { wamask = CWBorderPixel | CWColormap | CWEventMask; wa.colormap = window->x11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask; _glfwGrabXErrorHandler(); window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, 0, 0, wndconfig->width, wndconfig->height, 0, // Border width visual->depth, // Color depth InputOutput, visual->visual, wamask, &wa); _glfwReleaseXErrorHandler(); if (!window->x11.handle) { _glfwInputXError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); return GL_FALSE; } if (!wndconfig->decorated) { MotifWmHints hints; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.MOTIF_WM_HINTS, _glfw.x11.MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char*) &hints, sizeof(MotifWmHints) / sizeof(long)); } XSaveContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context, (XPointer) window); } if (window->monitor && !_glfw.x11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window // manager ignore the window completely (ICCCM, section 4) // The good thing is that this makes undecorated fullscreen windows // easy to do; the bad thing is that we have to do everything manually // and some things (like iconify/restore) won't work at all, as those // are tasks usually performed by the window manager XSetWindowAttributes attributes; attributes.override_redirect = True; XChangeWindowAttributes(_glfw.x11.display, window->x11.handle, CWOverrideRedirect, &attributes); window->x11.overrideRedirect = GL_TRUE; } // Declare the WM protocols supported by GLFW { int count = 0; Atom protocols[2]; // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol if (_glfw.x11.WM_DELETE_WINDOW) protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; // The _NET_WM_PING EWMH protocol // Tells the WM to ping the GLFW window and flag the application as // unresponsive if the WM doesn't get a reply within a few seconds if (_glfw.x11.NET_WM_PING) protocols[count++] = _glfw.x11.NET_WM_PING; if (count > 0) { XSetWMProtocols(_glfw.x11.display, window->x11.handle, protocols, count); } } if (_glfw.x11.NET_WM_PID) { const pid_t pid = getpid(); XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &pid, 1); } // Set ICCCM WM_HINTS property { XWMHints* hints = XAllocWMHints(); if (!hints) { _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints"); return GL_FALSE; } hints->flags = StateHint; hints->initial_state = NormalState; XSetWMHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) { XSizeHints* hints = XAllocSizeHints(); hints->flags = 0; if (wndconfig->monitor) { hints->flags |= PPosition; _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); } else { // HACK: Explicitly setting PPosition to any value causes some WMs, // notably Compiz and Metacity, to honor the position of // unmapped windows set by XMoveWindow hints->flags |= PPosition; hints->x = hints->y = 0; } if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); hints->min_width = hints->max_width = wndconfig->width; hints->min_height = hints->max_height = wndconfig->height; } XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_CLASS property // HACK: Until a mechanism for specifying the application name is added, the // initial window title is used as the window class name if (strlen(wndconfig->title)) { XClassHint* hint = XAllocClassHint(); hint->res_name = (char*) wndconfig->title; hint->res_class = (char*) wndconfig->title; XSetClassHint(_glfw.x11.display, window->x11.handle, hint); XFree(hint); } if (_glfw.x11.xi.available) { // Select for XInput2 events XIEventMask eventmask; unsigned char mask[] = { 0 }; eventmask.deviceid = 2; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_Motion); XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } if (_glfw.x11.XdndAware) { // Announce support for Xdnd (drag and drop) const Atom version = 5; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*) &version, 1); } if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS) { // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to // function before the window is mapped XEvent event; memset(&event, 0, sizeof(event)); event.type = ClientMessage; event.xclient.window = window->x11.handle; event.xclient.format = 32; // Data is 32-bit longs event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS; XSendEvent(_glfw.x11.display, _glfw.x11.root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window); } _glfwPlatformSetWindowTitle(window, wndconfig->title); XRRSelectInput(_glfw.x11.display, window->x11.handle, RRScreenChangeNotifyMask); _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); return GL_TRUE; }
Bool RenderWindowLinux::Open( const VideoMode & p_VideoMode, const std::string & p_Title, const Uint32 p_Style ) { // open a connection with X server if( ( m_pDisplay = XOpenDisplay( NULL ) ) == NULL ) { std::cout << "[RenderWindowLinux::Create] Can not connect to X server." << std::endl; return false; } // Initialize the X thread // Should we?!?! XInitThreads( ); // Get the screen m_Screen = DefaultScreen( m_pDisplay ); // Creat the window attributes XSetWindowAttributes WindowAttributes; WindowAttributes.colormap = DefaultColormap( m_pDisplay, m_Screen ); WindowAttributes.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | FocusChangeMask | ExposureMask | StructureNotifyMask; // Create the window m_Window = XCreateWindow( m_pDisplay, DefaultRootWindow( m_pDisplay ), 0, 0, p_VideoMode.GetSize( ).x, p_VideoMode.GetSize( ).y, 0, DefaultDepth( m_pDisplay, m_Screen ), InputOutput, DefaultVisual( m_pDisplay, m_Screen ), CWBorderPixel | CWEventMask | CWColormap, &WindowAttributes ); // It's very important to set the delete message. Else we wont be able to close the window. ::Atom wmDeleteMessage = XInternAtom( m_pDisplay, "WM_DELETE_WINDOW", false ); XSetWMProtocols( m_pDisplay, m_Window, &wmDeleteMessage, 1 ); // Set the window title SetTitle( p_Title.c_str( ) ); // Let's set up the window decoration and the functionality ::Atom PropertyAtom = XInternAtom( m_pDisplay, "_MOTIF_WM_HINTS", false ); if( PropertyAtom ) { struct HintsStruct { Uint32 Flags; Uint32 Functions; Uint32 Decorations; Int32 InputMode; Uint32 State; }; HintsStruct Hints; Hints.Flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_FUNCTIONS; Hints.Functions = 0; Hints.Decorations = 0; // Go through all the styles we want to apply to the window if( p_Style == Bit::Style::Default ) { Hints.Functions |= MWM_FUNC_ALL; Hints.Decorations |= MWM_DECOR_ALL; } else { // Always set the resize and maximize functions and decorations. // Some window managers seems to require this. // Resizing can be disabled. Hints.Functions |= MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE; Hints.Decorations |= MWM_DECOR_RESIZEH | MWM_DECOR_MAXIMIZE; if( p_Style & Bit::Style::Close ) { Hints.Functions |= MWM_FUNC_CLOSE; } if( p_Style & Bit::Style::Minimize ) { Hints.Functions |= MWM_FUNC_MINIMIZE; Hints.Decorations |= MWM_DECOR_MINIMIZE; } if( p_Style & Bit::Style::TitleBar ) { Hints.Functions |= MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE; Hints.Decorations |= MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE; } } // Apply the changes XChangeProperty( m_pDisplay, m_Window, PropertyAtom, PropertyAtom, 32, PropModeReplace, (unsigned char *) &Hints, 5 ); // Force x server to disable window resizing if (!( p_Style & Bit::Style::Resize ) ) { XSizeHints * SizeHints = XAllocSizeHints( ); SizeHints->flags = PMinSize | PMaxSize; SizeHints->min_width = p_VideoMode.GetSize( ).x; SizeHints->min_height = p_VideoMode.GetSize( ).y; SizeHints->max_width = p_VideoMode.GetSize( ).x; SizeHints->max_height = p_VideoMode.GetSize( ).y; // Set the hints XSetWMNormalHints( m_pDisplay, m_Window, SizeHints); // Free the size hints XFree(SizeHints); } } else { std::cout << "[RenderWindowLinux::Open] Can not get the property atom \"_MOTIF_WM_HINTS\"." << std::endl; } // Display the window. XMapWindow( m_pDisplay, m_Window ); XFlush( m_pDisplay ); // Set the rest of the member variables m_VideoMode = p_VideoMode; m_Title = p_Title; m_Style = p_Style; m_Size = p_VideoMode.GetSize( ); m_Open = true; m_Focused = true; return true; }
int puglCreateWindow(PuglView* view, const char* title) { PuglInternals* const impl = view->impl; impl->display = XOpenDisplay(NULL); impl->screen = DefaultScreen(impl->display); XVisualInfo* const vi = getVisual(view); if (!vi) { XCloseDisplay(impl->display); impl->display = NULL; return 1; } #ifdef PUGL_HAVE_GL int glxMajor, glxMinor; glXQueryVersion(impl->display, &glxMajor, &glxMinor); PUGL_LOGF("GLX Version %d.%d\n", glxMajor, glxMinor); #endif Window xParent = view->parent ? (Window)view->parent : RootWindow(impl->display, impl->screen); Colormap cmap = XCreateColormap( impl->display, xParent, vi->visual, AllocNone); XSetWindowAttributes attr; memset(&attr, 0, sizeof(XSetWindowAttributes)); attr.background_pixel = BlackPixel(impl->display, impl->screen); attr.border_pixel = BlackPixel(impl->display, impl->screen); attr.colormap = cmap; attr.event_mask = (ExposureMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask); impl->win = XCreateWindow( impl->display, xParent, 0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual, CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &attr); if (!createContext(view, vi)) { XDestroyWindow(impl->display, impl->win); impl->win = 0; XCloseDisplay(impl->display); impl->display = NULL; return 1; } XSizeHints sizeHints; memset(&sizeHints, 0, sizeof(sizeHints)); if (!view->resizable) { sizeHints.flags = PMinSize|PMaxSize; sizeHints.min_width = view->width; sizeHints.min_height = view->height; sizeHints.max_width = view->width; sizeHints.max_height = view->height; XSetNormalHints(impl->display, impl->win, &sizeHints); } else if (view->min_width > 0 && view->min_height > 0) { sizeHints.flags = PMinSize; sizeHints.min_width = view->min_width; sizeHints.min_height = view->min_height; XSetNormalHints(impl->display, impl->win, &sizeHints); } if (title) { XStoreName(impl->display, impl->win, title); } if (!view->parent) { Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True); XSetWMProtocols(impl->display, impl->win, &wmDelete, 1); } if (glXIsDirect(impl->display, impl->ctx)) { PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n"); } else { PUGL_LOG("No DRI available\n"); } XFree(vi); return PUGL_SUCCESS; }
int main(int argc, char **argv) { char *file_name = NULL; int i; XtAppContext xtcontext; Arg topLevelArgs[2]; Widget entry; XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL); toplevel = XtAppInitialize(&xtcontext, "Xditview", options, XtNumber (options), &argc, argv, NULL, NULL, 0); if (argc > 2) Syntax(argv[0]); XtAppAddActions(xtcontext, xditview_actions, XtNumber (xditview_actions)); XtOverrideTranslations (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()")); XtSetArg (topLevelArgs[0], XtNiconPixmap, XCreateBitmapFromData (XtDisplay (toplevel), XtScreen(toplevel)->root, (char *) xdit_bits, xdit_width, xdit_height)); XtSetArg (topLevelArgs[1], XtNiconMask, XCreateBitmapFromData (XtDisplay (toplevel), XtScreen(toplevel)->root, (char *) xdit_mask_bits, xdit_mask_width, xdit_mask_height)); XtSetValues (toplevel, topLevelArgs, 2); if (argc > 1) file_name = argv[1]; /* * create the popup menu and insert the entries */ popupMenu = XtCreatePopupShell ("popupMenu", simpleMenuWidgetClass, toplevel, NULL, 0); for (i = 0; i < XtNumber (popupMenuEntries); i++) { entry = XtCreateManagedWidget(popupMenuEntries[i].name, smeBSBObjectClass, popupMenu, NULL, (Cardinal) 0); XtAddCallback(entry, XtNcallback, popupMenuEntries[i].function, NULL); } paned = XtCreateManagedWidget("paned", panedWidgetClass, toplevel, NULL, (Cardinal) 0); menuBar = XtCreateManagedWidget ("menuBar", boxWidgetClass, paned, NULL, 0); fileMenuButton = XtCreateManagedWidget ("fileMenuButton", menuButtonWidgetClass, menuBar, NULL, (Cardinal) 0); fileMenu = XtCreatePopupShell ("fileMenu", simpleMenuWidgetClass, fileMenuButton, NULL, (Cardinal) 0); for (i = 0; i < XtNumber (fileMenuEntries); i++) { entry = XtCreateManagedWidget(fileMenuEntries[i].name, smeBSBObjectClass, fileMenu, NULL, (Cardinal) 0); XtAddCallback (entry, XtNcallback, fileMenuEntries[i].function, NULL); } (void) XtCreateManagedWidget ("prevButton", commandWidgetClass, menuBar, NULL, (Cardinal) 0); pageNumber = XtCreateManagedWidget("pageNumber", asciiTextWidgetClass, menuBar, NULL, (Cardinal) 0); (void) XtCreateManagedWidget ("nextButton", commandWidgetClass, menuBar, NULL, (Cardinal) 0); #ifdef NOTDEF form = XtCreateManagedWidget ("form", formWidgetClass, paned, NULL, (Cardinal) 0); panner = XtCreateManagedWidget ("panner", pannerWidgetClass, form, NULL, 0); porthole = XtCreateManagedWidget ("porthole", portholeWidgetClass, form, NULL, 0); XtAddCallback(porthole, XtNreportCallback, PortholeCallback, (XtPointer) panner); XtAddCallback(panner, XtNreportCallback, PannerCallback, (XtPointer) porthole); #else porthole = XtCreateManagedWidget ("viewport", viewportWidgetClass, paned, NULL, 0); #endif dvi = XtCreateManagedWidget ("dvi", dviWidgetClass, porthole, NULL, 0); if (file_name) VisitFile (file_name, FALSE); XtRealizeWidget (toplevel); wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", False); (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), &wm_delete_window, 1); XtAppMainLoop(xtcontext); return 0; }
/* FIXME: bits is currently unused */ GLWindow * createGLWindow(struct display_camera *camera) { GLWindow *x11_gl_window = New( GLWindow ); XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; MemSet( x11_gl_window, 0, sizeof( GLWindow ) ); camera->hVidCore->x11_gl_window = x11_gl_window; x11_gl_window->fs = 0;//fullscreenflag; /* set best mode to current */ bestMode = 0; /* get a connection */ x11_gl_window->dpy = XOpenDisplay(0); if( x11_gl_window->dpy ) { x11_gl_window->screen = DefaultScreen(x11_gl_window->dpy); #if 0 x11_gl_window->atom_create = XInternAtom( x11_gl_window->dpy, "UserCreateWindow", 0 ); XF86VidModeQueryVersion(x11_gl_window->dpy, &vidModeMajorVersion, &vidModeMinorVersion); printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion); if( x11_gl_window->fs ) { XF86VidModeGetAllModeLines(x11_gl_window->dpy, x11_gl_window->screen, &modeNum, &modes); /* save desktop-resolution before switching modes */ x11_gl_window->deskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == camera->w) && (modes[i]->vdisplay == camera->h)) { bestMode = i; } } } #endif /* get an appropriate visual */ vi = glXChooseVisual(x11_gl_window->dpy, x11_gl_window->screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(x11_gl_window->dpy, x11_gl_window->screen, attrListSgl); x11_gl_window->doubleBuffered = False; printf("Only Singlebuffered Visual!\n"); } else { x11_gl_window->doubleBuffered = True; printf("Got Doublebuffered Visual!\n"); } glXQueryVersion(x11_gl_window->dpy, &glxMajorVersion, &glxMinorVersion); printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion); /* create a GLX context */ x11_gl_window->ctx = glXCreateContext(x11_gl_window->dpy, vi, 0, GL_TRUE); /* create a color map */ lprintf( "colormap..." ); cmap = XCreateColormap(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), vi->visual, AllocNone); x11_gl_window->attr.colormap = cmap; x11_gl_window->attr.border_pixel = 0; x11_gl_window->attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | StructureNotifyMask; if (x11_gl_window->fs) { XF86VidModeSwitchToMode(x11_gl_window->dpy, x11_gl_window->screen, modes[bestMode]); XF86VidModeSetViewPort(x11_gl_window->dpy, x11_gl_window->screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; printf("Resolution %dx%d\n", dpyWidth, dpyHeight); XFree(modes); /* create a fullscreen window */ x11_gl_window->attr.override_redirect = True; x11_gl_window->win = XCreateWindow(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &x11_gl_window->attr); XWarpPointer(x11_gl_window->dpy, None, x11_gl_window->win, 0, 0, 0, 0, 0, 0); XMapRaised(x11_gl_window->dpy, x11_gl_window->win); XGrabKeyboard(x11_gl_window->dpy, x11_gl_window->win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(x11_gl_window->dpy, x11_gl_window->win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11_gl_window->win, None, CurrentTime); } else { /* create a window in window mode*/ lprintf( "create window... %d,%d %d", camera->w, camera->h, vi->depth ); x11_gl_window->win = XCreateWindow(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), 0, 0, camera->w, camera->h, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &x11_gl_window->attr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(x11_gl_window->dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(x11_gl_window->dpy, x11_gl_window->win, &wmDelete, 1); XSetStandardProperties(x11_gl_window->dpy, x11_gl_window->win, "No Title", "No Title", None, NULL, 0, NULL); XMapRaised(x11_gl_window->dpy, x11_gl_window->win); } /* connect the glx-context to the window */ SetActiveGLDisplayView( camera, 0 ); //glXMakeCurrent(x11_gl_window->dpy, x11_gl_window->win, x11_gl_window->ctx); XGetGeometry(x11_gl_window->dpy, x11_gl_window->win, &winDummy, &x11_gl_window->x, &x11_gl_window->y, &x11_gl_window->width, &x11_gl_window->height, &borderDummy, &x11_gl_window->depth); printf("Depth %d\n", x11_gl_window->depth); if (glXIsDirect(x11_gl_window->dpy, x11_gl_window->ctx)) printf("Congrats, you have Direct Rendering!\n"); else printf("Sorry, no Direct Rendering possible!\n"); } else { lprintf( "Failed to open display" ); return NULL; } return x11_gl_window; }
int main(int argc,char *argv[]) { int i; unsigned int borderwidth ; char *display_name = NULL; char *wname = "asclock"; XGCValues gcv; unsigned long gcm; XEvent Event; XTextProperty name; XClassHint classHint; Geometry = ""; /* Parse command line options */ config(); parseArgs(argc, argv); if(analog_visible || hour_visible || min_visible || sec_visible) { fprintf(stderr, "%s does not support analog clocks yet.\n", VERSION); fprintf(stderr, "You want the asclock-gtk versions\n"); } /* Open the display */ if (!(dpy = XOpenDisplay(display_name))) { fprintf(stderr,"asclock: can't open display %s\n", XDisplayName(display_name)); exit (1); } screen= DefaultScreen(dpy); Root = RootWindow(dpy, screen); d_depth = DefaultDepth(dpy, screen); x_fd = XConnectionNumber(dpy); /* Icon Daten nach XImage konvertieren */ GetXPM(); postconfig(); /* Create a window to hold the banner */ mysizehints.flags= USSize|USPosition; mysizehints.x = 0; mysizehints.y = 0; back_pix = GetColor("white"); fore_pix = GetColor("black"); XWMGeometry(dpy, screen, Geometry, "64x64+0+0", (borderwidth =1), &mysizehints, &mysizehints.x,&mysizehints.y,&mysizehints.width,&mysizehints.height, &i); mysizehints.width = asclock.attributes.width; mysizehints.height= asclock.attributes.height; win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y, mysizehints.width,mysizehints.height, borderwidth,fore_pix,back_pix); iconwin = XCreateSimpleWindow(dpy,win,mysizehints.x,mysizehints.y, mysizehints.width,mysizehints.height, borderwidth,fore_pix,back_pix); wm_delete_window = XInternAtom (dpy, "WM_DELETE_WINDOW", False); (void) XSetWMProtocols (dpy, win, &wm_delete_window, 1); /* Hints aktivieren */ XSetWMNormalHints(dpy, win, &mysizehints); classHint.res_name = "asclock"; classHint.res_class = "ASClock"; XSetClassHint(dpy, win, &classHint); XSelectInput(dpy,win,MW_EVENTS); XSelectInput(dpy,iconwin,MW_EVENTS); if (XStringListToTextProperty(&wname, 1, &name) ==0) { fprintf(stderr, "asclock: can't allocate window name\n"); exit(-1); } XSetWMName(dpy, win, &name); /* Create a GC for drawing */ gcm = GCForeground|GCBackground|GCGraphicsExposures; gcv.foreground = fore_pix; gcv.background = back_pix; gcv.graphics_exposures = FALSE; NormalGC = XCreateGC(dpy, Root, gcm, &gcv); /* if (ONLYSHAPE) { try to make shaped window here */ XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, asclock.mask, ShapeSet); XShapeCombineMask(dpy, iconwin, ShapeBounding, 0, 0, asclock.mask, ShapeSet); mywmhints.initial_state = (itdocks ? WithdrawnState : (ICONIFIED ? IconicState : NormalState)); mywmhints.icon_window = iconwin; mywmhints.icon_x = mysizehints.x; mywmhints.icon_y = mysizehints.y; mywmhints.flags = StateHint | IconWindowHint | IconPositionHint; if (itdocks) { mywmhints.window_group = win; mywmhints.flags |= WindowGroupHint; } XSetWMHints(dpy, win, &mywmhints); if (itdocks) XSetCommand(dpy, win, argv, argc); XMapWindow(dpy,win); InsertTime(); RedrawWindow(&visible); while(1) { if (actualtime != mytime()) { actualtime = mytime(); if(actualmin != actualtime / 60) { InsertTime(); if (!itblinks) RedrawWindow(&visible); } if( beats_visible ) { int beats = (int) (( ( actualtime + 60*60) % (24*60*60) ) / 86.4); swatch_beats(beats); RedrawWindow(&visible); } if (led_visible) if( itblinks ) { if (actualtime % 2) XCopyArea(dpy, led.pixmap, visible.pixmap, NormalGC, 10*led_elem_width, 0, (led_elem_width+1)/2, led_elem_height, ((showampm!=0) ? led_12h_colon_x : led_24h_colon_x), ((showampm!=0) ? led_12h_y : led_24h_y)); else /* Sekunden Doppelpunkt aus */ XCopyArea(dpy, asclock.pixmap, visible.pixmap, NormalGC, ((showampm!=0) ? led_12h_colon_x : led_24h_colon_x), ((showampm!=0) ? led_12h_y : led_24h_y), (led_elem_width+1)/2, led_elem_height, ((showampm!=0) ? led_12h_colon_x : led_24h_colon_x), ((showampm!=0) ? led_12h_y : led_24h_y)); RedrawWindow(&visible); } } /* read a packet */ while (XPending(dpy)) { XNextEvent(dpy,&Event); switch(Event.type) { case Expose: if(Event.xexpose.count == 0 ) RedrawWindow(&visible); break; case ButtonPress: system(exec_str); break; case DestroyNotify: /* XFreeGC(dpy, NormalGC); XDestroyWindow(dpy, win); XDestroyWindow(dpy, iconwin); */ XCloseDisplay(dpy); exit(0); case ClientMessage: { if( Event.xclient.data.l[0] == wm_delete_window) { XCloseDisplay(dpy); exit(0); } } break; default: break; } } XFlush(dpy); #ifdef SYSV poll((struct poll *) 0, (size_t) 0, 50); #else usleep(50000L); /* 5/100 sec */ #endif } return 0; }
static void winopen(void) { XWMHints *wmhints; XClassHint *classhint; xdpy = XOpenDisplay(NULL); if (!xdpy) fz_throw(gapp.ctx, "cannot open display"); XA_CLIPBOARD = XInternAtom(xdpy, "CLIPBOARD", False); XA_TARGETS = XInternAtom(xdpy, "TARGETS", False); XA_TIMESTAMP = XInternAtom(xdpy, "TIMESTAMP", False); XA_UTF8_STRING = XInternAtom(xdpy, "UTF8_STRING", False); WM_DELETE_WINDOW = XInternAtom(xdpy, "WM_DELETE_WINDOW", False); NET_WM_STATE = XInternAtom(xdpy, "_NET_WM_STATE", False); NET_WM_STATE_FULLSCREEN = XInternAtom(xdpy, "_NET_WM_STATE_FULLSCREEN", False); xscr = DefaultScreen(xdpy); ximage_init(xdpy, xscr, DefaultVisual(xdpy, xscr)); xcarrow = XCreateFontCursor(xdpy, XC_left_ptr); xchand = XCreateFontCursor(xdpy, XC_hand2); xcwait = XCreateFontCursor(xdpy, XC_watch); xccaret = XCreateFontCursor(xdpy, XC_xterm); xbgcolor.red = 0x7000; xbgcolor.green = 0x7000; xbgcolor.blue = 0x7000; xshcolor.red = 0x4000; xshcolor.green = 0x4000; xshcolor.blue = 0x4000; XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xbgcolor); XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xshcolor); xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy), 10, 10, 200, 100, 0, ximage_get_depth(), InputOutput, ximage_get_visual(), 0, NULL); if (xwin == None) fz_throw(gapp.ctx, "cannot create window"); XSetWindowColormap(xdpy, xwin, ximage_get_colormap()); XSelectInput(xdpy, xwin, StructureNotifyMask | ExposureMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); mapped = 0; xgc = XCreateGC(xdpy, xwin, 0, NULL); XDefineCursor(xdpy, xwin, xcarrow); wmhints = XAllocWMHints(); if (wmhints) { wmhints->flags = IconPixmapHint | IconMaskHint; xicon = XCreateBitmapFromData(xdpy, xwin, (char*)mupdf_icon_bitmap_16_bits, mupdf_icon_bitmap_16_width, mupdf_icon_bitmap_16_height); xmask = XCreateBitmapFromData(xdpy, xwin, (char*)mupdf_icon_bitmap_16_mask_bits, mupdf_icon_bitmap_16_mask_width, mupdf_icon_bitmap_16_mask_height); if (xicon && xmask) { wmhints->icon_pixmap = xicon; wmhints->icon_mask = xmask; XSetWMHints(xdpy, xwin, wmhints); } XFree(wmhints); } classhint = XAllocClassHint(); if (classhint) { classhint->res_name = "mupdf"; classhint->res_class = "MuPDF"; XSetClassHint(xdpy, xwin, classhint); XFree(classhint); } XSetWMProtocols(xdpy, xwin, &WM_DELETE_WINDOW, 1); x11fd = ConnectionNumber(xdpy); }
bool CreateWindowGL (GL_Window* window) { XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; int x, y; bestMode = 0; window->init.dpy = XOpenDisplay( NULL ); window->init.screen = DefaultScreen( window->init.dpy ); XF86VidModeQueryVersion( window->init.dpy, &vidModeMajorVersion, &vidModeMinorVersion ); printf( "XF86VMExt-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion ); XF86VidModeGetAllModeLines( window->init.dpy, window->init.screen, &modeNum, &modes ); window->init.deskMode = *modes[0]; for( i=0;i<modeNum;i++ ) { if( (modes[i]->hdisplay == window->init.width) && (modes[i]->vdisplay == window->init.height) ) bestMode = i; } vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListDbl ); if( vi == NULL ) { vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListSgl ); window->init.doubleBuffered = false; printf( "Single Buffered visual\n" ); } else { window->init.doubleBuffered = true; printf( "Double Buffered visual\n" ); } glXQueryVersion( window->init.dpy, &glxMajorVersion, &glxMinorVersion ); printf( "glx-version %d.%d\n", glxMajorVersion, glxMinorVersion ); window->init.ctx = glXCreateContext( window->init.dpy, vi, 0, GL_TRUE ); cmap = XCreateColormap( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), vi->visual, AllocNone ); window->init.attr.colormap = cmap; window->init.attr.border_pixel = 0; if( window->init.isFullScreen ) { XF86VidModeSwitchToMode( window->init.dpy, window->init.screen, modes[bestMode] ); XF86VidModeSetViewPort( window->init.dpy, window->init.screen, 0, 0 ); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree( modes ); window->init.attr.override_redirect = true; window->init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window->init.win = XCreateWindow( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &window->init.attr ); XWarpPointer( window->init.dpy, None, window->init.win, 0, 0, 0, 0, 0, 0 ); XMapRaised( window->init.dpy, window->init.win ); XGrabKeyboard( window->init.dpy, window->init.win, True, GrabModeAsync, GrabModeAsync, CurrentTime ); XGrabPointer( window->init.dpy, window->init.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window->init.win, None, CurrentTime ); } else { window->init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window->init.win = XCreateWindow( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), 0, 0, window->init.width, window->init.height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &window->init.attr ); wmDelete = XInternAtom( window->init.dpy, "WM_DELETE_WINDOW", True ); XSetWMProtocols( window->init.dpy, window->init.win, &wmDelete, 1 ); XSetStandardProperties( window->init.dpy, window->init.win, window->init.title, window->init.title, None, NULL, 0, NULL ); XMapRaised( window->init.dpy, window->init.win ); } glXMakeCurrent( window->init.dpy, window->init.win, window->init.ctx ); XGetGeometry( window->init.dpy, window->init.win, &winDummy, &x, &y, &window->init.width, &window->init.height, &borderDummy, &window->init.depth ); if( glXIsDirect( window->init.dpy, window->init.ctx ) ) printf( "Direct rendering\n" ); else printf( "Not Direct rendering\n" ); return true; }
/*!***************************************************************************************************************************************** @Function CreateNativeWindow @Input nativeDisplay Native display used by the application @Output nativeWindow Native window type to create @Return Whether the function succeeded or not. @Description Creates a native window for the application to render into. *******************************************************************************************************************************************/ bool CreateNativeWindow(Display* nativeDisplay, Window* nativeWindow) { // Get the default screen for the display int defaultScreen = XDefaultScreen(nativeDisplay); // Get the default depth of the display int defaultDepth = DefaultDepth(nativeDisplay, defaultScreen); // Select a visual info XVisualInfo* visualInfo = new XVisualInfo; XMatchVisualInfo( nativeDisplay, defaultScreen, defaultDepth, TrueColor, visualInfo); if (!visualInfo) { printf("Error: Unable to acquire visual\n"); return false; } // Get the root window for the display and default screen Window rootWindow = RootWindow(nativeDisplay, defaultScreen); // Create a colour map from the display, root window and visual info Colormap colourMap = XCreateColormap(nativeDisplay, rootWindow, visualInfo->visual, AllocNone); // Now setup the final window by specifying some attributes XSetWindowAttributes windowAttributes; // Set the colour map that was just created windowAttributes.colormap = colourMap; // Set events that will be handled by the app, add to these for other events. windowAttributes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask; // Create the window *nativeWindow =XCreateWindow(nativeDisplay, // The display used to create the window rootWindow, // The parent (root) window - the desktop 0, // The horizontal (x) origin of the window 0, // The vertical (y) origin of the window WINDOW_WIDTH, // The width of the window WINDOW_HEIGHT, // The height of the window 0, // Border size - set it to zero visualInfo->depth, // Depth from the visual info InputOutput, // Window type - this specifies InputOutput. visualInfo->visual, // Visual to use CWEventMask | CWColormap, // Mask specifying these have been defined in the window attributes &windowAttributes); // Pointer to the window attribute structure // Make the window viewable by mapping it to the display XMapWindow(nativeDisplay, *nativeWindow); // Set the window title XStoreName(nativeDisplay, *nativeWindow, APPLICATION_NAME); // Setup the window manager protocols to handle window deletion events Atom windowManagerDelete = XInternAtom(nativeDisplay, "WM_DELETE_WINDOW", True); XSetWMProtocols(nativeDisplay, *nativeWindow, &windowManagerDelete , 1); // Delete the visual info delete visualInfo; return true; }
//create gl window bool openglx_1o5_renderer::makeWindow( char* title, int width, int height, int bits, bool fullscreenflag ) { XVisualInfo *vi; Colormap cmap; Window winDummy; unsigned int borderDummy; this->gl.fs = fullscreenflag; //open display this->gl.dpy = XOpenDisplay( 0 ); this->gl.screen = DefaultScreen( this->gl.dpy ); //set visual format static int attrListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; vi = glXChooseVisual( this->gl.dpy, this->gl.screen, attrListDbl ); this->gl.doubleBuffered = vi != 0; if( !vi ) vi = glXChooseVisual(this->gl.dpy, this->gl.screen, attrListSgl ); if( !vi ) { XCloseDisplay( this->gl.dpy ); this->gl.dpy = 0; return 0; } //create context this->gl.ctx = glXCreateContext( this->gl.dpy, vi, 0, GL_TRUE ); if( !this->gl.ctx ) { XCloseDisplay( this->gl.dpy ); this->gl.dpy = 0; return 0; } //colormap cmap = XCreateColormap( this->gl.dpy, RootWindow( this->gl.dpy, vi->screen ), vi->visual, AllocNone ); this->gl.attr.colormap = cmap; this->gl.attr.border_pixel = 0; //create window this->gl.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; this->gl.win = XCreateWindow( this->gl.dpy, RootWindow( this->gl.dpy, vi->screen ), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &this->gl.attr ); if( !this->gl.win ) { glXDestroyContext( this->gl.dpy, this->gl.ctx ); XCloseDisplay( this->gl.dpy ); this->gl.dpy = 0; this->gl.ctx = 0; return 0; } //setup close button event this->gl.wm_delete_window = XInternAtom( this->gl.dpy, "WM_DELETE_WINDOW", True ); XSetWMProtocols( this->gl.dpy, this->gl.win, &this->gl.wm_delete_window, 1 ); //set title XSetStandardProperties( this->gl.dpy, this->gl.win, title, title, None, NULL, 0, NULL ); XMapRaised( this->gl.dpy, this->gl.win ); //male context active glXMakeCurrent( this->gl.dpy, this->gl.win, this->gl.ctx ); //get window position XGetGeometry( this->gl.dpy, this->gl.win, &winDummy, &this->gl.x, &this->gl.y, &this->gl.width, &this->gl.height, &borderDummy, &this->gl.depth ); glDisable(GL_CULL_FACE); glShadeModel( GL_SMOOTH ); glClearColor( 0.0f, 0.0f, 0.0f, 0.5f ); glClearDepth( 1.0f ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glEnable( GL_TEXTURE_2D ); return 1; }
CXlibToolkit::CXlibToolkit(void *parentWindow, CEditor *editor) { this->parentWindow = parentWindow; this->editor = editor; char *displayName = getenv("DISPLAY"); if (!displayName || !strlen(displayName)) { displayName = (char*)":0.0"; } if (!XInitThreads()) { fprintf(stderr, "Xlib threads support unavailable"); return; } this->display = XOpenDisplay(displayName); if (!parentWindow) { parentWindow = (void*)RootWindow(this->display, DefaultScreen(this->display)); } window = XCreateWindow(this->display, (Window)parentWindow, 0, 0, GUI_WIDTH, GUI_HEIGHT, 0, 24, InputOutput, CopyFromParent, 0, 0); gc = XCreateGC(this->display, window, 0, 0); XSelectInput(this->display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | KeyPressMask); XMapWindow(this->display, window); XFlush(this->display); this->WM_TIMER = XInternAtom(this->display, "WM_TIMER" , false); this->WM_DELETE_WINDOW = XInternAtom(this->display, "WM_DELETE_WINDOW", false); XSetWMProtocols(this->display, window, &WM_DELETE_WINDOW, 1); offscreen = XCreatePixmap(this->display, window, GUI_WIDTH, GUI_HEIGHT, 24); memset(bmps, 0, sizeof(bmps)); char path[PATH_MAX]; GetResourcesPath(path, PATH_MAX); char fullPath[PATH_MAX]; snprintf(fullPath, PATH_MAX, "%s/%s", path, "chars.bmp" ); bmps[BMP_CHARS ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "knob.bmp" ); bmps[BMP_KNOB ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "knob2.bmp" ); bmps[BMP_KNOB2 ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "knob3.bmp" ); bmps[BMP_KNOB3 ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "key.bmp" ); bmps[BMP_KEY ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "bg.bmp" ); bmps[BMP_BG ] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "buttons.bmp"); bmps[BMP_BUTTONS] = LoadImageFromFile(fullPath); snprintf(fullPath, PATH_MAX, "%s/%s", path, "ops.bmp" ); bmps[BMP_OPS ] = LoadImageFromFile(fullPath); if (!bmps[BMP_CHARS ]) bmps[BMP_CHARS ] = LoadImageFromBuffer(chars_bmp ); if (!bmps[BMP_KNOB ]) bmps[BMP_KNOB ] = LoadImageFromBuffer(knob_bmp ); if (!bmps[BMP_KNOB2 ]) bmps[BMP_KNOB2 ] = LoadImageFromBuffer(knob2_bmp ); if (!bmps[BMP_KNOB3 ]) bmps[BMP_KNOB3 ] = LoadImageFromBuffer(knob3_bmp ); if (!bmps[BMP_KEY ]) bmps[BMP_KEY ] = LoadImageFromBuffer(key_bmp ); if (!bmps[BMP_BG ]) bmps[BMP_BG ] = LoadImageFromBuffer(bg_bmp ); if (!bmps[BMP_BUTTONS]) bmps[BMP_BUTTONS] = LoadImageFromBuffer(buttons_bmp); if (!bmps[BMP_OPS ]) bmps[BMP_OPS ] = LoadImageFromBuffer(ops_bmp ); thread1Finished = true; thread2Finished = true; }
/*!*********************************************************************** @Function OpenX11Window @Return true on success @Description Opens an X11 window. This must be called after SelectEGLConfiguration() for gEglConfig to be valid *************************************************************************/ int PVRShellInitOS::OpenX11Window(const PVRShell &shell) { XSetWindowAttributes WinAttibutes; XSizeHints sh; XEvent event; unsigned long mask; #ifdef BUILD_OGL XF86VidModeModeInfo **modes; // modes of display int numModes; // number of modes of display int chosenMode; int edimx,edimy; //established width and height of the chosen modeline int i; #endif int depth = DefaultDepth(m_X11Display, m_X11Screen); m_X11Visual = new XVisualInfo; XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual); if( !m_X11Visual ) { shell.PVRShellOutputDebug( "Unable to acquire visual" ); return false; } m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone ); #ifdef BUILD_OGL m_i32OriginalModeDotClock = XF86VidModeBadClock; if(shell.m_pShellData->bFullScreen) { // Get mode lines to see if there is requested modeline XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes); // look for mode with requested resolution chosenMode = -1; i=0; while((chosenMode == -1)&&(i<numModes)) { if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY)) { chosenMode = i; } ++i; } // If there is no requested resolution among modelines then terminate if(chosenMode == -1) { shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" ); return false; } // save desktop-resolution before switching modes XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode ); XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]); XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0); edimx = modes[chosenMode]->hdisplay; edimy = modes[chosenMode]->vdisplay; printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode); XFree(modes); WinAttibutes.colormap = m_X11ColorMap; WinAttibutes.background_pixel = 0xFFFFFFFF; WinAttibutes.border_pixel = 0; WinAttibutes.override_redirect = true; // add to these for handling other events WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; // The diffrence is that we want to ignore influence of window manager for our fullscreen window mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect; m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes); // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0); // Map and then wait till mapped, grabbing should be after mapping the window XMapWindow( m_X11Display, m_X11Window ); XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime); XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); } else #endif { // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it) // so if requested resolution differs from the display dims then we quit #ifndef BUILD_OGL int display_width = XDisplayWidth(m_X11Display,m_X11Screen); int display_height = XDisplayHeight(m_X11Display,m_X11Screen); if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) { shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" ); return false; } #endif WinAttibutes.colormap = m_X11ColorMap; WinAttibutes.background_pixel = 0xFFFFFFFF; WinAttibutes.border_pixel = 0; // add to these for handling other events WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; // The attribute mask mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ; m_X11Window = XCreateWindow( m_X11Display, // Display RootWindow(m_X11Display, m_X11Screen), // Parent shell.m_pShellData->nShellPosX, // X position of window shell.m_pShellData->nShellPosY, // Y position of window shell.m_pShellData->nShellDimX, // Window width shell.m_pShellData->nShellDimY, // Window height 0, // Border width CopyFromParent, // Depth (taken from parent) InputOutput, // Window class CopyFromParent, // Visual type (taken from parent) mask, // Attributes mask &WinAttibutes); // Attributes // Set the window position sh.flags = USPosition; sh.x = shell.m_pShellData->nShellPosX; sh.y = shell.m_pShellData->nShellPosY; XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh ); // Map and then wait till mapped XMapWindow( m_X11Display, m_X11Window ); XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2) if(shell.m_pShellData->bFullScreen) { XEvent xev; Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False); Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False); memset(&xev, 0, sizeof(XEvent)); xev.type = ClientMessage; xev.xclient.window = m_X11Window; xev.xclient.message_type = wmState; xev.xclient.format = 32; xev.xclient.data.l[0] = 1; xev.xclient.data.l[1] = wmStateFullscreen; xev.xclient.data.l[2] = 0; XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev); } Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True); XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1); XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 ); } XFlush( m_X11Display ); return true; }
bool X11Window::initialize(const std::string &name, size_t width, size_t height) { destroy(); mDisplay = XOpenDisplay(NULL); if (!mDisplay) { return false; } { int screen = DefaultScreen(mDisplay); Window root = RootWindow(mDisplay, screen); Colormap colormap = XCreateColormap(mDisplay, root, DefaultVisual(mDisplay, screen), AllocNone); int depth = DefaultDepth(mDisplay, screen); Visual *visual = DefaultVisual(mDisplay, screen); XSetWindowAttributes attributes; unsigned long attributeMask = CWBorderPixel | CWColormap | CWEventMask; attributes.event_mask = StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask; attributes.border_pixel = 0; attributes.colormap = colormap; mWindow = XCreateWindow(mDisplay, root, 0, 0, width, height, 0, depth, InputOutput, visual, attributeMask, &attributes); XFreeColormap(mDisplay, colormap); } if (!mWindow) { destroy(); return false; } // Tell the window manager to notify us when the user wants to close the // window so we can do it ourselves. WM_DELETE_WINDOW = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False); WM_PROTOCOLS = XInternAtom(mDisplay, "WM_PROTOCOLS", False); if (WM_DELETE_WINDOW == None || WM_PROTOCOLS == None) { destroy(); return false; } if(XSetWMProtocols(mDisplay, mWindow, &WM_DELETE_WINDOW, 1) == 0) { destroy(); return false; } // Create an atom to identify our test event TEST_EVENT = XInternAtom(mDisplay, "ANGLE_TEST_EVENT", False); if (TEST_EVENT == None) { destroy(); return false; } XFlush(mDisplay); mX = 0; mY = 0; mWidth = width; mHeight = height; return true; }
/* FIXME: bits is currently unused */ Bool createGLWindow(char* title, int width, int height, int bits, Bool fullscreenflag) { XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; GLWin.fs = fullscreenflag; /* set best mode to current */ bestMode = 0; /* get a connection */ GLWin.dpy = XOpenDisplay(0); GLWin.screen = DefaultScreen(GLWin.dpy); XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion, &vidModeMinorVersion); printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion); XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes); /* save desktop-resolution before switching modes */ GLWin.deskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) { bestMode = i; } } /* get an appropriate visual */ vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl); printf("Only Singlebuffered Visual!\n"); } else { printf("Got Doublebuffered Visual!\n"); } glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion); printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion); /* create a GLX context */ GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), vi->visual, AllocNone); GLWin.attr.colormap = cmap; GLWin.attr.border_pixel = 0; if (GLWin.fs) { XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]); XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; printf("Resolution %dx%d\n", dpyWidth, dpyHeight); XFree(modes); /* create a fullscreen window */ GLWin.attr.override_redirect = True; GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &GLWin.attr); XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0); XMapRaised(GLWin.dpy, GLWin.win); XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime); } else { /* create a window in window mode*/ GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1); XSetStandardProperties(GLWin.dpy, GLWin.win, title, title, None, NULL, 0, NULL); XMapRaised(GLWin.dpy, GLWin.win); } /* connect the glx-context to the window */ glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); printf("Depth %d\n", GLWin.depth); if (glXIsDirect(GLWin.dpy, GLWin.ctx)) printf("Congrats, you have Direct Rendering!\n"); else printf("Sorry, no Direct Rendering possible!\n"); initGL(); return True; }
/* Must be called in the gl thread */ GstGLWindow * gst_gl_window_new (gulong external_gl_context) { GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL); GstGLWindowPrivate *priv = window->priv; EGLint config_attrib[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint context_attrib[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint majorVersion; EGLint minorVersion; EGLint numConfigs; EGLConfig config; XSetWindowAttributes win_attr; XTextProperty text_property; XWMHints wm_hints; unsigned long mask; const gchar *title = "OpenGL renderer"; Atom wm_atoms[3]; static gint x = 0; static gint y = 0; setlocale (LC_NUMERIC, "C"); priv->x_lock = g_mutex_new (); priv->cond_send_message = g_cond_new (); priv->running = TRUE; priv->visible = FALSE; priv->parent = 0; priv->allow_extra_expose_events = TRUE; g_mutex_lock (priv->x_lock); priv->device = XOpenDisplay (priv->display_name); XSynchronize (priv->device, FALSE); g_debug ("gl device id: %ld\n", (gulong) priv->device); priv->disp_send = XOpenDisplay (priv->display_name); XSynchronize (priv->disp_send, FALSE); g_debug ("gl display sender: %ld\n", (gulong) priv->disp_send); priv->screen_num = DefaultScreen (priv->device); priv->root = RootWindow (priv->device, priv->screen_num); priv->depth = DefaultDepth (priv->device, priv->screen_num); g_debug ("gl root id: %lud\n", (gulong) priv->root); priv->device_width = DisplayWidth (priv->device, priv->screen_num); priv->device_height = DisplayHeight (priv->device, priv->screen_num); priv->visual_info = g_new0 (XVisualInfo, 1); XMatchVisualInfo (priv->device, priv->screen_num, priv->depth, TrueColor, priv->visual_info); win_attr.event_mask = StructureNotifyMask | ExposureMask | VisibilityChangeMask; win_attr.do_not_propagate_mask = NoEventMask; win_attr.background_pixmap = None; win_attr.background_pixel = 0; win_attr.border_pixel = 0; win_attr.colormap = XCreateColormap (priv->device, priv->root, priv->visual_info->visual, AllocNone); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; x += 20; y += 20; priv->internal_win_id = XCreateWindow (priv->device, priv->root, x, y, 1, 1, 0, priv->visual_info->depth, InputOutput, priv->visual_info->visual, mask, &win_attr); XSync (priv->device, FALSE); XSetWindowBackgroundPixmap (priv->device, priv->internal_win_id, None); g_debug ("gl window id: %lud\n", (gulong) priv->internal_win_id); g_debug ("gl window props: x:%d y:%d\n", x, y); wm_atoms[0] = XInternAtom (priv->device, "WM_DELETE_WINDOW", True); if (wm_atoms[0] == None) g_debug ("Cannot create WM_DELETE_WINDOW\n"); wm_atoms[1] = XInternAtom (priv->device, "WM_GL_WINDOW", False); if (wm_atoms[1] == None) g_debug ("Cannot create WM_GL_WINDOW\n"); wm_atoms[2] = XInternAtom (priv->device, "WM_QUIT_LOOP", False); if (wm_atoms[2] == None) g_debug ("Cannot create WM_QUIT_LOOP\n"); XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2); wm_hints.flags = StateHint; wm_hints.initial_state = NormalState; wm_hints.input = False; XStringListToTextProperty ((char **) &title, 1, &text_property); XSetWMProperties (priv->device, priv->internal_win_id, &text_property, &text_property, 0, 0, NULL, &wm_hints, NULL); XFree (text_property.value); priv->gl_display = eglGetDisplay ((EGLNativeDisplayType) priv->device); if (eglInitialize (priv->gl_display, &majorVersion, &minorVersion)) g_debug ("egl initialized: %d.%d\n", majorVersion, minorVersion); else g_debug ("failed to initialize egl %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); if (eglChooseConfig (priv->gl_display, config_attrib, &config, 1, &numConfigs)) g_debug ("config set: %ld, %ld\n", (gulong) config, (gulong) numConfigs); else g_debug ("failed to set config %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); priv->gl_surface = eglCreateWindowSurface (priv->gl_display, config, (EGLNativeWindowType) priv->internal_win_id, NULL); if (priv->gl_surface != EGL_NO_SURFACE) g_debug ("surface created: %ld\n", (gulong) priv->gl_surface); else g_debug ("failed to create surface %ld, %ld, %ld, %s\n", (gulong) priv->gl_display, (gulong) priv->gl_surface, (gulong) priv->gl_display, EGLErrorString ()); priv->gl_context = eglCreateContext (priv->gl_display, config, (EGLContext) (guint) external_gl_context, context_attrib); if (priv->gl_context != EGL_NO_CONTEXT) g_debug ("gl context created: %ld\n", (gulong) priv->gl_context); else g_debug ("failed to create glcontext %ld, %ld, %s\n", (gulong) priv->gl_context, (gulong) priv->gl_display, EGLErrorString ()); if (!eglMakeCurrent (priv->gl_display, priv->gl_surface, priv->gl_surface, priv->gl_context)) g_debug ("failed to make opengl context current %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); g_mutex_unlock (priv->x_lock); return window; }
/* * Popup a window with wrapped text in it. * For Motif, the text is explicitly wrapped inside this method. */ static Widget internal_popup_window(Widget parent, popupMessageSizeHintT size, popupMessageT type, int x_coord, int y_coord, const char *helptext, char *msg_buf, #ifndef MOTIF const char *xaw_ret_action_str, #endif pre_message_cbT pre_cb, XtPointer arg, const char *yes_button, message_cbT yes_cb, XtPointer yes_arg, const char *no_button, message_cbT no_cb, XtPointer no_arg, const char *cancel_button, message_cbT cancel_cb, XtPointer cancel_arg) { int my_popup_num = 0; #ifdef MOTIF XmString str; #endif Widget ret; ASSERT(type < (sizeof my_msg_map / sizeof my_msg_map[0]), "too few elements in my_msg_map"); #if DEBUG fprintf(stderr, "internal_popup_window called with prompt: \"%s\"\n", msg_buf); #endif if (globals.widgets.top_level == 0) { /* If toplevel window hasn't been created yet, dump messages to STDERR and return. */ fprintf(stderr, "\n%s:\n%s\n", my_msg_map[type].window_title, msg_buf); if (helptext) { fputs("---------- helptext ----------\n", stderr); fputs(helptext, stderr); fputs("\n---------- end of helptext ----------\n", stderr); } return NULL; } /* search for first free position in g_popup_array */ while (my_popup_num < MAX_POPUPS && (g_popup_array[my_popup_num] == 1)) { my_popup_num++; } if (my_popup_num == MAX_POPUPS) { /* already enough popups on screen, just dump it to stderr */ fprintf(stderr, "%s: %s\n", my_msg_map[type].window_title, msg_buf); /* Note: If a mad function continues to open popups, this will * stop after MAX_POPUPS, but open a new window for each * window the user pops down. Maybe we ought to do something * about this. */ return NULL; } else { /* mark it as non-free */ g_popup_array[my_popup_num] = 1; } #if DEBUG fprintf(stderr, "first free position in g_popup_array: %d\n", my_popup_num); #endif /* just to make sure ... */ if (parent == NULL) parent = globals.widgets.top_level; /* create a new set of widgets for the additional popup. */ ret = create_dialogs(size, parent, my_popup_num, helptext, pre_cb, arg, yes_button, yes_cb, yes_arg, no_button, no_cb, no_arg, cancel_button, cancel_cb, cancel_arg); #ifdef MOTIF XtVaSetValues(popup_window[my_popup_num], XmNtitle, my_msg_map[type].window_title, NULL); XtVaSetValues(dialog[my_popup_num], XmNdialogType, my_msg_map[type].motif_msg_type, NULL); { /* wrap message at space before MSG_WRAP_LEN */ char *testwrap = msg_buf; int ctr; for (ctr = 0; *testwrap++; ctr++) { if (*testwrap == '\n') { ctr = 0; } else if (ctr > MSG_WRAP_LEN) { size_t before_len = 0, after_len = 0; char *before_ptr, *after_ptr; before_ptr = after_ptr = testwrap; /* try to find shortest sequence before or after point to wrap at; this seems to give the most pleasing results. */ while (before_ptr > msg_buf && !isspace((int)*--before_ptr)) { before_len++; } while (*after_ptr != '\0' && !isspace((int)*++after_ptr)) { after_len++; } if (before_len < after_len && isspace((int)*before_ptr)) { /* use last in sequence of multiple spaces */ while (isspace((int)*++before_ptr)) { ; } /* back up, and wrap */ *--before_ptr = '\n'; ctr = 0; } else if (isspace((int)*after_ptr)) { /* use last in sequence of multiple spaces */ while (isspace((int)*++after_ptr)) { ; } /* back up, and wrap */ *--after_ptr = '\n'; ctr = 0; } } } } str = XmStringCreateLtoR((char *)msg_buf, G_charset); XtVaSetValues(dialog[my_popup_num], XmNmessageString, str, XmNtraversalOn, True, XmNhighlightOnEnter, True, NULL); XmStringFree(str); XtManageChild(dialog[my_popup_num]); if (x_coord > 0 && y_coord > 0) { position_window(XtParent(dialog[my_popup_num]), (Position)x_coord, (Position)y_coord); } XtPopup(XtParent(dialog[my_popup_num]), XtGrabNone); /* XtPopup(XtParent(dialog[my_popup_num]), XtGrabExclusive); */ #else /* MOTIF */ /* add a binding of xaw_ret_action_str to <Return> to relevant widgets. The callbacks (xaw_ret_action_str) are responsible for parsing the passed arguments (pointers, or empty arguments). */ if (xaw_ret_action_str != NULL) { XtTranslations xlats; char *translation_str; if (yes_arg != NULL) translation_str = get_string_va("<Key>Return:close-popup(%d)%s(%p)", my_popup_num, xaw_ret_action_str, yes_arg); else translation_str = get_string_va("<Key>Return:close-popup(%d)%s()", my_popup_num, xaw_ret_action_str); xlats = XtParseTranslationTable(translation_str); free(translation_str); XtOverrideTranslations(popup_window[my_popup_num], xlats); XtOverrideTranslations(message_paned[my_popup_num], xlats); XtOverrideTranslations(message_text[my_popup_num], xlats); } XtVaSetValues(popup_window[my_popup_num], XtNtitle, my_msg_map[type].window_title, NULL); XtVaSetValues(message_text[my_popup_num], XtNstring, msg_buf, NULL); XtRealizeWidget(popup_window[my_popup_num]); XSetWMProtocols(XtDisplay(popup_window[my_popup_num]), XtWindow(popup_window[my_popup_num]), &WM_DELETE_WINDOW, 1); if (x_coord <= 0 || y_coord <= 0) center_window(popup_window[my_popup_num], parent); else position_window(popup_window[my_popup_num], (Position)x_coord, (Position)y_coord); if (my_popup_num > 0) { /* some window managers position new windows exactly above the existing one; to prevent this, move it with some offset from the previous one: */ Position x = 0, y = 0; XtVaGetValues(popup_window[my_popup_num-1], XtNx, &x, XtNy, &y, NULL); XtVaSetValues(popup_window[my_popup_num], XtNx, x + POPUP_OFFSET, XtNy, y + POPUP_OFFSET, NULL); } XtPopup(popup_window[my_popup_num], XtGrabNone); /* XtPopup(XtParent(popup_window[my_popup_num]), XtGrabExclusive); */ if (XtIsManaged(message_not_ok[my_popup_num]) && XtIsManaged(message_help[my_popup_num])) { /* center the help button. This is something of a sham, since it won't survive resizing; but in general most users won't resize dialogs ;-) */ Position x1, x2, bw; int w, dist; XtVaGetValues(message_ok[my_popup_num], XtNx, &x1, XtNwidth, &w, XtNborderWidth, &bw, NULL); XtVaGetValues(message_help[my_popup_num], XtNx, &x2, NULL); /* following formula is measured, not calculated - I have no idea why it's e.g. 2 * w, not 1.5 * w ... */ dist = (x2 - x1 - 2 * w) / 2 - 2 * bw; XtVaSetValues(message_not_ok[my_popup_num], XtNhorizDistance, dist, NULL); } #endif /* MOTIF */ return ret; }
bool x11_init(XRESOURCES* res, CFG* config){ Window root; XSetWindowAttributes window_attributes; unsigned width, height; Atom wm_state_fullscreen; int xdbe_major, xdbe_minor; XTextProperty window_name; pid_t pid = getpid(); //allocate some structures XSizeHints* size_hints = XAllocSizeHints(); XWMHints* wm_hints = XAllocWMHints(); XClassHint* class_hints = XAllocClassHint(); if(!size_hints || !wm_hints || !class_hints){ fprintf(stderr, "Failed to allocate X data structures\n"); return false; } //x data initialization res->display = XOpenDisplay(NULL); if(!(res->display)){ fprintf(stderr, "Failed to open display\n"); XFree(size_hints); XFree(wm_hints); XFree(class_hints); return false; } if(config->double_buffer){ config->double_buffer = (XdbeQueryExtension(res->display, &xdbe_major, &xdbe_minor) != 0); } else{ config->double_buffer = false; } errlog(config, LOG_INFO, "Double buffering %s\n", config->double_buffer ? "enabled":"disabled"); res->screen = DefaultScreen(res->display); root = RootWindow(res->display, res->screen); //start xft if(!XftInit(NULL)){ fprintf(stderr, "Failed to initialize Xft\n"); XFree(size_hints); XFree(wm_hints); XFree(class_hints); return false; } //set up colors res->text_color = colorspec_parse(config->text_color, res->display, res->screen); res->bg_color = colorspec_parse(config->bg_color, res->display, res->screen); res->debug_color = colorspec_parse(config->debug_color, res->display, res->screen); //set up window params window_attributes.background_pixel = res->bg_color.pixel; window_attributes.cursor = None; window_attributes.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; width = DisplayWidth(res->display, res->screen); height = DisplayHeight(res->display, res->screen); //create window res->main = XCreateWindow(res->display, root, 0, 0, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWCursor | CWEventMask, &window_attributes); //set window properties if(XStringListToTextProperty(&(config->window_name), 1, &window_name) == 0){ fprintf(stderr, "Failed to create string list, aborting\n"); return false; } wm_hints->flags = 0; class_hints->res_name = "xecho"; class_hints->res_class = "xecho"; XSetWMProperties(res->display, res->main, &window_name, NULL, NULL, 0, NULL, wm_hints, class_hints); XFree(window_name.value); XFree(size_hints); XFree(wm_hints); XFree(class_hints); //set fullscreen mode if(!config->windowed){ wm_state_fullscreen = XInternAtom(res->display, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(res->display, res->main, XInternAtom(res->display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char*) &wm_state_fullscreen, 1); } XChangeProperty(res->display, res->main, XInternAtom(res->display, "_NET_WM_PID", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&pid, 1); //allocate back drawing buffer if(config->double_buffer){ res->back_buffer = XdbeAllocateBackBufferName(res->display, res->main, XdbeBackground); } //make xft drawable from window res->drawable = XftDrawCreate(res->display, (config->double_buffer?res->back_buffer:res->main), DefaultVisual(res->display, res->screen), DefaultColormap(res->display, res->screen)); if(!res->drawable){ fprintf(stderr, "Failed to allocate drawable\n"); return false; } //register for WM_DELETE_WINDOW messages res->wm_delete = XInternAtom(res->display, "WM_DELETE_WINDOW", False); XSetWMProtocols(res->display, res->main, &(res->wm_delete), 1); //map window XMapRaised(res->display, res->main); //get x socket fds if(!xfd_add(&(res->xfds), XConnectionNumber(res->display))){ fprintf(stderr, "Failed to allocate xfd memory\n"); return false; } if(XAddConnectionWatch(res->display, xconn_watch, (void*)(&(res->xfds))) == 0){ fprintf(stderr, "Failed to register connection watch procedure\n"); return false; } return true; }
void win_open(win_t *win) { win_env_t *e; XClassHint classhint; XSetWindowAttributes attr; unsigned long attr_mask; XColor col; char none_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; Pixmap none; int gmask; if (win == NULL) return; e = &win->env; /* determine window offsets, width & height */ if (options->geometry == NULL) gmask = 0; else gmask = XParseGeometry(options->geometry, &win->x, &win->y, &win->w, &win->h); if ((gmask & WidthValue) != 0) win->sizehints.flags |= USSize; else win->w = WIN_WIDTH; if ((gmask & HeightValue) != 0) win->sizehints.flags |= USSize; else win->h = WIN_HEIGHT; if ((gmask & XValue) != 0) { if ((gmask & XNegative) != 0) { win->x += e->scrw - win->w; win->sizehints.win_gravity = NorthEastGravity; } win->sizehints.flags |= USPosition; } else { win->x = (e->scrw - win->w) / 2; } if ((gmask & YValue) != 0) { if ((gmask & YNegative) != 0) { win->y += e->scrh - win->h; if (win->sizehints.win_gravity == NorthEastGravity) win->sizehints.win_gravity = SouthEastGravity; else win->sizehints.win_gravity = SouthWestGravity; } win->sizehints.flags |= USPosition; } else { win->y = (e->scrh - win->h) / 2; } attr.background_pixel = win->bgcol; attr_mask = CWBackPixel; win->xwin = XCreateWindow(e->dpy, RootWindow(e->dpy, e->scr), win->x, win->y, win->w, win->h, 0, e->depth, InputOutput, e->vis, attr_mask, &attr); if (win->xwin == None) die("could not create window"); XSelectInput(e->dpy, win->xwin, ExposureMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | PointerMotionMask | StructureNotifyMask); carrow = XCreateFontCursor(e->dpy, XC_left_ptr); chand = XCreateFontCursor(e->dpy, XC_fleur); cwatch = XCreateFontCursor(e->dpy, XC_watch); if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black", &col, &col) == 0) { die("could not allocate color: black"); } none = XCreateBitmapFromData(e->dpy, win->xwin, none_data, 8, 8); cnone = XCreatePixmapCursor(e->dpy, none, none, &col, &col, 0, 0); gc = XCreateGC(e->dpy, win->xwin, 0, None); win_set_title(win, "sxiv"); classhint.res_class = "Sxiv"; classhint.res_name = options->res_name != NULL ? options->res_name : "sxiv"; XSetClassHint(e->dpy, win->xwin, &classhint); XSetWMProtocols(e->dpy, win->xwin, &wm_delete_win, 1); win->h -= win->bar.h; win_update_sizehints(win); XMapWindow(e->dpy, win->xwin); XFlush(e->dpy); if (options->fullscreen) win_toggle_fullscreen(win); }
void *WindowThreadFunc(void *userdata){ tWindow *p = (tWindow*)userdata; int screen, startx, starty; unsigned long win_mask; XSetWindowAttributes win_attrib; XSizeHints sizehints; Display* ptemp; /* should probably pass these from main.. */ char **argv=NULL; int argc=0; if(vb)printf("ThreadFunc\n"); if ((p->display = XOpenDisplay(NULL)) == NULL) { fprintf(stderr, "warning: can't XOpenDisplay %s\n",XDisplayName(NULL)); return NULL; } if (vb) printf("XDisplay:%p\n",(void*)p->display); screen = DefaultScreen(p->display); startx = 10; starty = 20; win_mask = CWBackPixel | CWBorderPixel; win_attrib.border_pixel =WhitePixel(p->display,screen); win_attrib.background_pixel =WhitePixel(p->display,screen); /* BlackPixel */ win_attrib.override_redirect = 0; if(vb)printf("creating XWindow..\n"); p->window = XCreateWindow( p->display, DefaultRootWindow(p->display), startx,starty, p->width, p->height, 0, /* borderwidth */ DefaultDepth(p->display,screen), InputOutput, CopyFromParent, win_mask, &win_attrib ); /* tell the window manager NOT to quit on delete window - we will handle it */ /* if this doesn't go here, but later, then valgrind doesn't like it */ p->atom_delwin_proto = XInternAtom (p->display, "WM_PROTOCOLS",False); p->atom_delwin = XInternAtom (p->display, "WM_DELETE_WINDOW", False); XSetWMProtocols (p->display, p->window, &p->atom_delwin_proto, 1); XSetWMProtocols (p->display, p->window, &p->atom_delwin, 1); if(vb)printf("created X window:%p\n",(void*)p->window); sizehints.flags = PSize | PMinSize; /* let windowmanager decide - PPosition */ /* sizehints.x=0;sizehints.y=0; */ sizehints.height = p->height; sizehints.width = p->width; sizehints.min_height = sizehints.height; sizehints.min_width = sizehints.width; if (vb) printf("setting properties..\n"); XSetStandardProperties( p->display, p->window, p->name, "", None, /* icon name and pixmap */ argv, argc, &sizehints); /* GC gc = XCreateGC(p->display,p->window,0,NULL); */ XMapRaised(p->display, p->window); /* visible and on top - else XMapWindow */ XSelectInput(p->display, p->window, ExposureMask | KeyPressMask | DestroyNotify | StructureNotifyMask | PointerMotionMask | /* PointerMotionHintMask | */ ButtonPressMask | ButtonReleaseMask ); /* ClientMessage always reported */ /* _init_display(p, p->width,p->height); */ p->valid=1; /* = True; */ /* lock and unlock pthread->init mutex - this ensures that calling thread is in pthread_wait before we send continue condition back */ /* ( because condition_wait unlocks it) */ mutex_lock(&p->thread_init_mutex); mutex_unlock(&p->thread_init_mutex); if(vb)printf("X11:init condition send:%p\n", (void*)&p->thread_init_cond); condition_send(&p->thread_init_cond); while (1) { if (XPending(p->display)>0) if(handle_events(p->display, p )==False) break; usleep(100); }; mutex_lock(&p->mutex); p->valid=0; /* global lock should be made when querying or change any windows valid state. */ XSetCloseDownMode(p->display, DestroyAll); ptemp = p->display; p->display=NULL; XCloseDisplay(ptemp); /* after X close */ if(vb)printf("X11:freeing cairo surface\n"); /* _clean_display(p); */ mutex_unlock(&p->mutex); if(vb)printf("X11:window thread quit\n"); return NULL; }
int geCreateMainWindow(const char* title, int Width, int Height, int flags){ initializing = true; XInitThreads(); LibGE_LinuxContext* context = (LibGE_LinuxContext*)geMalloc(sizeof(LibGE_LinuxContext)); libge_context->syscontext = (unsigned long)context; win_hints = XAllocWMHints(); win_size_hints = XAllocSizeHints(); libge_context->width = Width; libge_context->height = Height; context->fs = flags & GE_WINDOW_FULLSCREEN; int nSamples = 1; if(flags & GE_WINDOW_MSAA2X){ nSamples = 2; } if(flags & GE_WINDOW_MSAA4X){ nSamples = 4; } if(flags & GE_WINDOW_MSAA8X){ nSamples = 8; } Colormap cmap; Window winDummy; unsigned int borderDummy; context->dpy = XOpenDisplay(0); context->screen = DefaultScreen(context->dpy); // get an appropriate visual context->vi = glXChooseVisual(context->dpy, context->screen, attributes); context->doubleBuffered = True; // create a color map cmap = XCreateColormap(context->dpy, RootWindow(context->dpy, context->vi->screen), context->vi->visual, AllocNone); context->attr.colormap = cmap; context->attr.border_pixel = 0; context->attr.background_pixmap = None; win_size_hints->flags = PSize; if(!(flags & GE_WINDOW_RESIZABLE)){ win_size_hints->flags = PSize | PMinSize | PMaxSize; win_size_hints->min_width = libge_context->width; win_size_hints->min_height = libge_context->height; win_size_hints->max_width = libge_context->width; win_size_hints->max_height = libge_context->height; win_size_hints->base_width = libge_context->width; win_size_hints->base_height = libge_context->height; } XWindowAttributes attribs; XGetWindowAttributes(context->dpy, RootWindow(context->dpy, context->vi->screen), &attribs); if(Width < 0){ libge_context->width = attribs.width; } if(Height < 0){ libge_context->height = attribs.height; } context->attr.override_redirect = false; context->attr.event_mask = event_mask; context->win = XCreateWindow(context->dpy, RootWindow(context->dpy, context->vi->screen), 0, 0, libge_context->width, libge_context->height, 0, context->vi->depth, InputOutput, context->vi->visual, CWBorderPixel | CWBackPixmap | CWColormap | CWEventMask | CWOverrideRedirect, &context->attr); XSetStandardProperties(context->dpy, context->win, title, title, None, NULL, 0, NULL); XMapRaised(context->dpy, context->win); if(context->fs){ Atom wm_fullscreen = XInternAtom(context->dpy, "_NET_WM_STATE_FULLSCREEN", true); XChangeProperty(context->dpy, context->win, XInternAtom(context->dpy, "_NET_WM_STATE", true), XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_fullscreen, 1); } // create a GLX context context->ctx = glXCreateContext(context->dpy, context->vi, 0, true); Atom wmDelete = XInternAtom(context->dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(context->dpy, context->win, &wmDelete, 1); Pixmap bm_no; XColor black; static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; bm_no = XCreateBitmapFromData(context->dpy, context->win, bm_no_data, 8, 8); invisible_cursor = XCreatePixmapCursor(context->dpy, bm_no, bm_no, &black, &black, 0, 0); if (bm_no!=None)XFreePixmap(context->dpy, bm_no); XSetWMNormalHints(context->dpy, context->win, win_size_hints); XSetWMHints(context->dpy, context->win, win_hints); XSelectInput(context->dpy, context->win, event_mask); // connect the glx-context to the window glXMakeCurrent(context->dpy, context->win, context->ctx); XGetGeometry(context->dpy, context->win, &winDummy, &context->x, &context->y, (u32*)&libge_context->width, (u32*)&libge_context->height, &borderDummy, (u32*)&context->depth); gePrintDebug(0x100, "X11 Window: %dx%d depth:%d Direct rendering: %s\n", libge_context->width, libge_context->height, context->depth, glXIsDirect(context->dpy, context->ctx)?"yes":"no"); LinuxInit(); geWaitVsync(true); gePrintDebug(0x100, "Current OpenGL version: %s\n", (const char*)glGetString(GL_VERSION)); geInitVideo(); geInitShaders(); geGraphicsInit(); geDrawingMode(GE_DRAWING_MODE_2D); atexit(_ge_exit); initializing = false; return 0; }
// function create GUI window bool StWindowImpl::create() { myKeysState.reset(); // replace default XError handler to ignore some errors XSetErrorHandler(stXErrorHandler); myInitState = STWIN_INITNOTSTART; // X-server implementation // create window on unix systems throw X-server int dummy; // open a connection to the X server StXDisplayH stXDisplay = new StXDisplay(); if(!stXDisplay->isOpened()) { stXDisplay.nullify(); stError("X, could not open display"); myInitState = STWIN_ERROR_X_OPENDISPLAY; return false; } myMaster.stXDisplay = stXDisplay; Display* hDisplay = stXDisplay->hDisplay; #if defined(ST_HAVE_EGL) myMaster.hRC = new StWinGlrc(eglGetDisplay(hDisplay), attribs.IsGlDebug, attribs.GlDepthSize); if(!myMaster.hRC->isValid()) { myMaster.close(); mySlave.close(); myInitState = STWIN_ERROR_X_GLRC_CREATE; return false; } XVisualInfo aVisInfo; aVisInfo.visualid = 0; if (eglGetConfigAttrib(myMaster.hRC->getDisplay(), myMaster.hRC->getConfig(), EGL_NATIVE_VISUAL_ID, (EGLint* )&aVisInfo.visualid) != EGL_TRUE) { myMaster.close(); mySlave.close(); myInitState = STWIN_ERROR_X_GLRC_CREATE; return false; } int aNbVisuals = 0; stXDisplay->hVisInfo = XGetVisualInfo(hDisplay, VisualIDMask, &aVisInfo, &aNbVisuals); #else // GLX // make sure OpenGL's GLX extension supported if(!glXQueryExtension(hDisplay, &dummy, &dummy)) { myMaster.close(); stError("X, server has no OpenGL GLX extension"); myInitState = STWIN_ERROR_X_NOGLX; return false; } int anAttribsBuff[] = { GLX_STEREO, attribs.IsGlStereo ? True : False, GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 0, GLX_DEPTH_SIZE, attribs.GlDepthSize, GLX_STENCIL_SIZE, 0, GLX_DOUBLEBUFFER, True, //GLX_SAMPLE_BUFFERS, 1, //GLX_SAMPLES, 4, None }; // FBConfigs were added in GLX version 1.3 int aGlxMajor = 0; int aGlxMinor = 0; const bool hasFBCfg = glXQueryVersion(hDisplay, &aGlxMajor, &aGlxMinor) && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1)); int aFBCount = 0; GLXFBConfig* aFBCfgList = NULL; if(hasFBCfg) { aFBCfgList = glXChooseFBConfig(hDisplay, DefaultScreen(hDisplay), anAttribsBuff, &aFBCount); } if(aFBCfgList == NULL && hasFBCfg && attribs.IsGlStereo) { ST_ERROR_LOG("X, no Quad Buffered visual"); anAttribsBuff[1] = False; aFBCfgList = glXChooseFBConfig(hDisplay, DefaultScreen(hDisplay), anAttribsBuff, &aFBCount); } if(aFBCfgList != NULL && aFBCount >= 1) { stXDisplay->FBCfg = aFBCfgList[0]; stXDisplay->hVisInfo = glXGetVisualFromFBConfig(hDisplay, stXDisplay->FBCfg); } else { // try to use glXChooseVisual... pointless? int aDblBuff[] = { GLX_RGBA, GLX_DEPTH_SIZE, attribs.GlDepthSize, GLX_DOUBLEBUFFER, None }; if(attribs.IsGlStereo) { // find an appropriate visual int aQuadBuff[] = { GLX_RGBA, GLX_DEPTH_SIZE, attribs.GlDepthSize, GLX_DOUBLEBUFFER, GLX_STEREO, None }; stXDisplay->hVisInfo = glXChooseVisual(hDisplay, DefaultScreen(hDisplay), aQuadBuff); if(stXDisplay->hVisInfo == NULL) { ST_ERROR_LOG("X, no Quad Buffered visual"); stXDisplay->hVisInfo = glXChooseVisual(hDisplay, DefaultScreen(hDisplay), aDblBuff); if(stXDisplay->hVisInfo == NULL) { myMaster.close(); stError("X, no RGB visual with depth buffer"); myInitState = STWIN_ERROR_X_NORGB; return false; } } } else { // find an appropriate visual // find an OpenGL-capable RGB visual with depth buffer stXDisplay->hVisInfo = glXChooseVisual(hDisplay, DefaultScreen(hDisplay), aDblBuff); if(stXDisplay->hVisInfo == NULL) { myMaster.close(); stError("X, no RGB visual with depth buffer"); myInitState = STWIN_ERROR_X_NORGB; return false; } } } XFree(aFBCfgList); #endif if(attribs.Slave != StWinSlave_slaveOff) { // just copy handle mySlave.stXDisplay = stXDisplay; } // create an X window with the selected visual XSetWindowAttributes aWinAttribsX = createDefaultAttribs(stXDisplay); updateChildRect(); Window aParentWin = (Window )myParentWin; if(aParentWin == 0 && !attribs.IsNoDecor) { aWinAttribsX.override_redirect = False; myMaster.hWindow = XCreateWindow(hDisplay, stXDisplay->getRootWindow(), myRectNorm.left(), myRectNorm.top(), myRectNorm.width(), myRectNorm.height(), 0, stXDisplay->getDepth(), InputOutput, stXDisplay->getVisual(), CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttribsX); if(myMaster.hWindow == 0) { myMaster.close(); stError("X, XCreateWindow failed for Master"); myInitState = STWIN_ERROR_X_CREATEWIN; return false; } aParentWin = myMaster.hWindow; XSetStandardProperties(hDisplay, myMaster.hWindow, myWindowTitle.toCString(), myWindowTitle.toCString(), None, NULL, 0, NULL); // setup WM_CLASS in sync with .desktop StartupWMClass entity // to ensure Window Manager would show an propriate icon for application XClassHint* aClassHint = XAllocClassHint(); if(aClassHint != NULL) { StString aName = StProcess::getProcessName(); StString aClass("sView"); // const_cast should be harmless here and it seems to be just broken signature of XClassHint structure aClassHint->res_name = const_cast<char* >(aName.toCString()); aClassHint->res_class = const_cast<char* >(aClass.toCString()); XSetClassHint(hDisplay, myMaster.hWindow, aClassHint); XFree(aClassHint); } } aWinAttribsX.override_redirect = True; // GL window always undecorated myMaster.hWindowGl = XCreateWindow(hDisplay, (aParentWin != 0) ? aParentWin : stXDisplay->getRootWindow(), 0, 0, myRectNorm.width(), myRectNorm.height(), 0, stXDisplay->getDepth(), InputOutput, stXDisplay->getVisual(), CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttribsX); if(myMaster.hWindowGl == 0) { myMaster.close(); stError("X, XCreateWindow failed for Master"); myInitState = STWIN_ERROR_X_CREATEWIN; return false; } XSetStandardProperties(hDisplay, myMaster.hWindowGl, "master window", "master window", None, NULL, 0, NULL); if(attribs.Slave != StWinSlave_slaveOff) { aWinAttribsX.event_mask = NoEventMask; // we do not parse any events to slave window! aWinAttribsX.override_redirect = True; // slave window always undecorated mySlave.hWindowGl = XCreateWindow(hDisplay, stXDisplay->getRootWindow(), getSlaveLeft(), getSlaveTop(), getSlaveWidth(), getSlaveHeight(), 0, stXDisplay->getDepth(), InputOutput, stXDisplay->getVisual(), CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttribsX); if(mySlave.hWindowGl == 0) { myMaster.close(); mySlave.close(); stError("X, XCreateWindow failed for Slave"); myInitState = STWIN_ERROR_X_CREATEWIN; return false; } XSetStandardProperties(hDisplay, mySlave.hWindowGl, "slave window", "slave window", None, NULL, 0, NULL); } int isGlCtx = myMaster.glCreateContext(attribs.Slave != StWinSlave_slaveOff ? &mySlave : NULL, myRectNorm, attribs.GlDepthSize, attribs.IsGlStereo, attribs.IsGlDebug); if(isGlCtx != STWIN_INIT_SUCCESS) { myMaster.close(); mySlave.close(); myInitState = isGlCtx; return false; } myGlContext = new StGLContext(myResMgr); if(!myGlContext->stglInit()) { myMaster.close(); mySlave.close(); stError("Critical error - broken GL context!\nInvalid OpenGL driver?"); myInitState = STWIN_ERROR_X_GLRC_CREATE; return false; } // handle close window event if(myMaster.hWindow != 0) { XSetWMProtocols(hDisplay, myMaster.hWindow, &(stXDisplay->wndDestroyAtom), 1); } // Announce XDND support myMaster.setupXDND(); // Initialize XRandr events reception if(XRRQueryExtension(hDisplay, &myMaster.xrandrEventBase, &dummy)) { XRRSelectInput(hDisplay, stXDisplay->getRootWindow(), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputPropertyNotifyMask); myMaster.isRecXRandrEvents = true; } else { myMaster.isRecXRandrEvents = false; } // request the X window to be displayed on the screen if(attribs.Slave != StWinSlave_slaveOff) { // request the X window to be displayed on the screen if(!attribs.IsSlaveHidden && (!isSlaveIndependent() || myMonitors.size() > 1)) { XMapWindow(hDisplay, mySlave.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )mySlave.hWindowGl); } // always hise mouse cursor on slave window mySlave.setupNoCursor(); } if(!attribs.IsHidden) { if(myMaster.hWindow != 0) { XMapWindow(hDisplay, myMaster.hWindow); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )myMaster.hWindow); } XMapWindow(hDisplay, myMaster.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )myMaster.hWindowGl); } // setup default icon if((Window )myParentWin == 0) { XpmCreatePixmapFromData(hDisplay, myMaster.hWindow, (char** )sview_xpm, &myMaster.iconImage, &myMaster.iconShape, NULL); XWMHints anIconHints; anIconHints.flags = IconPixmapHint | IconMaskHint; anIconHints.icon_pixmap = myMaster.iconImage; anIconHints.icon_mask = myMaster.iconShape; XSetWMHints(hDisplay, myMaster.hWindow, &anIconHints); } // we need this call to go around bugs if(!attribs.IsFullScreen && myMaster.hWindow != 0) { XMoveResizeWindow(hDisplay, myMaster.hWindow, myRectNorm.left(), myRectNorm.top(), myRectNorm.width(), myRectNorm.height()); } // flushes the output buffer, most client apps needn't use this cause buffer is automatically flushed as needed by calls to XNextEvent()... XFlush(hDisplay); myMonitors.registerUpdater(true); myIsUpdated = true; myInitState = STWIN_INIT_SUCCESS; return true; }
int main(int argc, char const *argv[]) { Display *display; Window window; int screen; display = XOpenDisplay(0); if (display == 0) { fprintf(stderr, "Cannot open display\n"); return 1; } screen = DefaultScreen(display); u32 border_color = WhitePixel(display, screen); u32 bg_color = BlackPixel(display, screen); window = XCreateSimpleWindow(display, RootWindow(display, screen), 300, 300, kWindowWidth * SCREEN_ZOOM, kWindowHeight * SCREEN_ZOOM, 0, border_color, bg_color); XSetStandardProperties(display, window, "6502 virtual machine", "Hi!", None, NULL, 0, NULL); XSelectInput(display, window, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | StructureNotifyMask); XMapRaised(display, window); Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, window, &wmDeleteMessage, 1); GC gc; XGCValues gcvalues; // Create x image { for (;;) { XEvent e; XNextEvent(display, &e); if (e.type == MapNotify) break; } gXImage = XGetImage(display, window, 0, 0, kWindowWidth * SCREEN_ZOOM, kWindowHeight * SCREEN_ZOOM, AllPlanes, ZPixmap); gLinuxBitmapMemory = (void *)gXImage->data; gc = XCreateGC(display, window, 0, &gcvalues); } // Init VM memory gMachineMemory = malloc(kMachineMemorySize); gVideoMemory = (u8 *)gMachineMemory + 0x0200; // Load the program at $D400 LoadProgram("test/pong.s", 0xD400); gRunning = true; // Run the machine pthread_t thread_id; if (pthread_create(&thread_id, 0, &machine_thread, 0) != 0) { fprintf(stderr, "Cannot create thread\n"); return 1; } while (gRunning) { // Process events while (XPending(display)) { XEvent event; XNextEvent(display, &event); // Close window message if (event.type == ClientMessage) { if (event.xclient.data.l[0] == wmDeleteMessage) { gRunning = false; } } } // Copy data from the machine's video memory to our "display" // and stretch pixels for (int y = 0; y < kWindowHeight; y++) { for (int x = 0; x < kWindowWidth; x++) { u8 *src_pixel = gVideoMemory + kWindowWidth * y + x; u32 *dest_pixel = (u32 *)gLinuxBitmapMemory + (kWindowWidth * SCREEN_ZOOM * y + x) * SCREEN_ZOOM; u32 color = GetColor(*src_pixel); for (int py = 0; py < SCREEN_ZOOM; py++) { for (int px = 0; px < SCREEN_ZOOM; px++) { *(dest_pixel + py * kWindowWidth * SCREEN_ZOOM + px) = color; } } } } XPutImage(display, window, gc, gXImage, 0, 0, 0, 0, kWindowWidth * SCREEN_ZOOM, kWindowHeight * SCREEN_ZOOM); } XCloseDisplay(display); return 0; }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; unsigned long mask; unsigned int current_DisplayMode = fgState.DisplayMode ; /* Save the display mode if we are creating a menu window */ if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; window->Window.VisualInfo = fgChooseVisual( ); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; if( ! window->Window.VisualInfo ) { /* * The "fgChooseVisual" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode &= ~GLUT_DOUBLE; } /* * GLUT also checks for multi-sampling, but I don't see that * anywhere else in FREEGLUT so I won't bother with it for the moment. */ } FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL, "Visual with necessary capabilities not found", "fgOpenWindow" ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.Display, fgDisplay.RootWindow, window->Window.VisualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu || ( gameMode == GL_TRUE ) ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } window->Window.Handle = XCreateWindow( fgDisplay.Display, window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, window->Window.VisualInfo->depth, InputOutput, window->Window.VisualInfo->visual, mask, &winAttr ); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateContext( fgDisplay.Display, fgStructure.MenuContext->VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } /* window->Window.Context = fgStructure.MenuContext->Context; */ window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else if( fgState.UseCurrentContext ) { window->Window.Context = glXGetCurrentContext( ); if( ! window->Window.Context ) window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); #if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) if( !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", title ); } #endif /* * XXX Assume the new window is visible by default * XXX Is this a safe assumption? */ window->State.Visible = GL_TRUE; sizeHints.flags = 0; if ( fgState.Position.Use ) sizeHints.flags |= USPosition; if ( fgState.Size.Use ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolete, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XFree( textProperty.value ); XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); XMapWindow( fgDisplay.Display, window->Window.Handle ); #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE WNDCLASS wc; DWORD flags; DWORD exFlags = 0; ATOM atom; /* Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found", "fgOpenWindow" ); if( gameMode ) { FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL, "Game mode being invoked on a subwindow", "fgOpenWindow" ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { #if !TARGET_HOST_WINCE if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* * Update the window dimensions, taking account of window * decorations. "freeglut" is to create the window with the * outside of its border at (x,y) and with dimensions (w,h). */ w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } #endif /* TARGET_HOST_WINCE */ if( ! fgState.Position.Use ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( ! fgState.Size.Use ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } /* * There's a small difference between creating the top, child and * game mode windows */ flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if !TARGET_HOST_WINCE else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif else flags |= WS_CHILD; } #if TARGET_HOST_WINCE { wchar_t* wstr = fghWstrFromStr(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowExA( exFlags, "FREEGLUT", title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.Instance, (LPVOID) window ); #endif /* TARGET_HOST_WINCE */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if TARGET_HOST_WINCE ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ #endif fgSetWindow( window ); window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0; if ( ! window->Window.DoubleBuffered ) { glDrawBuffer ( GL_FRONT ); glReadBuffer ( GL_FRONT ); } }