Exemple #1
0
// Creates the event addon
void* FcitxTabletCreate(FcitxInstance* instance) {
	FcitxTablet* tablet = fcitx_utils_new(FcitxTablet);
	FcitxTabletLoadConfig(&tablet->config);
	// TODO select driver from config, currently using lxbi

	{ // Initialise the driver
		switch(tablet->config.Driver) {
		case DRIVER_LXBI:
			tablet->driverInstance = &lxbi;
		break;
		// add other drivers here
		}
		tablet->driverData = tablet->driverInstance->Create();
		tablet->driverPacket = (char*) malloc(tablet->driverInstance->packet_size);
	}

	{ // Initialise the X display
		if(NULL == (tablet->xDisplay = FcitxX11GetDisplay(instance)))  {
			FcitxLog(ERROR, "Unable to open X display");
			return NULL;
		}
		// get dimensions
		int screen = DefaultScreen(tablet->xDisplay);
		tablet->xWidth = tablet->config.Width;
		tablet->xHeight = tablet->config.Height;
		int x = tablet->config.XPos > 0 ? tablet->config.XPos : XDisplayWidth(tablet->xDisplay, screen) - tablet->xWidth + tablet->config.XPos;
		int y = tablet->config.YPos > 0 ? tablet->config.YPos : XDisplayHeight(tablet->xDisplay, screen) - tablet->xHeight + tablet->config.YPos;
		// create colours
		XColor back;
		XColor fore;
		{
			char colourString[32];
			{
				int r = (255*tablet->config.BackgroundColour.r);
				int g = (255*tablet->config.BackgroundColour.g);
				int b = (255*tablet->config.BackgroundColour.b);
				sprintf(colourString,"rgb:%x/%x/%x",r,g,b);
			}
			Colormap defaultCMap = DefaultColormap(tablet->xDisplay, screen);
			XParseColor(tablet->xDisplay, defaultCMap, colourString, &back);
			XAllocColor(tablet->xDisplay, defaultCMap, &back);
			{
				int r = (255*tablet->config.StrokeColour.r);
				int g = (255*tablet->config.StrokeColour.g);
				int b = (255*tablet->config.StrokeColour.b);
				sprintf(colourString,"rgb:%x/%x/%x",r,g,b);
			}
			XParseColor(tablet->xDisplay, defaultCMap, colourString, &fore);
			XAllocColor(tablet->xDisplay, defaultCMap, &fore);
		}
		// set window attributes and create window
		XSetWindowAttributes attrs;
		attrs.override_redirect = True;
		attrs.background_pixel = back.pixel;
		tablet->xWindow = XCreateWindow(tablet->xDisplay, DefaultRootWindow(tablet->xDisplay),
			 x, y, tablet->xWidth, tablet->xHeight, tablet->config.BorderWidth, CopyFromParent,
			 InputOutput, CopyFromParent, CWBackPixel | CWOverrideRedirect, &attrs);
		// set up the foreground line (stroke) style
		XGCValues gcv;
		gcv.function = GXcopy;
		gcv.subwindow_mode = IncludeInferiors;
		gcv.line_width = 3;
		gcv.cap_style = CapRound;
		gcv.join_style = JoinRound;
		tablet->xGC = XCreateGC(tablet->xDisplay, tablet->xWindow, GCFunction | GCSubwindowMode | GCLineWidth | GCCapStyle | GCJoinStyle, &gcv);
		XSetForeground(tablet->xDisplay, tablet->xGC, fore.pixel);
		// prevent the window from getting focus or input
		XRectangle rect = {0,0,0,0};
		XserverRegion region = XFixesCreateRegion(tablet->xDisplay,&rect, 1);
		XFixesSetWindowShapeRegion(tablet->xDisplay, tablet->xWindow, ShapeInput, 0, 0, region);
		XFixesDestroyRegion(tablet->xDisplay, region);
	}

	{ // Initialise the stroke buffer
		tablet->strokesBufferSize = 2048; // should be heaps. Will get automatically enlarged if required
		tablet->strokesBuffer = (pt_t*) malloc(sizeof(pt_t) * tablet->strokesBufferSize);
		tablet->strokesPtr = tablet->strokesBuffer;
	}

	{ // instantiate the engine
		switch(tablet->config.Engine) {
		case ENGINE_ZINNIA:
			tablet->engineInstance = &engZinnia;
			break;
		case ENGINE_FORK:
			tablet->engineInstance = &engFork;
			break;
		// add other engines here
		}
		tablet->engineData = tablet->engineInstance->Create(&tablet->config);
	}

	{ // set up the timerfd
		tablet->timeoutFd = timerfd_create(CLOCK_MONOTONIC, 0);
		tablet->delay.it_interval.tv_sec = 0;
		tablet->delay.it_interval.tv_nsec = 0;
		tablet->delay.it_value.tv_sec = tablet->config.CommitCharMs / 1000;
		tablet->delay.it_value.tv_nsec = (tablet->config.CommitCharMs % 1000) * 1000000;
		tablet->timeoutCommitPending = 0;
	}

	tablet->fcitx = instance;
	return tablet;
}
Exemple #2
0
void* XimCreate(FcitxInstance* instance, int frontendid)
{
    if (ximfrontend != NULL)
        return NULL;
    FcitxXimFrontend *xim = fcitx_utils_new(FcitxXimFrontend);
    if (xim == NULL)
        return NULL;

    ximfrontend = xim;

    char *imname = NULL;
    char *p;

    UT_array *addons = FcitxInstanceGetAddons(instance);
    FcitxAddon *ximaddon = FcitxAddonsGetAddonByName(addons, "fcitx-xim");
    xim->display = FcitxX11GetDisplay(instance);

    if (xim->display == NULL) {
        FcitxLog(FATAL, _("X11 not initialized"));
        free(xim);
        return NULL;
    }

    xim->iScreen = DefaultScreen(xim->display);
    xim->owner = instance;
    xim->frontendid = frontendid;
    xim->xim_window = XCreateWindow(xim->display, DefaultRootWindow(xim->display),
                                    0, 0, 1, 1, 0, 0, InputOnly,
                                    CopyFromParent, 0, NULL);
    if (!xim->xim_window) {
        FcitxLog(FATAL, _("Can't Create imWindow"));
        free(xim);
        return NULL;
    }

    if (!imname) {
        imname = getenv("XMODIFIERS");
        if (imname) {
            if (!strncmp(imname, "@im=", strlen("@im="))) {
                imname += 4;
            } else {
                FcitxLog(WARNING, _("XMODIFIERS Error."));
                imname = DEFAULT_IMNAME;
            }
        } else {
            FcitxLog(WARNING, _("Please set XMODIFIERS."));
            imname = DEFAULT_IMNAME;
        }
    }
    XimQueueInit(xim);

    if (GetXimConfigDesc() == NULL)
        xim->bUseOnTheSpotStyle = false;
    else {
        FcitxConfigFileDesc* configDesc = GetXimConfigDesc();

        FILE *fp;
        char *file;
        fp = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "r", &file);
        FcitxLog(DEBUG, "Load Config File %s", file);
        free(file);
        if (!fp) {
            if (errno == ENOENT) {
                char *file;
                FILE *fp2 = FcitxXDGGetFileUserWithPrefix("conf", "fcitx-xim.config", "w", &file);
                FcitxLog(DEBUG, "Save Config to %s", file);
                FcitxConfigSaveConfigFileFp(fp2, &xim->gconfig, configDesc);
                free(file);
                if (fp2)
                    fclose(fp2);
            }
        }

        FcitxConfigFile *cfile = FcitxConfigParseConfigFileFp(fp, configDesc);

        FcitxXimFrontendConfigBind(xim, cfile, configDesc);
        FcitxConfigBindSync((FcitxGenericConfig*)xim);

        if (fp)
            fclose(fp);
    }

    XIMStyles input_styles;
    if (xim->bUseOnTheSpotStyle) {
        input_styles.count_styles =
            sizeof(OnTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles.supported_styles = OnTheSpot_Styles;
    } else {
        input_styles.count_styles =
            sizeof(OverTheSpot_Styles) / sizeof(XIMStyle) - 1;
        input_styles.supported_styles = OverTheSpot_Styles;
    }

    XIMEncodings encodings = {
        .count_encodings = sizeof(zhEncodings) / sizeof(XIMEncoding) - 1,
        .supported_encodings = zhEncodings
    };

    p = getenv("LC_CTYPE");
    if (!p) {
        p = getenv("LC_ALL");
        if (!p)
            p = getenv("LANG");
    }
    if (p) {
        int p_l = strlen(p);
        if (strlen(LOCALES_STRING) + p_l + 1 < LOCALES_BUFSIZE) {
            strLocale[strlen(LOCALES_STRING)] = ',';
            memcpy(strLocale + strlen(LOCALES_STRING) + 1, p, p_l + 1);
        }
    }

    xim->ims = IMOpenIM(xim->display,
                        IMModifiers, "Xi18n",
                        IMServerWindow, xim->xim_window,
                        IMServerName, imname,
                        IMLocale, strLocale,
                        IMServerTransport, "X/",
                        IMInputStyles, &input_styles,
                        IMEncodingList, &encodings,
                        IMProtocolHandler, XimProtocolHandler,
                        IMFilterEventMask, KeyPressMask | KeyReleaseMask,
                        NULL);

    if (xim->ims == (XIMS) NULL) {
        FcitxLog(ERROR, _("Start XIM error. Another XIM daemon named %s is running?"), imname);
        XimDestroy(xim);
        FcitxInstanceEnd(instance);
        return NULL;
    }

    FcitxModuleAddFunction(ximaddon, XimConsumeQueue);

    return xim;
}

Bool XimProtocolHandler(XIMS _ims, IMProtocol * call_data)
{
    switch (call_data->major_code) {
    case XIM_OPEN:
        FcitxLog(DEBUG, "XIM_OPEN:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_CLOSE:
        FcitxLog(DEBUG, "XIM_CLOSE:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_CREATE_IC:
        FcitxLog(DEBUG, "XIM_CREATE_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_DESTROY_IC:
        FcitxLog(DEBUG, "XIM_DESTROY_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_SET_IC_VALUES:
        FcitxLog(DEBUG, "XIM_SET_IC_VALUES:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_GET_IC_VALUES:
        FcitxLog(DEBUG, "XIM_GET_IC_VALUES:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_FORWARD_EVENT:
        FcitxLog(DEBUG, "XIM_FORWARD_EVENT:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_SET_IC_FOCUS:
        FcitxLog(DEBUG, "XIM_SET_IC_FOCUS:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_UNSET_IC_FOCUS:
        FcitxLog(DEBUG, "XIM_UNSET_IC_FOCUS:\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_RESET_IC:
        FcitxLog(DEBUG, "XIM_RESET_IC:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    case XIM_TRIGGER_NOTIFY:
        FcitxLog(DEBUG, "XIM_TRIGGER_NOTIFY:\t\ticid=%d\tconnect_id=%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id);
        break;
    default:
        FcitxLog(DEBUG, "XIM_DEFAULT:\t\ticid=%d\tconnect_id=%d\t%d", ((IMForwardEventStruct *) call_data)->icid,
                 ((IMForwardEventStruct *) call_data)->connect_id, call_data->major_code);
        break;
    }

    switch (call_data->major_code) {
    case XIM_OPEN:
        return XIMOpenHandler(ximfrontend, (IMOpenStruct *) call_data);
    case XIM_CLOSE:
        return XIMCloseHandler(ximfrontend, (IMOpenStruct *) call_data);
    case XIM_CREATE_IC:
        return XIMCreateICHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_DESTROY_IC:
        return XIMDestroyICHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_SET_IC_VALUES:
        return XIMSetICValuesHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_GET_IC_VALUES:
        return XIMGetICValuesHandler(ximfrontend, (IMChangeICStruct *) call_data);
    case XIM_FORWARD_EVENT:
        XIMProcessKey(ximfrontend, (IMForwardEventStruct *) call_data);
        return True;
    case XIM_SET_IC_FOCUS:
        return XIMSetFocusHandler(ximfrontend, (IMChangeFocusStruct *) call_data);
    case XIM_UNSET_IC_FOCUS:
        return XIMUnsetFocusHandler(ximfrontend, (IMChangeICStruct *) call_data);;
    case XIM_RESET_IC:
        return True;
    case XIM_PREEDIT_START_REPLY:
        return 0;
    case XIM_PREEDIT_CARET_REPLY:
        return 0;
    case XIM_SYNC_REPLY:
        return 0;
    default:
        return True;
    }
}

boolean XimDestroy(void* arg)
{
    FcitxXimFrontend* xim = (FcitxXimFrontend*) arg;
    /**
     * Destroy the window BEFORE(!!!!!) CloseIM!!!
     * Work arround for a bug in libX11. See wengxt's commit log:
     * f773dd4f7152a4b4b7f406fe01bff466e0de3dc2
     * [xim, x11] correctly shutdown xim, destroy x11 with error handling
     **/
    if (xim->xim_window) {
        XDestroyWindow(xim->display, xim->xim_window);
    }
    if (xim->ims) {
        IMCloseIM(xim->ims);
        xim->ims = NULL;
    }
    XimQueueDestroy(xim);
    free(xim);
    return true;
}
Exemple #3
0
void* ClassicUICreate(FcitxInstance* instance)
{
    FcitxAddon* classicuiaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_CLASSIC_UI_NAME);
    FcitxClassicUI* classicui = fcitx_utils_malloc0(sizeof(FcitxClassicUI));
    classicui->owner = instance;
    if (!LoadClassicUIConfig(classicui)) {
        free(classicui);
        return NULL;
    }
    if (GetSkinDesc() == NULL) {
        free(classicui);
        return NULL;
    }
    classicui->dpy = FcitxX11GetDisplay(instance);
    if (classicui->dpy == NULL) {
        free(classicui);
        return NULL;
    }

    FcitxX11GetDPI(instance, &classicui->dpi, NULL);
    if (classicui->dpi <= 0)
        classicui->dpi = 96;

    if (LoadSkinConfig(&classicui->skin, &classicui->skinType)) {
        free(classicui);
        return NULL;
    }

    classicui->isfallback = FcitxUIIsFallback(instance, classicuiaddon);

    classicui->iScreen = DefaultScreen(classicui->dpy);

    classicui->protocolAtom = XInternAtom(classicui->dpy, "WM_PROTOCOLS", False);
    classicui->killAtom = XInternAtom(classicui->dpy, "WM_DELETE_WINDOW", False);


    InitSkinMenu(classicui);
    FcitxUIRegisterMenu(instance, &classicui->skinMenu);
    /* Main Menu Initial */
    FcitxMenuInit(&classicui->mainMenu);
    classicui->mainMenu.UpdateMenu = UpdateMainMenu;
    classicui->mainMenu.MenuAction = MainMenuAction;
    classicui->mainMenu.priv = classicui;
    classicui->mainMenu.mark = -1;


    classicui->inputWindow = CreateInputWindow(classicui);
    classicui->mainWindow = CreateMainWindow(classicui);
    classicui->trayWindow = CreateTrayWindow(classicui);
    classicui->messageWindow = CreateMessageWindow(classicui);
    classicui->mainMenuWindow = CreateMainMenuWindow(classicui);

    FcitxIMEventHook resethk;
    resethk.arg = classicui;
    resethk.func = ClassicUIInputReset;
    FcitxInstanceRegisterResetInputHook(instance, resethk);

    DisplaySkin(classicui, classicui->skinType);

    /* ensure order ! */
    FcitxModuleAddFunction(classicuiaddon, ClassicUILoadImage);
    FcitxModuleAddFunction(classicuiaddon, ClassicUIGetKeyBoardFontColor);
    FcitxModuleAddFunction(classicuiaddon, ClassicUIGetFont);

    return classicui;
}