📄 3ddeskd.cpp
字号:
cfg->options->recalc = 0; } // reload face set if different number of columns or rows if (col_count != faces->get_number_of_columns() || row_count != faces->get_number_of_rows() ) { msgout (DEBUG, "++++ column_count changed from %d to %d\n", faces->get_number_of_columns(), col_count); face_set->reconfigure(row_count, col_count); set_arrangement (cfg->options->default_z_offset_distance); } done = 1; break; default: msgout (ERROR, "Unknown message! mytpe = %d\n", msgmgr.msg.mtype); break; } } while (!done); state = STATE_NORMAL; msgout (DEBUG, "Activated\n"); return goto_coords;}#if 0static voididle_func (void){ static int count = 0; // context every 30 calls if (++count >= 30) { msgout (DEBUG, "a;lskdjf;asldfjasldkjf\n"); context_switch(); count = 0; } render_scene(); }#endif#if 1static void idle_func(void){ // This prevents the scene from being rendered more then 1000 // times a second ie 1000fps -- by limiting it like this we sneak // in some context switches so the CPU usage isn't through the // roof. long start = get_milli_time(); if ( (start - last_renderscene_time) >= 1 ) { //msgout (DEBUG, "diff = %lu\n", start - last_renderscene_time); render_scene(); } else { //sleep_ms(1); // allow context switch context_switch(); }} // END idle_func#endifstatic int main_loop(void){ XEvent event; KeySym key; Bool quit = False; desktop_coords_t goto_coords; desktop_coords_t current_count; desktop_coords_t current_coords; while(!quit) { goto_coords.column = NO_GOTO; goto_coords.column = NO_GOTO; goto_on_flag = 0; goto_coords = wait_for_activation(); current_coords.column = faces->get_current_column(); current_coords.row = faces->get_current_row(); current_count.column = faces->get_number_of_columns(); current_count.row = faces->get_number_of_rows(); #ifndef SCAN_MODE if (do_screenshot) { if (GLWin.grab_screenshot_data() < 0) { msgout (ERROR, "couldn't grab screen image\n"); end_program(-1); } face_set->load_texture_data(current_coords.column + (current_coords.row * current_count.column), cfg->texture_size, GLWin.get_screenshot_data_ptr() ); faces->make_display_list(); }#endif GLWin.unhide_GL_window(); initiate_destroy = 0; if (goto_coords.column != NO_GOTO || goto_coords.row != NO_GOTO) { setup_goto_face(goto_coords, current_coords, current_count); } state = STATE_ENTRY; em.trigger_event (ENTRY_MOVEMENT_START); end_X_event_loop = False; // finally this is so the "fun" behavior doesn't start right away last_keypress = get_milli_time(); // wait for events while (!end_X_event_loop) { // handle the events in the queue while (XPending(GLWin.get_display()) > 0) { XNextEvent(GLWin.get_display(), &event); switch (event.type) { case Expose: if (event.xexpose.count != 0) break; render_scene(); break; case ConfigureNotify: // call resizeGLScene only if our window-size changed if (((unsigned int)event.xconfigure.width != GLWin.get_width()) || ((unsigned int)event.xconfigure.height != GLWin.get_height())) { GLWin.resize_scene(event.xconfigure.width, event.xconfigure.height); } break; // exit in case of a mouse button press case ButtonPress: mouse_pressed (event.xbutton.button); break; case KeyPress: key = XLookupKeysym(&event.xkey, 0); key_pressed (key); break; case ClientMessage: if (*XGetAtomName(GLWin.get_display(), event.xclient.message_type) == *"WM_PROTOCOLS") { msgout(INFO, "Exiting sanely...\n"); end_X_event_loop = True; quit = True; } break; default: break; } } if (cfg->options->use_context_switch) idle_func(); else render_scene(); } GLWin.hide_GL_window(); } return 0;} // END main_loopstatic voidgl_init (void){ // Color to clear color buffer to. glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Depth to clear depth buffer to; type of test. glClearDepth(1.0); glDepthFunc(GL_LESS); // Enables Smooth Color Shading; try GL_FLAT for (lack of) fun. glShadeModel(GL_SMOOTH); glLoadIdentity(); // A handy trick -- have surface material mirror the color. //glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); //glEnable(GL_COLOR_MATERIAL); //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); float ones[] = { 1.0, 1.0, 1.0, 1.0 }; //float halfs[] = { .50, .50, .50, .50 }; glMaterialfv(GL_FRONT, GL_DIFFUSE, ones); glMaterialfv(GL_FRONT, GL_SPECULAR, ones); glMaterialf(GL_FRONT, GL_SHININESS, 100.0);#if 0 float spot_direction[] = { 0.0, 0.0, -1.0 }; glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction); glLighti(GL_LIGHT1, GL_SPOT_EXPONENT, 30); glLighti(GL_LIGHT1, GL_SPOT_CUTOFF, 180);#endif if (cfg->options->use_breathing) breathing.init(&ambient_value, 1.7, 3.0, 200, Movement::MOVE_TYPE_SINE); else light_ambient2[0] = light_ambient2[1] = light_ambient2[2] = 2.0;} // END gl_initstatic void load_digits(void) { char filename[100]; unsigned char *data; unsigned int sizex, sizey; extern Config *cfg; // load digits for screens we don't have yet // allocate space for texture data = new unsigned char [256 * 256 * 4]; if (data == NULL) { msgout(ERROR, "Error allocating space for image"); end_program(0); } // try loading /usr/share/3ddesktop/digits.bmp // /usr/local/share/3ddesktop/digits.bmp // ~/.3ddesktop/digits.bmp // ./digits.bmp sprintf (filename, "%s/digits.bmp", cfg->options->base_dir); if (!load_image(filename, data, &sizex, &sizey, 1)) { sprintf (filename, SHAREDIR "/digits.bmp"); if (!load_image(filename, data, &sizex, &sizey, 1)) { sprintf (filename, "%s/digits.bmp", cfg->working_dir); if (!load_image(filename, data, &sizex, &sizey, 1)) { sprintf (filename, "./digits.bmp"); if (!load_image(filename, data, &sizex, &sizey, 1)) { msgout (DEBUG, "no digits.bmp found\n"); cfg->options->show_digits = 0; return ; } } } } // Create Texture glGenTextures(1, &digit_texture ); glBindTexture(GL_TEXTURE_2D, digit_texture ); // 2d texture (x and y size) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, MIN_FILTER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, MAX_FILTER); // 2d texture, 3 components (red, green, blue), x size from image, y size from image, // rgb color data, unsigned byte data, and finally the data itself. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sizex, sizey, GL_RGBA, GL_UNSIGNED_BYTE, data); //glTexImage2D(GL_TEXTURE_2D, 0, 3, sizex, sizey, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); delete data;} // END load_digits// accesses global cfgstatic voidinitialize_3ddesktop (void){ // creates ~/.3ddesktop or /tmp/.3ddesktop-user if not alread there // used for pid file but no longer the screenshot //cfg->create_working_dir_if_necessary (); // there is a race between here and marking that I am running // but it should be small. We must separate these because the // semaphore ownership is not inherited if we daemonize. if (check_if_i_am_running()) { msgout (ERROR, "3ddesktop is already running. bye\n"); exit (1); } if (vdesks.init (cfg) < 0) { msgout (ERROR, "Failed to initialize display.\n"); exit(1); } int current_row = 0, current_col = 0; int row_count = 0, col_count = 0; vdesks.get_vdesktop_info (¤t_col, ¤t_row, &col_count, &row_count);#if 0 if ((row_count * col_count) > MAX_FACES) { msgout (ERROR, "Can't support this many virtual desktops (%d), MAX is %d.\n", row_count * col_count, MAX_FACES); end_program (1); }#endif#if 0 if (row_count <= 1 && col_count <= 1) { msgout (ERROR, "You only have %d x %d virtual desktop(s)! Need at least 2 to\n" "switch between them...\n", col_count, row_count); end_program (1); }#endif // the actual acquire is done below but the message must be here, // before we daemonize if (cfg->options->acquire) msgout(INFO, "\n" "================================================================\n" "3ddesktop will be acquiring images in one moment. Please wait...\n" "================================================================\n\n"); // become a daemon if (!cfg->verbose) { openlog ("3ddeskd", LOG_CONS, LOG_DAEMON); if (daemon_init() < 0) { msgout(ERROR, "Failed to daemonize.\n"); end_program(-1); } cfg->options->daemonized = 1; } struct sigaction sa; sigset_t mask; sigemptyset (&mask); memset (&sa, 0, sizeof (struct sigaction)); sa.sa_mask = mask; sa.sa_handler = end_program; sigaction (SIGTERM, &sa, NULL); sigaction (SIGINT, &sa, NULL); sigaction (SIGQUIT, &sa, NULL); // open the messaging mechanism (message queue) we will listen on if (msgmgr.open(MessageManager::CREATE) < 0) { msgout(ERROR, "Could not create message queue! %s\n", strerror(errno)); end_program(-1); } if (flag_that_i_am_running()) { // (if we've daemonized this goes to syslog which is not easily seen) msgout(ERROR, "Oops, someone beat us to start up!! Amazing!\n"); end_program(-1); } if (cfg->make_pidfile() < 0) end_program(-1); // initialize opengl // our own init function. gl_init(); GLWin.open_display(); GLWin.create_GL_window("Enhanced 3-dimensional workspace visualization magic machine", cfg->options->do_fullscreen); cfg->texture_size = GLWin.get_best_texture_size(cfg->texture_size); // Loads up the correct perspective matrix GLWin.resize_scene(); GLWin.hide_GL_window(); // this must be here after opengl is initialized since the FaceSet // constructor loads the digit textures. face_set = new FaceSet(row_count, col_count); // never deleted if (face_set == NULL) { msgout (ERROR, "Out of memory: face_set\n"); end_program(-1); } last_time = get_milli_time(); initialize_arrangements(); set_arrangement(cfg->options->default_z_offset_distance); // loop through desktops and capture their images... if (cfg->options->acquire) { sleep(1); int i, j; for (i = 0; i < row_count; i++) { for (j = 0; j < col_count; j++) { vdesks.set_vdesktop (j, i); if (cfg->options->acquire > 1) sleep_ms (cfg->options->acquire); if (GLWin.grab_screenshot_data() < 0) { msgout (ERROR, "couldn't grab screen image\n"); end_program(-1); } face_set->load_texture_data(j + (i * col_count), cfg->texture_size, GLWin.get_screenshot_data_ptr() ); } } // go back to current vdesks.set_vdesktop (current_col, current_row); } load_digits(); em.add_event (ENTRY_MOVEMENT_START, entry_move_start_hook, NULL, 1); em.add_event (EXIT_MOVEMENT_START, exit_move_start_hook, NULL, 1); } // END initialize_3ddesktopint main(int argc,char **argv){ cfg = new Config(); // deleted in end_program() if (!cfg) { msgout (ERROR, "new Config: out of memory\n"); end_program(-1); } cfg->init (argc, argv); cfg->load_conf(); initialize_3ddesktop(); return main_loop();} // END main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -