ControllerSlotConfigPtr ControllerSlotConfig::create(UInput& uinput, int slot, bool extra_devices, const ControllerSlotOptions& opts) { ControllerSlotConfigPtr m_config(new ControllerSlotConfig); for(ControllerSlotOptions::Options::const_iterator i = opts.get_options().begin(); i != opts.get_options().end(); ++i) { const ControllerOptions& ctrl_opt = i->second; ControllerConfigPtr config(new ControllerConfig(uinput, slot, extra_devices, ctrl_opt)); create_modifier(ctrl_opt, &config->get_modifier()); m_config->add_config(config); #ifdef FIXME // introspection of the config std::cout << "==[[ Active Modifier ]]==" << std::endl; for(std::vector<ModifierPtr>::iterator mod = config->get_modifier().begin(); mod != config->get_modifier().end(); ++mod) { std::cout << (*mod)->str() << std::endl; } #endif } // LED //ioctl(fd, UI_SET_EVBIT, EV_LED); //ioctl(fd, UI_SET_LEDBIT, LED_MISC); if (opts.get_force_feedback()) { // FF_GAIN - relative strength of rumble // FF_RUMBLE - basic rumble (delay, time) // FF_CONSTANT - envelope, emulate with rumble // FF_RAMP - same as constant, except strength grows // FF_PERIODIC - envelope // |- FF_SINE types of periodic effects // |- FF_TRIANGLE // |- FF_SQUARE // |- FF_SAW_UP // |- FF_SAW_DOWN // '- FF_CUSTOM // FIXME: this should go through the regular resolution process uint32_t ff_device = UInput::create_device_id(slot, opts.get_ff_device()); // basic types uinput.add_ff(ff_device, FF_RUMBLE); uinput.add_ff(ff_device, FF_PERIODIC); uinput.add_ff(ff_device, FF_CONSTANT); uinput.add_ff(ff_device, FF_RAMP); // periodic effect subtypes uinput.add_ff(ff_device, FF_SINE); uinput.add_ff(ff_device, FF_TRIANGLE); uinput.add_ff(ff_device, FF_SQUARE); uinput.add_ff(ff_device, FF_SAW_UP); uinput.add_ff(ff_device, FF_SAW_DOWN); uinput.add_ff(ff_device, FF_CUSTOM); // gin support uinput.add_ff(ff_device, FF_GAIN); // Unsupported effects // uinput.add_ff(ff_device, FF_SPRING); // uinput.add_ff(ff_device, FF_FRICTION); // uinput.add_ff(ff_device, FF_DAMPER); // uinput.add_ff(ff_device, FF_INERTIA); uinput.set_ff_callback(ff_device, boost::bind(&ControllerSlotConfig::set_rumble, m_config.get(), _1, _2)); } return m_config; }
MainWin * mainwin_create(Display *dpy, dlist *config) { const char *tmp; XColor screen_color, exact_color; XSetWindowAttributes wattr; XWindowAttributes rootattr; unsigned long valuemask = CWEventMask; #ifdef XINERAMA int event_base, error_base; #endif /* XINERAMA */ MainWin *mw = (MainWin *)malloc(sizeof(MainWin)); mw->screen = DefaultScreen(dpy); mw->visual = imlib_get_best_visual(dpy, mw->screen, &mw->depth); mw->colormap = DefaultColormap(dpy, mw->screen); mw->root = RootWindow(dpy, mw->screen); mw->background = 0; mw->bg_pixmap = None; #ifdef XINERAMA mw->xin_info = mw->xin_active = 0; mw->xin_screens = 0; #endif /* XINERAMA */ mw->x = mw->y = 0; mw->no_free_color = 0; mw->pressed = mw->focus = 0; mw->tooltip = 0; mw->cod = 0; mw->cm_normal = mw->cm_highlight = 0; mw->key_up = XKeysymToKeycode(dpy, XK_Up); mw->key_down = XKeysymToKeycode(dpy, XK_Down); mw->key_left = XKeysymToKeycode(dpy, XK_Left); mw->key_right = XKeysymToKeycode(dpy, XK_Right); mw->key_enter = XKeysymToKeycode(dpy, XK_Return); mw->key_space = XKeysymToKeycode(dpy, XK_space); mw->key_escape = XKeysymToKeycode(dpy, XK_Escape); mw->key_q = XKeysymToKeycode(dpy, XK_q); XGetWindowAttributes(dpy, mw->root, &rootattr); mw->width = rootattr.width; mw->height = rootattr.height; mw->dpy = dpy; valuemask |= CWBackPixel; wattr.background_pixel = BlackPixel(dpy, mw->screen); wattr.event_mask = VisibilityChangeMask | ButtonReleaseMask; mw->window = XCreateWindow(dpy, mw->root, 0, 0, mw->width, mw->height, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &wattr); if(mw->window == None) { free(mw); return 0; } #ifdef XINERAMA # ifdef DEBUG fprintf(stderr, "--> checking for Xinerama extension... "); # endif /* DEBUG */ if(XineramaQueryExtension(dpy, &event_base, &error_base)) { # ifdef DEBUG fprintf(stderr, "yes\n--> checking if Xinerama is enabled... "); # endif /* DEBUG */ if(XineramaIsActive(dpy)) { # ifdef DEBUG fprintf(stderr, "yes\n--> fetching Xinerama info... "); # endif /* DEBUG */ mw->xin_info = XineramaQueryScreens(mw->dpy, &mw->xin_screens); # ifdef DEBUG fprintf(stderr, "done (%i screens)\n", mw->xin_screens); # endif /* DEBUG */ } # ifdef DEBUG else fprintf(stderr, "no\n"); # endif /* DEBUG */ } # ifdef DEBUG else fprintf(stderr, "no\n"); # endif /* DEBUG */ #endif /* XINERAMA */ tmp = config_get(config, "normal", "border", "black"); if(! XAllocNamedColor(mw->dpy, mw->colormap, tmp, &screen_color, &exact_color)) { fprintf(stderr, "WARNING: Invalid color '%s', reverting to black.\n", tmp); BORDER_COLOR(mw) = BlackPixel(mw->dpy, mw->screen); mw->no_free_color = 1; } else BORDER_COLOR(mw) = screen_color.pixel; tmp = config_get(config, "highlight", "border", "#d0d0ff"); if(! XAllocNamedColor(mw->dpy, mw->colormap, tmp, &screen_color, &exact_color)) { fprintf(stderr, "WARNING: Invalid color '%s', reverting to white.\n", tmp); HIGHLIGHT_COLOR(mw) = WhitePixel(mw->dpy, mw->screen); mw->no_free_color |= 2; } else HIGHLIGHT_COLOR(mw) = screen_color.pixel; tmp = config_get(config, "general", "distance", "50"); DISTANCE(mw) = MAX(1, strtol(tmp, 0, 10)); if(! strcasecmp(config_get(config, "tooltip", "show", "true"), "true")) mw->tooltip = tooltip_create(mw, config); mw->cm_normal = create_modifier(mw, config, "normal", "0.0", "white", "200"); mw->cm_highlight = create_modifier(mw, config, "highlight", "0.05", "#d0d0ff", "255"); return mw; }